Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21fd192f authored by Kweku Adams's avatar Kweku Adams
Browse files

Make it possible to check processed DeviceConfig flags.

Make it possible to track the most recently processed DeviceConfig flags
and get the value that was processed to help deflake tests.

Bug: 271128261
Bug: 322031031
Bug: 322871938
Bug: 323084558
Bug: 323621598
Test: atest --rerun-until-failure 25 CtsJobSchedulerTestCases:FlexibilityConstraintTest
Change-Id: Iaec284b6670cef490a1ea93b5849fd5065cefe80
parent e7143188
Loading
Loading
Loading
Loading
+43 −1
Original line number Original line Diff line number Diff line
@@ -485,6 +485,32 @@ public class JobSchedulerService extends com.android.server.SystemService


    private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
    private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
            EconomyManagerInternal.TareStateChangeListener {
            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() {
        public void start() {
            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
                    AppSchedulingModuleThread.getExecutor(), this);
                    AppSchedulingModuleThread.getExecutor(), this);
@@ -513,11 +539,15 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
            }


            synchronized (mLock) {
            synchronized (mLock) {
                if (mCacheConfigChanges) {
                    mLastPropertiesPulled =
                            DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
                }
                for (String name : properties.getKeyset()) {
                for (String name : properties.getKeyset()) {
                    if (name == null) {
                    if (name == null) {
                        continue;
                        continue;
                    }
                    }
                    if (DEBUG) {
                    if (DEBUG || mCacheConfigChanges) {
                        Slog.d(TAG, "DeviceConfig " + name
                        Slog.d(TAG, "DeviceConfig " + name
                                + " changed to " + properties.getString(name, null));
                                + " changed to " + properties.getString(name, null));
                    }
                    }
@@ -5554,6 +5584,18 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
        }
    }
    }


    void setCacheConfigChanges(boolean enabled) {
        synchronized (mLock) {
            mConstantsObserver.setCacheConfigChangesLocked(enabled);
        }
    }

    String getConfigValue(String key) {
        synchronized (mLock) {
            return mConstantsObserver.getValueLocked(key);
        }
    }

    int getStorageSeq() {
    int getStorageSeq() {
        synchronized (mLock) {
        synchronized (mLock) {
            return mStorageController.getTracker().getSeq();
            return mStorageController.getTracker().getSeq();
+53 −3
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.job;
package com.android.server.job;


import android.Manifest;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppGlobals;
@@ -66,6 +67,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
                    return getBatteryCharging(pw);
                    return getBatteryCharging(pw);
                case "get-battery-not-low":
                case "get-battery-not-low":
                    return getBatteryNotLow(pw);
                    return getBatteryNotLow(pw);
                case "get-config-value":
                    return getConfigValue(pw);
                case "get-estimated-download-bytes":
                case "get-estimated-download-bytes":
                    return getEstimatedNetworkBytes(pw, BYTE_OPTION_DOWNLOAD);
                    return getEstimatedNetworkBytes(pw, BYTE_OPTION_DOWNLOAD);
                case "get-estimated-upload-bytes":
                case "get-estimated-upload-bytes":
@@ -82,6 +85,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
                    return getJobState(pw);
                    return getJobState(pw);
                case "heartbeat":
                case "heartbeat":
                    return doHeartbeat(pw);
                    return doHeartbeat(pw);
                case "cache-config-changes":
                    return cacheConfigChanges(pw);
                case "reset-execution-quota":
                case "reset-execution-quota":
                    return resetExecutionQuota(pw);
                    return resetExecutionQuota(pw);
                case "reset-schedule-quota":
                case "reset-schedule-quota":
@@ -100,13 +105,16 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
    }
    }


    private void checkPermission(String operation) throws Exception {
    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();
        final int uid = Binder.getCallingUid();
        if (uid == 0) {
        if (uid == 0) {
            // Root can do anything.
            // Root can do anything.
            return;
            return;
        }
        }
        final int perm = mPM.checkUidPermission(
        final int perm = mPM.checkUidPermission(permission, uid);
                "android.permission.CHANGE_APP_IDLE_STATE", uid);
        if (perm != PackageManager.PERMISSION_GRANTED) {
        if (perm != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Uid " + uid
            throw new SecurityException("Uid " + uid
                    + " not permitted to " + operation);
                    + " not permitted to " + operation);
@@ -339,7 +347,7 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
    }
    }


    private int getAconfigFlagState(PrintWriter pw) throws Exception {
    private int getAconfigFlagState(PrintWriter pw) throws Exception {
        checkPermission("get aconfig flag state");
        checkPermission("get aconfig flag state", Manifest.permission.DUMP);


        final String flagName = getNextArgRequired();
        final String flagName = getNextArgRequired();


@@ -390,6 +398,20 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        return 0;
        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 {
    private int getEstimatedNetworkBytes(PrintWriter pw, int byteOption) throws Exception {
        checkPermission("get estimated bytes");
        checkPermission("get estimated bytes");


@@ -540,6 +562,28 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        return -1;
        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 {
    private int resetExecutionQuota(PrintWriter pw) throws Exception {
        checkPermission("reset execution quota");
        checkPermission("reset execution quota");


@@ -726,6 +770,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        pw.println("         is null (no namespace).");
        pw.println("         is null (no namespace).");
        pw.println("  heartbeat [num]");
        pw.println("  heartbeat [num]");
        pw.println("    No longer used.");
        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("  monitor-battery [on|off]");
        pw.println("    Control monitoring of all battery changes.  Off by default.  Turning");
        pw.println("    Control monitoring of all battery changes.  Off by default.  Turning");
        pw.println("    on makes get-battery-seq useful.");
        pw.println("    on makes get-battery-seq useful.");
@@ -738,6 +785,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        pw.println("    Return whether the battery is currently considered to be charging.");
        pw.println("    Return whether the battery is currently considered to be charging.");
        pw.println("  get-battery-not-low");
        pw.println("  get-battery-not-low");
        pw.println("    Return whether the battery is currently considered to not be 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]"
        pw.println("  get-estimated-download-bytes [-u | --user USER_ID]"
                + " [-n | --namespace NAMESPACE] PACKAGE JOB_ID");
                + " [-n | --namespace NAMESPACE] PACKAGE JOB_ID");
        pw.println("    Return the most recent estimated download bytes for the job.");
        pw.println("    Return the most recent estimated download bytes for the job.");