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 <https://github.com/Genymobile/scrcpy/pull/2802>
This commit is contained in:
Romain Vimont 2021-11-16 22:40:53 +01:00
parent 67170437f1
commit 94feae71f2
5 changed files with 62 additions and 24 deletions

View file

@ -168,11 +168,19 @@ public final class CleanUp {
Settings settings = new Settings(serviceManager); Settings settings = new Settings(serviceManager);
if (config.disableShowTouches) { if (config.disableShowTouches) {
Ln.i("Disabling \"show touches\""); 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);
}
} }
if (config.restoreStayOn != -1) { if (config.restoreStayOn != -1) {
Ln.i("Restoring \"stay awake\""); 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

@ -27,13 +27,18 @@ public final class Server {
if (options.getShowTouches() || options.getStayAwake()) { if (options.getShowTouches() || options.getStayAwake()) {
Settings settings = Device.getSettings(); Settings settings = Device.getSettings();
if (options.getShowTouches()) { 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 // If "show touches" was disabled, it must be disabled back on clean up
mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue); mustDisableShowTouchesOnCleanUp = !"1".equals(oldValue);
} catch (SettingsException e) {
Ln.e("Could not change \"show_touches\"", e);
}
} }
if (options.getStayAwake()) { if (options.getStayAwake()) {
int stayOn = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; 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 { try {
restoreStayOn = Integer.parseInt(oldValue); restoreStayOn = Integer.parseInt(oldValue);
@ -44,6 +49,9 @@ public final class Server {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
restoreStayOn = 0; restoreStayOn = 0;
} }
} catch (SettingsException e) {
Ln.e("Could not change \"stay_on_while_plugged_in\"", e);
}
} }
} }

View file

@ -15,19 +15,19 @@ public class Settings {
this.serviceManager = serviceManager; 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()) { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) {
return provider.getValue(table, key); 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()) { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) {
provider.putValue(table, key, value); 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()) { try (ContentProvider provider = serviceManager.getActivityManager().createSettingsProvider()) {
String oldValue = provider.getValue(table, key); String oldValue = provider.getValue(table, key);
if (!value.equals(oldValue)) { if (!value.equals(oldValue)) {

View file

@ -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);
}
}

View file

@ -1,6 +1,7 @@
package com.genymobile.scrcpy.wrappers; package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.Ln; import com.genymobile.scrcpy.Ln;
import com.genymobile.scrcpy.SettingsException;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Bundle; import android.os.Bundle;
@ -87,7 +88,8 @@ public class ContentProvider implements Closeable {
return attributionSource; 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 { try {
Method method = getCallMethod(); Method method = getCallMethod();
Object[] args; Object[] args;
@ -108,7 +110,7 @@ public class ContentProvider implements Closeable {
return (Bundle) method.invoke(provider, args); return (Bundle) method.invoke(provider, args);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) { } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
Ln.e("Could not invoke method", 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); String method = getGetMethod(table);
Bundle arg = new Bundle(); Bundle arg = new Bundle();
arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID); arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID);
try {
Bundle bundle = call(method, key, arg); Bundle bundle = call(method, key, arg);
if (bundle == null) { if (bundle == null) {
return null; return null;
} }
return bundle.getString("value"); return bundle.getString("value");
} catch (Exception e) {
throw new SettingsException(table, "get", key, null, e);
} }
public void putValue(String table, String key, String value) { }
public void putValue(String table, String key, String value) throws SettingsException {
String method = getPutMethod(table); String method = getPutMethod(table);
Bundle arg = new Bundle(); Bundle arg = new Bundle();
arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID); arg.putInt(CALL_METHOD_USER_KEY, ServiceManager.USER_ID);
arg.putString(NAME_VALUE_TABLE_VALUE, value); arg.putString(NAME_VALUE_TABLE_VALUE, value);
try {
call(method, key, arg); call(method, key, arg);
} catch (Exception e) {
throw new SettingsException(table, "put", key, value, e);
}
} }
} }