diff options
8 files changed, 452 insertions, 433 deletions
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml index 57bad8c83fc9..09092f40226f 100644 --- a/packages/Keyguard/res/values-hi/strings.xml +++ b/packages/Keyguard/res/values-hi/strings.xml @@ -101,7 +101,7 @@ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम PIN डालें"</string> <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN डालें"</string> <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</string> - <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</string> + <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए कैरियर से संपर्क करें."</string> <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित पिन कोड डालें"</string> <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड की पुष्टि करें"</string> <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलॉक कर रहा है…"</string> diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml index ad4e84115101..33a99c802a83 100644 --- a/packages/Keyguard/res/values-nl/strings.xml +++ b/packages/Keyguard/res/values-nl/strings.xml @@ -29,7 +29,7 @@ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Typ pincode om te ontgrendelen"</string> <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Onjuiste pincode."</string> <string name="keyguard_label_text" msgid="861796461028298424">"Druk op \'Menu\' en vervolgens op 0 om te ontgrendelen."</string> - <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Face Unlock overschreden"</string> + <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Ontgrendelen via gezichtsherkenning overschreden"</string> <string name="keyguard_charged" msgid="3272223906073492454">"Opgeladen"</string> <string name="keyguard_plugged_in" msgid="8117572000639998388">"Opladen, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> <string name="keyguard_low_battery" msgid="8143808018719173859">"Sluit de oplader aan."</string> @@ -61,7 +61,7 @@ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ontgrendelingsgebied uitvouwen."</string> <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ontgrendeling via schuiven."</string> <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ontgrendeling via patroon."</string> - <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendeling via gezichtsherkenning."</string> + <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendelen via gezichtsherkenning"</string> <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ontgrendeling via pincode."</string> <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ontgrendeling via wachtwoord."</string> <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Tekengebied voor patroon."</string> diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml index 4424faf91f39..350feb0c440d 100644 --- a/packages/Keyguard/res/values-zu/strings.xml +++ b/packages/Keyguard/res/values-zu/strings.xml @@ -125,8 +125,8 @@ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string> <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string> <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string> <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Inkinombo yethrekhi yangaphambilini"</string> diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index f3be0ea10fcd..5ad554452bdd 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -900,7 +900,7 @@ public final class ActivityManagerService extends ActivityManagerNative static ActivityManagerService mSelf; static ActivityThread mSystemThread; - private int mCurrentUserId = 0; + int mCurrentUserId = 0; private UserManagerService mUserManager; private final class AppDeathRecipient implements IBinder.DeathRecipient { @@ -962,6 +962,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; static final int FIRST_COMPAT_MODE_MSG = 300; + static final int FIRST_SUPERVISOR_STACK_MSG = 100; AlertDialog mUidAlert; CompatModeDialog mCompatModeDialog; @@ -1488,6 +1489,7 @@ public final class ActivityManagerService extends ActivityManagerNative public void setWindowManager(WindowManagerService wm) { mWindowManager = wm; + mStackSupervisor.setWindowManager(wm); wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f); } @@ -1520,7 +1522,6 @@ public final class ActivityManagerService extends ActivityManagerNative m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); - m.mStackSupervisor.init(m.mCurrentUserId); m.mBatteryStatsService.publish(context); m.mUsageStatsService.publish(context); @@ -2659,7 +2660,7 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized (this) { // If this is coming from the currently resumed activity, it is // effectively saying that app switches are allowed at this point. - final ActivityStack stack = getTopStack(); + final ActivityStack stack = getFocusedStack(); if (stack.mResumedActivity != null && stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { mAppSwitchesAllowedTime = 0; @@ -7243,7 +7244,7 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { final long origId = Binder.clearCallingIdentity(); try { - getTopStack().unhandledBackLocked(); + getFocusedStack().unhandledBackLocked(); } finally { Binder.restoreCallingIdentity(origId); } @@ -7649,7 +7650,7 @@ public final class ActivityManagerService extends ActivityManagerNative PendingActivityExtras pae; Bundle extras = new Bundle(); synchronized (this) { - ActivityRecord activity = getTopStack().mResumedActivity; + ActivityRecord activity = getFocusedStack().mResumedActivity; if (activity == null) { Slog.w(TAG, "getTopActivityExtras failed: no resumed activity"); return null; @@ -7745,7 +7746,7 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean isTopActivityImmersive() { enforceNotIsolatedCaller("startActivity"); synchronized (this) { - ActivityRecord r = getTopStack().topRunningActivityLocked(null); + ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); return (r != null) ? r.immersive : false; } } @@ -9651,7 +9652,7 @@ public final class ActivityManagerService extends ActivityManagerNative } pw.println(" mConfiguration: " + mConfiguration); if (dumpAll) { - pw.println(" mConfigWillChange: " + getTopStack().mConfigWillChange); + pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); if (mCompatModePackages.getPackages().size() > 0) { boolean printed = false; for (Map.Entry<String, Integer> entry @@ -9711,8 +9712,8 @@ public final class ActivityManagerService extends ActivityManagerNative pw.print(" mLastPowerCheckUptime="); TimeUtils.formatDuration(mLastPowerCheckUptime, pw); pw.println(""); - pw.println(" mGoingToSleep=" + getTopStack().mGoingToSleep); - pw.println(" mLaunchingActivity=" + getTopStack().mLaunchingActivity); + pw.println(" mGoingToSleep=" + getFocusedStack().mGoingToSleep); + pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity); pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs + " mNumHiddenProcs=" + mNumHiddenProcs @@ -12451,8 +12452,8 @@ public final class ActivityManagerService extends ActivityManagerNative return config; } - ActivityStack getTopStack() { - return mStackSupervisor.getTopStack(); + ActivityStack getFocusedStack() { + return mStackSupervisor.getFocusedStack(); } public Configuration getConfiguration() { @@ -12596,7 +12597,7 @@ public final class ActivityManagerService extends ActivityManagerNative } boolean kept = true; - final ActivityStack mainStack = mStackSupervisor.getTopStack(); + final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); if (changes != 0 && starting == null) { // If the configuration changed, and the caller is not already // in the process of starting an activity, then find the top diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 351d329f936e..88bcdab4cfaa 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -803,7 +803,7 @@ final class ActivityRecord { } Log.i(ActivityManagerService.TAG, sb.toString()); } - stack.reportActivityLaunchedLocked(false, this, thisTime, totalTime); + mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime); if (totalTime > 0) { service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime); } @@ -818,7 +818,7 @@ final class ActivityRecord { public void windowsVisible() { synchronized(service) { final ActivityStack stack = task.stack; - stack.reportActivityVisibleLocked(this); + mStackSupervisor.reportActivityVisibleLocked(this); if (ActivityManagerService.DEBUG_SWITCH) Log.v( ActivityManagerService.TAG, "windowsVisible(): " + this); if (!nowVisible) { @@ -845,9 +845,7 @@ final class ActivityRecord { "Was waiting for visible: " + r); } mStackSupervisor.mWaitingVisibleActivities.clear(); - Message msg = Message.obtain(); - msg.what = ActivityStack.IDLE_NOW_MSG; - stack.mHandler.sendMessage(msg); + mStackSupervisor.scheduleIdleLocked(); } } service.scheduleAppGcsLocked(); @@ -960,7 +958,8 @@ final class ActivityRecord { @Override public String toString() { if (stringName != null) { - return stringName + " t" + task.taskId + (finishing ? " f}" : "}"); + return stringName + " t" + (task == null ? -1 : task.taskId) + + (finishing ? " f}" : "}"); } StringBuilder sb = new StringBuilder(128); sb.append("ActivityRecord{"); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index e02fcacfee42..9f3198287395 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -23,19 +23,18 @@ import com.android.internal.util.Objects; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.wm.AppTransition; import com.android.server.wm.TaskGroup; +import com.android.server.wm.WindowManagerService; 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; import android.app.IApplicationThread; import android.app.ResultInfo; import android.app.ActivityManager.RunningTaskInfo; -import android.app.IActivityManager.WaitResult; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -91,10 +90,6 @@ final class ActivityStack { static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS; - // How long we wait until giving up on the last activity telling us it - // is idle. - static final int IDLE_TIMEOUT = 10*1000; - // Ticks during which we check progress while waiting for an app to launch. static final int LAUNCH_TICK = 500; @@ -143,6 +138,7 @@ final class ActivityStack { } final ActivityManagerService mService; + final WindowManagerService mWindowManager; final Context mContext; @@ -167,38 +163,13 @@ final class ActivityStack { /** * List of activities that are in the process of going to sleep. */ - final ArrayList<ActivityRecord> mGoingToSleepActivities - = new ArrayList<ActivityRecord>(); + final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); /** * Animations that for the current transition have requested not to * be considered for the transition animation. */ - final ArrayList<ActivityRecord> mNoAnimActivities - = new ArrayList<ActivityRecord>(); - - /** - * List of activities that are ready to be finished, but waiting - * for the previous activity to settle down before doing so. It contains - * HistoryRecord objects. - */ - final ArrayList<ActivityRecord> mFinishingActivities - = new ArrayList<ActivityRecord>(); - - /** - * List of people waiting to find out about the next launched activity. - */ - final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched - = new ArrayList<IActivityManager.WaitResult>(); - - /** - * List of people waiting to find out about the next visible activity. - */ - final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible - = new ArrayList<IActivityManager.WaitResult>(); - - final ArrayList<UserStartedState> mStartingUsers - = new ArrayList<UserStartedState>(); + final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>(); /** * Set when the system is going to sleep, until we have @@ -260,12 +231,6 @@ final class ActivityStack { private ActivityRecord mLastScreenshotActivity = null; private Bitmap mLastScreenshotBitmap = null; - /** - * List of ActivityRecord objects that have been finished and must - * still report back to a pending thumbnail receiver. - */ - private final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); - int mThumbnailWidth = -1; int mThumbnailHeight = -1; @@ -278,14 +243,12 @@ final class ActivityStack { static final int SLEEP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG; static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1; - static final int IDLE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2; - static final int IDLE_NOW_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3; - static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4; - static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; - static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; - static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; - static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8; - static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 9; + static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2; + static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3; + static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4; + static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; + static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; + static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; static class ScheduleDestroyArgs { final ProcessRecord mOwner; @@ -334,22 +297,6 @@ final class ActivityStack { activityPausedLocked(r != null ? r.appToken : null, true); } } break; - case IDLE_TIMEOUT_MSG: { - if (mService.mDidDexOpt) { - mService.mDidDexOpt = false; - Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); - nmsg.obj = msg.obj; - mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); - return; - } - // We don't at this point know if the activity is fullscreen, - // so we need to be conservative and assume it isn't. - ActivityRecord r = (ActivityRecord)msg.obj; - Slog.w(TAG, "Activity idle timeout for " + r); - synchronized (mService) { - activityIdleInternalLocked(r != null ? r.appToken : null, true, null); - } - } break; case LAUNCH_TICK_MSG: { ActivityRecord r = (ActivityRecord)msg.obj; synchronized (mService) { @@ -368,12 +315,6 @@ final class ActivityStack { activityDestroyedLocked(r != null ? r.appToken : null); } } break; - case IDLE_NOW_MSG: { - ActivityRecord r = (ActivityRecord)msg.obj; - synchronized (mService) { - activityIdleInternalLocked(r != null ? r.appToken : null, false, null); - } - } break; case LAUNCH_TIMEOUT_MSG: { if (mService.mDidDexOpt) { mService.mDidDexOpt = false; @@ -390,7 +331,7 @@ final class ActivityStack { } break; case RESUME_TOP_ACTIVITY_MSG: { synchronized (mService) { - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } } break; case STOP_TIMEOUT_MSG: { @@ -422,19 +363,20 @@ final class ActivityStack { return count; } - ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId, - ActivityStackSupervisor supervisor, int userId) { + ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId) { mHandler = new ActivityStackHandler(looper); mService = service; + mWindowManager = service.mWindowManager; + mStackSupervisor = service.mStackSupervisor; mContext = context; PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); - mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); + mLaunchingActivity = + pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); mLaunchingActivity.setReferenceCounted(false); mStackId = stackId; - mStackSupervisor = supervisor; - mCurrentUser = userId; + mCurrentUser = service.mCurrentUserId; } private boolean okToShow(ActivityRecord r) { @@ -641,7 +583,6 @@ final class ActivityStack { if (VALIDATE_TOKENS) { validateAppTokensLocked(); } - mStartingUsers.add(uss); if (mCurrentUser == userId) { return true; } @@ -717,6 +658,7 @@ final class ActivityStack { for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + // TODO: Skip if finishing? activities.get(activityNdx).setSleeping(false); } } @@ -753,7 +695,7 @@ final class ActivityStack { // Still need to tell some activities to stop; can't sleep yet. if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " + mStackSupervisor.mStoppingActivities.size() + " activities"); - scheduleIdleLocked(); + mStackSupervisor.scheduleIdleLocked(); return; } @@ -809,7 +751,7 @@ final class ActivityStack { || mLastScreenshotBitmap.getWidth() != w || mLastScreenshotBitmap.getHeight() != h) { mLastScreenshotActivity = who; - mLastScreenshotBitmap = mService.mWindowManager.screenshotApplications( + mLastScreenshotBitmap = mWindowManager.screenshotApplications( who.appToken, Display.DEFAULT_DISPLAY, w, h); } if (mLastScreenshotBitmap != null) { @@ -828,7 +770,7 @@ final class ActivityStack { if (prev == null) { Slog.e(TAG, "Trying to pause when nothing is resumed", new RuntimeException("here").fillInStackTrace()); - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); return; } if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev); @@ -896,7 +838,7 @@ final class ActivityStack { // This activity failed to schedule the // pause, so just treat it as being paused now. if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next."); - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } } @@ -954,7 +896,7 @@ final class ActivityStack { } else { if (r.configDestroy) { destroyActivityLocked(r, true, false, "stop-config"); - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } else { // Now that this process has stopped, we may want to consider // it to be the previous app to try to keep around in case @@ -1009,7 +951,7 @@ final class ActivityStack { // them out. Or if r is the last of activity of the last task the stack // will be empty and must be cleared immediately. if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle"); - scheduleIdleLocked(); + mStackSupervisor.scheduleIdleLocked(); } else { checkReadyForSleepLocked(); } @@ -1021,7 +963,7 @@ final class ActivityStack { mPausingActivity = null; } - final ActivityStack topStack = mStackSupervisor.getTopStack(); + final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDown()) { topStack.resumeTopActivityLocked(prev); } else { @@ -1075,31 +1017,12 @@ final class ActivityStack { next.newIntents = null; // schedule an idle timeout in case the app doesn't do it for us. - Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); - msg.obj = next; - mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); + mStackSupervisor.scheduleIdleTimeoutLocked(next); - if (false) { - // The activity was never told to pause, so just keep - // things going as-is. To maintain our own state, - // we need to emulate it coming back and saying it is - // idle. - msg = mHandler.obtainMessage(IDLE_NOW_MSG); - msg.obj = next; - mHandler.sendMessage(msg); - } + mStackSupervisor.reportResumedActivityLocked(next); - if (mStackSupervisor.isFrontStack(this)) { - // TODO: Should this be done for all stacks, not just mMainStack? - mService.reportResumedActivityLocked(next); - mService.setFocusedActivityLocked(next); - } - if (mStackSupervisor.allResumedActivitiesComplete()) { - next.resumeKeyDispatchingLocked(); - mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); - mService.mWindowManager.executeAppTransition(); - mNoAnimActivities.clear(); - } + next.resumeKeyDispatchingLocked(); + mNoAnimActivities.clear(); // Mark the point when the activity is resuming // TODO: To be more accurate, the mark should be before the onCreate, @@ -1166,7 +1089,7 @@ final class ActivityStack { if (!r.visible) { if (DEBUG_VISBILITY) Slog.v( TAG, "Starting and making visible: " + r); - mService.mWindowManager.setAppVisibility(r.appToken, true); + mWindowManager.setAppVisibility(r.appToken, true); } if (r != starting) { mStackSupervisor.startSpecificActivityLocked(r, false, false); @@ -1189,7 +1112,7 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v( TAG, "Making visible and scheduling visibility: " + r); try { - mService.mWindowManager.setAppVisibility(r.appToken, true); + mWindowManager.setAppVisibility(r.appToken, true); r.sleeping = false; r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); @@ -1223,7 +1146,7 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r); r.visible = false; try { - mService.mWindowManager.setAppVisibility(r.appToken, false); + mWindowManager.setAppVisibility(r.appToken, false); if ((r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) && r.app != null && r.app.thread != null) { @@ -1293,7 +1216,7 @@ final class ActivityStack { mStackSupervisor.allResumedActivitiesComplete()) { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. - mService.mWindowManager.executeAppTransition(); + mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); ActivityOptions.abort(options); return false; @@ -1311,7 +1234,7 @@ final class ActivityStack { && mStackSupervisor.allPausedActivitiesComplete()) { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. - mService.mWindowManager.executeAppTransition(); + mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); ActivityOptions.abort(options); return false; @@ -1424,7 +1347,7 @@ final class ActivityStack { // previous should actually be hidden depending on whether the // new one is found to be full-screen or not. if (prev.finishing) { - mService.mWindowManager.setAppVisibility(prev.appToken, false); + mWindowManager.setAppVisibility(prev.appToken, false); if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: " + prev + ", waitingVisible=" + (prev != null ? prev.waitingVisible : null) @@ -1458,42 +1381,37 @@ final class ActivityStack { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare close transition: prev=" + prev); if (mNoAnimActivities.contains(prev)) { - mService.mWindowManager.prepareAppTransition( - AppTransition.TRANSIT_NONE, false); + noAnim = true; + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); } else { - mService.mWindowManager.prepareAppTransition(prev.task == next.task + mWindowManager.prepareAppTransition(prev.task == next.task ? AppTransition.TRANSIT_ACTIVITY_CLOSE : AppTransition.TRANSIT_TASK_CLOSE, false); } - mService.mWindowManager.setAppWillBeHidden(prev.appToken); - mService.mWindowManager.setAppVisibility(prev.appToken, false); + mWindowManager.setAppWillBeHidden(prev.appToken); + mWindowManager.setAppVisibility(prev.appToken, false); } else { - if (DEBUG_TRANSITION) Slog.v(TAG, - "Prepare open transition: prev=" + prev); + if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev); if (mNoAnimActivities.contains(next)) { noAnim = true; - mService.mWindowManager.prepareAppTransition( - AppTransition.TRANSIT_NONE, false); + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); } else { - mService.mWindowManager.prepareAppTransition(prev.task == next.task + mWindowManager.prepareAppTransition(prev.task == next.task ? AppTransition.TRANSIT_ACTIVITY_OPEN : AppTransition.TRANSIT_TASK_OPEN, false); } } if (false) { - mService.mWindowManager.setAppWillBeHidden(prev.appToken); - mService.mWindowManager.setAppVisibility(prev.appToken, false); + mWindowManager.setAppWillBeHidden(prev.appToken); + mWindowManager.setAppVisibility(prev.appToken, false); } } else { - if (DEBUG_TRANSITION) Slog.v(TAG, - "Prepare open transition: no previous"); + if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous"); if (mNoAnimActivities.contains(next)) { noAnim = true; - mService.mWindowManager.prepareAppTransition( - AppTransition.TRANSIT_NONE, false); + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); } else { - mService.mWindowManager.prepareAppTransition( - AppTransition.TRANSIT_ACTIVITY_OPEN, false); + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false); } } if (!noAnim) { @@ -1506,7 +1424,7 @@ final class ActivityStack { if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next); // This activity is now becoming visible. - mService.mWindowManager.setAppVisibility(next.appToken, true); + mWindowManager.setAppVisibility(next.appToken, true); // schedule launch ticks to collect information about slow apps. next.startLaunchTickingLocked(); @@ -1529,7 +1447,7 @@ final class ActivityStack { // the screen based on the new activity order. boolean updated = false; if (mStackSupervisor.isFrontStack(this)) { - Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( + Configuration config = mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, next.mayFreezeScreenLocked(next.app) ? next.appToken : null); if (config != null) { @@ -1552,12 +1470,7 @@ final class ActivityStack { // Do over! mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); } - if (mStackSupervisor.isFrontStack(this)) { - mService.setFocusedActivityLocked(next); - } - if (mStackSupervisor.allResumedActivitiesComplete()) { - ensureActivitiesVisibleLocked(null, 0); - mService.mWindowManager.executeAppTransition(); + if (mStackSupervisor.reportResumedActivityLocked(next)) { mNoAnimActivities.clear(); return true; } @@ -1606,7 +1519,7 @@ final class ActivityStack { next.hasBeenLaunched = true; } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null && mStackSupervisor.isFrontStack(lastStack)) { - mService.mWindowManager.setAppStartingWindow( + mWindowManager.setAppStartingWindow( next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked(next.info.applicationInfo), next.nonLocalizedLabel, next.labelRes, next.icon, next.windowFlags, @@ -1637,7 +1550,7 @@ final class ActivityStack { next.hasBeenLaunched = true; } else { if (SHOW_APP_STARTING_PREVIEW) { - mService.mWindowManager.setAppStartingWindow( + mWindowManager.setAppStartingWindow( next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked( next.info.applicationInfo), @@ -1666,7 +1579,7 @@ final class ActivityStack { mTaskHistory.remove(rTask); // Now put task at top. mTaskHistory.add(rTask); - mService.mWindowManager.moveTaskToTop(taskId); + mWindowManager.moveTaskToTop(taskId); } if (!newTask) { // If starting in an existing task, find where that is... @@ -1682,9 +1595,8 @@ final class ActivityStack { + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r); r.putInHistory(); - mService.mWindowManager.addAppToken(task.mActivities.indexOf(r), - r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, - r.fullscreen, + mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, + r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); if (VALIDATE_TOKENS) { validateAppTokensLocked(); @@ -1735,17 +1647,16 @@ final class ActivityStack { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: starting " + r); if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - mService.mWindowManager.prepareAppTransition( - AppTransition.TRANSIT_NONE, keepCurTransition); + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition); mNoAnimActivities.add(r); } else { - mService.mWindowManager.prepareAppTransition(newTask + mWindowManager.prepareAppTransition(newTask ? AppTransition.TRANSIT_TASK_OPEN : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition); mNoAnimActivities.remove(r); } r.updateOptionsLocked(options); - mService.mWindowManager.addAppToken(task.mActivities.indexOf(r), + mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); boolean doShow = true; @@ -1778,7 +1689,7 @@ final class ActivityStack { prev = null; } } - mService.mWindowManager.setAppStartingWindow( + mWindowManager.setAppStartingWindow( r.appToken, r.packageName, r.theme, mService.compatibilityInfoForPackageLocked( r.info.applicationInfo), r.nonLocalizedLabel, @@ -1788,7 +1699,7 @@ final class ActivityStack { } else { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. - mService.mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, + mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); ActivityOptions.abort(options); @@ -1821,7 +1732,7 @@ final class ActivityStack { group.tokens.add(r.appToken); } } - mService.mWindowManager.validateAppTokens(mStackId, mValidateAppTokens); + mWindowManager.validateAppTokens(mStackId, mValidateAppTokens); } /** @@ -1836,8 +1747,7 @@ final class ActivityStack { * @param forceReset * @return An ActivityOptions that needs to be processed. */ - final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, - boolean forceReset) { + final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) { ActivityOptions topOptions = null; int replyChainEnd = -1; @@ -1901,7 +1811,7 @@ final class ActivityStack { final TaskRecord targetTask = target.task; final int targetTaskId = targetTask.taskId; - mService.mWindowManager.setAppGroupId(target.appToken, targetTaskId); + mWindowManager.setAppGroupId(target.appToken, targetTaskId); ThumbnailHolder curThumbHolder = target.thumbHolder; boolean gotOptions = !canMoveOptions; @@ -1929,10 +1839,10 @@ final class ActivityStack { p.setTask(targetTask, curThumbHolder, false); targetTask.addActivityAtBottom(p); - mService.mWindowManager.setAppGroupId(p.appToken, targetTaskId); + mWindowManager.setAppGroupId(p.appToken, targetTaskId); } - mService.mWindowManager.moveTaskToBottom(targetTaskId); + mWindowManager.moveTaskToBottom(targetTaskId); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -2064,9 +1974,9 @@ final class ActivityStack { new RuntimeException("here").fillInStackTrace()); if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " from " + srcPos + " in to resetting task " + task); - mService.mWindowManager.setAppGroupId(p.appToken, taskId); + mWindowManager.setAppGroupId(p.appToken, taskId); } - mService.mWindowManager.moveTaskToTop(taskId); + mWindowManager.moveTaskToTop(taskId); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -2167,34 +2077,6 @@ final class ActivityStack { return null; } - void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, - long thisTime, long totalTime) { - for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) { - WaitResult w = mWaitingActivityLaunched.get(i); - w.timeout = timeout; - if (r != null) { - w.who = new ComponentName(r.info.packageName, r.info.name); - } - w.thisTime = thisTime; - w.totalTime = totalTime; - } - mService.notifyAll(); - } - - void reportActivityVisibleLocked(ActivityRecord r) { - for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { - WaitResult w = mWaitingActivityVisible.get(i); - w.timeout = false; - if (r != null) { - w.who = new ComponentName(r.info.packageName, r.info.name); - } - w.totalTime = SystemClock.uptimeMillis() - w.thisTime; - w.thisTime = w.totalTime; - } - mService.notifyAll(); - mStackSupervisor.dismissKeyguard(); - } - void sendActivityResultLocked(int callingUid, ActivityRecord r, String resultWho, int requestCode, int resultCode, Intent data) { @@ -2221,7 +2103,7 @@ final class ActivityStack { r.addResultLocked(null, resultWho, requestCode, resultCode, data); } - private final void stopActivityLocked(ActivityRecord r) { + final void stopActivityLocked(ActivityRecord r) { if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r); if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { @@ -2254,7 +2136,7 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v( TAG, "Stopping visible=" + r.visible + " for " + r); if (!r.visible) { - mService.mWindowManager.setAppVisibility(r.appToken, false); + mWindowManager.setAppVisibility(r.appToken, false); } r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags); if (mService.isSleepingOrShuttingDown()) { @@ -2279,12 +2161,6 @@ final class ActivityStack { } } - final void scheduleIdleLocked() { - Message msg = Message.obtain(); - msg.what = IDLE_NOW_MSG; - mHandler.sendMessage(msg); - } - // Checked. final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, Configuration config) { @@ -2302,145 +2178,18 @@ final class ActivityStack { boolean enableScreen = false; boolean activityRemoved = false; - ActivityRecord r = ActivityRecord.forToken(token); - if (r != null) { - mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); - r.finishLaunchTickingLocked(); - } - // Get the activity record. - if (isInStackLocked(token) != null) { - res = r; - - if (fromTimeout) { - reportActivityLaunchedLocked(fromTimeout, r, -1, -1); - } - - // This is a hack to semi-deal with a race condition - // in the client where it can be constructed with a - // newer configuration from when we asked it to launch. - // We'll update with whatever configuration it now says - // it used to launch. - if (config != null) { - r.configuration = config; - } - + res = isInStackLocked(token); + if (res != null) { // No longer need to keep the device awake. - if (mResumedActivity == r && mLaunchingActivity.isHeld()) { + if (mResumedActivity == res && mLaunchingActivity.isHeld()) { mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); mLaunchingActivity.release(); } - // We are now idle. If someone is waiting for a thumbnail from - // us, we can now deliver. - r.idle = true; - if (mStackSupervisor.allResumedActivitiesIdle()) { - mService.scheduleAppGcsLocked(); - } - if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { - sendThumbnail = r.app.thread; - r.thumbnailNeeded = false; - } - // If this activity is fullscreen, set up to hide those under it. - - if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + r); + if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + res); ensureActivitiesVisibleLocked(null, 0); - - //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); - if (!mService.mBooted && mStackSupervisor.isFrontStack(this)) { - mService.mBooted = true; - enableScreen = true; - } - } else if (fromTimeout) { - reportActivityLaunchedLocked(fromTimeout, null, -1, -1); - } - - // Atomically retrieve all of the other things to do. - stops = mStackSupervisor.processStoppingActivitiesLocked(true); - NS = stops != null ? stops.size() : 0; - if ((NF=mFinishingActivities.size()) > 0) { - finishes = new ArrayList<ActivityRecord>(mFinishingActivities); - mFinishingActivities.clear(); - } - - final ArrayList<ActivityRecord> thumbnails; - final int NT = mCancelledThumbnails.size(); - if (NT > 0) { - thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); - mCancelledThumbnails.clear(); - } else { - thumbnails = null; - } - - if (mStackSupervisor.isFrontStack(this)) { - booting = mService.mBooting; - mService.mBooting = false; - } - - if (mStartingUsers.size() > 0) { - startingUsers = new ArrayList<UserStartedState>(mStartingUsers); - mStartingUsers.clear(); - } - - // Perform the following actions from unsynchronized state. - final IApplicationThread thumbnailThread = sendThumbnail; - mHandler.post(new Runnable() { - @Override - public void run() { - if (thumbnailThread != null) { - try { - thumbnailThread.requestThumbnail(token); - } catch (Exception e) { - Slog.w(TAG, "Exception thrown when requesting thumbnail", e); - mService.sendPendingThumbnail(null, token, null, null, true); - } - } - - // Report back to any thumbnail receivers. - for (int i = 0; i < NT; i++) { - ActivityRecord r = thumbnails.get(i); - mService.sendPendingThumbnail(r, null, null, null, true); - } - } - }); - - // Stop any activities that are scheduled to do so but have been - // waiting for the next one to start. - for (int i = 0; i < NS; i++) { - r = stops.get(i); - if (r.finishing) { - finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); - } else { - r.task.stack.stopActivityLocked(r); - } - } - - // Finish any activities that are scheduled to do so but have been - // waiting for the next one to start. - for (int i = 0; i < NF; i++) { - r = finishes.get(i); - activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); - } - - if (booting) { - mService.finishBooting(); - } else if (startingUsers != null) { - for (int i = 0; i < startingUsers.size(); i++) { - mService.finishUserSwitch(startingUsers.get(i)); - } - } - - mService.trimApplications(); - //dump(); - //mWindowManager.dump(); - - if (enableScreen) { - mService.enableScreenAfterBoot(); - } - - if (activityRemoved) { - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); } return res; @@ -2563,8 +2312,8 @@ final class ActivityStack { * @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) { + final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, + String reason, boolean oomAdj) { if (r.finishing) { Slog.w(TAG, "Duplicate finish request for " + r); return false; @@ -2603,19 +2352,19 @@ final class ActivityStack { // There are clients waiting to receive thumbnails so, in case // this is an activity that someone is waiting for, add it // to the pending list so we can correctly update the clients. - mCancelledThumbnails.add(r); + mStackSupervisor.mCancelledThumbnails.add(r); } if (mResumedActivity == r) { boolean endTask = index <= 0; if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare close transition: finishing " + r); - mService.mWindowManager.prepareAppTransition(endTask + mWindowManager.prepareAppTransition(endTask ? AppTransition.TRANSIT_TASK_CLOSE : AppTransition.TRANSIT_ACTIVITY_CLOSE, false); // Tell window manager to prepare for this one to be removed. - mService.mWindowManager.setAppVisibility(r.appToken, false); + mWindowManager.setAppVisibility(r.appToken, false); if (mPausingActivity == null) { if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r); @@ -2635,12 +2384,11 @@ final class ActivityStack { return false; } - private static final int FINISH_IMMEDIATELY = 0; - private static final int FINISH_AFTER_PAUSE = 1; - private static final int FINISH_AFTER_VISIBLE = 2; + static final int FINISH_IMMEDIATELY = 0; + static final int FINISH_AFTER_PAUSE = 1; + static final int FINISH_AFTER_VISIBLE = 2; - private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, - int mode, boolean oomAdj) { + final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) { // First things first: if this activity is currently visible, // and the resumed activity is not yet visible, then hold off on // finishing until the resumed one becomes visible. @@ -2653,7 +2401,7 @@ final class ActivityStack { // then give up on things going idle and start clearing // them out. Or if r is the last of activity of the last task the stack // will be empty and must be cleared immediately. - scheduleIdleLocked(); + mStackSupervisor.scheduleIdleLocked(); } else { checkReadyForSleepLocked(); } @@ -2686,7 +2434,7 @@ final class ActivityStack { boolean activityRemoved = destroyActivityLocked(r, true, oomAdj, "finish-imm"); if (activityRemoved) { - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } return activityRemoved ? null : r; } @@ -2694,8 +2442,8 @@ final class ActivityStack { // 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); - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.mFinishingActivities.add(r); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); return r; } @@ -2807,7 +2555,7 @@ final class ActivityStack { // Make sure this record is no longer in the pending finishes list. // This could happen, for example, if we are trimming activities // down to the max limit while they are still waiting to finish. - mFinishingActivities.remove(r); + mStackSupervisor.mFinishingActivities.remove(r); mStackSupervisor.mWaitingVisibleActivities.remove(r); // Remove any pending results. @@ -2829,7 +2577,7 @@ final class ActivityStack { // There are clients waiting to receive thumbnails so, in case // this is an activity that someone is waiting for, add it // to the pending list so we can correctly update the clients. - mCancelledThumbnails.add(r); + mStackSupervisor.mCancelledThumbnails.add(r); } // Get rid of any pending idle timeouts. @@ -2837,9 +2585,9 @@ final class ActivityStack { } private void removeTimeoutsForActivityLocked(ActivityRecord r) { + mStackSupervisor.removeTimeoutsForActivityLocked(r); mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); mHandler.removeMessages(STOP_TIMEOUT_MSG, r); - mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); r.finishLaunchTickingLocked(); } @@ -2864,7 +2612,7 @@ final class ActivityStack { r.state = ActivityState.DESTROYED; if (DEBUG_APP) Slog.v(TAG, "Clearing app during remove for activity " + r); r.app = null; - mService.mWindowManager.removeAppToken(r.appToken); + mWindowManager.removeAppToken(r.appToken); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -2928,7 +2676,7 @@ final class ActivityStack { } } if (activityRemoved) { - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } } @@ -3045,7 +2793,7 @@ final class ActivityStack { removeActivityFromHistoryLocked(r); } } - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); } finally { Binder.restoreCallingIdentity(origId); } @@ -3076,7 +2824,8 @@ final class ActivityStack { removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities"); removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app, "mWaitingVisibleActivities"); - removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities"); + removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app, + "mFinishingActivities"); boolean hasVisibleActivities = false; @@ -3161,7 +2910,7 @@ final class ActivityStack { ActivityOptions.abort(options); } } - mService.mWindowManager.prepareAppTransition(transit, false); + mWindowManager.prepareAppTransition(transit, false); } final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { @@ -3205,7 +2954,7 @@ final class ActivityStack { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr); if (reason != null && (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); ActivityRecord r = topRunningActivityLocked(null); if (r != null) { mNoAnimActivities.add(r); @@ -3215,9 +2964,9 @@ final class ActivityStack { updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); } - mService.mWindowManager.moveTaskToTop(tr.taskId); + mWindowManager.moveTaskToTop(tr.taskId); - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); if (VALIDATE_TOKENS) { @@ -3226,13 +2975,13 @@ final class ActivityStack { } /** - * Worker method for rearranging history stack. Implements the function of moving all - * activities for a specific task (gathering them if disjoint) into a single group at the + * Worker method for rearranging history stack. Implements the function of moving all + * activities for a specific task (gathering them if disjoint) into a single group at the * bottom of the stack. - * + * * If a watcher is installed, the action is preflighted and the watcher has an opportunity * to premeptively cancel the move. - * + * * @param task The taskId to collect and move to the bottom. * @return Returns true if the move completed, false if not. */ @@ -3272,17 +3021,17 @@ final class ActivityStack { mTaskHistory.add(0, tr); if (reason != null && - (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); + (reason.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { + mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); ActivityRecord r = topRunningActivityLocked(null); if (r != null) { mNoAnimActivities.add(r); } } else { - mService.mWindowManager.prepareAppTransition( + mWindowManager.prepareAppTransition( AppTransition.TRANSIT_TASK_TO_BACK, false); } - mService.mWindowManager.moveTaskToBottom(task); + mWindowManager.moveTaskToBottom(task); if (VALIDATE_TOKENS) { validateAppTokensLocked(); @@ -3294,7 +3043,7 @@ final class ActivityStack { return mStackSupervisor.resumeHomeActivity(null); } - mStackSupervisor.getTopStack().resumeTopActivityLocked(null); + mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); return true; } @@ -3444,7 +3193,7 @@ final class ActivityStack { "Skipping config check (will change): " + r); return true; } - + if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, "Ensuring correct configuration: " + r); @@ -3456,7 +3205,7 @@ final class ActivityStack { "Configuration unchanged in " + r); return true; } - + // We don't worry about activities that are finishing. if (r.finishing) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, @@ -3464,7 +3213,7 @@ final class ActivityStack { r.stopFreezingScreenLocked(false); return true; } - + // Okay we now are going to make this activity have the new config. // But then we need to figure out how it needs to deal with that. Configuration oldConfig = r.configuration; @@ -3490,7 +3239,7 @@ final class ActivityStack { r.forceNewConfig = false; return true; } - + // Figure out how to handle the changes between the configurations. if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" @@ -3530,12 +3279,12 @@ final class ActivityStack { relaunchActivityLocked(r, r.configChangeFlags, false); r.configChangeFlags = 0; } - + // All done... tell the caller we weren't able to keep this // activity around. return false; } - + // Default case: the activity can handle this new configuration, so // hand it over. Note that we don't need to give it the new // configuration, since we always send configuration changes to all @@ -3550,7 +3299,7 @@ final class ActivityStack { } } r.stopFreezingScreenLocked(false); - + return true; } @@ -3758,7 +3507,7 @@ final class ActivityStack { boolean hasVisibleActivities = removeHistoryRecordsForAppLocked(app); if (!restarting) { - ActivityStack stack = mStackSupervisor.getTopStack(); + ActivityStack stack = mStackSupervisor.getFocusedStack(); if (stack == null) { mStackSupervisor.resumeHomeActivity(null); } else if (!stack.resumeTopActivityLocked(null)) { diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 05d721b742db..af358c2abeca 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -32,6 +32,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; +import android.app.IActivityManager; import android.app.IApplicationThread; import android.app.IThumbnailReceiver; import android.app.PendingIntent; @@ -50,6 +51,7 @@ import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.os.Binder; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; @@ -64,6 +66,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.am.ActivityStack.ActivityState; import com.android.server.wm.StackBox; +import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; import java.io.IOException; @@ -82,10 +85,21 @@ public class ActivityStackSupervisor { public static final int HOME_STACK_ID = 0; + /** How long we wait until giving up on the last activity telling us it is idle. */ + static final int IDLE_TIMEOUT = 10*1000; + + static final int IDLE_TIMEOUT_MSG = ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; + static final int IDLE_NOW_MSG = ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG + 1; + final ActivityManagerService mService; final Context mContext; final Looper mLooper; + final ActivityStackSupervisorHandler mHandler; + + /** Short cut */ + WindowManagerService mWindowManager; + /** Dismiss the keyguard after the next activity is displayed? */ private boolean mDismissKeyguardOnNextActivity = false; @@ -119,10 +133,29 @@ public class ActivityStackSupervisor { * whatever operation they are supposed to do. */ final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); + /** List of processes waiting to find out about the next visible activity. */ + final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = + new ArrayList<IActivityManager.WaitResult>(); + + /** List of processes waiting to find out about the next launched activity. */ + final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = + new ArrayList<IActivityManager.WaitResult>(); + /** List of activities that are ready to be stopped, but waiting for the next activity to * settle down before doing so. */ final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); + /** List of activities that are ready to be finished, but waiting for the previous activity to + * settle down before doing so. It contains ActivityRecord objects. */ + final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); + + /** List of ActivityRecord objects that have been finished and must still report back to a + * pending thumbnail receiver. */ + final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); + + /** Used on user changes */ + final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); + /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity * is being brought in front of us. */ boolean mUserLeaving = false; @@ -132,21 +165,23 @@ public class ActivityStackSupervisor { mService = service; mContext = context; mLooper = looper; + mHandler = new ActivityStackSupervisorHandler(looper); } - void init(int userId) { - mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID, this, userId); + void setWindowManager(WindowManagerService wm) { + mWindowManager = wm; + mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID); mStacks.add(mHomeStack); } void dismissKeyguard() { if (mDismissKeyguardOnNextActivity) { mDismissKeyguardOnNextActivity = false; - mService.mWindowManager.dismissKeyguard(); + mWindowManager.dismissKeyguard(); } } - ActivityStack getTopStack() { + ActivityStack getFocusedStack() { if (mFocusedStack == null) { return mHomeStack; } @@ -173,8 +208,12 @@ public class ActivityStackSupervisor { } } + boolean isFocusedStack(ActivityStack stack) { + return getFocusedStack() == stack; + } + boolean isFrontStack(ActivityStack stack) { - return !(stack.isHomeStack() ^ getTopStack().isHomeStack()); + return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); } boolean homeIsInFront() { @@ -256,7 +295,7 @@ public class ActivityStackSupervisor { if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); mStacks.remove(stack); final int stackId = stack.mStackId; - final int nextStackId = mService.mWindowManager.removeStack(stackId); + final int nextStackId = mWindowManager.removeStack(stackId); // TODO: Perhaps we need to let the ActivityManager determine the next focus... if (mFocusedStack.mStackId == stackId) { mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); @@ -265,7 +304,10 @@ public class ActivityStackSupervisor { } ActivityRecord resumedAppLocked() { - ActivityStack stack = getTopStack(); + ActivityStack stack = getFocusedStack(); + if (stack == null) { + return null; + } ActivityRecord resumedActivity = stack.mResumedActivity; if (resumedActivity == null || resumedActivity.app == null) { resumedActivity = stack.mPausingActivity; @@ -361,6 +403,34 @@ public class ActivityStackSupervisor { return true; } + void reportActivityVisibleLocked(ActivityRecord r) { + for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { + WaitResult w = mWaitingActivityVisible.get(i); + w.timeout = false; + if (r != null) { + w.who = new ComponentName(r.info.packageName, r.info.name); + } + w.totalTime = SystemClock.uptimeMillis() - w.thisTime; + w.thisTime = w.totalTime; + } + mService.notifyAll(); + dismissKeyguard(); + } + + void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, + long thisTime, long totalTime) { + for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { + WaitResult w = mWaitingActivityLaunched.get(i); + w.timeout = timeout; + if (r != null) { + w.who = new ComponentName(r.info.packageName, r.info.name); + } + w.thisTime = thisTime; + w.totalTime = totalTime; + } + mService.notifyAll(); + } + ActivityRecord topRunningActivityLocked() { ActivityRecord r = null; if (mFocusedStack != null) { @@ -478,7 +548,7 @@ public class ActivityStackSupervisor { callingPid = callingUid = -1; } - final ActivityStack stack = getTopStack(); + final ActivityStack stack = getFocusedStack(); stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0; if (DEBUG_CONFIGURATION) Slog.v(TAG, @@ -578,7 +648,7 @@ public class ActivityStackSupervisor { if (outResult != null) { outResult.result = res; if (res == ActivityManager.START_SUCCESS) { - stack.mWaitingActivityLaunched.add(outResult); + mWaitingActivityLaunched.add(outResult); do { try { mService.wait(); @@ -594,7 +664,7 @@ public class ActivityStackSupervisor { outResult.thisTime = 0; } else { outResult.thisTime = SystemClock.uptimeMillis(); - stack.mWaitingActivityVisible.add(outResult); + mWaitingActivityVisible.add(outResult); do { try { mService.wait(); @@ -694,7 +764,7 @@ public class ActivityStackSupervisor { throws RemoteException { r.startFreezingScreenLocked(app, 0); - mService.mWindowManager.setAppVisibility(r.appToken, true); + mWindowManager.setAppVisibility(r.appToken, true); // schedule launch ticks to collect information about slow apps. r.startLaunchTickingLocked(); @@ -706,7 +776,7 @@ public class ActivityStackSupervisor { // because the activity is not currently running so we are // just restarting it anyway. if (checkConfig) { - Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( + Configuration config = mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, r.mayFreezeScreenLocked(app) ? r.appToken : null); mService.updateConfigurationLocked(config, r, false, false); @@ -1028,7 +1098,7 @@ public class ActivityStackSupervisor { outActivity[0] = r; } - final ActivityStack stack = getTopStack(); + final ActivityStack stack = getFocusedStack(); if (stack.mResumedActivity == null || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { @@ -1123,7 +1193,7 @@ public class ActivityStackSupervisor { if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { ActivityRecord checkedCaller = sourceRecord; if (checkedCaller == null) { - checkedCaller = getTopStack().topRunningNonDelayedActivityLocked(notTop); + checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); } if (!checkedCaller.realActivity.equals(r.realActivity)) { // Caller is not the same as launcher, so always needed. @@ -1363,7 +1433,7 @@ public class ActivityStackSupervisor { // If the activity being launched is the same as the one currently // at the top, then we need to check if it should only be launched // once. - ActivityStack topStack = getTopStack(); + ActivityStack topStack = getFocusedStack(); ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) { if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { @@ -1519,6 +1589,154 @@ public class ActivityStackSupervisor { return ActivityManager.START_SUCCESS; } + // Checked. + final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, + Configuration config) { + if (localLOGV) Slog.v(TAG, "Activity idle: " + token); + + ActivityRecord res = null; + + ArrayList<ActivityRecord> stops = null; + ArrayList<ActivityRecord> finishes = null; + ArrayList<UserStartedState> startingUsers = null; + int NS = 0; + int NF = 0; + IApplicationThread sendThumbnail = null; + boolean booting = false; + boolean enableScreen = false; + boolean activityRemoved = false; + + ActivityRecord r = ActivityRecord.forToken(token); + if (r != null) { + mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); + r.finishLaunchTickingLocked(); + res = r.task.stack.activityIdleInternalLocked(token, fromTimeout, config); + if (res != null) { + if (fromTimeout) { + reportActivityLaunchedLocked(fromTimeout, r, -1, -1); + } + + // This is a hack to semi-deal with a race condition + // in the client where it can be constructed with a + // newer configuration from when we asked it to launch. + // We'll update with whatever configuration it now says + // it used to launch. + if (config != null) { + r.configuration = config; + } + + // We are now idle. If someone is waiting for a thumbnail from + // us, we can now deliver. + r.idle = true; + if (allResumedActivitiesIdle()) { + mService.scheduleAppGcsLocked(); + } + if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { + sendThumbnail = r.app.thread; + r.thumbnailNeeded = false; + } + + //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); + if (!mService.mBooted && isFrontStack(r.task.stack)) { + mService.mBooted = true; + enableScreen = true; + } + } else if (fromTimeout) { + reportActivityLaunchedLocked(fromTimeout, null, -1, -1); + } + } + + // Atomically retrieve all of the other things to do. + stops = processStoppingActivitiesLocked(true); + NS = stops != null ? stops.size() : 0; + if ((NF=mFinishingActivities.size()) > 0) { + finishes = new ArrayList<ActivityRecord>(mFinishingActivities); + mFinishingActivities.clear(); + } + + final ArrayList<ActivityRecord> thumbnails; + final int NT = mCancelledThumbnails.size(); + if (NT > 0) { + thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); + mCancelledThumbnails.clear(); + } else { + thumbnails = null; + } + + if (isFrontStack(mHomeStack)) { + booting = mService.mBooting; + mService.mBooting = false; + } + + if (mStartingUsers.size() > 0) { + startingUsers = new ArrayList<UserStartedState>(mStartingUsers); + mStartingUsers.clear(); + } + + // Perform the following actions from unsynchronized state. + final IApplicationThread thumbnailThread = sendThumbnail; + mHandler.post(new Runnable() { + @Override + public void run() { + if (thumbnailThread != null) { + try { + thumbnailThread.requestThumbnail(token); + } catch (Exception e) { + Slog.w(TAG, "Exception thrown when requesting thumbnail", e); + mService.sendPendingThumbnail(null, token, null, null, true); + } + } + + // Report back to any thumbnail receivers. + for (int i = 0; i < NT; i++) { + ActivityRecord r = thumbnails.get(i); + mService.sendPendingThumbnail(r, null, null, null, true); + } + } + }); + + // Stop any activities that are scheduled to do so but have been + // waiting for the next one to start. + for (int i = 0; i < NS; i++) { + r = stops.get(i); + final ActivityStack stack = r.task.stack; + if (r.finishing) { + stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); + } else { + stack.stopActivityLocked(r); + } + } + + // Finish any activities that are scheduled to do so but have been + // waiting for the next one to start. + for (int i = 0; i < NF; i++) { + r = finishes.get(i); + activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); + } + + if (booting) { + mService.finishBooting(); + } else if (startingUsers != null) { + for (int i = 0; i < startingUsers.size(); i++) { + mService.finishUserSwitch(startingUsers.get(i)); + } + } + + mService.trimApplications(); + //dump(); + //mWindowManager.dump(); + + if (enableScreen) { + mService.enableScreenAfterBoot(); + } + + if (activityRemoved) { + getFocusedStack().resumeTopActivityLocked(null); + } + + return res; + } + void handleAppDiedLocked(ProcessRecord app, boolean restarting) { // Just in case. final int numStacks = mStacks.size(); @@ -1567,12 +1785,6 @@ public class ActivityStackSupervisor { } } - void scheduleIdleLocked() { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - mStacks.get(stackNdx).scheduleIdleLocked(); - } - } - void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { @@ -1605,8 +1817,7 @@ public class ActivityStackSupervisor { break; } } - mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId, this, - mCurrentUser)); + mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); return mLastStackId; } } @@ -1673,17 +1884,29 @@ public class ActivityStackSupervisor { } void comeOutOfSleepIfNeededLocked() { - final boolean homeIsBack = !homeIsInFront(); - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); - if (stack.isHomeStack() ^ homeIsBack) { - stack.awakeFromSleepingLocked(); + stack.awakeFromSleepingLocked(); + if (isFrontStack(stack)) { stack.resumeTopActivityLocked(null); } } } + boolean reportResumedActivityLocked(ActivityRecord r) { + final ActivityStack stack = r.task.stack; + if (isFrontStack(stack)) { + mService.reportResumedActivityLocked(r); + mService.setFocusedActivityLocked(r); + } + if (allResumedActivitiesComplete()) { + ensureActivitiesVisibleLocked(null, 0); + mWindowManager.executeAppTransition(); + return true; + } + return false; + } + void handleAppCrashLocked(ProcessRecord app) { final int numStacks = mStacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { @@ -1708,12 +1931,12 @@ public class ActivityStackSupervisor { boolean switchUserLocked(int userId, UserStartedState uss) { mCurrentUser = userId; - boolean homeInBack = !homeIsInFront(); + mStartingUsers.add(uss); boolean haveActivities = false; final int numStacks = mStacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); - if (stack.isHomeStack() ^ homeInBack) { + if (isFrontStack(stack)) { haveActivities |= stack.switchUserLocked(userId, uss); } } @@ -1742,7 +1965,7 @@ public class ActivityStackSupervisor { // normal flow and hide it once we determine that it is // hidden by the activities in front of it. if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); - mService.mWindowManager.setAppVisibility(s.appToken, false); + mWindowManager.setAppVisibility(s.appToken, false); } } if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { @@ -1766,7 +1989,7 @@ public class ActivityStackSupervisor { } ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { - return getTopStack().getDumpActivitiesLocked(name); + return getFocusedStack().getDumpActivitiesLocked(name); } boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, @@ -1786,12 +2009,6 @@ public class ActivityStackSupervisor { dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false, dumpPackage); } - if (stack.mFinishingActivities.size() > 0) { - pw.println(" "); - pw.println(" Activities waiting to finish:"); - dumpHistoryList(fd, pw, stack.mFinishingActivities, " ", "Fin", false, - !dumpAll, false, dumpPackage); - } pw.print(" Stack #"); pw.println(mStacks.indexOf(stack)); if (stack.mPausingActivity != null) { @@ -1804,6 +2021,13 @@ public class ActivityStackSupervisor { } } + if (mFinishingActivities.size() > 0) { + pw.println(" "); + pw.println(" Activities waiting to finish:"); + dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false, + dumpPackage); + } + if (mStoppingActivities.size() > 0) { pw.println(" "); pw.println(" Activities waiting to stop:"); @@ -1893,4 +2117,50 @@ public class ActivityStackSupervisor { } } } + + void scheduleIdleTimeoutLocked(ActivityRecord next) { + mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next).sendToTarget(); + } + + final void scheduleIdleLocked() { + mHandler.obtainMessage(IDLE_NOW_MSG).sendToTarget(); + } + + void removeTimeoutsForActivityLocked(ActivityRecord r) { + mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); + } + + private final class ActivityStackSupervisorHandler extends Handler { + + public ActivityStackSupervisorHandler(Looper looper) { + super(looper); + } + + void activityIdleInternal(ActivityRecord r) { + synchronized (mService) { + activityIdleInternalLocked(r != null ? r.appToken : null, true, null); + } + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case IDLE_TIMEOUT_MSG: { + if (mService.mDidDexOpt) { + mService.mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); + nmsg.obj = msg.obj; + mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); + return; + } + // We don't at this point know if the activity is fullscreen, + // so we need to be conservative and assume it isn't. + activityIdleInternal((ActivityRecord)msg.obj); + } break; + case IDLE_NOW_MSG: { + activityIdleInternal((ActivityRecord)msg.obj); + } break; + } + } + } } diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index 64b9572d4c73..e697f88f8729 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -165,7 +165,7 @@ public class CompatModePackages { } public boolean getFrontActivityAskCompatModeLocked() { - ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null); + ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); if (r == null) { return false; } @@ -177,7 +177,7 @@ public class CompatModePackages { } public void setFrontActivityAskCompatModeLocked(boolean ask) { - ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null); + ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); if (r != null) { setPackageAskCompatModeLocked(r.packageName, ask); } @@ -199,7 +199,7 @@ public class CompatModePackages { } public int getFrontActivityScreenCompatModeLocked() { - ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null); + ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); if (r == null) { return ActivityManager.COMPAT_MODE_UNKNOWN; } @@ -207,7 +207,7 @@ public class CompatModePackages { } public void setFrontActivityScreenCompatModeLocked(int mode) { - ActivityRecord r = mService.getTopStack().topRunningActivityLocked(null); + ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null); if (r == null) { Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); return; @@ -294,7 +294,7 @@ public class CompatModePackages { Message msg = mHandler.obtainMessage(MSG_WRITE); mHandler.sendMessageDelayed(msg, 10000); - final ActivityStack stack = mService.getTopStack(); + final ActivityStack stack = mService.getFocusedStack(); ActivityRecord starting = stack.restartPackage(packageName); // Tell all processes that loaded this package about the change. |