Compare commits

..

10 Commits

Author SHA1 Message Date
Romain Vimont
7b75a3c966 clean up 2022-10-02 16:36:05 +02:00
Romain Vimont
64b70724e0 Expose APK path from Java 2022-10-02 16:36:05 +02:00
Romain Vimont
2bc1f59b5b Add option --reinstall
With --install, the server is installed only if the current version is
not already installed. Passing --reinstall force reinstallation is all
cases.
2022-10-02 15:52:59 +02:00
Romain Vimont
bef5b11e45 Add option --install
When this flag is set, the scrcpy is installed rather than pushed to
/data/local/tmp.
2022-10-02 15:52:59 +02:00
Romain Vimont
c96c77656a Add "adb uninstall"
This will allow to uninstall the server when necessary.
2022-10-02 15:52:59 +02:00
Romain Vimont
a73a04da87 Add util function to get the APK version
Use "dumpsys package com.genymobile.scrcpy" to get the APK version.
2022-10-02 15:52:59 +02:00
Romain Vimont
00766b8ab6 Add util function to get the APK path
Use "pm list package -f" to find where the APK is actually installed on
the device.
2022-10-02 15:52:59 +02:00
Romain Vimont
88499cd101 Make build_without_gradle generate a signed APK 2022-10-02 15:52:59 +02:00
Romain Vimont
b5b431fa32 Sign APK with credentials from keystore.properties 2022-10-02 15:52:59 +02:00
Romain Vimont
f34075ff52 Rename server to scrcpy-server.apk
This will allow to install it.
2022-10-02 15:52:59 +02:00
5 changed files with 68 additions and 57 deletions

View File

@@ -1,5 +1,7 @@
package com.genymobile.scrcpy;
import com.genymobile.scrcpy.wrappers.ServiceManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;
@@ -118,8 +120,8 @@ public final class CleanUp {
// not instantiable
}
public static void configure(boolean installed, int displayId, int restoreStayOn, boolean disableShowTouches, boolean restoreNormalPowerMode,
boolean powerOffScreen) throws IOException {
public static void configure(boolean installed, int displayId, int restoreStayOn, boolean disableShowTouches, boolean restoreNormalPowerMode, boolean powerOffScreen)
throws IOException {
Config config = new Config();
config.installed = installed;
config.displayId = displayId;
@@ -140,9 +142,9 @@ public final class CleanUp {
private static void startProcess(Config config) throws IOException {
String[] cmd = {"app_process", "/", CleanUp.class.getName(), config.toBase64()};
// TODO if scrcpy is "installed", then we must find the install path!
ProcessBuilder builder = new ProcessBuilder(cmd);
String serverPath = config.installed ? Device.getInstalledApkPath() : SERVER_PATH;
builder.environment().put("CLASSPATH", serverPath);
builder.environment().put("CLASSPATH", SERVER_PATH);
builder.start();
}
@@ -172,10 +174,12 @@ public final class CleanUp {
Ln.i("Cleaning up");
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);
}
@@ -183,7 +187,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);
}

View File

@@ -34,6 +34,9 @@ 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 +69,9 @@ public final class Device {
public Device(Options options) {
displayId = options.getDisplayId();
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
DisplayInfo displayInfo = SERVICE_MANAGER.getDisplayManager().getDisplayInfo(displayId);
if (displayInfo == null) {
int[] displayIds = ServiceManager.getDisplayManager().getDisplayIds();
int[] displayIds = SERVICE_MANAGER.getDisplayManager().getDisplayIds();
throw new InvalidDisplayIdException(displayId, displayIds);
}
@@ -82,7 +85,7 @@ public final class Device {
screenInfo = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), deviceSize, crop, maxSize, lockVideoOrientation);
layerStack = displayInfo.getLayerStack();
ServiceManager.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() {
SERVICE_MANAGER.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() {
@Override
public void onRotationChanged(int rotation) {
synchronized (Device.this) {
@@ -98,7 +101,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 = ServiceManager.getClipboardManager();
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
if (clipboardManager != null) {
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
@Override
@@ -192,7 +195,7 @@ public final class Device {
return false;
}
return ServiceManager.getInputManager().injectInputEvent(inputEvent, injectMode);
return SERVICE_MANAGER.getInputManager().injectInputEvent(inputEvent, injectMode);
}
public boolean injectEvent(InputEvent event, int injectMode) {
@@ -220,7 +223,7 @@ public final class Device {
}
public static boolean isScreenOn() {
return ServiceManager.getPowerManager().isScreenOn();
return SERVICE_MANAGER.getPowerManager().isScreenOn();
}
public synchronized void setRotationListener(RotationListener rotationListener) {
@@ -232,19 +235,19 @@ public final class Device {
}
public static void expandNotificationPanel() {
ServiceManager.getStatusBarManager().expandNotificationsPanel();
SERVICE_MANAGER.getStatusBarManager().expandNotificationsPanel();
}
public static void expandSettingsPanel() {
ServiceManager.getStatusBarManager().expandSettingsPanel();
SERVICE_MANAGER.getStatusBarManager().expandSettingsPanel();
}
public static void collapsePanels() {
ServiceManager.getStatusBarManager().collapsePanels();
SERVICE_MANAGER.getStatusBarManager().collapsePanels();
}
public static String getClipboardText() {
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
if (clipboardManager == null) {
return null;
}
@@ -256,7 +259,7 @@ public final class Device {
}
public boolean setClipboardText(String text) {
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
if (clipboardManager == null) {
return false;
}
@@ -299,7 +302,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 = ServiceManager.getWindowManager();
WindowManager wm = SERVICE_MANAGER.getWindowManager();
boolean accelerometerRotation = !wm.isRotationFrozen();
@@ -316,8 +319,12 @@ public final class Device {
}
}
public static String getInstalledApkPath() {
ApplicationInfo info = ServiceManager.getPackageManager().getApplicationInfo(SCRCPY_PACKAGE_NAME);
public static Settings getSettings() {
return SETTINGS;
}
public static String getApkPath() {
ApplicationInfo info = SERVICE_MANAGER.getPackageManager().getApplicationInfo(SCRCPY_PACKAGE_NAME);
if (info == null) {
return null;
}

View File

@@ -20,9 +20,10 @@ 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) {
@@ -33,7 +34,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) {

View File

@@ -7,14 +7,16 @@ import android.os.Build;
import java.io.IOException;
public final class Settings {
public 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 Settings() {
/* not instantiable */
private final ServiceManager serviceManager;
public Settings(ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
private static void execSettingsPut(String table, String key, String value) throws SettingsException {
@@ -33,10 +35,10 @@ public final class Settings {
}
}
public static String getValue(String table, String key) throws SettingsException {
public String getValue(String table, String key) throws SettingsException {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
// on Android >= 12, it always fails: <https://github.com/Genymobile/scrcpy/issues/2788>
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);
@@ -46,10 +48,10 @@ public final class Settings {
return execSettingsGet(table, key);
}
public static void putValue(String table, String key, String value) throws SettingsException {
public 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: <https://github.com/Genymobile/scrcpy/issues/2788>
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);
@@ -59,10 +61,10 @@ public final class Settings {
execSettingsPut(table, key, value);
}
public static String getAndPutValue(String table, String key, String value) throws SettingsException {
public 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: <https://github.com/Genymobile/scrcpy/issues/2788>
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);

View File

@@ -13,31 +13,28 @@ public final class ServiceManager {
public static final String PACKAGE_NAME = "com.android.shell";
public static final int USER_ID = 0;
private static final Method GET_SERVICE_METHOD;
static {
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;
private PackageManager packageManager;
public ServiceManager() {
try {
GET_SERVICE_METHOD = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class);
getServiceMethod = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class);
} catch (Exception e) {
throw new AssertionError(e);
}
}
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 static PackageManager packageManager;
private ServiceManager() {
/* not instantiable */
}
private static IInterface getService(String service, String type) {
private IInterface getService(String service, String type) {
try {
IBinder binder = (IBinder) GET_SERVICE_METHOD.invoke(null, service);
IBinder binder = (IBinder) getServiceMethod.invoke(null, service);
Method asInterfaceMethod = Class.forName(type + "$Stub").getMethod("asInterface", IBinder.class);
return (IInterface) asInterfaceMethod.invoke(null, binder);
} catch (Exception e) {
@@ -45,14 +42,14 @@ public final class ServiceManager {
}
}
public static WindowManager getWindowManager() {
public WindowManager getWindowManager() {
if (windowManager == null) {
windowManager = new WindowManager(getService("window", "android.view.IWindowManager"));
}
return windowManager;
}
public static DisplayManager getDisplayManager() {
public DisplayManager getDisplayManager() {
if (displayManager == null) {
try {
Class<?> clazz = Class.forName("android.hardware.display.DisplayManagerGlobal");
@@ -66,7 +63,7 @@ public final class ServiceManager {
return displayManager;
}
public static InputManager getInputManager() {
public InputManager getInputManager() {
if (inputManager == null) {
try {
Method getInstanceMethod = android.hardware.input.InputManager.class.getDeclaredMethod("getInstance");
@@ -79,21 +76,21 @@ public final class ServiceManager {
return inputManager;
}
public static PowerManager getPowerManager() {
public PowerManager getPowerManager() {
if (powerManager == null) {
powerManager = new PowerManager(getService("power", "android.os.IPowerManager"));
}
return powerManager;
}
public static StatusBarManager getStatusBarManager() {
public StatusBarManager getStatusBarManager() {
if (statusBarManager == null) {
statusBarManager = new StatusBarManager(getService("statusbar", "com.android.internal.statusbar.IStatusBarService"));
}
return statusBarManager;
}
public static ClipboardManager getClipboardManager() {
public ClipboardManager getClipboardManager() {
if (clipboardManager == null) {
IInterface clipboard = getService("clipboard", "android.content.IClipboard");
if (clipboard == null) {
@@ -107,7 +104,7 @@ public final class ServiceManager {
return clipboardManager;
}
public static ActivityManager getActivityManager() {
public ActivityManager getActivityManager() {
if (activityManager == null) {
try {
// On old Android versions, the ActivityManager is not exposed via AIDL,
@@ -124,7 +121,7 @@ public final class ServiceManager {
return activityManager;
}
public static PackageManager getPackageManager() {
public PackageManager getPackageManager() {
if (packageManager == null) {
try {
//IInterface manager = getService("package", "android.content.pm.IPackageManager");