From 94feae71f2bf603b1cbd78611a2fdecdfcf40b67 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 16 Nov 2021 22:40:53 +0100 Subject: [PATCH] Report settings errors via Exceptions Settings read/write errors were silently ignored. Report them via a SettingsException so that the caller can handle them. This allows to log a proper error message, and will also allow to fallback to a different settings method in case of failure. PR #2802 --- .../java/com/genymobile/scrcpy/CleanUp.java | 12 ++++++-- .../java/com/genymobile/scrcpy/Server.java | 28 +++++++++++------- .../java/com/genymobile/scrcpy/Settings.java | 6 ++-- .../genymobile/scrcpy/SettingsException.java | 11 +++++++ .../scrcpy/wrappers/ContentProvider.java | 29 +++++++++++++------ 5 files changed, 62 insertions(+), 24 deletions(-) create mode 100644 server/src/main/java/com/genymobile/scrcpy/SettingsException.java diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java index 9001eef7..319a957d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java +++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java @@ -168,11 +168,19 @@ public final class CleanUp { Settings settings = new Settings(serviceManager); if (config.disableShowTouches) { Ln.i("Disabling \"show touches\""); - settings.putValue(Settings.TABLE_SYSTEM, "show_touches", "0"); + try { + settings.putValue(Settings.TABLE_SYSTEM, "show_touches", "0"); + } catch (SettingsException e) { + Ln.e("Could not restore \"show_touches\"", e); + } } if (config.restoreStayOn != -1) { Ln.i("Restoring \"stay awake\""); - settings.putValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(config.restoreStayOn)); + try { + 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/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index c900f872..efb295b3 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -27,22 +27,30 @@ public final class Server { if (options.getShowTouches() || options.getStayAwake()) { Settings settings = Device.getSettings(); if (options.getShowTouches()) { - 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); + try { + 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) { + Ln.e("Could not change \"show_touches\"", e); + } } if (options.getStayAwake()) { int stayOn = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; - String oldValue = settings.getAndPutValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn)); try { - restoreStayOn = Integer.parseInt(oldValue); - if (restoreStayOn == stayOn) { - // No need to restore - restoreStayOn = -1; + String oldValue = settings.getAndPutValue(Settings.TABLE_GLOBAL, "stay_on_while_plugged_in", String.valueOf(stayOn)); + try { + restoreStayOn = Integer.parseInt(oldValue); + if (restoreStayOn == stayOn) { + // No need to restore + restoreStayOn = -1; + } + } catch (NumberFormatException e) { + restoreStayOn = 0; } - } catch (NumberFormatException e) { - restoreStayOn = 0; + } catch (SettingsException e) { + Ln.e("Could not change \"stay_on_while_plugged_in\"", e); } } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Settings.java b/server/src/main/java/com/genymobile/scrcpy/Settings.java index b59188d5..83b63477 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Settings.java +++ b/server/src/main/java/com/genymobile/scrcpy/Settings.java @@ -15,19 +15,19 @@ public class Settings { this.serviceManager = serviceManager; } - public String getValue(String table, String key) { + public String getValue(String table, String key) throws SettingsException { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { return provider.getValue(table, key); } } - public void putValue(String table, String key, String value) { + public void putValue(String table, String key, String value) throws SettingsException { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { provider.putValue(table, key, value); } } - public String getAndPutValue(String table, String key, String value) { + public String getAndPutValue(String table, String key, String value) throws SettingsException { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) { String oldValue = provider.getValue(table, key); if (!value.equals(oldValue)) { diff --git a/server/src/main/java/com/genymobile/scrcpy/SettingsException.java b/server/src/main/java/com/genymobile/scrcpy/SettingsException.java new file mode 100644 index 00000000..36ef63ee --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/SettingsException.java @@ -0,0 +1,11 @@ +package com.genymobile.scrcpy; + +public class SettingsException extends Exception { + private static String createMessage(String method, String table, String key, String value) { + return "Could not access settings: " + method + " " + table + " " + key + (value != null ? " " + value : ""); + } + + public SettingsException(String method, String table, String key, String value, Throwable cause) { + super(createMessage(method, table, key, value), cause); + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java index ab95f0df..47eae64d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java @@ -1,6 +1,7 @@ package com.genymobile.scrcpy.wrappers; import com.genymobile.scrcpy.Ln; +import com.genymobile.scrcpy.SettingsException; import android.annotation.SuppressLint; import android.os.Bundle; @@ -87,7 +88,8 @@ public class ContentProvider implements Closeable { return attributionSource; } - private Bundle call(String callMethod, String arg, Bundle extras) { + private Bundle call(String callMethod, String arg, Bundle extras) + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { try { Method method = getCallMethod(); Object[] args; @@ -108,7 +110,7 @@ public class ContentProvider implements Closeable { return (Bundle) method.invoke(provider, args); } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) { Ln.e("Could not invoke method", e); - return null; + throw e; } } @@ -142,22 +144,31 @@ public class ContentProvider implements Closeable { } } - public String getValue(String table, String key) { + public String getValue(String table, String key) throws SettingsException { String method = getGetMethod(table); Bundle arg = new Bundle(); arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID); - Bundle bundle = call(method, key, arg); - if (bundle == null) { - return null; + try { + Bundle bundle = call(method, key, arg); + if (bundle == null) { + return null; + } + return bundle.getString("value"); + } catch (Exception e) { + throw new SettingsException(table, "get", key, null, e); } - return bundle.getString("value"); + } - public void putValue(String table, String key, String value) { + public void putValue(String table, String key, String value) throws SettingsException { String method = getPutMethod(table); Bundle arg = new Bundle(); arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID); arg.putString(NAME_VALUE_TABLE_VALUE, value); - call(method, key, arg); + try { + call(method, key, arg); + } catch (Exception e) { + throw new SettingsException(table, "put", key, value, e); + } } }