Search in sources :

Example 26 with ResultInfo

use of android.app.ResultInfo in project android_frameworks_base by crdroidandroid.

the class ActivityStack method resumeTopActivityInnerLocked.

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (DEBUG_LOCKSCREEN)
        mService.logLockScreen("");
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }
    ActivityRecord parent = mActivityContainer.mParentActivity;
    if ((parent != null && parent.state != ActivityState.RESUMED) || !mActivityContainer.isAttachedLocked()) {
        // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
        return false;
    }
    mStackSupervisor.cancelInitializingActivities();
    // Find the first activity that is not finishing.
    final ActivityRecord next = topRunningActivityLocked();
    // Remember how we'll process this pause/resume situation, and ensure
    // that the state is reset however we wind up proceeding.
    final boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;
    final TaskRecord prevTask = prev != null ? prev.task : null;
    if (next == null) {
        // There are no more activities!
        final String reason = "noMoreActivities";
        final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
        if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
            // stack is not covering the entire screen.
            return mStackSupervisor.resumeFocusedStackTopActivityLocked(mStackSupervisor.getFocusedStack(), prev, null);
        }
        // Let's just start up the Launcher...
        ActivityOptions.abort(options);
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: No more activities go home");
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        // Only resume home if on home display
        return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
    }
    next.delayedResume = false;
    // If the top activity is the resumed one, nothing to do.
    if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) {
        // Make sure we have executed any pending transitions, since there
        // should be nothing left to do at this point.
        mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
        ActivityOptions.abort(options);
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: Top activity resumed " + next);
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    final TaskRecord nextTask = next.task;
    if (prevTask != null && prevTask.stack == this && prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        if (prevTask == nextTask) {
            prevTask.setFrontOfTask();
        } else if (prevTask != topTask()) {
            // This task is going away but it was supposed to return to the home stack.
            // Now the task above it has to return to the home task instead.
            final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
            mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
        } else if (!isOnHomeDisplay()) {
            return false;
        } else if (!isHomeStack()) {
            if (DEBUG_STATES)
                Slog.d(TAG_STATES, "resumeTopActivityLocked: Launching home next");
            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
            return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
        }
    }
    // activity is paused, well that is the state we want.
    if (mService.isSleepingOrShuttingDownLocked() && mLastPausedActivity == next && mStackSupervisor.allPausedActivitiesComplete()) {
        // Make sure we have executed any pending transitions, since there
        // should be nothing left to do at this point.
        mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
        ActivityOptions.abort(options);
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: Going to sleep and all paused");
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    // another user's activities to the top of the stack.
    if (!mService.mUserController.hasStartedUserState(next.userId)) {
        Slog.w(TAG, "Skipping resume of top activity " + next + ": user " + next.userId + " is stopped");
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    // Some activities may want to alter the system power management
    if (mStackSupervisor.mService.mPerf != null) {
        mStackSupervisor.mService.mPerf.activityResumed(next.intent);
    }
    // The activity may be waiting for stop, but that is no longer
    // appropriate for it.
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mWaitingVisibleActivities.remove(next);
    if (DEBUG_SWITCH)
        Slog.v(TAG_SWITCH, "Resuming " + next);
    // If we are currently pausing an activity, then don't do anything until that is done.
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES)
            Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing.");
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    // We need to start pausing the current activity so the top one can be resumed...
    final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
    if (mResumedActivity != null) {
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
    }
    if (pausing) {
        if (DEBUG_SWITCH || DEBUG_STATES)
            Slog.v(TAG_STATES, "resumeTopActivityLocked: Skip resume: need to start pausing");
        // happens to be sitting towards the end.
        if (next.app != null && next.app.thread != null) {
            mService.updateLruProcessLocked(next.app, true, null);
        }
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return true;
    } else if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) {
        // It is possible for the activity to be resumed when we paused back stacks above if the
        // next activity doesn't have to wait for pause to complete.
        // So, nothing else to-do except:
        // Make sure we have executed any pending transitions, since there
        // should be nothing left to do at this point.
        mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
        ActivityOptions.abort(options);
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
        if (DEBUG_STACK)
            mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
    // sure to finish it as we're making a new activity topmost.
    if (mService.isSleepingLocked() && mLastNoHistoryActivity != null && !mLastNoHistoryActivity.finishing) {
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "no-history finish of " + mLastNoHistoryActivity + " on new resume");
        requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED, null, "resume-no-history", false);
        mLastNoHistoryActivity = null;
    }
    if (prev != null && prev != next) {
        if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev) && next != null && !next.nowVisible) {
            mStackSupervisor.mWaitingVisibleActivities.add(prev);
            if (DEBUG_SWITCH)
                Slog.v(TAG_SWITCH, "Resuming top, waiting visible to hide: " + prev);
        } else {
            // new one is found to be full-screen or not.
            if (prev.finishing) {
                mWindowManager.setAppVisibility(prev.appToken, false);
                if (DEBUG_SWITCH)
                    Slog.v(TAG_SWITCH, "Not waiting for visible to hide: " + prev + ", waitingVisible=" + mStackSupervisor.mWaitingVisibleActivities.contains(prev) + ", nowVisible=" + next.nowVisible);
            } else {
                if (DEBUG_SWITCH)
                    Slog.v(TAG_SWITCH, "Previous already visible but still waiting to hide: " + prev + ", waitingVisible=" + mStackSupervisor.mWaitingVisibleActivities.contains(prev) + ", nowVisible=" + next.nowVisible);
            }
        }
    }
    // considered stopped.
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(next.packageName, false, next.userId);
    /* TODO: Verify if correct userid */
    } catch (RemoteException e1) {
    } catch (IllegalArgumentException e) {
        Slog.w(TAG, "Failed trying to unstop package " + next.packageName + ": " + e);
    }
    // We are starting up the next activity, so tell the window manager
    // that the previous one will be hidden soon.  This way it can know
    // to ignore it when computing the desired screen orientation.
    boolean anim = true;
    if (prev != null) {
        if (prev.finishing) {
            if (DEBUG_TRANSITION)
                Slog.v(TAG_TRANSITION, "Prepare close transition: prev=" + prev);
            if (mNoAnimActivities.contains(prev)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(prev.task == next.task ? TRANSIT_ACTIVITY_CLOSE : TRANSIT_TASK_CLOSE, false);
                if (prev.task != next.task) {
                    if (mStackSupervisor.mService.mPerf != null) {
                        mStackSupervisor.mService.mPerf.cpuBoost(2000 * 1000);
                    }
                }
            }
            mWindowManager.setAppVisibility(prev.appToken, false);
        } else {
            if (DEBUG_TRANSITION)
                Slog.v(TAG_TRANSITION, "Prepare open transition: prev=" + prev);
            if (mNoAnimActivities.contains(next)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(prev.task == next.task ? TRANSIT_ACTIVITY_OPEN : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND : TRANSIT_TASK_OPEN, false);
                if (prev.task != next.task) {
                    if (mStackSupervisor.mService.mPerf != null) {
                        mStackSupervisor.mService.mPerf.cpuBoost(2000 * 1000);
                    }
                }
            }
        }
    } else {
        if (DEBUG_TRANSITION)
            Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
        if (mNoAnimActivities.contains(next)) {
            anim = false;
            mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
        } else {
            mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
        }
    }
    Bundle resumeAnimOptions = null;
    if (anim) {
        ActivityOptions opts = next.getOptionsForTargetActivityLocked();
        if (opts != null) {
            resumeAnimOptions = opts.toBundle();
        }
        next.applyOptionsLocked();
    } else {
        next.clearOptionsLocked();
    }
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        if (DEBUG_SWITCH)
            Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped + " visible=" + next.visible);
        // If the previous activity is translucent, force a visibility update of
        // the next activity, so that it's added to WM's opening app list, and
        // transition animation can be set up properly.
        // For example, pressing Home button with a translucent activity in focus.
        // Launcher is already visible in this case. If we don't add it to opening
        // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
        // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
        final boolean lastActivityTranslucent = lastStack != null && (!lastStack.mFullscreen || (lastStack.mLastPausedActivity != null && !lastStack.mLastPausedActivity.fullscreen));
        // This activity is now becoming visible.
        if (!next.visible || next.stopped || lastActivityTranslucent) {
            mWindowManager.setAppVisibility(next.appToken, true);
        }
        // schedule launch ticks to collect information about slow apps.
        next.startLaunchTickingLocked();
        ActivityRecord lastResumedActivity = lastStack == null ? null : lastStack.mResumedActivity;
        ActivityState lastState = next.state;
        mService.updateCpuStats();
        if (DEBUG_STATES)
            Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
        next.state = ActivityState.RESUMED;
        mResumedActivity = next;
        next.task.touchActiveTime();
        mRecentTasks.addLocked(next.task);
        mService.updateLruProcessLocked(next.app, true, null);
        updateLRUListLocked(next);
        mService.updateOomAdjLocked();
        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.
        boolean notUpdated = true;
        if (mStackSupervisor.isFocusedStack(this)) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration, next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
            if (config != null) {
                next.frozenBeforeDestroy = true;
            }
            notUpdated = !mService.updateConfigurationLocked(config, next, false);
        }
        if (notUpdated) {
            // The configuration update wasn't able to keep the existing
            // instance of the activity, and instead started a new one.
            // We should be all done, but let's just make sure our activity
            // is still at the top and schedule another run if something
            // weird happened.
            ActivityRecord nextNext = topRunningActivityLocked();
            if (DEBUG_SWITCH || DEBUG_STATES)
                Slog.i(TAG_STATES, "Activity config changed during resume: " + next + ", new next: " + nextNext);
            if (nextNext != next) {
                // Do over!
                mStackSupervisor.scheduleResumeTopActivities();
            }
            if (mStackSupervisor.reportResumedActivityLocked(next)) {
                mNoAnimActivities.clear();
                if (DEBUG_STACK)
                    mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
            if (DEBUG_STACK)
                mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
        try {
            // Deliver all pending results.
            ArrayList<ResultInfo> a = next.results;
            if (a != null) {
                final int N = a.size();
                if (!next.finishing && N > 0) {
                    if (DEBUG_RESULTS)
                        Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
                    next.app.thread.scheduleSendResult(next.appToken, a);
                }
            }
            boolean allowSavedSurface = true;
            if (next.newIntents != null) {
                // what's left last time.
                for (int i = next.newIntents.size() - 1; i >= 0; i--) {
                    final Intent intent = next.newIntents.get(i);
                    if (intent != null && !ActivityRecord.isMainIntent(intent)) {
                        allowSavedSurface = false;
                        break;
                    }
                }
                next.app.thread.scheduleNewIntent(next.newIntents, next.appToken, false);
            }
            // Well the app will no longer be stopped.
            // Clear app token stopped state in window manager if needed.
            mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface);
            EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.task.taskId, next.shortComponentName);
            next.sleeping = false;
            mService.showUnsupportedZoomDialogIfNeededLocked(next);
            mService.showAskCompatModeDialogLocked(next);
            next.app.pendingUiClean = true;
            next.app.forceProcessStateUpTo(mService.mTopProcessState);
            next.clearOptionsLocked();
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, mService.isNextTransitionForward(), resumeAnimOptions);
            mStackSupervisor.checkReadyForSleepLocked();
            if (DEBUG_STATES)
                Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
        } catch (Exception e) {
            // Whoops, need to restart this activity!
            if (DEBUG_STATES)
                Slog.v(TAG_STATES, "Resume failed; resetting state to " + lastState + ": " + next);
            next.state = lastState;
            if (lastStack != null) {
                lastStack.mResumedActivity = lastResumedActivity;
            }
            Slog.i(TAG, "Restarting because process died: " + next);
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null && mStackSupervisor.isFrontStack(lastStack)) {
                next.showStartingWindow(null, true);
            }
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            if (DEBUG_STACK)
                mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }
        // to recover the activity.
        try {
            completeResumeLocked(next);
        } catch (Exception e) {
            // If any exception gets thrown, toss away this
            // activity and try the next one.
            Slog.w(TAG, "Exception thrown during resume of " + next, e);
            requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, "resume-exception", true);
            if (DEBUG_STACK)
                mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null, true);
            }
            if (DEBUG_SWITCH)
                Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES)
            Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    if (DEBUG_STACK)
        mStackSupervisor.validateTopActivitiesLocked();
    return true;
}
Also used : Configuration(android.content.res.Configuration) Bundle(android.os.Bundle) PersistableBundle(android.os.PersistableBundle) ReferrerIntent(com.android.internal.content.ReferrerIntent) Intent(android.content.Intent) Point(android.graphics.Point) RemoteException(android.os.RemoteException) RemoteException(android.os.RemoteException) ResultInfo(android.app.ResultInfo) ActivityOptions(android.app.ActivityOptions)

Aggregations

ResultInfo (android.app.ResultInfo)26 RemoteException (android.os.RemoteException)26 Configuration (android.content.res.Configuration)19 ReferrerIntent (com.android.internal.content.ReferrerIntent)15 Intent (android.content.Intent)14 IOException (java.io.IOException)9 Message (android.os.Message)7 ParcelFileDescriptor (android.os.ParcelFileDescriptor)7 ArrayList (java.util.ArrayList)7 ActivityOptions (android.app.ActivityOptions)5 ProfilerInfo (android.app.ProfilerInfo)5 Point (android.graphics.Point)5 Bundle (android.os.Bundle)5 PersistableBundle (android.os.PersistableBundle)5 PendingIntent (android.app.PendingIntent)4 BoostFramework (android.util.BoostFramework)1