From 40644994e8fb400dfd298810cd05227a7d5915eb Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 2 Oct 2022 17:39:23 +0200 Subject: [PATCH] Make ServiceManager and Settings methods static There were exactly one instance of ServiceManager and Settings, stored in Device. Since a Device instance is not created by the CleanUp executable, it was not straightforward to call wrapper methods on cleanup. Remove this artificial restriction and expose them publicly via static methods (this is equivalent to expose a singleton, but less verbose). --- .../java/com/genymobile/scrcpy/CleanUp.java | 8 +--- .../java/com/genymobile/scrcpy/Device.java | 31 +++++-------- .../java/com/genymobile/scrcpy/Server.java | 5 +-- .../java/com/genymobile/scrcpy/Settings.java | 20 ++++----- .../scrcpy/wrappers/ServiceManager.java | 45 ++++++++++--------- 5 files changed, 49 insertions(+), 60 deletions(-) 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,