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