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

Commit bb79690b authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Revert^2 "Add exemptions to flex policy."" into main

parents 3342ec9a db03591e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
@@ -77,6 +78,9 @@ public interface DeviceIdleInternal {

    int[] getPowerSaveTempWhitelistAppIds();

    @NonNull
    String[] getFullPowerWhitelistExceptIdle();

    /**
     * Listener to be notified when DeviceIdleController determines that the device has moved or is
     * stationary.
+12 −4
Original line number Diff line number Diff line
@@ -2374,6 +2374,11 @@ public class DeviceIdleController extends SystemService
            return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
        }

        @Override
        public String[] getFullPowerWhitelistExceptIdle() {
            return DeviceIdleController.this.getFullPowerWhitelistInternalUnchecked();
        }

        /**
         * Returns the array of app ids whitelisted by user. Take care not to
         * modify this, as it is a reference to the original copy. But the reference
@@ -3100,10 +3105,14 @@ public class DeviceIdleController extends SystemService
    }

    private String[] getFullPowerWhitelistInternal(final int callingUid, final int callingUserId) {
        final String[] apps;
        return ArrayUtils.filter(getFullPowerWhitelistInternalUnchecked(), String[]::new,
                (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId));
    }

    private String[] getFullPowerWhitelistInternalUnchecked() {
        synchronized (this) {
            int size = mPowerSaveWhitelistApps.size() + mPowerSaveWhitelistUserApps.size();
            apps = new String[size];
            final String[] apps = new String[size];
            int cur = 0;
            for (int i = 0; i < mPowerSaveWhitelistApps.size(); i++) {
                apps[cur] = mPowerSaveWhitelistApps.keyAt(i);
@@ -3113,9 +3122,8 @@ public class DeviceIdleController extends SystemService
                apps[cur] = mPowerSaveWhitelistUserApps.keyAt(i);
                cur++;
            }
            return apps;
        }
        return ArrayUtils.filter(apps, String[]::new,
                (pkg) -> !mPackageManagerInternal.filterAppAccess(pkg, callingUid, callingUserId));
    }

    public boolean isPowerSaveWhitelistExceptIdleAppInternal(String packageName) {
+4 −0
Original line number Diff line number Diff line
@@ -318,6 +318,10 @@ public final class BackgroundJobsController extends StateController {

        try {
            final boolean isStopped = mPackageManagerInternal.isPackageStopped(packageName, uid);
            if (DEBUG) {
                Slog.d(TAG,
                        "Pulled stopped state of " + packageName + " (" + uid + "): " + isStopped);
            }
            mPackageStoppedState.add(uid, packageName, isStopped);
            return isStopped;
        } catch (PackageManager.NameNotFoundException e) {
+145 −18
Original line number Diff line number Diff line
@@ -30,11 +30,15 @@ import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.job.JobInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
@@ -48,6 +52,8 @@ import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.AppSchedulingModuleThread;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.utils.AlarmQueue;

@@ -127,6 +133,19 @@ public final class FlexibilityController extends StateController {
    @GuardedBy("mLock")
    private final SparseLongArray mLastSeenConstraintTimesElapsed = new SparseLongArray();

    private DeviceIdleInternal mDeviceIdleInternal;
    private final ArraySet<String> mPowerAllowlistedApps = new ArraySet<>();

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
                    mHandler.post(FlexibilityController.this::updatePowerAllowlistCache);
                    break;
            }
        }
    };
    @VisibleForTesting
    @GuardedBy("mLock")
    final FlexibilityTracker mFlexibilityTracker;
@@ -180,8 +199,16 @@ public final class FlexibilityController extends StateController {
                }
            };

    private static final int MSG_UPDATE_JOBS = 0;
    private static final int MSG_UPDATE_JOB = 1;
    private static final int MSG_CHECK_ALL_JOBS = 0;
    /** Check the jobs in {@link #mJobsToCheck} */
    private static final int MSG_CHECK_JOBS = 1;
    /** Check the jobs of packages in {@link #mPackagesToCheck} */
    private static final int MSG_CHECK_PACKAGES = 2;

    @GuardedBy("mLock")
    private final ArraySet<JobStatus> mJobsToCheck = new ArraySet<>();
    @GuardedBy("mLock")
    private final ArraySet<String> mPackagesToCheck = new ArraySet<>();

    public FlexibilityController(
            JobSchedulerService service, PrefetchController prefetchController) {
@@ -204,6 +231,16 @@ public final class FlexibilityController extends StateController {
        mPercentToDropConstraints =
                mFcConfig.DEFAULT_PERCENT_TO_DROP_FLEXIBLE_CONSTRAINTS;
        mPrefetchController = prefetchController;

        if (mFlexibilityEnabled) {
            registerBroadcastReceiver();
        }
    }

    @Override
    public void onSystemServicesReady() {
        mDeviceIdleInternal = LocalServices.getService(DeviceIdleInternal.class);
        mHandler.post(FlexibilityController.this::updatePowerAllowlistCache);
    }

    @Override
@@ -241,6 +278,7 @@ public final class FlexibilityController extends StateController {
            mFlexibilityAlarmQueue.removeAlarmForKey(js);
            mFlexibilityTracker.remove(js);
        }
        mJobsToCheck.remove(js);
    }

    @Override
@@ -266,7 +304,14 @@ public final class FlexibilityController extends StateController {
    @GuardedBy("mLock")
    boolean isFlexibilitySatisfiedLocked(JobStatus js) {
        return !mFlexibilityEnabled
                // Exclude all jobs of the TOP app
                || mService.getUidBias(js.getSourceUid()) == JobInfo.BIAS_TOP_APP
                // Only exclude DEFAULT+ priority jobs for BFGS+ apps
                || (mService.getUidBias(js.getSourceUid()) >= JobInfo.BIAS_BOUND_FOREGROUND_SERVICE
                        && js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT)
                // For apps in the power allowlist, automatically exclude DEFAULT+ priority jobs.
                || (js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT
                        && mPowerAllowlistedApps.contains(js.getSourcePackageName()))
                || hasEnoughSatisfiedConstraintsLocked(js)
                || mService.isCurrentlyRunningLocked(js);
    }
@@ -371,7 +416,7 @@ public final class FlexibilityController extends StateController {

                // Push the job update to the handler to avoid blocking other controllers and
                // potentially batch back-to-back controller state updates together.
                mHandler.obtainMessage(MSG_UPDATE_JOBS).sendToTarget();
                mHandler.obtainMessage(MSG_CHECK_ALL_JOBS).sendToTarget();
            }
        }
    }
@@ -485,7 +530,9 @@ public final class FlexibilityController extends StateController {
    @Override
    @GuardedBy("mLock")
    public void onUidBiasChangedLocked(int uid, int prevBias, int newBias) {
        if (prevBias != JobInfo.BIAS_TOP_APP && newBias != JobInfo.BIAS_TOP_APP) {
        if (prevBias < JobInfo.BIAS_BOUND_FOREGROUND_SERVICE
                && newBias < JobInfo.BIAS_BOUND_FOREGROUND_SERVICE) {
            // All changes are below BFGS. There's no significant change to care about.
            return;
        }
        final long nowElapsed = sElapsedRealtimeClock.millis();
@@ -557,6 +604,39 @@ public final class FlexibilityController extends StateController {
        mFcConfig.processConstantLocked(properties, key);
    }

    private void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
        mContext.registerReceiver(mBroadcastReceiver, filter);
    }

    private void unregisterBroadcastReceiver() {
        mContext.unregisterReceiver(mBroadcastReceiver);
    }

    private void updatePowerAllowlistCache() {
        if (mDeviceIdleInternal == null) {
            return;
        }

        // Don't call out to DeviceIdleController with the lock held.
        final String[] allowlistedPkgs = mDeviceIdleInternal.getFullPowerWhitelistExceptIdle();
        final ArraySet<String> changedPkgs = new ArraySet<>();
        synchronized (mLock) {
            changedPkgs.addAll(mPowerAllowlistedApps);
            mPowerAllowlistedApps.clear();
            for (final String pkgName : allowlistedPkgs) {
                mPowerAllowlistedApps.add(pkgName);
                if (changedPkgs.contains(pkgName)) {
                    changedPkgs.remove(pkgName);
                } else {
                    changedPkgs.add(pkgName);
                }
            }
            mPackagesToCheck.addAll(changedPkgs);
            mHandler.sendEmptyMessage(MSG_CHECK_PACKAGES);
        }
    }

    @VisibleForTesting
    class FlexibilityTracker {
        final ArrayList<ArraySet<JobStatus>> mTrackedJobs;
@@ -710,7 +790,8 @@ public final class FlexibilityController extends StateController {
                    }
                    mFlexibilityTracker.setNumDroppedFlexibleConstraints(js,
                            js.getNumAppliedFlexibleConstraints());
                    mHandler.obtainMessage(MSG_UPDATE_JOB, js).sendToTarget();
                    mJobsToCheck.add(js);
                    mHandler.sendEmptyMessage(MSG_CHECK_JOBS);
                    return;
                }
                if (nextTimeElapsed == NO_LIFECYCLE_END) {
@@ -761,10 +842,12 @@ public final class FlexibilityController extends StateController {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_JOBS:
                    removeMessages(MSG_UPDATE_JOBS);
                case MSG_CHECK_ALL_JOBS:
                    removeMessages(MSG_CHECK_ALL_JOBS);

                    synchronized (mLock) {
                        mJobsToCheck.clear();
                        mPackagesToCheck.clear();
                        final long nowElapsed = sElapsedRealtimeClock.millis();
                        final ArraySet<JobStatus> changedJobs = new ArraySet<>();

@@ -790,19 +873,50 @@ public final class FlexibilityController extends StateController {
                    }
                    break;

                case MSG_UPDATE_JOB:
                case MSG_CHECK_JOBS:
                    synchronized (mLock) {
                        final JobStatus js = (JobStatus) msg.obj;
                        final long nowElapsed = sElapsedRealtimeClock.millis();
                        ArraySet<JobStatus> changedJobs = new ArraySet<>();

                        for (int i = mJobsToCheck.size() - 1; i >= 0; --i) {
                            final JobStatus js = mJobsToCheck.valueAt(i);
                            if (DEBUG) {
                            Slog.d("blah", "Checking on " + js.toShortString());
                                Slog.d(TAG, "Checking on " + js.toShortString());
                            }
                            if (js.setFlexibilityConstraintSatisfied(
                                    nowElapsed, isFlexibilitySatisfiedLocked(js))) {
                                changedJobs.add(js);
                            }
                        }

                        mJobsToCheck.clear();
                        if (changedJobs.size() > 0) {
                            mStateChangedListener.onControllerStateChanged(changedJobs);
                        }
                    }
                    break;

                case MSG_CHECK_PACKAGES:
                    synchronized (mLock) {
                        final long nowElapsed = sElapsedRealtimeClock.millis();
                        final ArraySet<JobStatus> changedJobs = new ArraySet<>();

                        mService.getJobStore().forEachJob(
                                (js) -> mPackagesToCheck.contains(js.getSourcePackageName())
                                        || mPackagesToCheck.contains(js.getCallingPackageName()),
                                (js) -> {
                                    if (DEBUG) {
                                        Slog.d(TAG, "Checking on " + js.toShortString());
                                    }
                                    if (js.setFlexibilityConstraintSatisfied(
                                            nowElapsed, isFlexibilitySatisfiedLocked(js))) {
                            // TODO(141645789): add method that will take a single job
                            ArraySet<JobStatus> changedJob = new ArraySet<>();
                            changedJob.add(js);
                            mStateChangedListener.onControllerStateChanged(changedJob);
                                        changedJobs.add(js);
                                    }
                                });

                        mPackagesToCheck.clear();
                        if (changedJobs.size() > 0) {
                            mStateChangedListener.onControllerStateChanged(changedJobs);
                        }
                    }
                    break;
@@ -882,10 +996,12 @@ public final class FlexibilityController extends StateController {
                            mFlexibilityEnabled = true;
                            mPrefetchController
                                    .registerPrefetchChangedListener(mPrefetchChangedListener);
                            registerBroadcastReceiver();
                        } else {
                            mFlexibilityEnabled = false;
                            mPrefetchController
                                    .unRegisterPrefetchChangedListener(mPrefetchChangedListener);
                            unregisterBroadcastReceiver();
                        }
                    }
                    break;
@@ -985,7 +1101,14 @@ public final class FlexibilityController extends StateController {
            pw.println(":");
            pw.increaseIndent();

            pw.print(KEY_APPLIED_CONSTRAINTS, APPLIED_CONSTRAINTS).println();
            pw.print(KEY_APPLIED_CONSTRAINTS, APPLIED_CONSTRAINTS);
            pw.print("(");
            if (APPLIED_CONSTRAINTS != 0) {
                JobStatus.dumpConstraints(pw, APPLIED_CONSTRAINTS);
            } else {
                pw.print("nothing");
            }
            pw.println(")");
            pw.print(KEY_DEADLINE_PROXIMITY_LIMIT, DEADLINE_PROXIMITY_LIMIT_MS).println();
            pw.print(KEY_FALLBACK_FLEXIBILITY_DEADLINE, FALLBACK_FLEXIBILITY_DEADLINE_MS).println();
            pw.print(KEY_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS,
@@ -1043,6 +1166,10 @@ public final class FlexibilityController extends StateController {
        }
        pw.decreaseIndent();

        pw.println();
        pw.print("Power allowlisted packages: ");
        pw.println(mPowerAllowlistedApps);

        pw.println();
        mFlexibilityTracker.dump(pw, predicate);
        pw.println();
+122 −16

File changed.

Preview size limit exceeded, changes collapsed.