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

Commit 8901fa17 authored by alexbianchi's avatar alexbianchi
Browse files

Disable Flexibility Controller for Android Auto

Added boolean to controller that tracks if a device supports flexible
job constraints. If a false, jobs will not be tracked and the
flexibility constraint will always be satisfied. Android Auto devices
are currently the only devices that don't support flexible job
constraints.

Bug: 238887961

Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/job
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/job
Test: atest CtsJobSchedulerTestCases
Change-Id: Iacdf25f58525d308f55d77ca7d175ec41192119c
parent 1562909b
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.job.JobInfo;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.DeviceConfig;
@@ -80,18 +81,6 @@ public final class FlexibilityController extends StateController {

    private static final long NO_LIFECYCLE_END = Long.MAX_VALUE;

    /**
     * Keeps track of what flexible constraints are satisfied at the moment.
     * Is updated by the other controllers.
     */
    @VisibleForTesting
    @GuardedBy("mLock")
    int mSatisfiedFlexibleConstraints;

    /** Hard cutoff to remove flexible constraints. */
    private long mDeadlineProximityLimitMs =
            FcConfig.DEFAULT_DEADLINE_PROXIMITY_LIMIT_MS;

    /**
     * The default deadline that all flexible constraints should be dropped by if a job lacks
     * a deadline.
@@ -109,6 +98,10 @@ public final class FlexibilityController extends StateController {
    private long mMinTimeBetweenFlexibilityAlarmsMs =
            FcConfig.DEFAULT_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS;

    /** Hard cutoff to remove flexible constraints. */
    private long mDeadlineProximityLimitMs =
            FcConfig.DEFAULT_DEADLINE_PROXIMITY_LIMIT_MS;

    /**
     * The percent of a job's lifecycle to drop number of required constraints.
     * mPercentToDropConstraints[i] denotes that at x% of a Jobs lifecycle,
@@ -116,6 +109,17 @@ public final class FlexibilityController extends StateController {
     */
    private int[] mPercentToDropConstraints;

    @VisibleForTesting
    boolean mDeviceSupportsFlexConstraints;

    /**
     * Keeps track of what flexible constraints are satisfied at the moment.
     * Is updated by the other controllers.
     */
    @VisibleForTesting
    @GuardedBy("mLock")
    int mSatisfiedFlexibleConstraints;

    @VisibleForTesting
    @GuardedBy("mLock")
    final FlexibilityTracker mFlexibilityTracker;
@@ -124,7 +128,6 @@ public final class FlexibilityController extends StateController {
    final FlexibilityAlarmQueue mFlexibilityAlarmQueue;
    @VisibleForTesting
    final FcConfig mFcConfig;

    @VisibleForTesting
    final PrefetchController mPrefetchController;

@@ -172,6 +175,9 @@ public final class FlexibilityController extends StateController {
    public FlexibilityController(
            JobSchedulerService service, PrefetchController prefetchController) {
        super(service);
        mDeviceSupportsFlexConstraints = !mContext.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE);
        mFlexibilityEnabled &= mDeviceSupportsFlexConstraints;
        mFlexibilityTracker = new FlexibilityTracker(NUM_FLEXIBLE_CONSTRAINTS);
        mFcConfig = new FcConfig();
        mFlexibilityAlarmQueue = new FlexibilityAlarmQueue(
@@ -191,10 +197,14 @@ public final class FlexibilityController extends StateController {
    @GuardedBy("mLock")
    public void maybeStartTrackingJobLocked(JobStatus js, JobStatus lastJob) {
        if (js.hasFlexibilityConstraint()) {
            mFlexibilityTracker.add(js);
            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
            final long nowElapsed = sElapsedRealtimeClock.millis();
            if (!mDeviceSupportsFlexConstraints) {
                js.setFlexibilityConstraintSatisfied(nowElapsed, true);
                return;
            }
            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
            mFlexibilityTracker.add(js);
            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed);
        }
    }
@@ -655,7 +665,8 @@ public final class FlexibilityController extends StateController {
                @NonNull String key) {
            switch (key) {
                case KEY_FLEXIBILITY_ENABLED:
                    FLEXIBILITY_ENABLED = properties.getBoolean(key, DEFAULT_FLEXIBILITY_ENABLED);
                    FLEXIBILITY_ENABLED = properties.getBoolean(key, DEFAULT_FLEXIBILITY_ENABLED)
                            && mDeviceSupportsFlexConstraints;
                    if (mFlexibilityEnabled != FLEXIBILITY_ENABLED) {
                        mFlexibilityEnabled = FLEXIBILITY_ENABLED;
                        mShouldReevaluateConstraints = true;
+6 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.BatteryManagerInternal;
import android.os.RemoteException;
@@ -75,6 +76,8 @@ public class BatteryControllerTest {
    private JobSchedulerService mJobSchedulerService;
    @Mock
    private PackageManagerInternal mPackageManagerInternal;
    @Mock
    private PackageManager mPackageManager;

    @Before
    public void setUp() {
@@ -100,6 +103,9 @@ public class BatteryControllerTest {
        ArgumentCaptor<BroadcastReceiver> receiverCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);

        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(false);
        mFlexibilityController =
                new FlexibilityController(mJobSchedulerService, mock(PrefetchController.class));
        mBatteryController = new BatteryController(mJobSchedulerService, mFlexibilityController);
+10 −4
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.annotation.Nullable;
import android.app.job.JobInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
@@ -96,6 +97,8 @@ public class ConnectivityControllerTest {
    private NetworkPolicyManagerInternal mNetPolicyManagerInternal;
    @Mock
    private JobSchedulerService mService;
    @Mock
    private PackageManager mPackageManager;

    private Constants mConstants;

@@ -115,10 +118,6 @@ public class ConnectivityControllerTest {
        LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
        LocalServices.addService(NetworkPolicyManagerInternal.class, mNetPolicyManagerInternal);

        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
        mFlexibilityController =
                new FlexibilityController(mService, mock(PrefetchController.class));

        // Freeze the clocks at this moment in time
        JobSchedulerService.sSystemClock =
                Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
@@ -142,6 +141,13 @@ public class ConnectivityControllerTest {
        when(mService.getTestableContext()).thenReturn(mContext);
        when(mService.getLock()).thenReturn(mService);
        when(mService.getConstants()).thenReturn(mConstants);
        // Instantiate Flexibility Controller
        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(false);
        mFlexibilityController =
                new FlexibilityController(mService, mock(PrefetchController.class));
    }

    @Test
+29 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.app.AlarmManager;
import android.app.job.JobInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Looper;
import android.provider.DeviceConfig;
@@ -92,6 +93,8 @@ public class FlexibilityControllerTest {
    private JobSchedulerService mJobSchedulerService;
    @Mock
    private PrefetchController mPrefetchController;
    @Mock
    private PackageManager mPackageManager;

    @Before
    public void setup() {
@@ -109,6 +112,9 @@ public class FlexibilityControllerTest {
        // Called in FlexibilityController constructor.
        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
        when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(false);
        // Used in FlexibilityController.FcConstants.
        doAnswer((Answer<Void>) invocationOnMock -> null)
                .when(() -> DeviceConfig.addOnPropertiesChangedListener(
@@ -859,6 +865,29 @@ public class FlexibilityControllerTest {

    }

    @Test
    public void testDeviceDisabledFlexibility_Auto() {
        when(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(true);
        mFlexibilityController =
                new FlexibilityController(mJobSchedulerService, mPrefetchController);
        assertFalse(mFlexibilityController.mFlexibilityEnabled);

        JobStatus js = createJobStatus("testIsAuto", createJob(0));

        mFlexibilityController.maybeStartTrackingJobLocked(js, null);
        assertTrue(js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE));

        setDeviceConfigBoolean(KEY_FLEXIBILITY_ENABLED, true);
        assertFalse(mFlexibilityController.mFlexibilityEnabled);

        ArrayList<ArraySet<JobStatus>> jobs =
                mFlexibilityController.mFlexibilityTracker.getArrayList();
        for (int i = 0; i < jobs.size(); i++) {
            assertEquals(0, jobs.get(i).size());
        }
    }

    private void setUidBias(int uid, int bias) {
        int prevBias = mJobSchedulerService.getUidBias(uid);
        doReturn(bias).when(mJobSchedulerService).getUidBias(uid);