Merge "Make it possible to check processed DeviceConfig flags." into main
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index e6ee975..2b27526 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -485,6 +485,32 @@
private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
EconomyManagerInternal.TareStateChangeListener {
+ @Nullable
+ @GuardedBy("mLock")
+ private DeviceConfig.Properties mLastPropertiesPulled;
+ @GuardedBy("mLock")
+ private boolean mCacheConfigChanges = false;
+
+ @Nullable
+ @GuardedBy("mLock")
+ public String getValueLocked(String key) {
+ if (mLastPropertiesPulled == null) {
+ return null;
+ }
+ return mLastPropertiesPulled.getString(key, null);
+ }
+
+ @GuardedBy("mLock")
+ public void setCacheConfigChangesLocked(boolean enabled) {
+ if (enabled && !mCacheConfigChanges) {
+ mLastPropertiesPulled =
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
+ } else {
+ mLastPropertiesPulled = null;
+ }
+ mCacheConfigChanges = enabled;
+ }
+
public void start() {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
AppSchedulingModuleThread.getExecutor(), this);
@@ -513,11 +539,15 @@
}
synchronized (mLock) {
+ if (mCacheConfigChanges) {
+ mLastPropertiesPulled =
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
+ }
for (String name : properties.getKeyset()) {
if (name == null) {
continue;
}
- if (DEBUG) {
+ if (DEBUG || mCacheConfigChanges) {
Slog.d(TAG, "DeviceConfig " + name
+ " changed to " + properties.getString(name, null));
}
@@ -5554,6 +5584,18 @@
}
}
+ void setCacheConfigChanges(boolean enabled) {
+ synchronized (mLock) {
+ mConstantsObserver.setCacheConfigChangesLocked(enabled);
+ }
+ }
+
+ String getConfigValue(String key) {
+ synchronized (mLock) {
+ return mConstantsObserver.getValueLocked(key);
+ }
+ }
+
int getStorageSeq() {
synchronized (mLock) {
return mStorageController.getTracker().getSeq();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index 90b4630..43e2888 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -16,6 +16,7 @@
package com.android.server.job;
+import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -66,6 +67,8 @@
return getBatteryCharging(pw);
case "get-battery-not-low":
return getBatteryNotLow(pw);
+ case "get-config-value":
+ return getConfigValue(pw);
case "get-estimated-download-bytes":
return getEstimatedNetworkBytes(pw, BYTE_OPTION_DOWNLOAD);
case "get-estimated-upload-bytes":
@@ -82,6 +85,8 @@
return getJobState(pw);
case "heartbeat":
return doHeartbeat(pw);
+ case "cache-config-changes":
+ return cacheConfigChanges(pw);
case "reset-execution-quota":
return resetExecutionQuota(pw);
case "reset-schedule-quota":
@@ -100,13 +105,16 @@
}
private void checkPermission(String operation) throws Exception {
+ checkPermission(operation, Manifest.permission.CHANGE_APP_IDLE_STATE);
+ }
+
+ private void checkPermission(String operation, String permission) throws Exception {
final int uid = Binder.getCallingUid();
if (uid == 0) {
// Root can do anything.
return;
}
- final int perm = mPM.checkUidPermission(
- "android.permission.CHANGE_APP_IDLE_STATE", uid);
+ final int perm = mPM.checkUidPermission(permission, uid);
if (perm != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Uid " + uid
+ " not permitted to " + operation);
@@ -339,7 +347,7 @@
}
private int getAconfigFlagState(PrintWriter pw) throws Exception {
- checkPermission("get aconfig flag state");
+ checkPermission("get aconfig flag state", Manifest.permission.DUMP);
final String flagName = getNextArgRequired();
@@ -390,6 +398,20 @@
return 0;
}
+ private int getConfigValue(PrintWriter pw) throws Exception {
+ checkPermission("get device config value", Manifest.permission.DUMP);
+
+ final String key = getNextArgRequired();
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ pw.println(mInternal.getConfigValue(key));
+ return 0;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
private int getEstimatedNetworkBytes(PrintWriter pw, int byteOption) throws Exception {
checkPermission("get estimated bytes");
@@ -540,6 +562,28 @@
return -1;
}
+ private int cacheConfigChanges(PrintWriter pw) throws Exception {
+ checkPermission("change config caching", Manifest.permission.DUMP);
+ String opt = getNextArgRequired();
+ boolean enabled;
+ if ("on".equals(opt)) {
+ enabled = true;
+ } else if ("off".equals(opt)) {
+ enabled = false;
+ } else {
+ getErrPrintWriter().println("Error: unknown option " + opt);
+ return 1;
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mInternal.setCacheConfigChanges(enabled);
+ pw.println("Config caching " + (enabled ? "enabled" : "disabled"));
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return 0;
+ }
+
private int resetExecutionQuota(PrintWriter pw) throws Exception {
checkPermission("reset execution quota");
@@ -726,6 +770,9 @@
pw.println(" is null (no namespace).");
pw.println(" heartbeat [num]");
pw.println(" No longer used.");
+ pw.println(" cache-config-changes [on|off]");
+ pw.println(" Control caching the set of most recently processed config flags.");
+ pw.println(" Off by default. Turning on makes get-config-value useful.");
pw.println(" monitor-battery [on|off]");
pw.println(" Control monitoring of all battery changes. Off by default. Turning");
pw.println(" on makes get-battery-seq useful.");
@@ -738,6 +785,9 @@
pw.println(" Return whether the battery is currently considered to be charging.");
pw.println(" get-battery-not-low");
pw.println(" Return whether the battery is currently considered to not be low.");
+ pw.println(" get-config-value KEY");
+ pw.println(" Return the most recently processed and cached config value for the KEY.");
+ pw.println(" Only useful if caching is turned on with cache-config-changes.");
pw.println(" get-estimated-download-bytes [-u | --user USER_ID]"
+ " [-n | --namespace NAMESPACE] PACKAGE JOB_ID");
pw.println(" Return the most recent estimated download bytes for the job.");