ActivityStackSupervisor.java revision 20e7227454bf6f3500c6eb97a17483dd8b764341
1de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org/* 29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * Copyright (C) 2013 The Android Open Source Project 39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * 49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * Licensed under the Apache License, Version 2.0 (the "License"); 59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * you may not use this file except in compliance with the License. 69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * You may obtain a copy of the License at 79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * 89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * http://www.apache.org/licenses/LICENSE-2.0 99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * 109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * Unless required by applicable law or agreed to in writing, software 119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * distributed under the License is distributed on an "AS IS" BASIS, 129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * See the License for the specific language governing permissions and 149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * limitations under the License. 159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com */ 169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.compackage com.android.server.am; 189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport static com.android.server.am.ActivityManagerService.DEBUG_CLEANUP; 209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport static com.android.server.am.ActivityManagerService.DEBUG_PAUSE; 219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport static com.android.server.am.ActivityManagerService.TAG; 229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.app.IThumbnailReceiver; 249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.app.ActivityManager.RunningTaskInfo; 259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.content.Context; 269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.content.Intent; 279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.content.pm.ActivityInfo; 289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.os.Bundle; 299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.os.Looper; 309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comimport android.os.RemoteException; 313291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport android.util.Slog; 323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport java.io.FileDescriptor; 343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport java.io.IOException; 353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport java.io.PrintWriter; 363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport java.util.ArrayList; 373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgimport java.util.List; 383291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.orgpublic class ActivityStackSupervisor { 403291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org public static final int HOME_STACK_ID = 0; 41160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 423291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final ActivityManagerService mService; 433291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final Context mContext; 449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final Looper mLooper; 453291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 463291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org /** Dismiss the keyguard after the next activity is displayed? */ 47b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org private boolean mDismissKeyguardOnNextActivity = false; 48b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 49b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org /** Identifier counter for all ActivityStacks */ 509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com private int mLastStackId = 0; 519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 52de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org /** Task identifier that activities are currently being started in. Incremented each time a 53de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org * new task is created. */ 54de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org private int mCurTaskId = 0; 559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com /** The stack containing the launcher app */ 573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org private ActivityStack mHomeStack; 583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org /** The stack currently receiving input or launching the next activity */ 603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org private ActivityStack mMainStack; 61de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 623291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org /** All the non-launcher stacks */ 63de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 64de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org public ActivityStackSupervisor(ActivityManagerService service, Context context, 663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Looper looper) { 679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com mService = service; 689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com mContext = context; 69160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org mLooper = looper; 709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 72de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org void init() { 73de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID, this); 743291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org setMainStack(mHomeStack); 753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org mStacks.add(mHomeStack); 769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 78de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org void dismissKeyguard() { 79de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org if (mDismissKeyguardOnNextActivity) { 80de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org mDismissKeyguardOnNextActivity = false; 81de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org mService.mWindowManager.dismissKeyguard(); 82de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 83de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 84de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org boolean isHomeStackMain() { 869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return mHomeStack == mMainStack; 879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com boolean isMainStack(ActivityStack stack) { 909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return stack == mMainStack; 919a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com ActivityStack getMainStack() { 949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return mMainStack; 959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com void setMainStack(ActivityStack stack) { 989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com mMainStack = stack; 999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1013291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org void setDismissKeyguard(boolean dismiss) { 1023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org mDismissKeyguardOnNextActivity = dismiss; 1033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 1043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org TaskRecord anyTaskForIdLocked(int id) { 1063291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org ActivityStack stack = mStacks.get(stackNdx); 1083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org TaskRecord task = stack.taskForIdLocked(id); 1093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (task != null) { 1103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return task; 1119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return null; 1149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 116b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org int getNextTaskId() { 1179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com do { 1189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com mCurTaskId++; 1199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (mCurTaskId <= 0) { 1203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org mCurTaskId = 1; 1213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 1223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } while (anyTaskForIdLocked(mCurTaskId) != null); 1233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return mCurTaskId; 1243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 1253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 1263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { 1279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com boolean didSomething = false; 1283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final String processName = app.processName; 1299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final ActivityStack stack = mStacks.get(stackNdx); 1319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com ActivityRecord hr = stack.topRunningActivityLocked(null); 1323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (hr != null) { 1333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (hr.app == null && app.uid == hr.info.applicationInfo.uid 1349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com && processName.equals(hr.processName)) { 1353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org try { 1369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (headless) { 1373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Slog.e(TAG, "Starting activities not supported on headless device: " 1389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com + hr); 1393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } else if (stack.realStartActivityLocked(hr, app, true, true)) { 140160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org didSomething = true; 1413291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 1423291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } catch (Exception e) { 1433291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org Slog.w(TAG, "Exception in new application when starting activity " 1443291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org + hr.intent.getComponent().flattenToShortString(), e); 1453291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org throw e; 146160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 147160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 148160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org stack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 149160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 150160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 151160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 152160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org return didSomething; 153160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 154ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 155ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org boolean allResumedActivitiesIdle() { 156ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (mStacks.get(stackNdx).mResumedActivity == null || 1583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org !mStacks.get(stackNdx).mResumedActivity.idle) { 1599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return false; 1609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return true; 163aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com } 1649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 1659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 1669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 1679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com ActivityRecord r = null; 1689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final int numStacks = mStacks.size(); 1699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final ActivityStack stack = mStacks.get(stackNdx); 1719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final ActivityRecord ar = 1729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com stack.getTasksLocked(maxNum - list.size(), receiver, pending, list); 1739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (isMainStack(stack)) { 1749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com r = ar; 1759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com return r; 1783291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 179ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 1809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com void startHomeActivity(Intent intent, ActivityInfo aInfo) { 1819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com mHomeStack.startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 182de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org null, false, null); 1839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 184aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com 185aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com void handleAppDiedLocked(ProcessRecord app, boolean restarting) { 186aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com // Just in case. 187aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com final int numStacks = mStacks.size(); 188aca4968107b0e84a87cee0bad8e5ca21a02e4053christian.plesner.hansen@gmail.com for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final ActivityStack stack = mStacks.get(stackNdx); 1909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (stack.mPausingActivity != null && stack.mPausingActivity.app == app) { 1919a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 1929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com "App died while pausing: " + stack.mPausingActivity); 1939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com stack.mPausingActivity = null; 1949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (stack.mLastPausedActivity != null && stack.mLastPausedActivity.app == app) { 1969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com stack.mLastPausedActivity = null; 1979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 1989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 1999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // Remove this application's activities from active lists. 2009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com boolean hasVisibleActivities = stack.removeHistoryRecordsForAppLocked(app); 2019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 2023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (!restarting) { 2033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (!stack.resumeTopActivityLocked(null)) { 2043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // If there was nothing to resume, and we are not already 2053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // restarting this process, but there is a visible activity that 2069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // is hosted by the process... then make sure all visible 2079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // activities are running, taking care of restarting this 2089a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com // process. 2093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org if (hasVisibleActivities) { 2103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org stack.ensureActivitiesVisibleLocked(null, 0); 2119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 2173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org void closeSystemDialogsLocked() { 2189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final int numStacks = mStacks.size(); 2193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final ActivityStack stack = mStacks.get(stackNdx); 2213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org stack.closeSystemDialogsLocked(); 2223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 2253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org /** 2269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * @return true if some activity was finished (or would have finished if doit were true). 2273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org */ 2283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org boolean didSomething = false; 2303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org final int numStacks = mStacks.size(); 2319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com final ActivityStack stack = mStacks.get(stackNdx); 2339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com didSomething = true; 2353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org } 2373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org return didSomething; 2389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com } 2399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 2409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com void resumeTopActivityLocked() { 241de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org final int start, end; 242de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org if (isHomeStackMain()) { 243de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org start = 0; 244de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org end = 1; 245de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } else { 246de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org start = 1; 247de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org end = mStacks.size(); 248de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 249de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org for (int stackNdx = start; stackNdx < end; ++stackNdx) { 250de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org mStacks.get(stackNdx).resumeTopActivityLocked(null); 251de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 252de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 253de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 254de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org void finishTopRunningActivityLocked(ProcessRecord app) { 255de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org final int numStacks = mStacks.size(); 256de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 257de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org final ActivityStack stack = mStacks.get(stackNdx); 258de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org stack.finishTopRunningActivityLocked(app); 259de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 260de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 261de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 262de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org void scheduleIdleLocked() { 263de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 264de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org mStacks.get(stackNdx).scheduleIdleLocked(); 265de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 266de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 267 268 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 269 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 270 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 271 return; 272 } 273 } 274 } 275 276 private ActivityStack getStack(int stackId) { 277 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 278 final ActivityStack stack = mStacks.get(stackNdx); 279 if (stack.getStackId() == stackId) { 280 return stack; 281 } 282 } 283 return null; 284 } 285 286 int createStack(int relativeStackId, int position, float weight) { 287 synchronized (this) { 288 while (true) { 289 if (++mLastStackId <= HOME_STACK_ID) { 290 mLastStackId = HOME_STACK_ID + 1; 291 } 292 if (getStack(mLastStackId) == null) { 293 break; 294 } 295 } 296 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId, this)); 297 return mLastStackId; 298 } 299 } 300 301 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 302 final ActivityStack stack = getStack(stackId); 303 if (stack == null) { 304 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 305 return; 306 } 307 stack.moveTask(taskId, toTop); 308 } 309 310 void goingToSleepLocked() { 311 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 312 mStacks.get(stackNdx).stopIfSleepingLocked(); 313 } 314 } 315 316 boolean shutdownLocked(int timeout) { 317 boolean timedout = false; 318 final int numStacks = mStacks.size(); 319 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 320 final ActivityStack stack = mStacks.get(stackNdx); 321 if (stack.mResumedActivity != null) { 322 stack.stopIfSleepingLocked(); 323 final long endTime = System.currentTimeMillis() + timeout; 324 while (stack.mResumedActivity != null || stack.mPausingActivity != null) { 325 long delay = endTime - System.currentTimeMillis(); 326 if (delay <= 0) { 327 Slog.w(TAG, "Activity manager shutdown timed out"); 328 timedout = true; 329 break; 330 } 331 try { 332 mService.wait(); 333 } catch (InterruptedException e) { 334 } 335 } 336 } 337 } 338 return timedout; 339 } 340 341 void comeOutOfSleepIfNeededLocked() { 342 final int numStacks = mStacks.size(); 343 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 344 final ActivityStack stack = mStacks.get(stackNdx); 345 stack.awakeFromSleepingLocked(); 346 stack.resumeTopActivityLocked(null); 347 } 348 } 349 350 void handleAppCrashLocked(ProcessRecord app) { 351 final int numStacks = mStacks.size(); 352 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 353 final ActivityStack stack = mStacks.get(stackNdx); 354 stack.handleAppCrashLocked(app); 355 } 356 } 357 358 boolean updateConfigurationLocked(int changes, ActivityRecord starting) { 359 boolean kept = true; 360 final int numStacks = mStacks.size(); 361 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 362 final ActivityStack stack = mStacks.get(stackNdx); 363 if (changes != 0 && starting == null) { 364 // If the configuration changed, and the caller is not already 365 // in the process of starting an activity, then find the top 366 // activity to check if its configuration needs to change. 367 starting = stack.topRunningActivityLocked(null); 368 } 369 370 if (starting != null) { 371 if (!stack.ensureActivityConfigurationLocked(starting, changes)) { 372 kept = false; 373 } 374 // And we need to make sure at this point that all other activities 375 // are made visible with the correct configuration. 376 stack.ensureActivitiesVisibleLocked(starting, changes); 377 } 378 } 379 return kept; 380 } 381 382 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 383 final int numStacks = mStacks.size(); 384 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 385 final ActivityStack stack = mStacks.get(stackNdx); 386 stack.scheduleDestroyActivities(app, false, reason); 387 } 388 } 389 390 boolean switchUserLocked(int userId, UserStartedState uss) { 391 boolean haveActivities = false; 392 final int numStacks = mStacks.size(); 393 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 394 final ActivityStack stack = mStacks.get(stackNdx); 395 haveActivities |= stack.switchUserLocked(userId, uss); 396 } 397 return haveActivities; 398 } 399 400 public void dump(PrintWriter pw, String prefix) { 401 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:"); 402 pw.println(mDismissKeyguardOnNextActivity); 403 } 404 405 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 406 return mMainStack.getDumpActivitiesLocked(name); 407 } 408 409 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 410 boolean dumpClient, String dumpPackage) { 411 final int numStacks = mStacks.size(); 412 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 413 final ActivityStack stack = mStacks.get(stackNdx); 414 pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":"); 415 stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); 416 pw.println(" "); 417 pw.println(" Running activities (most recent first):"); 418 dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, 419 dumpPackage); 420 if (stack.mWaitingVisibleActivities.size() > 0) { 421 pw.println(" "); 422 pw.println(" Activities waiting for another to become visible:"); 423 dumpHistoryList(fd, pw, stack.mWaitingVisibleActivities, " ", "Wait", false, 424 !dumpAll, false, dumpPackage); 425 } 426 if (stack.mStoppingActivities.size() > 0) { 427 pw.println(" "); 428 pw.println(" Activities waiting to stop:"); 429 dumpHistoryList(fd, pw, stack.mStoppingActivities, " ", "Stop", false, 430 !dumpAll, false, dumpPackage); 431 } 432 if (stack.mGoingToSleepActivities.size() > 0) { 433 pw.println(" "); 434 pw.println(" Activities waiting to sleep:"); 435 dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, " ", "Sleep", false, 436 !dumpAll, false, dumpPackage); 437 } 438 if (stack.mFinishingActivities.size() > 0) { 439 pw.println(" "); 440 pw.println(" Activities waiting to finish:"); 441 dumpHistoryList(fd, pw, stack.mFinishingActivities, " ", "Fin", false, 442 !dumpAll, false, dumpPackage); 443 } 444 } 445 446 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 447 final ActivityStack stack = mStacks.get(stackNdx); 448 pw.print(" Stack #"); pw.println(mStacks.indexOf(stack)); 449 if (stack.mPausingActivity != null) { 450 pw.println(" mPausingActivity: " + stack.mPausingActivity); 451 } 452 pw.println(" mResumedActivity: " + stack.mResumedActivity); 453 if (dumpAll) { 454 pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity); 455 pw.println(" mSleepTimeout: " + stack.mSleepTimeout); 456 } 457 } 458 459 if (dumpAll) { 460 pw.println(" "); 461 pw.println(" mCurTaskId: " + mCurTaskId); 462 } 463 return true; 464 } 465 466 static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 467 String prefix, String label, boolean complete, boolean brief, boolean client, 468 String dumpPackage) { 469 TaskRecord lastTask = null; 470 boolean needNL = false; 471 final String innerPrefix = prefix + " "; 472 final String[] args = new String[0]; 473 for (int i=list.size()-1; i>=0; i--) { 474 final ActivityRecord r = list.get(i); 475 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 476 continue; 477 } 478 final boolean full = !brief && (complete || !r.isInHistory()); 479 if (needNL) { 480 pw.println(" "); 481 needNL = false; 482 } 483 if (lastTask != r.task) { 484 lastTask = r.task; 485 pw.print(prefix); 486 pw.print(full ? "* " : " "); 487 pw.println(lastTask); 488 if (full) { 489 lastTask.dump(pw, prefix + " "); 490 } else if (complete) { 491 // Complete + brief == give a summary. Isn't that obvious?!? 492 if (lastTask.intent != null) { 493 pw.print(prefix); pw.print(" "); 494 pw.println(lastTask.intent.toInsecureStringWithClip()); 495 } 496 } 497 } 498 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 499 pw.print(" #"); pw.print(i); pw.print(": "); 500 pw.println(r); 501 if (full) { 502 r.dump(pw, innerPrefix); 503 } else if (complete) { 504 // Complete + brief == give a summary. Isn't that obvious?!? 505 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 506 if (r.app != null) { 507 pw.print(innerPrefix); pw.println(r.app); 508 } 509 } 510 if (client && r.app != null && r.app.thread != null) { 511 // flush anything that is already in the PrintWriter since the thread is going 512 // to write to the file descriptor directly 513 pw.flush(); 514 try { 515 TransferPipe tp = new TransferPipe(); 516 try { 517 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 518 r.appToken, innerPrefix, args); 519 // Short timeout, since blocking here can 520 // deadlock with the application. 521 tp.go(fd, 2000); 522 } finally { 523 tp.kill(); 524 } 525 } catch (IOException e) { 526 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 527 } catch (RemoteException e) { 528 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 529 } 530 needNL = true; 531 } 532 } 533 } 534} 535