import glob
import shutil
import platform
+import gbinder
import tools.config
import tools.helpers.run
make_entry("/dev/pvr_sync")
make_entry("/dev/pmsg0")
make_entry("/dev/dxg")
- make_entry("/dev/dri", options="bind,create=dir,optional 0 0")
+ make_entry(tools.helpers.gpu.getDriNode(args), "dev/dri/renderD128")
for n in glob.glob("/dev/fb*"):
make_entry(n)
make_entry("none", "dev/pts", "devpts", "defaults,mode=644,ptmxmode=666,create=dir 0 0", False)
make_entry("/dev/uhid")
+ # TUN/TAP device node for VPN
+ make_entry("/dev/net/tun", "dev/tun")
+
# Low memory killer sys node
make_entry("/sys/module/lowmemorykiller", options="bind,create=dir,optional 0 0")
make_entry("/dev/sw_sync")
make_entry("/sys/kernel/debug", options="rbind,create=dir,optional 0 0")
+ # Vibrator
+ make_entry("/sys/class/leds/vibrator",
+ options="bind,create=dir,optional 0 0")
+ make_entry("/sys/devices/virtual/timed_output/vibrator",
+ options="bind,create=dir,optional 0 0")
+
# Media dev nodes (for Mediatek)
make_entry("/dev/Vcodec")
make_entry("/dev/MTK_SMI")
make_entry("tmpfs", "var", "tmpfs", "nodev 0 0", False)
make_entry("/var/run", options="rbind,create=dir,optional 0 0")
+ # tmp
+ make_entry("tmpfs", "tmp", "tmpfs", "nodev 0 0", False)
+ for n in glob.glob("/tmp/run-*"):
+ make_entry(n, options="rbind,create=dir,optional 0 0")
+
+ # NFC config
+ make_entry("/system/etc/libnfc-nci.conf", options="bind,optional 0 0")
+
return nodes
def set_lxc_config(args):
lxc_path = tools.config.defaults["lxc"] + "/waydroid"
- config_file = "config_2"
lxc_ver = get_lxc_version(args)
if lxc_ver == 0:
raise OSError("LXC is not installed")
- elif lxc_ver <= 2:
- config_file = "config_1"
- config_path = tools.config.tools_src + "/data/configs/" + config_file
+ config_paths = tools.config.tools_src + "/data/configs/config_"
+ seccomp_profile = tools.config.tools_src + "/data/configs/waydroid.seccomp"
+ apparmor_profiles = [tools.config.tools_src + "/data/configs/" + "lxc-waydroid",tools.config.tools_src + "/data/configs/" + "android_app",tools.config.tools_src + "/data/configs/" + "adbd"]
+ apparmor_profile_dir = "/etc/apparmor.d/"
+
+ config_snippets = [ config_paths + "base" ]
+ # lxc v1 is a bit special because some options got renamed later
+ if lxc_ver == 1:
+ config_snippets.append(config_paths + "1")
+ else:
+ for ver in range(2, 5):
+ snippet = config_paths + str(ver)
+ if lxc_ver >= ver and os.path.exists(snippet):
+ config_snippets.append(snippet)
command = ["mkdir", "-p", lxc_path]
tools.helpers.run.user(args, command)
- command = ["cp", "-fpr", config_path, lxc_path + "/config"]
+ command = ["sh", "-c", "cat {} > \"{}\"".format(' '.join('"{0}"'.format(w) for w in config_snippets), lxc_path + "/config")]
tools.helpers.run.user(args, command)
command = ["sed", "-i", "s/LXCARCH/{}/".format(platform.machine()), lxc_path + "/config"]
tools.helpers.run.user(args, command)
+ command = ["cp", "-fpr", seccomp_profile, lxc_path + "/waydroid.seccomp"]
+ tools.helpers.run.user(args, command)
+
+ try:
+ command = ["cp", "-i", apparmor_profiles[0], apparmor_profile_dir + "lxc/lxc-waydroid"]
+ tools.helpers.run.user(args, command)
+ command = ["apparmor_parser", "-r", apparmor_profile_dir + "lxc/lxc-waydroid"]
+ tools.helpers.run.user(args, command)
+ command = ["cp", "-i", apparmor_profiles[1], apparmor_profile_dir + "android_app"]
+ tools.helpers.run.user(args, command)
+ command = ["apparmor_parser", "-r", apparmor_profile_dir + "android_app"]
+ tools.helpers.run.user(args, command)
+ command = ["cp", "-i", apparmor_profiles[2], apparmor_profile_dir + "adbd"]
+ tools.helpers.run.user(args, command)
+ command = ["apparmor_parser", "-r", apparmor_profile_dir + "adbd"]
+ tools.helpers.run.user(args, command)
+ except:
+ logging.warning("An error has occurred while installing AppArmor profiles. If profiles are not installed, or AppArmor is disabled or not supported on your system, then the container will run without AppArmor protection.")
nodes = generate_nodes_lxc_config(args)
config_nodes_tmp_path = args.work + "/config_nodes"
"ro.board.platform"]
for p in hardware_props:
prop = tools.helpers.props.host_get(args, p)
- hal_prop = ""
if prop != "":
- for lib in ["lib", "lib64"]:
- hal_file = "/vendor/" + lib + "/hw/" + hardware + "." + prop + ".so"
- command = ["readlink", "-f", hal_file]
- hal_file_path = tools.helpers.run.user(args, command, output_return=True).strip()
- if os.path.isfile(hal_file_path):
- hal_prop = re.sub(".*" + hardware + ".", "", hal_file_path)
- hal_prop = re.sub(".so", "", hal_prop)
- if hal_prop != "":
- return hal_prop
- if hal_prop != "":
- return hal_prop
+ for lib in ["/odm/lib", "/odm/lib64", "/vendor/lib", "/vendor/lib64", "/system/lib", "/system/lib64"]:
+ hal_file = lib + "/hw/" + hardware + "." + prop + ".so"
+ if os.path.isfile(hal_file):
+ return prop
return ""
+ def find_hidl(intf):
+ if args.vendor_type == "MAINLINE":
+ return False
+
+ try:
+ sm = gbinder.ServiceManager("/dev/hwbinder")
+ return intf in sm.list_sync()
+ except:
+ return False
+
props = []
+
+ if not os.path.exists("/dev/ashmem"):
+ props.append("sys.use_memfd=true")
+
egl = tools.helpers.props.host_get(args, "ro.hardware.egl")
+ dri = tools.helpers.gpu.getDriNode(args)
gralloc = find_hal("gralloc")
- if gralloc == "":
- if os.path.exists("/dev/dri"):
+ if not gralloc:
+ if find_hidl("android.hardware.graphics.allocator@4.0::IAllocator/default"):
+ gralloc = "android"
+ if not gralloc:
+ if dri:
gralloc = "gbm"
egl = "mesa"
else:
props.append("ro.vendor.extension_library=" + ext_library)
vulkan = find_hal("vulkan")
- if vulkan != "":
+ if not vulkan and dri:
+ vulkan = tools.helpers.gpu.getVulkanDriver(args, os.path.basename(dri))
+ if vulkan:
props.append("ro.hardware.vulkan=" + vulkan)
+ treble = tools.helpers.props.host_get(args, "ro.treble.enabled")
+ if treble != "true":
+ camera = find_hal("camera")
+ if camera != "":
+ props.append("ro.hardware.camera=" + camera)
+ else:
+ if args.vendor_type == "MAINLINE":
+ props.append("ro.hardware.camera=v4l2")
+
opengles = tools.helpers.props.host_get(args, "ro.opengles.version")
if opengles == "":
- opengles = "196608"
+ opengles = "196609"
props.append("ro.opengles.version=" + opengles)
- props.append("waydroid.system_ota=" + args.system_ota)
- props.append("waydroid.vendor_ota=" + args.vendor_ota)
+ if args.images_path not in tools.config.defaults["preinstalled_images_paths"]:
+ props.append("waydroid.system_ota=" + args.system_ota)
+ props.append("waydroid.vendor_ota=" + args.vendor_ota)
+ else:
+ props.append("waydroid.updater.disabled=true")
+
props.append("waydroid.tools_version=" + tools.config.version)
if args.vendor_type == "MAINLINE":
props.append("ro.vndk.lite=true")
+ for product in ["brand", "device", "manufacturer", "model", "name"]:
+ prop_product = tools.helpers.props.host_get(
+ args, "ro.product.vendor." + product)
+ if prop_product != "":
+ props.append("ro.product.waydroid." + product + "=" + prop_product)
+ else:
+ if os.path.isfile("/proc/device-tree/" + product):
+ with open("/proc/device-tree/" + product) as f:
+ f_value = f.read().strip().rstrip('\x00')
+ if f_value != "":
+ props.append("ro.product.waydroid." +
+ product + "=" + f_value)
+
+ prop_fp = tools.helpers.props.host_get(args, "ro.vendor.build.fingerprint")
+ if prop_fp != "":
+ props.append("ro.build.fingerprint=" + prop_fp)
+
+ # now append/override with values in [properties] section of waydroid.cfg
+ cfg = tools.config.load(args)
+ for k, v in cfg["properties"].items():
+ for idx, elem in enumerate(props):
+ if (k+"=") in elem:
+ props.pop(idx)
+ props.append(k+"="+v)
+
base_props = open(args.work + "/waydroid_base.prop", "w")
for prop in props:
base_props.write(prop + "\n")
def setup_host_perms(args):
+ if not os.path.exists(tools.config.defaults["host_perms"]):
+ os.mkdir(tools.config.defaults["host_perms"])
+
+ treble = tools.helpers.props.host_get(args, "ro.treble.enabled")
+ if treble != "true":
+ return
+
sku = tools.helpers.props.host_get(args, "ro.boot.product.hardware.sku")
copy_list = []
copy_list.extend(
copy_list.append(
"/odm/etc/permissions/sku_{}/android.hardware.consumerir.xml".format(sku))
- if not os.path.exists(tools.config.defaults["host_perms"]):
- os.mkdir(tools.config.defaults["host_perms"])
-
for filename in copy_list:
shutil.copy(filename, tools.config.defaults["host_perms"])
def status(args):
command = ["lxc-info", "-P", tools.config.defaults["lxc"], "-n", "waydroid", "-sH"]
- return subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
+ out = subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
+ os.chmod(args.log, 0o666)
+ return out
def start(args):
command = ["lxc-start", "-P", tools.config.defaults["lxc"],
command.append(args.COMMAND)
else:
command.append("/system/bin/sh")
- subprocess.run(command, env={"PATH": os.environ['PATH'] + "/system/bin:/vendor/bin"})
+ subprocess.run(command, env={"PATH": os.environ['PATH'] + ":/system/bin:/vendor/bin"})
def logcat(args):
if status(args) != "RUNNING":