diff --git a/app/build.gradle b/app/build.gradle index b66d3d8a..496875a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,5 +105,7 @@ dependencies { implementation 'androidx.webkit:webkit:1.10.0' implementation "com.github.topjohnwu.libsu:core:5.2.2" implementation "com.github.topjohnwu.libsu:service:5.2.2" + implementation "dev.rikka.shizuku:api:13.1.5" + implementation "dev.rikka.shizuku:provider:13.1.5" compileOnly project(path: ':app:hidden-api') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9ded9406..a047543d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,14 @@ + + diff --git a/app/src/main/java/xtr/keymapper/activity/MainActivity.java b/app/src/main/java/xtr/keymapper/activity/MainActivity.java index 9dd3daa8..96a91257 100644 --- a/app/src/main/java/xtr/keymapper/activity/MainActivity.java +++ b/app/src/main/java/xtr/keymapper/activity/MainActivity.java @@ -25,6 +25,7 @@ import xtr.keymapper.databinding.ActivityMainBinding; import xtr.keymapper.editor.EditorActivity; import xtr.keymapper.fragment.SettingsFragment; +import xtr.keymapper.keymap.KeymapConfig; import xtr.keymapper.server.RemoteServiceHelper; public class MainActivity extends AppCompatActivity { @@ -55,11 +56,13 @@ protected void onCreate(Bundle savedInstanceState) { intent = new Intent(context, TouchPointer.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); + RemoteServiceHelper.useShizuku = new KeymapConfig(context).useShizuku; + Shell.getShell(shell -> { Boolean rootAccess = Shell.isAppGrantedRoot(); if (rootAccess == null || !rootAccess) { Server.setupServer(this, mCallback); - alertRootAccessNotFound(); + if(!RemoteServiceHelper.useShizuku) alertRootAccessNotFound(); } setupButtons(); }); diff --git a/app/src/main/java/xtr/keymapper/fragment/SettingsFragment.java b/app/src/main/java/xtr/keymapper/fragment/SettingsFragment.java index e7deadc0..58690add 100644 --- a/app/src/main/java/xtr/keymapper/fragment/SettingsFragment.java +++ b/app/src/main/java/xtr/keymapper/fragment/SettingsFragment.java @@ -56,6 +56,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat binding.mouseAimKeyGrave.setChecked(keymapConfig.keyGraveMouseAim); binding.mouseAimRightClick.setChecked(keymapConfig.rightClickMouseAim); binding.autoProfileSwitch.setChecked(keymapConfig.disableAutoProfiling); + binding.useShizuku.setChecked(keymapConfig.useShizuku); loadKeyboardShortcuts(); binding.launchEditor.setOnKeyListener(this::onKey); @@ -197,6 +198,7 @@ public void onDestroyView() { keymapConfig.rightClickMouseAim = binding.mouseAimRightClick.isChecked(); keymapConfig.keyGraveMouseAim = binding.mouseAimKeyGrave.isChecked(); keymapConfig.disableAutoProfiling = binding.autoProfileSwitch.isChecked(); + keymapConfig.useShizuku = binding.useShizuku.isChecked(); keymapConfig.dpadRadiusMultiplier = binding.sliderDpad.getValue(); diff --git a/app/src/main/java/xtr/keymapper/keymap/KeymapConfig.java b/app/src/main/java/xtr/keymapper/keymap/KeymapConfig.java index 3f9c4df1..178d909f 100644 --- a/app/src/main/java/xtr/keymapper/keymap/KeymapConfig.java +++ b/app/src/main/java/xtr/keymapper/keymap/KeymapConfig.java @@ -14,7 +14,7 @@ public class KeymapConfig implements Parcelable { public Float mouseSensitivity, scrollSpeed; public Float dpadRadiusMultiplier; public boolean ctrlMouseWheelZoom, ctrlDragMouseGesture, rightClickMouseAim, keyGraveMouseAim; - public boolean disableAutoProfiling; + public boolean disableAutoProfiling , useShizuku; public int pauseResumeShortcutKey, launchEditorShortcutKey, switchProfileShortcutKey; public int swipeDelayMs; @@ -65,6 +65,7 @@ protected KeymapConfig(Parcel in) { mouseAimToggle = in.readByte() != 0; disableAutoProfiling = in.readByte() != 0; touchpadInputMode = in.readString(); + useShizuku = in.readByte() != 0; } public static final Creator CREATOR = new Creator<>() { @@ -86,6 +87,7 @@ private void loadSharedPrefs() { ctrlDragMouseGesture = sharedPref.getBoolean("ctrl_drag_mouse_gesture", true); mouseAimToggle = sharedPref.getBoolean("mouse_aim_shortcut_toggle", true); disableAutoProfiling = sharedPref.getBoolean("disable_auto_profile", true); + useShizuku = sharedPref.getBoolean("use_shizuku", false); launchEditorShortcutKey = sharedPref.getInt("launch_editor_shortcut", -1); pauseResumeShortcutKey = sharedPref.getInt("pause_resume_shortcut", -1); @@ -115,6 +117,7 @@ public void applySharedPrefs() { .putBoolean("right_click_mouse_aim", rightClickMouseAim) .putBoolean("mouse_aim_shortcut_toggle", mouseAimToggle) .putBoolean("disable_auto_profile", disableAutoProfiling) + .putBoolean("use_shizuku", useShizuku) .putInt("pause_resume_shortcut", pauseResumeShortcutKey) .putInt("launch_editor_shortcut", launchEditorShortcutKey) .putInt("switch_profile_shortcut", switchProfileShortcutKey) @@ -167,5 +170,6 @@ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeByte((byte) (mouseAimToggle ? 1 : 0)); dest.writeByte((byte) (disableAutoProfiling ? 1 : 0)); dest.writeString(touchpadInputMode); + dest.writeByte((byte) (useShizuku ? 1 : 0)); } } diff --git a/app/src/main/java/xtr/keymapper/server/RemoteService.java b/app/src/main/java/xtr/keymapper/server/RemoteService.java index 79281c38..66307dc7 100644 --- a/app/src/main/java/xtr/keymapper/server/RemoteService.java +++ b/app/src/main/java/xtr/keymapper/server/RemoteService.java @@ -1,5 +1,8 @@ package xtr.keymapper.server; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.RemoteException; import java.io.BufferedReader; @@ -21,6 +24,29 @@ public class RemoteService extends IRemoteService.Stub { private ActivityObserverService activityObserverService; String nativeLibraryDir = System.getProperty("java.library.path"); + public RemoteService() { + + } + + /* For Shizuku UserService */ + public RemoteService(Context context) { + loadLibraries(); + init(context); + } + + public RemoteService init(Context context) { + PackageManager pm = context.getPackageManager(); + String packageName = context.getPackageName(); + try { + ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + nativeLibraryDir = ai.nativeLibraryDir; + start_getevent(); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } + return this; + } + public static void loadLibraries() { System.loadLibrary("mouse_read"); System.loadLibrary("mouse_cursor"); diff --git a/app/src/main/java/xtr/keymapper/server/RemoteServiceHelper.java b/app/src/main/java/xtr/keymapper/server/RemoteServiceHelper.java index e500cf83..478434b0 100644 --- a/app/src/main/java/xtr/keymapper/server/RemoteServiceHelper.java +++ b/app/src/main/java/xtr/keymapper/server/RemoteServiceHelper.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -14,12 +15,14 @@ import java.io.IOException; +import rikka.shizuku.Shizuku; import xtr.keymapper.IRemoteService; public class RemoteServiceHelper { private static IRemoteService service = null; public static boolean isRootService = true; + public static boolean useShizuku = false; public static void pauseKeymap(Context context){ RemoteServiceHelper.getInstance(context, service -> { @@ -89,15 +92,30 @@ public static void getInstance(){ } } - public static void getInstance(Context context, RootRemoteServiceCallback cb){ + private static void bindShizukuService(Context context, RemoteServiceConnection connection) { + Shizuku.UserServiceArgs userServiceArgs = + new Shizuku.UserServiceArgs(new ComponentName(context, RemoteService.class.getName())) + .daemon(false) + .processNameSuffix("service") + .debuggable(false) + .version(11); + Shizuku.bindUserService(userServiceArgs, connection); +} + + public static void getInstance(Context context, RootRemoteServiceCallback callback){ getInstance(); - if (service != null) cb.onConnection(service); + if (service != null) callback.onConnection(service); else { - Boolean hasRootAccess = Shell.isAppGrantedRoot(); - if (hasRootAccess != null) isRootService = hasRootAccess; - RemoteServiceConnection connection = new RemoteServiceConnection(cb); - Intent intent = new Intent(context, RootRemoteService.class); - RootService.bind(intent, connection); + RemoteServiceConnection connection = new RemoteServiceConnection(callback); + if (useShizuku) { + if (Shizuku.pingBinder() && Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) + bindShizukuService(context, connection); + } else { + Boolean hasRootAccess = Shell.isAppGrantedRoot(); + if (hasRootAccess != null) isRootService = hasRootAccess; + Intent intent = new Intent(context, RootRemoteService.class); + RootService.bind(intent, connection); + } } } } diff --git a/app/src/main/java/xtr/keymapper/server/RootRemoteService.java b/app/src/main/java/xtr/keymapper/server/RootRemoteService.java index cd47210a..47a02d98 100644 --- a/app/src/main/java/xtr/keymapper/server/RootRemoteService.java +++ b/app/src/main/java/xtr/keymapper/server/RootRemoteService.java @@ -1,8 +1,6 @@ package xtr.keymapper.server; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.os.IBinder; import android.os.Process; @@ -20,19 +18,12 @@ class RootRemoteService extends RootService { RemoteService.loadLibraries(); } - public final RemoteService mService = new RemoteService(); - + private RemoteService mService = null; @Override public IBinder onBind(@NonNull Intent intent) { - PackageManager pm = this.getPackageManager(); - String packageName = this.getPackageName(); - try { - ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); - mService.nativeLibraryDir = ai.nativeLibraryDir; - mService.start_getevent(); - } catch (PackageManager.NameNotFoundException e) { - throw new RuntimeException(e); + if (mService == null) { + mService = new RemoteService().init(this); } return mService; } diff --git a/app/src/main/res/layout/fragment_settings_dialog.xml b/app/src/main/res/layout/fragment_settings_dialog.xml index 688e4a25..8262663b 100644 --- a/app/src/main/res/layout/fragment_settings_dialog.xml +++ b/app/src/main/res/layout/fragment_settings_dialog.xml @@ -347,6 +347,13 @@ + + Disable auto profiling Touchpad Input Launch App + Use Shizuku \ No newline at end of file