diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java index 319a957d..831dc994 100644 --- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java +++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java @@ -1,7 +1,5 @@ package com.genymobile.scrcpy; -import com.genymobile.scrcpy.wrappers.ServiceManager; - import android.os.Parcel; import android.os.Parcelable; import android.util.Base64; @@ -164,12 +162,10 @@ public final class CleanUp { Config config = Config.fromBase64(args[0]); if (config.disableShowTouches || config.restoreStayOn != -1) { - ServiceManager serviceManager = new ServiceManager(); - Settings settings = new Settings(serviceManager); if (config.disableShowTouches) { Ln.i("Disabling \"show touches\""); try { - settings.putValue(Settings.TABLE_SYSTEM, "show_touches", "0"); + Settings.putValue(Settings.TABLE_SYSTEM, "show_touches", "0"); } catch (SettingsException e) { Ln.e("Could not restore \"show_touches\"", e); } @@ -177,7 +173,7 @@ public final class CleanUp { if (config.restoreStayOn != -1) { Ln.i("Restoring \"stay awake\""); try { - settings.putValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(config.restoreStayOn)); + Settings.putValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(config.restoreStayOn)); } catch (SettingsException e) { Ln.e("Could not restore \"stay_on_while_plugged_in\"", e); } diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 763a7fad..97b25b22 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -31,9 +31,6 @@ public final class Device { public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1; public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2; - private static final ServiceManager SERVICE_MANAGER = new ServiceManager(); - private static final Settings SETTINGS = new Settings(SERVICE_MANAGER); - public interface RotationListener { void onRotationChanged(int rotation); } @@ -66,9 +63,9 @@ public final class Device { public Device(Options options) { displayId = options.getDisplayId(); - DisplayInfo displayInfo = SERVICE_MANAGER.getDisplayManager().getDisplayInfo(displayId); + DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId); if (displayInfo == null) { - int[] displayIds = SERVICE_MANAGER.getDisplayManager().getDisplayIds(); + int[] displayIds = ServiceManager.getDisplayManager().getDisplayIds(); throw new InvalidDisplayIdException(displayId, displayIds); } @@ -82,7 +79,7 @@ public final class Device { screenInfo = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), deviceSize, crop, maxSize, lockVideoOrientation); layerStack = displayInfo.getLayerStack(); - SERVICE_MANAGER.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() { + ServiceManager.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() { @Override public void onRotationChanged(int rotation) { synchronized (Device.this) { @@ -98,7 +95,7 @@ public final class Device { if (options.getControl() && options.getClipboardAutosync()) { // If control and autosync are enabled, synchronize Android clipboard to the computer automatically - ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager(); + ClipboardManager clipboardManager = ServiceManager.getClipboardManager(); if (clipboardManager != null) { clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() { @Override @@ -192,7 +189,7 @@ public final class Device { return false; } - return SERVICE_MANAGER.getInputManager().injectInputEvent(inputEvent, injectMode); + return ServiceManager.getInputManager().injectInputEvent(inputEvent, injectMode); } public boolean injectEvent(InputEvent event, int injectMode) { @@ -220,7 +217,7 @@ public final class Device { } public static boolean isScreenOn() { - return SERVICE_MANAGER.getPowerManager().isScreenOn(); + return ServiceManager.getPowerManager().isScreenOn(); } public synchronized void setRotationListener(RotationListener rotationListener) { @@ -232,19 +229,19 @@ public final class Device { } public static void expandNotificationPanel() { - SERVICE_MANAGER.getStatusBarManager().expandNotificationsPanel(); + ServiceManager.getStatusBarManager().expandNotificationsPanel(); } public static void expandSettingsPanel() { - SERVICE_MANAGER.getStatusBarManager().expandSettingsPanel(); + ServiceManager.getStatusBarManager().expandSettingsPanel(); } public static void collapsePanels() { - SERVICE_MANAGER.getStatusBarManager().collapsePanels(); + ServiceManager.getStatusBarManager().collapsePanels(); } public static String getClipboardText() { - ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager(); + ClipboardManager clipboardManager = ServiceManager.getClipboardManager(); if (clipboardManager == null) { return null; } @@ -256,7 +253,7 @@ public final class Device { } public boolean setClipboardText(String text) { - ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager(); + ClipboardManager clipboardManager = ServiceManager.getClipboardManager(); if (clipboardManager == null) { return false; } @@ -299,7 +296,7 @@ public final class Device { * Disable auto-rotation (if enabled), set the screen rotation and re-enable auto-rotation (if it was enabled). */ public static void rotateDevice() { - WindowManager wm = SERVICE_MANAGER.getWindowManager(); + WindowManager wm = ServiceManager.getWindowManager(); boolean accelerometerRotation = !wm.isRotationFrozen(); @@ -315,8 +312,4 @@ public final class Device { wm.thawRotation(); } } - - public static Settings getSettings() { - return SETTINGS; - } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 1df91552..ec03515e 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -20,10 +20,9 @@ public final class Server { int restoreStayOn = -1; boolean restoreNormalPowerMode = options.getControl(); // only restore power mode if control is enabled if (options.getShowTouches() || options.getStayAwake()) { - Settings settings = Device.getSettings(); if (options.getShowTouches()) { try { - String oldValue = settings.getAndPutValue(Settings.TABLE_SYSTEM, "show_touches", "1"); + String oldValue = Settings.getAndPutValue(Settings.TABLE_SYSTEM, "show_touches", "1"); // If "show touches" was disabled, it must be disabled back on clean up mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue); } catch (SettingsException e) { @@ -34,7 +33,7 @@ public final class Server { if (options.getStayAwake()) { int stayOn = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; try { - String oldValue = settings.getAndPutValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn)); + String oldValue = Settings.getAndPutValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn)); try { restoreStayOn = Integer.parseInt(oldValue); if (restoreStayOn == stayOn) { diff --git a/server/src/main/java/com/genymobile/scrcpy/Settings.java b/server/src/main/java/com/genymobile/scrcpy/Settings.java index cb15ebb4..1d38814d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Settings.java +++ b/server/src/main/java/com/genymobile/scrcpy/Settings.java @@ -7,16 +7,14 @@ import android.os.Build; import java.io.IOException; -public class Settings { +public final class Settings { public static final String TABLE_SYSTEM = ContentProvider.TABLE_SYSTEM; public static final String TABLE_SECURE = ContentProvider.TABLE_SECURE; public static final String TABLE_GLOBAL = ContentProvider.TABLE_GLOBAL; - private final ServiceManager serviceManager; - - public Settings(ServiceManager serviceManager) { - this.serviceManager = serviceManager; + private Settings() { + /* not instantiable */ } private static void execSettingsPut(String table, String key, String value) throws SettingsException { @@ -35,10 +33,10 @@ public class Settings { } } - public String getValue(String table, String key) throws SettingsException { + public static String getValue(String table, String key) throws SettingsException { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { // on Android >= 12, it always fails: - try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { + try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) { return provider.getValue(table, key); } catch (SettingsException e) { Ln.w("Could not get settings value via ContentProvider, fallback to settings process", e); @@ -48,10 +46,10 @@ public class Settings { return execSettingsGet(table, key); } - public void putValue(String table, String key, String value) throws SettingsException { + public static void putValue(String table, String key, String value) throws SettingsException { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { // on Android >= 12, it always fails: - try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { + try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) { provider.putValue(table, key, value); } catch (SettingsException e) { Ln.w("Could not put settings value via ContentProvider, fallback to settings process", e); @@ -61,10 +59,10 @@ public class Settings { execSettingsPut(table, key, value); } - public String getAndPutValue(String table, String key, String value) throws SettingsException { + public static String getAndPutValue(String table, String key, String value) throws SettingsException { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { // on Android >= 12, it always fails: - try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { + try (ContentProvider provider = ServiceManager.getActivityManager().createSettingsProvider()) { String oldValue = provider.getValue(table, key); if (!value.equals(oldValue)) { provider.putValue(table, key, value); diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java index 68f6817d..cb6863b6 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ServiceManager.java @@ -13,27 +13,30 @@ public final class ServiceManager { public static final String PACKAGE_NAME = "com.android.shell"; public static final int USER_ID = 0; - private final Method getServiceMethod; - - private WindowManager windowManager; - private DisplayManager displayManager; - private InputManager inputManager; - private PowerManager powerManager; - private StatusBarManager statusBarManager; - private ClipboardManager clipboardManager; - private ActivityManager activityManager; - - public ServiceManager() { + private static final Method GET_SERVICE_METHOD; + static { try { - getServiceMethod = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class); + GET_SERVICE_METHOD = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class); } catch (Exception e) { throw new AssertionError(e); } } - private IInterface getService(String service, String type) { + private static WindowManager windowManager; + private static DisplayManager displayManager; + private static InputManager inputManager; + private static PowerManager powerManager; + private static StatusBarManager statusBarManager; + private static ClipboardManager clipboardManager; + private static ActivityManager activityManager; + + private ServiceManager() { + /* not instantiable */ + } + + private static IInterface getService(String service, String type) { try { - IBinder binder = (IBinder) getServiceMethod.invoke(null, service); + IBinder binder = (IBinder) GET_SERVICE_METHOD.invoke(null, service); Method asInterfaceMethod = Class.forName(type + "$Stub").getMethod("asInterface", IBinder.class); return (IInterface) asInterfaceMethod.invoke(null, binder); } catch (Exception e) { @@ -41,14 +44,14 @@ public final class ServiceManager { } } - public WindowManager getWindowManager() { + public static WindowManager getWindowManager() { if (windowManager == null) { windowManager = new WindowManager(getService("window", "android.view.IWindowManager")); } return windowManager; } - public DisplayManager getDisplayManager() { + public static DisplayManager getDisplayManager() { if (displayManager == null) { try { Class clazz = Class.forName("android.hardware.display.DisplayManagerGlobal"); @@ -62,7 +65,7 @@ public final class ServiceManager { return displayManager; } - public InputManager getInputManager() { + public static InputManager getInputManager() { if (inputManager == null) { try { Method getInstanceMethod = android.hardware.input.InputManager.class.getDeclaredMethod("getInstance"); @@ -75,21 +78,21 @@ public final class ServiceManager { return inputManager; } - public PowerManager getPowerManager() { + public static PowerManager getPowerManager() { if (powerManager == null) { powerManager = new PowerManager(getService("power", "android.os.IPowerManager")); } return powerManager; } - public StatusBarManager getStatusBarManager() { + public static StatusBarManager getStatusBarManager() { if (statusBarManager == null) { statusBarManager = new StatusBarManager(getService("statusbar", "com.android.internal.statusbar.IStatusBarService")); } return statusBarManager; } - public ClipboardManager getClipboardManager() { + public static ClipboardManager getClipboardManager() { if (clipboardManager == null) { IInterface clipboard = getService("clipboard", "android.content.IClipboard"); if (clipboard == null) { @@ -103,7 +106,7 @@ public final class ServiceManager { return clipboardManager; } - public ActivityManager getActivityManager() { + public static ActivityManager getActivityManager() { if (activityManager == null) { try { // On old Android versions, the ActivityManager is not exposed via AIDL,