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

Commit 05d6272b authored by Craig Mautner's avatar Craig Mautner
Browse files

Add AppWindowTokens to TaskList.

- Add/remove/move TaskLists from ActivityStack.
- Further isolate mHistory.
- Cleanup warnings by parameterizing ArrayList.
- Fix previous bugs.

Change-Id: Ife8c7b7347479c70f10467cc384283456149ac50
parent 72baa8fb
Loading
Loading
Loading
Loading
+4 −114
Original line number Diff line number Diff line
@@ -2838,13 +2838,10 @@ public final class ActivityManagerService extends ActivityManagerNative
            for (int i=0; i<activities.size(); i++) {
                ActivityRecord r = activities.get(i);
                if (!r.finishing) {
                    int index = mMainStack.indexOfTokenLocked(r.appToken);
                    if (index >= 0) {
                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
                    mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
                            null, "finish-heavy", true);
                }
            }
            }
            
            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
                    mHeavyWeightProcess.userId, 0));
@@ -8001,33 +7998,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            mMainStack.resumeTopActivityLocked(null);
        } else {
            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
            if (r != null && r.app == app) {
                // If the top running activity is from this crashing
                // process, then terminate it to avoid getting in a loop.
                Slog.w(TAG, "  Force finishing activity "
                        + r.intent.getComponent().flattenToShortString());
                int index = mMainStack.indexOfActivityLocked(r);
                r.stack.finishActivityLocked(r, index,
                        Activity.RESULT_CANCELED, null, "crashed", false);
                // Also terminate any activities below it that aren't yet
                // stopped, to avoid a situation where one will get
                // re-start our crashing activity once it gets resumed again.
                index--;
                if (index >= 0) {
                    r = mMainStack.getActivityAtIndex(index);
                    if (r.state == ActivityState.RESUMED
                            || r.state == ActivityState.PAUSING
                            || r.state == ActivityState.PAUSED) {
                        if (!r.isHomeActivity || mHomeProcess != r.app) {
                            Slog.w(TAG, "  Force finishing activity "
                                    + r.intent.getComponent().flattenToShortString());
                            r.stack.finishActivityLocked(r, index,
                                    Activity.RESULT_CANCELED, null, "crashed", false);
                        }
                    }
                }
            }
            mMainStack.finishTopRunningActivityLocked(app);
        }
        // Bump up the crash count of any services currently running in the proc.
@@ -12364,7 +12335,6 @@ public final class ActivityManagerService extends ActivityManagerNative
    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
            Intent resultData) {
        ComponentName dest = destIntent.getComponent();
        synchronized (this) {
            ActivityRecord srec = ActivityRecord.forToken(token);
@@ -12372,87 +12342,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                return false;
            }
            ActivityStack stack = srec.stack;
            final int start = stack.indexOfActivityLocked(srec);
            if (start < 0) {
                // Current activity is not in history stack; do nothing.
                return false;
            }
            int finishTo = start - 1;
            ActivityRecord parent = null;
            boolean foundParentInTask = false;
            if (dest != null) {
                TaskRecord tr = srec.task;
                for (int i = start - 1; i >= 0; i--) {
                    ActivityRecord r = stack.getActivityAtIndex(i);
                    if (tr != r.task) {
                        // Couldn't find parent in the same task; stop at the one above this.
                        // (Root of current task; in-app "home" behavior)
                        // Always at least finish the current activity.
                        finishTo = Math.min(start - 1, i + 1);
                        parent = stack.getActivityAtIndex(finishTo);
                        break;
                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
                            r.info.name.equals(dest.getClassName())) {
                        finishTo = i;
                        parent = r;
                        foundParentInTask = true;
                        break;
                    }
                }
            }
            if (mController != null) {
                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
                if (next != null) {
                    // ask watcher if this is allowed
                    boolean resumeOK = true;
                    try {
                        resumeOK = mController.activityResuming(next.packageName);
                    } catch (RemoteException e) {
                        mController = null;
                    }
                    if (!resumeOK) {
                        return false;
                    }
                }
            }
            final long origId = Binder.clearCallingIdentity();
            for (int i = start; i > finishTo; i--) {
                ActivityRecord r = stack.getActivityAtIndex(i);
                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
                        "navigate-up", true);
                // Only return the supplied result for the first activity finished
                resultCode = Activity.RESULT_CANCELED;
                resultData = null;
            }
            if (parent != null && foundParentInTask) {
                final int parentLaunchMode = parent.info.launchMode;
                final int destIntentFlags = destIntent.getFlags();
                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
                } else {
                    try {
                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
                                destIntent.getComponent(), 0, srec.userId);
                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
                                null, aInfo, parent.appToken, null,
                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
                                0, null, true, null);
                        foundParentInTask = res == ActivityManager.START_SUCCESS;
                    } catch (RemoteException e) {
                        foundParentInTask = false;
                    }
                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
                            resultData, "navigate-up", true);
                }
            }
            Binder.restoreCallingIdentity(origId);
            return foundParentInTask;
            return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData);
        }
    }
+3 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.server.am.ActivityStack.ActivityState;

import android.app.Activity;
import android.app.ActivityOptions;
import android.app.ResultInfo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -95,9 +96,9 @@ final class ActivityRecord {
    ActivityRecord resultTo; // who started this entry, so will get our reply
    final String resultWho; // additional identifier for use by resultTo.
    final int requestCode;  // code given by requester (resultTo)
    ArrayList results;      // pending ActivityResult objs we have received
    ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
    HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
    ArrayList newIntents;   // any pending new intents for single-top mode
    ArrayList<Intent> newIntents; // any pending new intents for single-top mode
    ActivityOptions pendingOptions; // most recently given options
    HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
    UriPermissionOwner uriPermissions; // current special URI access perms.
+165 −35
Original line number Diff line number Diff line
@@ -24,11 +24,13 @@ import com.android.internal.os.BatteryStatsImpl;
import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.wm.AppTransition;
import com.android.server.wm.TaskGroup;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
import android.app.IActivityManager;
import android.app.IThumbnailReceiver;
import android.app.IThumbnailRetriever;
@@ -501,14 +503,10 @@ final class ActivityStack {
        return null;
    }

    final int indexOfTokenLocked(IBinder token) {
    private final int indexOfTokenLocked(IBinder token) {
        return mHistory.indexOf(ActivityRecord.forToken(token));
    }

    final int indexOfActivityLocked(ActivityRecord r) {
        return mHistory.indexOf(r);
    }

    final ActivityRecord isInStackLocked(IBinder token) {
        ActivityRecord r = ActivityRecord.forToken(token);
        if (mHistory.contains(r)) {
@@ -517,14 +515,6 @@ final class ActivityStack {
        return null;
    }

    // TODO: This exposes mHistory too much, replace usage with ActivityStack methods. 
    final ActivityRecord getActivityAtIndex(int index) {
        if (index >= 0 && index < mHistory.size()) {
            return mHistory.get(index);
        }
        return null;
    }

    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
        TaskRecord lastTask = null;
        final int N = mHistory.size();
@@ -745,9 +735,15 @@ final class ActivityStack {
                try {
                    profileFd = profileFd.dup();
                } catch (IOException e) {
                    if (profileFd != null) {
                        try {
                            profileFd.close();
                        } catch (IOException o) {
                        }
                        profileFd = null;
                    }
                }
            }
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    new Configuration(mService.mConfiguration),
@@ -1758,7 +1754,7 @@ final class ActivityStack {
            
            try {
                // Deliver all pending results.
                ArrayList a = next.results;
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
@@ -2156,6 +2152,7 @@ final class ActivityStack {
                            }
                            i++;
                        }
                        mService.mWindowManager.moveTaskToBottom(target.task.taskId);
                        if (taskTop == p) {
                            taskTop = below;
                        }
@@ -2304,6 +2301,8 @@ final class ActivityStack {
                            validateAppTokensLocked();
                        }
                    }
                    // TODO: This is wrong because it doesn't take lastReparentPos into account.
                    mService.mWindowManager.moveTaskToTop(task.taskId);
                    replyChainEnd = -1;
                    
                    // Now we've moved it in to place...  but what if this is
@@ -2413,7 +2412,7 @@ final class ActivityStack {
                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
                    if (!ret.finishing) {
                        int index = indexOfTokenLocked(ret.appToken);
                        int index = mHistory.indexOf(ret);
                        if (index >= 0) {
                            finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
                                    null, "clear", false);
@@ -3568,7 +3567,7 @@ final class ActivityStack {
            }

            // Get the activity record.
            int index = indexOfActivityLocked(r);
            int index = mHistory.indexOf(r);
            if (index >= 0) {
                res = r;

@@ -3654,7 +3653,7 @@ final class ActivityStack {
        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (i=0; i<NS; i++) {
            ActivityRecord r = (ActivityRecord)stops.get(i);
            ActivityRecord r = stops.get(i);
            synchronized (mService) {
                if (r.finishing) {
                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
@@ -3667,7 +3666,7 @@ final class ActivityStack {
        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (i=0; i<NF; i++) {
            ActivityRecord r = (ActivityRecord)finishes.get(i);
            ActivityRecord r = finishes.get(i);
            synchronized (mService) {
                activityRemoved = destroyActivityLocked(r, true, false, "finish-idle");
            }
@@ -3675,7 +3674,7 @@ final class ActivityStack {

        // Report back to any thumbnail receivers.
        for (i=0; i<NT; i++) {
            ActivityRecord r = (ActivityRecord)thumbnails.get(i);
            ActivityRecord r = thumbnails.get(i);
            mService.sendPendingThumbnail(r, null, null, null, true);
        }

@@ -3730,7 +3729,7 @@ final class ActivityStack {

        int i;
        for (i=mHistory.size()-1; i>=0; i--) {
            ActivityRecord r = (ActivityRecord)mHistory.get(i);
            ActivityRecord r = mHistory.get(i);
            if (r.resultTo == self && r.requestCode == requestCode) {
                if ((r.resultWho == null && resultWho == null) ||
                    (r.resultWho != null && r.resultWho.equals(resultWho))) {
@@ -3742,6 +3741,36 @@ final class ActivityStack {
        mService.updateOomAdjLocked();
    }

    final void finishTopRunningActivityLocked(ProcessRecord app) {
        ActivityRecord r = topRunningActivityLocked(null);
        if (r != null && r.app == app) {
            // If the top running activity is from this crashing
            // process, then terminate it to avoid getting in a loop.
            Slog.w(TAG, "  Force finishing activity "
                    + r.intent.getComponent().flattenToShortString());
            int index = mHistory.indexOf(r);
            r.stack.finishActivityLocked(r, index,
                    Activity.RESULT_CANCELED, null, "crashed", false);
            // Also terminate any activities below it that aren't yet
            // stopped, to avoid a situation where one will get
            // re-start our crashing activity once it gets resumed again.
            index--;
            if (index >= 0) {
                r = mHistory.get(index);
                if (r.state == ActivityState.RESUMED
                        || r.state == ActivityState.PAUSING
                        || r.state == ActivityState.PAUSED) {
                    if (!r.isHomeActivity || mService.mHomeProcess != r.app) {
                        Slog.w(TAG, "  Force finishing activity "
                                + r.intent.getComponent().flattenToShortString());
                        r.stack.finishActivityLocked(r, index,
                                Activity.RESULT_CANCELED, null, "crashed", false);
                    }
                }
            }
        }
    }

    final boolean finishActivityAffinityLocked(IBinder token) {
        int index = indexOfTokenLocked(token);
        if (DEBUG_RESULTS) Slog.v(
@@ -3796,6 +3825,19 @@ final class ActivityStack {
        r.icicle = null;
    }

    /**
     * @return Returns true if this activity has been removed from the history
     * list, or false if it is still in the list and will be removed later.
     */
    final boolean finishActivityLocked(ActivityRecord r,
            int resultCode, Intent resultData, String reason, boolean oomAdj) {
        int index = mHistory.indexOf(r);
        if (index >= 0) {
            return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj);
        }
        return false;
    }

    /**
     * @return Returns true if this activity has been removed from the history
     * list, or false if it is still in the list and will be removed later.
@@ -3892,7 +3934,7 @@ final class ActivityStack {

    private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
            int mode, boolean oomAdj) {
        final int index = indexOfActivityLocked(r);
        final int index = mHistory.indexOf(r);
        if (index < 0) {
            return null;
        }
@@ -3948,16 +3990,102 @@ final class ActivityStack {
                resumeTopActivityLocked(null);
            }
            return activityRemoved ? null : r;
        } else {
        }

        // Need to go through the full pause cycle to get this
        // activity into the stopped state and then finish it.
        if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
        mFinishingActivities.add(r);
        resumeTopActivityLocked(null);
        }
        return r;
    }

    final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
            Intent resultData) {
        final int start = mHistory.indexOf(srec);
        if (start < 0) {
            // Current activity is not in history stack; do nothing.
            return false;
        }
        int finishTo = start - 1;
        ActivityRecord parent = null;
        boolean foundParentInTask = false;
        ComponentName dest = destIntent.getComponent();
        if (dest != null) {
            TaskRecord tr = srec.task;
            for (int i = start - 1; i >= 0; i--) {
                ActivityRecord r = mHistory.get(i);
                if (tr != r.task) {
                    // Couldn't find parent in the same task; stop at the one above this.
                    // (Root of current task; in-app "home" behavior)
                    // Always at least finish the current activity.
                    finishTo = Math.min(start - 1, i + 1);
                    parent = mHistory.get(finishTo);
                    break;
                } else if (r.info.packageName.equals(dest.getPackageName()) &&
                        r.info.name.equals(dest.getClassName())) {
                    finishTo = i;
                    parent = r;
                    foundParentInTask = true;
                    break;
                }
            }
        }

        IActivityController controller = mService.mController;
        if (controller != null) {
            ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
            if (next != null) {
                // ask watcher if this is allowed
                boolean resumeOK = true;
                try {
                    resumeOK = controller.activityResuming(next.packageName);
                } catch (RemoteException e) {
                    mService.mController = null;
                }

                if (!resumeOK) {
                    return false;
                }
            }
        }
        final long origId = Binder.clearCallingIdentity();
        for (int i = start; i > finishTo; i--) {
            ActivityRecord r = mHistory.get(i);
            requestFinishActivityLocked(r.appToken, resultCode, resultData,
                    "navigate-up", true);
            // Only return the supplied result for the first activity finished
            resultCode = Activity.RESULT_CANCELED;
            resultData = null;
        }

        if (parent != null && foundParentInTask) {
            final int parentLaunchMode = parent.info.launchMode;
            final int destIntentFlags = destIntent.getFlags();
            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
            } else {
                try {
                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
                            destIntent.getComponent(), 0, srec.userId);
                    int res = startActivityLocked(srec.app.thread, destIntent,
                            null, aInfo, parent.appToken, null,
                            0, -1, parent.launchedFromUid, parent.launchedFromPackage,
                            0, null, true, null);
                    foundParentInTask = res == ActivityManager.START_SUCCESS;
                } catch (RemoteException e) {
                    foundParentInTask = false;
                }
                requestFinishActivityLocked(parent.appToken, resultCode,
                        resultData, "navigate-up", true);
            }
        }
        Binder.restoreCallingIdentity(origId);
        return foundParentInTask;
    }
    /**
     * Perform the common clean-up of an activity record.  This is called both
     * as part of destroyActivityLocked() (when destroying the client-side
@@ -4216,7 +4344,7 @@ final class ActivityStack {
                    mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
                }

                int index = indexOfActivityLocked(r);
                int index = mHistory.indexOf(r);
                if (index >= 0) {
                    if (r.state == ActivityState.DESTROYING) {
                        cleanUpActivityLocked(r, true, false);
@@ -4230,15 +4358,15 @@ final class ActivityStack {
        }
    }
    
    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
            String listName) {
    private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
            ProcessRecord app, String listName) {
        int i = list.size();
        if (DEBUG_CLEANUP) Slog.v(
            TAG, "Removing app " + app + " from list " + listName
            + " with " + i + " entries");
        while (i > 0) {
            i--;
            ActivityRecord r = (ActivityRecord)list.get(i);
            ActivityRecord r = list.get(i);
            if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
            if (r.app == app) {
                if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
@@ -4264,7 +4392,7 @@ final class ActivityStack {
            TAG, "Removing app " + app + " from history with " + i + " entries");
        while (i > 0) {
            i--;
            ActivityRecord r = (ActivityRecord)mHistory.get(i);
            ActivityRecord r = mHistory.get(i);
            if (DEBUG_CLEANUP) Slog.v(
                TAG, "Record #" + i + " " + r + ": app=" + r.app);
            if (r.app == app) {
@@ -4440,6 +4568,7 @@ final class ActivityStack {
        if (VALIDATE_TOKENS) {
            validateAppTokensLocked();
        }
        mService.mWindowManager.moveTaskToTop(task);

        finishTaskMoveLocked(task);
        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task);
@@ -4532,6 +4661,7 @@ final class ActivityStack {
        if (VALIDATE_TOKENS) {
            validateAppTokensLocked();
        }
        mService.mWindowManager.moveTaskToBottom(task);

        finishTaskMoveLocked(task);
        return true;
@@ -4561,9 +4691,8 @@ final class ActivityStack {
        TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
        if (info.numSubThumbbails <= 0) {
            return info.mainThumbnail != null ? info.mainThumbnail : tr.lastThumbnail;
        } else {
            return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
        }
        return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
    }

    public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
@@ -4643,6 +4772,7 @@ final class ActivityStack {
        }
        if (thumbs.numSubThumbbails > 0) {
            thumbs.retriever = new IThumbnailRetriever.Stub() {
                @Override
                public Bitmap getThumbnail(int index) {
                    if (index < 0 || index >= thumbs.subtasks.size()) {
                        return null;
+135 −10

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.server.am;
package com.android.server.wm;

import android.view.IApplicationToken;

Loading