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

Commit 4ccec532 authored by Andrei Stingaceanu's avatar Andrei Stingaceanu
Browse files

Hide suspended apps from recents

* Introduce a new boolean realActivitySuspended in TaskRecord to
keep track of the suspended state (this also makes sure the
information is persisted across reboots).
* Introduce a new method onPackagesSuspendedChanged
in RecentTasks which flips the realActivitySuspended for each
TaskRecord for the desired user and packages sent
* Register a new broadcast receiver (for SUSPEND/UNSUSPEND)
in ActivityManager#finishBooting which calls
RecentTasks#markPackagesSuspendedStateForUser
* In ActivityManagerService#getRecentTasks filter out
Taskrecords for suspended apps by checking realActivitySuspended

Bug: 22776761
Change-Id: I52e3593ccb2dae223d1ea11d017a6b1626646639
parent de32f98b
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -9003,6 +9003,11 @@ public final class ActivityManagerService extends ActivityManagerNative
                    continue;
                }
                if (tr.realActivitySuspended) {
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
                    continue;
                }
                // Return the entry if desired by the caller.  We always return
                // the first entry, because callers always expect this to be the
                // foreground app.  We may filter others if the caller has
@@ -17587,6 +17592,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                case Intent.ACTION_PACKAGE_CHANGED:
                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                case Intent.ACTION_PACKAGES_SUSPENDED:
                case Intent.ACTION_PACKAGES_UNSUSPENDED:
                    // Handle special intents: if this broadcast is from the package
                    // manager about a package being removed, we need to remove all of
                    // its activities from the history stack.
@@ -17667,6 +17674,20 @@ public final class ActivityManagerService extends ActivityManagerNative
                                }
                            }
                            break;
                        case Intent.ACTION_PACKAGES_SUSPENDED:
                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
                                    intent.getAction());
                            final String[] packageNames = intent.getStringArrayExtra(
                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
                            final int userHandle = intent.getIntExtra(
                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                            synchronized(ActivityManagerService.this) {
                                mRecentTasks.onPackagesSuspendedChanged(
                                        packageNames, suspended, userHandle);
                            }
                            break;
                    }
                    break;
                case Intent.ACTION_PACKAGE_ADDED:
+18 −1
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;

import com.google.android.collect.Sets;

import android.app.ActivityManager;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -45,6 +47,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Set;

/**
 * Class for managing the recent tasks list.
@@ -188,6 +191,21 @@ class RecentTasks extends ArrayList<TaskRecord> {
        }
    }

    void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
        final Set<String> packageNames = Sets.newHashSet(packages);
        for (int i = size() - 1; i >= 0; --i) {
            final TaskRecord tr = get(i);
            if (tr.realActivity != null
                    && packageNames.contains(tr.realActivity.getPackageName())
                    && tr.userId == userId
                    && tr.realActivitySuspended != suspended) {
               tr.realActivitySuspended = suspended;
               notifyTaskPersisterLocked(tr, false);
            }
        }

    }

    /**
     * Update the recent tasks lists: make sure tasks should still be here (their
     * applications / activities still exist), update their availability, fix-up ordering
@@ -683,5 +701,4 @@ class RecentTasks extends ArrayList<TaskRecord> {
        // Let the caller know where we left off.
        return start + tmpSize;
    }

}
+11 −2
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ final class TaskRecord {
    private static final String TAG_INTENT = "intent";
    private static final String TAG_AFFINITYINTENT = "affinity_intent";
    static final String ATTR_REALACTIVITY = "real_activity";
    static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
    private static final String ATTR_ORIGACTIVITY = "orig_activity";
    private static final String TAG_ACTIVITY = "activity";
    private static final String ATTR_AFFINITY = "affinity";
@@ -136,6 +137,8 @@ final class TaskRecord {
    int effectiveUid;       // The current effective uid of the identity of this task.
    ComponentName origActivity; // The non-alias activity component of the intent.
    ComponentName realActivity; // The actual activity component that started the task.
    boolean realActivitySuspended; // True if the actual activity component that started the
                                   // task is suspended.
    long firstActiveTime;   // First time this task was active.
    long lastActiveTime;    // Last time this task was active, including sleep.
    boolean inRecents;      // Actually in the recents list?
@@ -305,7 +308,7 @@ final class TaskRecord {
            boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
            TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
            int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
            boolean resizeable, boolean privileged) {
            boolean resizeable, boolean privileged, boolean realActivitySuspended) {
        mService = service;
        mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                TaskPersister.IMAGE_EXTENSION;
@@ -319,6 +322,7 @@ final class TaskRecord {
        voiceSession = null;
        voiceInteractor = null;
        realActivity = _realActivity;
        realActivitySuspended = realActivitySuspended;
        origActivity = _origActivity;
        rootWasReset = _rootWasReset;
        isAvailable = true;
@@ -1027,6 +1031,7 @@ final class TaskRecord {
        if (realActivity != null) {
            out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
        }
        out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
        if (origActivity != null) {
            out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
        }
@@ -1105,6 +1110,7 @@ final class TaskRecord {
        Intent affinityIntent = null;
        ArrayList<ActivityRecord> activities = new ArrayList<>();
        ComponentName realActivity = null;
        boolean realActivitySuspended = false;
        ComponentName origActivity = null;
        String affinity = null;
        String rootAffinity = null;
@@ -1143,6 +1149,8 @@ final class TaskRecord {
                if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
            } else if (ATTR_REALACTIVITY.equals(attrName)) {
                realActivity = ComponentName.unflattenFromString(attrValue);
            } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
                realActivitySuspended = Boolean.valueOf(attrValue);
            } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
                origActivity = ComponentName.unflattenFromString(attrValue);
            } else if (ATTR_AFFINITY.equals(attrName)) {
@@ -1253,7 +1261,8 @@ final class TaskRecord {
                autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
                activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
                taskAffiliationColor, callingUid, callingPackage, resizeable, privileged);
                taskAffiliationColor, callingUid, callingPackage, resizeable, privileged,
                realActivitySuspended);
        task.updateOverrideConfiguration(bounds);

        for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {