X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/waydroid.git/blobdiff_plain/3e6872c0fd97dd5463d07315548187ad16a1eda1..HEAD:/tools/services/user_manager.py diff --git a/tools/services/user_manager.py b/tools/services/user_manager.py index 83a50cc..802472b 100644 --- a/tools/services/user_manager.py +++ b/tools/services/user_manager.py @@ -1,5 +1,6 @@ # Copyright 2021 Erfan Abdi # SPDX-License-Identifier: GPL-3.0-or-later +import glob import logging import os import threading @@ -7,6 +8,7 @@ import tools.config import tools.helpers.net from tools.interfaces import IUserMonitor from tools.interfaces import IPlatform +from gi.repository import GLib stopping = False @@ -14,65 +16,124 @@ def start(args, session, unlocked_cb=None): waydroid_data = session["waydroid_data"] apps_dir = session["xdg_data_home"] + "/applications/" - def makeDesktopFile(appInfo): + system_apps = [ + "com.android.calculator2", + "com.android.camera2", + "com.android.contacts", + "com.android.deskclock", + "com.android.documentsui", + "com.android.email", + "com.android.gallery3d", + "com.android.inputmethod.latin", + "com.android.settings", + "com.google.android.gms", + "org.lineageos.aperture", + "org.lineageos.eleven", + "org.lineageos.etar", + "org.lineageos.jelly", + "org.lineageos.recorder" + ] + + + def prepend_list(old_list, new_list): + for s in reversed(new_list): + if s not in old_list: + old_list.insert(0, s) + + def glib_key_file_get_string_list(key_file, group, key): + try: + return key_file.get_string_list(group, key) + except: + return [] + + def glib_key_file_prepend_string_list(key_file, group, key, new_list): + old_list = glib_key_file_get_string_list(key_file, group, key) + prepend_list(old_list, new_list) + key_file.set_string_list(group, key, new_list) + + def glib_key_file_has_value(key_file, group, key): + try: + key_file.get_value(group, key) + return True + except: + return False + + + # Creates, deletes, or updates desktop file + def updateDesktopFile(appInfo): if appInfo is None: - return -1 + return showApp = False for cat in appInfo["categories"]: if cat.strip() == "android.intent.category.LAUNCHER": showApp = True if not showApp: - return -1 + try: + os.remove(desktop_file_path) + except: + pass packageName = appInfo["packageName"] desktop_file_path = apps_dir + "/waydroid." + packageName + ".desktop" - if not os.path.exists(desktop_file_path): - with open(desktop_file_path, "w") as desktop_file: - desktop_file.write(f"""\ -[Desktop Entry] -Type=Application -Name={appInfo["name"]} -Exec=waydroid app launch {packageName} -Icon={waydroid_data}/icons/{packageName}.png -Categories=X-WayDroid-App; -X-Purism-FormFactor=Workstation;Mobile; -Actions=app_settings; - -[Desktop Action app_settings] -Name=App Settings -Exec=waydroid app intent android.settings.APPLICATION_DETAILS_SETTINGS package:{packageName} -Icon={waydroid_data}/icons/com.android.settings.png -""") - return 0 - - def makeWaydroidDesktopFile(hide): + desktop_file = GLib.KeyFile() + try: + flags = GLib.KeyFileFlags.KEEP_COMMENTS | GLib.KeyFileFlags.KEEP_TRANSLATIONS + desktop_file.load_from_file(desktop_file_path, flags) + except: + pass + + desktop_file.set_string("Desktop Entry", "Type", "Application") + desktop_file.set_string("Desktop Entry", "Name", appInfo["name"]) + desktop_file.set_string("Desktop Entry", "Exec", f"waydroid app launch {packageName}") + desktop_file.set_string("Desktop Entry", "Icon", f"{waydroid_data}/icons/{packageName}.png") + glib_key_file_prepend_string_list(desktop_file, "Desktop Entry", "Categories", ["X-WayDroid-App"]) + desktop_file.set_string_list("Desktop Entry", "X-Purism-FormFactor", ["Workstation", "Mobile"]) + glib_key_file_prepend_string_list(desktop_file, "Desktop Entry", "Actions", ["app_settings"]) + if packageName in system_apps and not glib_key_file_has_value(desktop_file, "Desktop Entry", "NoDisplay"): + desktop_file.set_boolean("Desktop Entry", "NoDisplay", True) + + desktop_file.set_string("Desktop Action app_settings", "Name", "App Settings") + desktop_file.set_string("Desktop Action app_settings", "Exec", f"waydroid app intent android.settings.APPLICATION_DETAILS_SETTINGS package:{packageName}") + desktop_file.set_string("Desktop Action app_settings", "Icon", f"{waydroid_data}/icons/com.android.settings.png") + + desktop_file.save_to_file(desktop_file_path) + + + def updateWaydroidDesktopFile(hide): desktop_file_path = apps_dir + "/Waydroid.desktop" # If the user has set the desktop file as read-only, we won't replace it - if not os.access(desktop_file_path, os.W_OK): + if os.path.isfile(desktop_file_path) and not os.access(desktop_file_path, os.W_OK): logging.info(f"Desktop file '{desktop_file_path}' is not writeable, not updating it") - else: - if os.path.isfile(desktop_file_path): - os.remove(desktop_file_path) - with open(desktop_file_path, "w") as desktop_file: - desktop_file.write(f"""\ -[Desktop Entry] -Type=Application -Name=Waydroid -Exec=waydroid show-full-ui -Categories=X-WayDroid-App; -X-Purism-FormFactor=Workstation;Mobile; -Icon=waydroid -NoDisplay={str(hide).lower()} -""") + return + + desktop_file = GLib.KeyFile() + try: + flags = GLib.KeyFileFlags.KEEP_COMMENTS | GLib.KeyFileFlags.KEEP_TRANSLATIONS + desktop_file.load_from_file(desktop_file_path, flags) + except: + pass + + desktop_file.set_string("Desktop Entry", "Type", "Application") + desktop_file.set_string("Desktop Entry", "Name", "Waydroid") + desktop_file.set_string("Desktop Entry", "Exec", "waydroid show-full-ui") + glib_key_file_prepend_string_list(desktop_file, "Desktop Entry", "Categories", ["X-WayDroid-App", "Utility"]) + desktop_file.set_string_list("Desktop Entry", "X-Purism-FormFactor", ["Workstation", "Mobile"]) + desktop_file.set_string("Desktop Entry", "Icon", "waydroid") + desktop_file.set_boolean("Desktop Entry", "NoDisplay", hide) + + desktop_file.save_to_file(desktop_file_path) def userUnlocked(uid): cfg = tools.config.load(args) logging.info("Android with user {} is ready".format(uid)) if cfg["waydroid"]["auto_adb"] == "True": - tools.helpers.net.adb_connect(args) + try: + tools.helpers.net.adb_connect(args) + except: + pass platformService = IPlatform.get_service(args) if platformService: @@ -80,27 +141,27 @@ NoDisplay={str(hide).lower()} os.mkdir(apps_dir, 0o700) appsList = platformService.getAppsInfo() for app in appsList: - makeDesktopFile(app) + updateDesktopFile(app) + for existing in glob.iglob(f'{apps_dir}/waydroid.*.desktop'): + if os.path.basename(existing) not in map(lambda appInfo: f"waydroid.{appInfo['packageName']}.desktop", appsList): + os.remove(existing) multiwin = platformService.getprop("persist.waydroid.multi_windows", "false") - makeWaydroidDesktopFile(multiwin == "true") + updateWaydroidDesktopFile(multiwin == "true") if unlocked_cb: unlocked_cb() def packageStateChanged(mode, packageName, uid): platformService = IPlatform.get_service(args) if platformService: - appInfo = platformService.getAppInfo(packageName) desktop_file_path = apps_dir + "/waydroid." + packageName + ".desktop" - if mode == 0: - # Package added - makeDesktopFile(appInfo) - elif mode == 1: - if os.path.isfile(desktop_file_path): + if mode == IUserMonitor.PACKAGE_REMOVED: + try: os.remove(desktop_file_path) + except: + pass else: - if os.path.isfile(desktop_file_path): - if makeDesktopFile(appInfo) == -1: - os.remove(desktop_file_path) + appInfo = platformService.getAppInfo(packageName) + updateDesktopFile(appInfo) def service_thread(): while not stopping: