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

Commit 10973add authored by Kweku Adams's avatar Kweku Adams
Browse files

Remove incorrect assumption.

The initial assumption was that PACKAGE_RESTARTED meant that the app
would be put into the stopped state and be kept in the stopped state
until the PACKAGE_UNSTOPPED broadcast was sent. However, there are cases
where the PACKAGE_RESTARTED broadcast is sent but the app is not put and
kept in the stopped state (eg. clearing app data). Change the logic to
no longer assume that PACKAGE_RESTARTED means the app is put and kept in
the stopped state.

Bug: 315171674
Test: atest android.permissionui.cts.SafetyLabelChangesJobServiceTest#runNotificationJob_packageSourceUnspecified_updatesSafetyLabelHistoryForApps
Test: atest FrameworksMockingServicesTests:BackgroundJobsControllerTest
Change-Id: I23efa966b4963ca1777bdac58bbdad2f250c4984
parent b9fc6225
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -98,7 +98,10 @@ public final class BackgroundJobsController extends StateController {
            switch (action) {
                case Intent.ACTION_PACKAGE_RESTARTED: {
                    synchronized (mLock) {
                        mPackageStoppedState.add(pkgUid, pkgName, Boolean.TRUE);
                        // ACTION_PACKAGE_RESTARTED doesn't always mean the app is placed and kept
                        // in the stopped state, so don't put TRUE in the cache. Remove any existing
                        // entry and rely on an explicit call to PackageManager's isStopped() API.
                        mPackageStoppedState.delete(pkgUid, pkgName);
                        updateJobRestrictionsForUidLocked(pkgUid, false);
                    }
                }
+46 −8
Original line number Diff line number Diff line
@@ -167,6 +167,11 @@ public class BackgroundJobsControllerTest {
    }

    private void setStoppedState(int uid, String pkgName, boolean stopped) {
        doReturn(stopped).when(mPackageManagerInternal).isPackageStopped(pkgName, uid);
        sendPackageStoppedBroadcast(uid, pkgName, stopped);
    }

    private void sendPackageStoppedBroadcast(int uid, String pkgName, boolean stopped) {
        Intent intent = new Intent(
                stopped ? Intent.ACTION_PACKAGE_RESTARTED : Intent.ACTION_PACKAGE_UNSTOPPED);
        intent.putExtra(Intent.EXTRA_UID, uid);
@@ -174,14 +179,6 @@ public class BackgroundJobsControllerTest {
        mStoppedReceiver.onReceive(mContext, intent);
    }

    private void setUidBias(int uid, int bias) {
        int prevBias = mJobSchedulerService.getUidBias(uid);
        doReturn(bias).when(mJobSchedulerService).getUidBias(uid);
        synchronized (mBackgroundJobsController.mLock) {
            mBackgroundJobsController.onUidBiasChangedLocked(uid, prevBias, bias);
        }
    }

    private void trackJobs(JobStatus... jobs) {
        for (JobStatus job : jobs) {
            mJobStore.add(job);
@@ -207,6 +204,47 @@ public class BackgroundJobsControllerTest {
        return js;
    }

    @Test
    public void testRestartedBroadcastWithoutStopping() {
        mSetFlagsRule.enableFlags(android.content.pm.Flags.FLAG_STAY_STOPPED);
        // Scheduled by SOURCE_UID:SOURCE_PACKAGE for itself.
        JobStatus directJob1 = createJobStatus("testStopped", SOURCE_PACKAGE, SOURCE_UID,
                createBaseJobInfoBuilder(SOURCE_PACKAGE, 1).build());
        // Scheduled by ALTERNATE_UID:ALTERNATE_SOURCE_PACKAGE for itself.
        JobStatus directJob2 = createJobStatus("testStopped",
                ALTERNATE_SOURCE_PACKAGE, ALTERNATE_UID,
                createBaseJobInfoBuilder(ALTERNATE_SOURCE_PACKAGE, 2).build());
        // Scheduled by CALLING_PACKAGE for SOURCE_PACKAGE.
        JobStatus proxyJob1 = createJobStatus("testStopped", SOURCE_PACKAGE, CALLING_UID,
                createBaseJobInfoBuilder(CALLING_PACKAGE, 3).build());
        // Scheduled by CALLING_PACKAGE for ALTERNATE_SOURCE_PACKAGE.
        JobStatus proxyJob2 = createJobStatus("testStopped",
                ALTERNATE_SOURCE_PACKAGE, CALLING_UID,
                createBaseJobInfoBuilder(CALLING_PACKAGE, 4).build());

        trackJobs(directJob1, directJob2, proxyJob1, proxyJob2);

        sendPackageStoppedBroadcast(ALTERNATE_UID, ALTERNATE_SOURCE_PACKAGE, true);
        assertTrue(directJob1.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(directJob1.isUserBgRestricted());
        assertTrue(directJob2.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(directJob2.isUserBgRestricted());
        assertTrue(proxyJob1.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(proxyJob1.isUserBgRestricted());
        assertTrue(proxyJob2.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(proxyJob2.isUserBgRestricted());

        sendPackageStoppedBroadcast(ALTERNATE_UID, ALTERNATE_SOURCE_PACKAGE, false);
        assertTrue(directJob1.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(directJob1.isUserBgRestricted());
        assertTrue(directJob2.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(directJob2.isUserBgRestricted());
        assertTrue(proxyJob1.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(proxyJob1.isUserBgRestricted());
        assertTrue(proxyJob2.isConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
        assertFalse(proxyJob2.isUserBgRestricted());
    }

    @Test
    public void testStopped_disabled() {
        mSetFlagsRule.disableFlags(android.content.pm.Flags.FLAG_STAY_STOPPED);