diff --git a/core/src/main/java/org/lsposed/lspd/service/ActivityManagerService.java b/core/src/main/java/org/lsposed/lspd/service/ActivityManagerService.java index 6df6daa7..ba1f19e4 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ActivityManagerService.java +++ b/core/src/main/java/org/lsposed/lspd/service/ActivityManagerService.java @@ -25,6 +25,7 @@ import android.app.IActivityManager; import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.ProfilerInfo; +import android.content.IContentProvider; import android.content.IIntentReceiver; import android.content.Intent; import android.content.IntentFilter; @@ -163,4 +164,14 @@ public class ActivityManagerService { return am.getCurrentUser(); } + public static IContentProvider getContentProvider(String auth, int userId) throws RemoteException { + IActivityManager am = getActivityManager(); + if (am == null) return null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return am.getContentProviderExternal(auth, userId, token, null).provider; + } else { + return am.getContentProviderExternal(auth, userId, token).provider; + } + } + } diff --git a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java index c169df97..8d9a0aab 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java @@ -598,13 +598,13 @@ public class LSPManagerService extends ILSPManagerService.Stub { @Override public void setHiddenIcon(boolean hide) { - var settings = new ServiceShellCommand("settings"); - var enable = hide ? "0" : "1"; - var args = new String[]{"put", "global", "show_hidden_icon_apps_enabled", enable}; + Bundle args = new Bundle(); + args.putString("value", hide ? "0" : "1"); + args.putString("_user", "0"); try { - settings.shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err, - args, new ResultReceiver(null)); - } catch (RemoteException e) { + ActivityManagerService.getContentProvider("settings", 0) + .call("android", null, "settings", "PUT_global", "show_hidden_icon_apps_enabled", args); + } catch (RemoteException | NullPointerException e) { Log.w(TAG, "setHiddenIcon: ", e); } } diff --git a/core/src/main/java/org/lsposed/lspd/service/ServiceShellCommand.java b/core/src/main/java/org/lsposed/lspd/service/ServiceShellCommand.java deleted file mode 100644 index d85b5e84..00000000 --- a/core/src/main/java/org/lsposed/lspd/service/ServiceShellCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.lsposed.lspd.service; - -import android.os.IBinder; -import android.os.Parcel; -import android.os.RemoteException; -import android.os.ResultReceiver; - -import java.io.FileDescriptor; - -class ServiceShellCommand { - private static final int SHELL_COMMAND_TRANSACTION = ('_' << 24) | ('C' << 16) | ('M' << 8) | 'D'; - private final IBinder binder; - - ServiceShellCommand(String name) { - binder = android.os.ServiceManager.getService(name); - } - - void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, - String[] args, ResultReceiver resultReceiver) throws RemoteException { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeFileDescriptor(in); - data.writeFileDescriptor(out); - data.writeFileDescriptor(err); - data.writeStringArray(args); - data.writeStrongBinder(null); - resultReceiver.writeToParcel(data, 0); - try { - binder.transact(SHELL_COMMAND_TRANSACTION, data, reply, 0); - reply.readException(); - } finally { - data.recycle(); - reply.recycle(); - } - } -} diff --git a/core/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java b/core/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java index a5dcb462..e641ad93 100644 --- a/core/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java +++ b/core/src/main/java/org/lsposed/lspd/util/ParasiticManagerHooker.java @@ -95,7 +95,9 @@ public class ParasiticManagerHooker { "android.app.ActivityThread$AppBindData", managerApkHooker); - XposedBridge.hookAllConstructors(ActivityThread.ActivityClientRecord.class, activityHooker); + + var activityClientRecordClass = XposedHelpers.findClass("android.app.ActivityThread$ActivityClientRecord", ActivityThread.class.getClassLoader()); + XposedBridge.hookAllConstructors(activityClientRecordClass, activityHooker); var unhooks = new XC_MethodHook.Unhook[]{null}; unhooks[0] = XposedHelpers.findAndHookMethod( @@ -124,6 +126,7 @@ public class ParasiticManagerHooker { }); XposedBridge.hookAllMethods(ActivityThread.class, "installProvider", new XC_MethodHook() { private Context originalContext = null; + @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { Hookers.logD("before install provider"); @@ -152,7 +155,7 @@ public class ParasiticManagerHooker { } }); - XposedHelpers.findAndHookMethod(ActivityThread.class, "deliverNewIntents", ActivityThread.ActivityClientRecord.class, List.class, new XC_MethodHook() { + XposedHelpers.findAndHookMethod(ActivityThread.class, "deliverNewIntents", activityClientRecordClass, List.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) { if (param.args[1] == null) return; diff --git a/hiddenapi-stubs/src/main/java/android/app/ContentProviderHolder.java b/hiddenapi-stubs/src/main/java/android/app/ContentProviderHolder.java new file mode 100644 index 00000000..9b390bd3 --- /dev/null +++ b/hiddenapi-stubs/src/main/java/android/app/ContentProviderHolder.java @@ -0,0 +1,7 @@ +package android.app; + +import android.content.IContentProvider; + +public class ContentProviderHolder { + public IContentProvider provider; +} diff --git a/hiddenapi-stubs/src/main/java/android/app/IActivityManager.java b/hiddenapi-stubs/src/main/java/android/app/IActivityManager.java index ea757376..e72b1a23 100644 --- a/hiddenapi-stubs/src/main/java/android/app/IActivityManager.java +++ b/hiddenapi-stubs/src/main/java/android/app/IActivityManager.java @@ -97,6 +97,13 @@ public interface IActivityManager extends IInterface { void setActivityController(IActivityController watcher, boolean imAMonkey) throws RemoteException; + @RequiresApi(29) + ContentProviderHolder getContentProviderExternal(String name, int userId, + IBinder token, String tag); + + ContentProviderHolder getContentProviderExternal(String name, int userId, + IBinder token); + abstract class Stub extends Binder implements IActivityManager { public static int TRANSACTION_setActivityController; diff --git a/hiddenapi-stubs/src/main/java/android/content/IContentProvider.java b/hiddenapi-stubs/src/main/java/android/content/IContentProvider.java new file mode 100644 index 00000000..f1a7061a --- /dev/null +++ b/hiddenapi-stubs/src/main/java/android/content/IContentProvider.java @@ -0,0 +1,11 @@ +package android.content; + +import android.os.Bundle; +import android.os.IInterface; +import android.os.RemoteException; + +public interface IContentProvider extends IInterface { + Bundle call(String callingPkg, String attributionTag, String authority, + String method, String arg, Bundle extras) throws RemoteException; + +}