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

Commit 2e5528c5 authored by Craig Mautner's avatar Craig Mautner Committed by Android (Google) Code Review
Browse files

Merge "Revert ActivityManager changes for tasks. DO NOT MERGE" into jb-mr2-dev

parents 19a38f6f 2ad92075
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -99,6 +99,9 @@ interface IWindowManager
    void startAppFreezingScreen(IBinder token, int configChanges);
    void stopAppFreezingScreen(IBinder token, boolean force);
    void removeAppToken(IBinder token);
    void moveAppToken(int index, IBinder token);
    void moveAppTokensToTop(in List<IBinder> tokens);
    void moveAppTokensToBottom(in List<IBinder> tokens);

    // Re-evaluate the current orientation from the caller's state.
    // If there is a change, the new Configuration is returned and the
+365 −42
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import dalvik.system.Zygote;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.ActivityThread;
@@ -197,7 +196,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    static final boolean DEBUG_MU = localLOGV || false;
    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
    static final boolean VALIDATE_TOKENS = true;
    static final boolean VALIDATE_TOKENS = false;
    static final boolean SHOW_ACTIVITY_START_TIME = true;
    
    // Control over CPU and battery monitoring.
@@ -329,7 +328,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    /**
     * List of intents that were used to start the most recent tasks.
     */
    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    public class PendingActivityExtras extends Binder implements Runnable {
        public final ActivityRecord activity;
@@ -597,8 +596,13 @@ public final class ActivityManagerService extends ActivityManagerNative
     * List of PendingThumbnailsRecord objects of clients who are still
     * waiting to receive all of the thumbnails for a task.
     */
    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
            new ArrayList<PendingThumbnailsRecord>();
    final ArrayList mPendingThumbnails = new ArrayList();
    /**
     * List of HistoryRecord objects that have been finished and must
     * still report back to a pending thumbnail receiver.
     */
    final ArrayList mCancelledThumbnails = new ArrayList();
    final ProviderMap mProviderMap;
@@ -2838,10 +2842,13 @@ public final class ActivityManagerService extends ActivityManagerNative
            for (int i=0; i<activities.size(); i++) {
                ActivityRecord r = activities.get(i);
                if (!r.finishing) {
                    mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
                    int index = mMainStack.indexOfTokenLocked(r.appToken);
                    if (index >= 0) {
                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
                                null, "finish-heavy", true);
                    }
                }
            }
            
            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
                    mHeavyWeightProcess.userId, 0));
@@ -2925,10 +2932,19 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
    }
    @Override
    public boolean willActivityBeVisible(IBinder token) {
        synchronized(this) {
            return mMainStack.willActivityBeVisibleLocked(token);
            int i;
            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
                if (r.appToken == token) {
                    return true;
                }
                if (r.fullscreen && !r.finishing) {
                    return false;
                }
            }
            return true;
        }
    }
    
@@ -3701,7 +3717,13 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        mWindowManager.closeSystemDialogs(reason);
        mMainStack.closeSystemDialogsLocked();
        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
                r.stack.finishActivityLocked(r, i,
                        Activity.RESULT_CANCELED, null, "close-sys", true);
            }
        }
        broadcastIntentLocked(null, null, intent, null,
                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
@@ -3909,11 +3931,36 @@ public final class ActivityManagerService extends ActivityManagerNative
                -100, callerWillRestart, true, doit, evenPersistent,
                name == null ? ("force stop user " + userId) : ("force stop " + name));
        
        if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
        TaskRecord lastTask = null;
        for (i=0; i<mMainStack.mHistory.size(); i++) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
            final boolean samePackage = r.packageName.equals(name)
                    || (name == null && r.userId == userId);
            if ((userId == UserHandle.USER_ALL || r.userId == userId)
                    && (samePackage || r.task == lastTask)
                    && (r.app == null || evenPersistent || !r.app.persistent)) {
                if (!doit) {
                    if (r.finishing) {
                        // If this activity is just finishing, then it is not
                        // interesting as far as something to stop.
                        continue;
                    }
                    return true;
                }
                didSomething = true;
                Slog.i(TAG, "  Force finishing activity " + r);
                if (samePackage) {
                    if (r.app != null) {
                        r.app.removed = true;
                    }
                    r.app = null;
                }
                lastTask = r.task;
                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
                        null, "force-stop", true)) {
                    i--;
                }
            }
        }
        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
@@ -5623,12 +5670,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    // TASK MANAGEMENT
    // =========================================================
    @Override
    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
    public List getTasks(int maxNum, int flags,
                         IThumbnailReceiver receiver) {
        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
        ArrayList list = new ArrayList();
        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
        PendingThumbnailsRecord pending = null;
        IApplicationThread topThumbnail = null;
        ActivityRecord topRecord = null;
        synchronized(this) {
@@ -5654,19 +5701,88 @@ public final class ActivityManagerService extends ActivityManagerNative
                throw new SecurityException(msg);
            }
            topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list);
            int pos = mMainStack.mHistory.size()-1;
            ActivityRecord next =
                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
            ActivityRecord top = null;
            TaskRecord curTask = null;
            int numActivities = 0;
            int numRunning = 0;
            while (pos >= 0 && maxNum > 0) {
                final ActivityRecord r = next;
                pos--;
                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
                // Initialize state for next task if needed.
                if (top == null ||
                        (top.state == ActivityState.INITIALIZING
                            && top.task == r.task)) {
                    top = r;
                    curTask = r.task;
                    numActivities = numRunning = 0;
                }
                // Add 'r' into the current task.
                numActivities++;
                if (r.app != null && r.app.thread != null) {
                    numRunning++;
                }
            if (!pending.pendingRecords.isEmpty()) {
                if (localLOGV) Slog.v(
                    TAG, r.intent.getComponent().flattenToShortString()
                    + ": task=" + r.task);
                // If the next one is a different task, generate a new
                // TaskInfo entry for what we have.
                if (next == null || next.task != curTask) {
                    ActivityManager.RunningTaskInfo ci
                            = new ActivityManager.RunningTaskInfo();
                    ci.id = curTask.taskId;
                    ci.baseActivity = r.intent.getComponent();
                    ci.topActivity = top.intent.getComponent();
                    if (top.thumbHolder != null) {
                        ci.description = top.thumbHolder.lastDescription;
                    }
                    ci.numActivities = numActivities;
                    ci.numRunning = numRunning;
                    //System.out.println(
                    //    "#" + maxNum + ": " + " descr=" + ci.description);
                    if (ci.thumbnail == null && receiver != null) {
                        if (localLOGV) Slog.v(
                            TAG, "State=" + top.state + "Idle=" + top.idle
                            + " app=" + top.app
                            + " thr=" + (top.app != null ? top.app.thread : null));
                        if (top.state == ActivityState.RESUMED
                                || top.state == ActivityState.PAUSING) {
                            if (top.idle && top.app != null
                                && top.app.thread != null) {
                                topRecord = top;
                                topThumbnail = top.app.thread;
                            } else {
                                top.thumbnailNeeded = true;
                            }
                        }
                        if (pending == null) {
                            pending = new PendingThumbnailsRecord(receiver);
                        }
                        pending.pendingRecords.add(top);
                    }
                    list.add(ci);
                    maxNum--;
                    top = null;
                }
            }
            if (pending != null) {
                mPendingThumbnails.add(pending);
            }
        }
        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
        if (topRecord != null) {
        if (topThumbnail != null) {
            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
            try {
                IApplicationThread topThumbnail = topRecord.app.thread;
                topThumbnail.requestThumbnail(topRecord.appToken);
            } catch (Exception e) {
                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
@@ -5901,6 +6017,43 @@ public final class ActivityManagerService extends ActivityManagerNative
        return false;
    }
    
    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
        int j;
        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 
        TaskRecord jt = startTask;
        
        // First look backwards
        for (j=startIndex-1; j>=0; j--) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
            if (r.task != jt) {
                jt = r.task;
                if (affinity.equals(jt.affinity)) {
                    return j;
                }
            }
        }
        
        // Now look forwards
        final int N = mMainStack.mHistory.size();
        jt = startTask;
        for (j=startIndex+1; j<N; j++) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
            if (r.task != jt) {
                if (affinity.equals(jt.affinity)) {
                    return j;
                }
                jt = r.task;
            }
        }
        
        // Might it be at the top?
        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
            return N-1;
        }
        
        return -1;
    }
    
    /**
     * TODO: Add mController hook
     */
@@ -5929,9 +6082,21 @@ public final class ActivityManagerService extends ActivityManagerNative
                    mMainStack.moveTaskToFrontLocked(tr, null, options);
                    return;
                }
                if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) {
                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
                    if (hr.task.taskId == task) {
                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
                            mMainStack.mUserLeaving = true;
                        }
                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
                            // Caller wants the home activity moved with it.  To accomplish this,
                            // we'll just move the home task to the top first.
                            mMainStack.moveHomeToFrontLocked();
                        }
                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
                        return;
                    }
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
@@ -5970,7 +6135,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        enforceNotIsolatedCaller("moveActivityTaskToBack");
        synchronized(this) {
            final long origId = Binder.clearCallingIdentity();
            int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot);
            int taskId = getTaskForActivityLocked(token, !nonRoot);
            if (taskId >= 0) {
                return mMainStack.moveTaskToBackLocked(taskId, null);
            }
@@ -6000,10 +6165,27 @@ public final class ActivityManagerService extends ActivityManagerNative
    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
        synchronized(this) {
            return mMainStack.getTaskForActivityLocked(token, onlyRoot);
            return getTaskForActivityLocked(token, onlyRoot);
        }
    }
    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
        final int N = mMainStack.mHistory.size();
        TaskRecord lastTask = null;
        for (int i=0; i<N; i++) {
            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
            if (r.appToken == token) {
                if (!onlyRoot || lastTask != r.task) {
                    return r.task.taskId;
                }
                return -1;
            }
            lastTask = r.task;
        }
        return -1;
    }
    // =========================================================
    // THUMBNAILS
    // =========================================================
@@ -6909,10 +7091,13 @@ public final class ActivityManagerService extends ActivityManagerNative
                "unhandledBack()");
        synchronized(this) {
            int count = mMainStack.mHistory.size();
            if (DEBUG_SWITCH) Slog.d(
                TAG, "Performing unhandledBack(): stack size = " + count);
            if (count > 1) {
                final long origId = Binder.clearCallingIdentity();
            try {
                mMainStack.unhandledBackLocked();
            } finally {
                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
                Binder.restoreCallingIdentity(origId);
            }
        }
@@ -7974,7 +8159,15 @@ public final class ActivityManagerService extends ActivityManagerNative
                    + " has crashed too many times: killing!");
            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
                    app.userId, app.info.processName, app.uid);
            mMainStack.handleAppCrashLocked(app);
            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
                if (r.app == app) {
                    Slog.w(TAG, "  Force finishing activity "
                        + r.intent.getComponent().flattenToShortString());
                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
                            null, "crashed", false);
                }
            }
            if (!app.persistent) {
                // We don't want to start this process again until the user
                // explicitly does so...  but for persistent process, we really
@@ -7999,7 +8192,33 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            mMainStack.resumeTopActivityLocked(null);
        } else {
            mMainStack.finishTopRunningActivityLocked(app);
            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 = (ActivityRecord)mMainStack.mHistory.get(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);
                        }
                    }
                }
            }
        }
        // Bump up the crash count of any services currently running in the proc.
@@ -9018,7 +9237,8 @@ public final class ActivityManagerService extends ActivityManagerNative
            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
        pw.println("  Main stack:");
        mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
                dumpPackage);
        pw.println(" ");
        pw.println("  Running activities (most recent first):");
        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
@@ -9548,10 +9768,32 @@ public final class ActivityManagerService extends ActivityManagerNative
     */
    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
            int opti, boolean dumpAll) {
        ArrayList<ActivityRecord> activities;
        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
        if ("all".equals(name)) {
            synchronized (this) {
                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
                    activities.add(r1);
                }
            }
        } else if ("top".equals(name)) {
            synchronized (this) {
                final int N = mMainStack.mHistory.size();
                if (N > 0) {
                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
                }
            }
        } else {
            ItemMatcher matcher = new ItemMatcher();
            matcher.build(name);
            synchronized (this) {
            activities = mMainStack.getDumpActivitiesLocked(name);
                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
                    if (matcher.match(r1, r1.intent.getComponent())) {
                        activities.add(r1);
                    }
                }
            }
        }
        if (activities.size() <= 0) {
@@ -9803,7 +10045,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        return needSep;
    }
    static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
            String prefix, String label, boolean complete, boolean brief, boolean client,
            String dumpPackage) {
        TaskRecord lastTask = null;
@@ -12341,14 +12583,95 @@ 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);
            if (srec == null) {
                return false;
            }
            ActivityStack stack = srec.stack;
            return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData);
            ArrayList<ActivityRecord> history = srec.stack.mHistory;
            final int start = history.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;
            if (dest != null) {
                TaskRecord tr = srec.task;
                for (int i = start - 1; i >= 0; i--) {
                    ActivityRecord r = history.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 = history.get(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 = history.get(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;
        }
    }
Loading