From 85a4d4eea16d40b755da06490c38cd351457c92e Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 19 May 2021 00:45:22 +0800 Subject: [PATCH] [core] A better way to launch daemon (#622) --- core/magisk_module/post-fs-data.sh | 10 +----- core/magisk_module/service.sh | 13 ++------ .../main/java/org/lsposed/lspd/core/Main.java | 11 +++---- .../lsposed/lspd/service/ConfigManager.java | 31 +++++++++++++++++++ .../lsposed/lspd/service/ServiceManager.java | 14 ++++++++- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/core/magisk_module/post-fs-data.sh b/core/magisk_module/post-fs-data.sh index c10c787d..0899dd01 100644 --- a/core/magisk_module/post-fs-data.sh +++ b/core/magisk_module/post-fs-data.sh @@ -135,12 +135,4 @@ if [ ! -z "${MISC_PATH}" ]; then start_log_catcher all "LSPosed:V XSharedPreferences:V LSPosed-Bridge:V LSPosedManager:V LSPosedService:V *:F" true ${LOG_VERBOSE} fi -start_app_process() { - while true; do - if [ -S "/dev/socket/zygote" ]; then - nohup /system/bin/app_process -Djava.class.path=$(magisk --path)/.magisk/modules/riru_lsposed/framework/lspd.dex /system/bin org.lsposed.lspd.core.Main --nice-name=lspd >/dev/null 2>&1 & echo $! > /data/adb/lspd/daemon.pid - return - fi - done -} -start_app_process & echo $! > /data/adb/lspd/daemon.pid +nohup /system/bin/app_process -Djava.class.path=$(magisk --path)/.magisk/modules/riru_lsposed/framework/lspd.dex /system/bin org.lsposed.lspd.core.Main --nice-name=lspd >/dev/null 2>&1 diff --git a/core/magisk_module/service.sh b/core/magisk_module/service.sh index 4182309d..14de1048 100644 --- a/core/magisk_module/service.sh +++ b/core/magisk_module/service.sh @@ -19,14 +19,5 @@ # Copyright (C) 2021 LSPosed Contributors # -CMDLINE="$(cat /proc/$(cat /data/adb/lspd/daemon.pid)/cmdline)" - -# if still waiting for zygote, cmdline should be like: -# $(magisk --path)/.magisk/busybox/busyboxsh/data/adb/modules/riru_lsposed/post-fs-data.sh -# if service started, cmdline should be lspd -# for other cases, post-fs-data.sh may not be executed properly -if [ "${CMDLINE##*riru_lsposed/}" != "post-fs-data.sh" ] && [ "${CMDLINE##*=}" != "lspd" ]; then - log -pw -t "LSPosedService" "Got $CMDLINE" - log -pw -t "LSPosedService" "LSPosed daemon is not started properly. Try for a late start..." - nohup /system/bin/app_process -Djava.class.path=$(magisk --path)/.magisk/modules/riru_lsposed/framework/lspd.dex /system/bin org.lsposed.lspd.core.Main --nice-name=lspd >/dev/null 2>&1 & echo $! > /data/adb/lspd/daemon.pid -fi +# post-fs-data.sh may be blocked by other modules. retry to start this +nohup /system/bin/app_process -Djava.class.path=$(magisk --path)/.magisk/modules/riru_lsposed/framework/lspd.dex /system/bin org.lsposed.lspd.core.Main --nice-name=lspd --from-service >/dev/null 2>&1 diff --git a/core/src/main/java/org/lsposed/lspd/core/Main.java b/core/src/main/java/org/lsposed/lspd/core/Main.java index 3e13cd16..74686f05 100644 --- a/core/src/main/java/org/lsposed/lspd/core/Main.java +++ b/core/src/main/java/org/lsposed/lspd/core/Main.java @@ -24,7 +24,6 @@ import android.annotation.SuppressLint; import android.app.ActivityThread; import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; -import android.ddm.DdmHandleAppName; import android.os.Environment; import android.os.IBinder; @@ -33,6 +32,7 @@ import java.io.File; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; + import org.lsposed.lspd.config.LSPApplicationServiceClient; import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter; import org.lsposed.lspd.hooker.HandleBindAppHooker; @@ -75,6 +75,7 @@ public class Main { SystemMainHooker.systemServerCL, "startBootstrapServices", paramTypesAndCallback); } + private static void installBootstrapHooks(boolean isSystem, String appDataDir) { // Initialize the Xposed framework try { @@ -92,6 +93,7 @@ public class Main { Utils.logE("error loading module list", exception); } } + private static void forkPostCommon(boolean isSystem, String appDataDir, String niceName) { // init logger YahfaHooker.init(); @@ -116,11 +118,6 @@ public class Main { } public static void main(String[] args) { - for (String arg : args) { - if (arg.equals("--debug")) { - DdmHandleAppName.setAppName("lspd", 0); - } - } - ServiceManager.start(); + ServiceManager.start(args); } } diff --git a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java index 68080af3..6378dc41 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java @@ -50,8 +50,12 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; import java.nio.file.Files; +import java.nio.file.OpenOption; import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.PosixFilePermissions; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -76,6 +80,7 @@ public class ConfigManager { private static final File basePath = new File("/data/adb/lspd"); private static final File configPath = new File(basePath, "config"); + private static final File lockPath = new File(basePath, "lock"); private static final SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(new File(configPath, "modules_config.db"), null); boolean packageStarted = false; @@ -97,6 +102,15 @@ public class ConfigManager { private static final File modulesLog = new File(logPath, "modules.log"); private static final File oldModulesLog = new File(logPath, "modules.old.log"); private static final File verboseLogPath = new File(logPath, "all.log"); + private static FileLock locker = null; + + static { + try { + Files.createDirectories(basePath.toPath()); + } catch (IOException e) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } private final Handler cacheHandler; @@ -165,6 +179,23 @@ public class ConfigManager { } } + public boolean tryLock() { + var openOptions = new HashSet(); + openOptions.add(StandardOpenOption.CREATE); + openOptions.add(StandardOpenOption.DELETE_ON_CLOSE); + openOptions.add(StandardOpenOption.WRITE); + var p = PosixFilePermissions.fromString("rw-------"); + var permissions = PosixFilePermissions.asFileAttribute(p); + + try { + var lockChannel = FileChannel.open(lockPath.toPath(), openOptions, permissions); + locker = lockChannel.tryLock(); + return locker != null && locker.isValid(); + } catch (Throwable e) { + return false; + } + } + // for system server, cache is not yet ready, we need to query database for it public boolean shouldSkipSystemServer() { if (!SELinux.checkSELinuxAccess("u:r:system_server:s0", "u:r:system_server:s0", "process", "execmem")) { diff --git a/core/src/main/java/org/lsposed/lspd/service/ServiceManager.java b/core/src/main/java/org/lsposed/lspd/service/ServiceManager.java index 68ed3ff7..1e0af5d1 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ServiceManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ServiceManager.java @@ -20,6 +20,7 @@ package org.lsposed.lspd.service; import android.content.Context; +import android.ddm.DdmHandleAppName; import android.os.IBinder; import android.os.IServiceManager; import android.os.Looper; @@ -55,7 +56,18 @@ public class ServiceManager { } // call by ourselves - public static void start() { + public static void start(String[] args) { + if (!ConfigManager.getInstance().tryLock()) return; + + android.os.Process.killProcess(android.system.Os.getppid()); + for (String arg : args) { + if (arg.equals("--debug")) { + DdmHandleAppName.setAppName("lspd", 0); + } + if (arg.equals("--from-service")) { + Log.w(TAG, "LSPosed daemon is not started properly. Try for a late start..."); + } + } Log.i(TAG, "starting server..."); Log.i(TAG, String.format("version %s (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_NAME));