ActivityStackSupervisor.java revision 2961ce599ebee4895d2c9720fff7f011e7d4a0cd
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.START_ANY_ACTIVITY; 20import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.server.am.ActivityManagerService.localLOGV; 24import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION; 25import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS; 26import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE; 27import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS; 28import static com.android.server.am.ActivityManagerService.DEBUG_STACK; 29import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH; 30import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; 31import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; 32import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 33import static com.android.server.am.ActivityManagerService.TAG; 34import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 35import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; 36import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 37 38import android.app.Activity; 39import android.app.ActivityManager; 40import android.app.ActivityManager.StackInfo; 41import android.app.ActivityOptions; 42import android.app.AppGlobals; 43import android.app.IActivityContainer; 44import android.app.IActivityContainerCallback; 45import android.app.IActivityManager; 46import android.app.IApplicationThread; 47import android.app.PendingIntent; 48import android.app.ActivityManager.RunningTaskInfo; 49import android.app.IActivityManager.WaitResult; 50import android.app.ResultInfo; 51import android.app.StatusBarManager; 52import android.app.admin.IDevicePolicyManager; 53import android.content.ComponentName; 54import android.content.Context; 55import android.content.IIntentSender; 56import android.content.Intent; 57import android.content.IntentSender; 58import android.content.pm.ActivityInfo; 59import android.content.pm.ApplicationInfo; 60import android.content.pm.PackageManager; 61import android.content.pm.ResolveInfo; 62import android.content.res.Configuration; 63import android.graphics.Point; 64import android.hardware.display.DisplayManager; 65import android.hardware.display.DisplayManager.DisplayListener; 66import android.hardware.display.DisplayManagerGlobal; 67import android.hardware.display.VirtualDisplay; 68import android.hardware.input.InputManager; 69import android.hardware.input.InputManagerInternal; 70import android.os.Binder; 71import android.os.Bundle; 72import android.os.Debug; 73import android.os.Handler; 74import android.os.IBinder; 75import android.os.Looper; 76import android.os.Message; 77import android.os.ParcelFileDescriptor; 78import android.os.PowerManager; 79import android.os.Process; 80import android.os.RemoteException; 81import android.os.ServiceManager; 82import android.os.SystemClock; 83import android.os.UserHandle; 84import android.provider.Settings; 85import android.provider.Settings.SettingNotFoundException; 86import android.service.voice.IVoiceInteractionSession; 87import android.util.EventLog; 88import android.util.Slog; 89import android.util.SparseArray; 90 91import android.util.SparseIntArray; 92import android.view.Display; 93import android.view.DisplayInfo; 94import android.view.InputEvent; 95import android.view.Surface; 96import com.android.internal.app.HeavyWeightSwitcherActivity; 97import com.android.internal.app.IVoiceInteractor; 98import com.android.internal.os.TransferPipe; 99import com.android.internal.statusbar.IStatusBarService; 100import com.android.server.LocalServices; 101import com.android.server.am.ActivityStack.ActivityState; 102import com.android.server.wm.WindowManagerService; 103 104 105import java.io.FileDescriptor; 106import java.io.IOException; 107import java.io.PrintWriter; 108import java.util.ArrayList; 109import java.util.List; 110 111public final class ActivityStackSupervisor implements DisplayListener { 112 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 113 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 114 static final boolean DEBUG_APP = DEBUG || false; 115 static final boolean DEBUG_CONTAINERS = DEBUG || false; 116 static final boolean DEBUG_IDLE = DEBUG || false; 117 static final boolean DEBUG_MEDIA_VISIBILITY = DEBUG || false; 118 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 119 static final boolean DEBUG_SCREENSHOTS = DEBUG || false; 120 static final boolean DEBUG_STATES = DEBUG || false; 121 122 public static final int HOME_STACK_ID = 0; 123 124 /** How long we wait until giving up on the last activity telling us it is idle. */ 125 static final int IDLE_TIMEOUT = 10*1000; 126 127 /** How long we can hold the sleep wake lock before giving up. */ 128 static final int SLEEP_TIMEOUT = 5*1000; 129 130 // How long we can hold the launch wake lock before giving up. 131 static final int LAUNCH_TIMEOUT = 10*1000; 132 133 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 134 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 135 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 136 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 137 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 138 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 139 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 140 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 141 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8; 142 static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9; 143 static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10; 144 static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11; 145 static final int CONTAINER_TASK_LIST_EMPTY_TIMEOUT = FIRST_SUPERVISOR_STACK_MSG + 12; 146 static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 13; 147 148 private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 149 150 private static final String LOCK_TASK_TAG = "Lock-to-App"; 151 152 /** Status Bar Service **/ 153 private IBinder mToken = new Binder(); 154 private IStatusBarService mStatusBarService; 155 private IDevicePolicyManager mDevicePolicyManager; 156 157 // For debugging to make sure the caller when acquiring/releasing our 158 // wake lock is the system process. 159 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 160 161 final ActivityManagerService mService; 162 163 final ActivityStackSupervisorHandler mHandler; 164 165 /** Short cut */ 166 WindowManagerService mWindowManager; 167 DisplayManager mDisplayManager; 168 169 /** Dismiss the keyguard after the next activity is displayed? */ 170 boolean mDismissKeyguardOnNextActivity = false; 171 172 /** Identifier counter for all ActivityStacks */ 173 private int mLastStackId = HOME_STACK_ID; 174 175 /** Task identifier that activities are currently being started in. Incremented each time a 176 * new task is created. */ 177 private int mCurTaskId = 0; 178 179 /** The current user */ 180 private int mCurrentUser; 181 182 /** The stack containing the launcher app. Assumed to always be attached to 183 * Display.DEFAULT_DISPLAY. */ 184 private ActivityStack mHomeStack; 185 186 /** The stack currently receiving input or launching the next activity. */ 187 private ActivityStack mFocusedStack; 188 189 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 190 * been resumed. If stacks are changing position this will hold the old stack until the new 191 * stack becomes resumed after which it will be set to mFocusedStack. */ 192 private ActivityStack mLastFocusedStack; 193 194 /** List of activities that are waiting for a new activity to become visible before completing 195 * whatever operation they are supposed to do. */ 196 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 197 198 /** List of processes waiting to find out about the next visible activity. */ 199 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = 200 new ArrayList<IActivityManager.WaitResult>(); 201 202 /** List of processes waiting to find out about the next launched activity. */ 203 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = 204 new ArrayList<IActivityManager.WaitResult>(); 205 206 /** List of activities that are ready to be stopped, but waiting for the next activity to 207 * settle down before doing so. */ 208 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 209 210 /** List of activities that are ready to be finished, but waiting for the previous activity to 211 * settle down before doing so. It contains ActivityRecord objects. */ 212 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); 213 214 /** List of activities that are in the process of going to sleep. */ 215 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); 216 217 /** Used on user changes */ 218 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); 219 220 /** Used to queue up any background users being started */ 221 final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<UserStartedState>(); 222 223 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 224 * is being brought in front of us. */ 225 boolean mUserLeaving = false; 226 227 /** Set when we have taken too long waiting to go to sleep. */ 228 boolean mSleepTimeout = false; 229 230 /** Indicates if we are running on a Leanback-only (TV) device. Only initialized after 231 * setWindowManager is called. **/ 232 private boolean mLeanbackOnlyDevice; 233 234 /** 235 * We don't want to allow the device to go to sleep while in the process 236 * of launching an activity. This is primarily to allow alarm intent 237 * receivers to launch an activity and get that to run before the device 238 * goes back to sleep. 239 */ 240 PowerManager.WakeLock mLaunchingActivity; 241 242 /** 243 * Set when the system is going to sleep, until we have 244 * successfully paused the current activity and released our wake lock. 245 * At that point the system is allowed to actually sleep. 246 */ 247 PowerManager.WakeLock mGoingToSleep; 248 249 /** Stack id of the front stack when user switched, indexed by userId. */ 250 SparseIntArray mUserStackInFront = new SparseIntArray(2); 251 252 // TODO: Add listener for removal of references. 253 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ 254 private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>(); 255 256 /** Mapping from displayId to display current state */ 257 private final SparseArray<ActivityDisplay> mActivityDisplays = 258 new SparseArray<ActivityDisplay>(); 259 260 InputManagerInternal mInputManagerInternal; 261 262 /** If non-null then the task specified remains in front and no other tasks may be started 263 * until the task exits or #stopLockTaskMode() is called. */ 264 TaskRecord mLockTaskModeTask; 265 /** Whether lock task has been entered by an authorized app and cannot 266 * be exited. */ 267 private boolean mLockTaskIsLocked; 268 /** 269 * Notifies the user when entering/exiting lock-task. 270 */ 271 private LockTaskNotify mLockTaskNotify; 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 /** 277 * Description of a request to start a new activity, which has been held 278 * due to app switches being disabled. 279 */ 280 static class PendingActivityLaunch { 281 final ActivityRecord r; 282 final ActivityRecord sourceRecord; 283 final int startFlags; 284 final ActivityStack stack; 285 286 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 287 int _startFlags, ActivityStack _stack) { 288 r = _r; 289 sourceRecord = _sourceRecord; 290 startFlags = _startFlags; 291 stack = _stack; 292 } 293 } 294 295 public ActivityStackSupervisor(ActivityManagerService service) { 296 mService = service; 297 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); 298 } 299 300 /** 301 * At the time when the constructor runs, the power manager has not yet been 302 * initialized. So we initialize our wakelocks afterwards. 303 */ 304 void initPowerManagement() { 305 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 306 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 307 mLaunchingActivity = 308 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 309 mLaunchingActivity.setReferenceCounted(false); 310 } 311 312 // This function returns a IStatusBarService. The value is from ServiceManager. 313 // getService and is cached. 314 private IStatusBarService getStatusBarService() { 315 synchronized (mService) { 316 if (mStatusBarService == null) { 317 mStatusBarService = IStatusBarService.Stub.asInterface( 318 ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); 319 if (mStatusBarService == null) { 320 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 321 } 322 } 323 return mStatusBarService; 324 } 325 } 326 327 private IDevicePolicyManager getDevicePolicyManager() { 328 synchronized (mService) { 329 if (mDevicePolicyManager == null) { 330 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 331 ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE)); 332 if (mDevicePolicyManager == null) { 333 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 334 } 335 } 336 return mDevicePolicyManager; 337 } 338 } 339 340 void setWindowManager(WindowManagerService wm) { 341 synchronized (mService) { 342 mWindowManager = wm; 343 344 mDisplayManager = 345 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 346 mDisplayManager.registerDisplayListener(this, null); 347 348 Display[] displays = mDisplayManager.getDisplays(); 349 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 350 final int displayId = displays[displayNdx].getDisplayId(); 351 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 352 mActivityDisplays.put(displayId, activityDisplay); 353 } 354 355 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY); 356 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID); 357 358 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 359 360 // Initialize this here, now that we can get a valid reference to PackageManager. 361 mLeanbackOnlyDevice = isLeanbackOnlyDevice(); 362 } 363 } 364 365 void dismissKeyguard() { 366 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); 367 if (mDismissKeyguardOnNextActivity) { 368 mDismissKeyguardOnNextActivity = false; 369 mWindowManager.dismissKeyguard(); 370 } 371 } 372 373 ActivityStack getFocusedStack() { 374 return mFocusedStack; 375 } 376 377 ActivityStack getLastStack() { 378 return mLastFocusedStack; 379 } 380 381 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the 382 // top of all visible stacks. 383 boolean isFrontStack(ActivityStack stack) { 384 final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 385 if (parent != null) { 386 stack = parent.task.stack; 387 } 388 ArrayList<ActivityStack> stacks = stack.mStacks; 389 if (stacks != null && !stacks.isEmpty()) { 390 return stack == stacks.get(stacks.size() - 1); 391 } 392 return false; 393 } 394 395 void moveHomeStack(boolean toFront) { 396 ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 397 int topNdx = stacks.size() - 1; 398 if (topNdx <= 0) { 399 return; 400 } 401 ActivityStack topStack = stacks.get(topNdx); 402 final boolean homeInFront = topStack == mHomeStack; 403 if (homeInFront != toFront) { 404 mLastFocusedStack = topStack; 405 stacks.remove(mHomeStack); 406 stacks.add(toFront ? topNdx : 0, mHomeStack); 407 mFocusedStack = stacks.get(topNdx); 408 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new=" 409 + mFocusedStack); 410 } 411 } 412 413 void moveHomeStackTaskToTop(int homeStackTaskType) { 414 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 415 mWindowManager.showRecentApps(); 416 return; 417 } 418 moveHomeStack(true); 419 mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); 420 } 421 422 boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) { 423 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 424 mWindowManager.showRecentApps(); 425 return false; 426 } 427 moveHomeStackTaskToTop(homeStackTaskType); 428 if (prev != null) { 429 prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 430 } 431 432 ActivityRecord r = mHomeStack.topRunningActivityLocked(null); 433 // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) { 434 if (r != null && r.isHomeActivity()) { 435 mService.setFocusedActivityLocked(r); 436 return resumeTopActivitiesLocked(mHomeStack, prev, null); 437 } 438 return mService.startHomeActivityLocked(mCurrentUser); 439 } 440 441 void setDismissKeyguard(boolean dismiss) { 442 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss); 443 mDismissKeyguardOnNextActivity = dismiss; 444 } 445 446 TaskRecord anyTaskForIdLocked(int id) { 447 int numDisplays = mActivityDisplays.size(); 448 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 449 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 450 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 451 ActivityStack stack = stacks.get(stackNdx); 452 TaskRecord task = stack.taskForIdLocked(id); 453 if (task != null) { 454 return task; 455 } 456 } 457 } 458 return null; 459 } 460 461 ActivityRecord isInAnyStackLocked(IBinder token) { 462 int numDisplays = mActivityDisplays.size(); 463 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 464 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 465 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 466 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); 467 if (r != null) { 468 return r; 469 } 470 } 471 } 472 return null; 473 } 474 475 void setNextTaskId(int taskId) { 476 if (taskId > mCurTaskId) { 477 mCurTaskId = taskId; 478 } 479 } 480 481 int getNextTaskId() { 482 do { 483 mCurTaskId++; 484 if (mCurTaskId <= 0) { 485 mCurTaskId = 1; 486 } 487 } while (anyTaskForIdLocked(mCurTaskId) != null); 488 return mCurTaskId; 489 } 490 491 ActivityRecord resumedAppLocked() { 492 ActivityStack stack = getFocusedStack(); 493 if (stack == null) { 494 return null; 495 } 496 ActivityRecord resumedActivity = stack.mResumedActivity; 497 if (resumedActivity == null || resumedActivity.app == null) { 498 resumedActivity = stack.mPausingActivity; 499 if (resumedActivity == null || resumedActivity.app == null) { 500 resumedActivity = stack.topRunningActivityLocked(null); 501 } 502 } 503 return resumedActivity; 504 } 505 506 boolean attachApplicationLocked(ProcessRecord app) throws Exception { 507 final String processName = app.processName; 508 boolean didSomething = false; 509 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 510 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 511 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 512 final ActivityStack stack = stacks.get(stackNdx); 513 if (!isFrontStack(stack)) { 514 continue; 515 } 516 ActivityRecord hr = stack.topRunningActivityLocked(null); 517 if (hr != null) { 518 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 519 && processName.equals(hr.processName)) { 520 try { 521 if (realStartActivityLocked(hr, app, true, true)) { 522 didSomething = true; 523 } 524 } catch (Exception e) { 525 Slog.w(TAG, "Exception in new application when starting activity " 526 + hr.intent.getComponent().flattenToShortString(), e); 527 throw e; 528 } 529 } 530 } 531 } 532 } 533 if (!didSomething) { 534 ensureActivitiesVisibleLocked(null, 0); 535 } 536 return didSomething; 537 } 538 539 boolean allResumedActivitiesIdle() { 540 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 541 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 542 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 543 final ActivityStack stack = stacks.get(stackNdx); 544 if (!isFrontStack(stack) || stack.numActivities() == 0) { 545 continue; 546 } 547 final ActivityRecord resumedActivity = stack.mResumedActivity; 548 if (resumedActivity == null || !resumedActivity.idle) { 549 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack=" 550 + stack.mStackId + " " + resumedActivity + " not idle"); 551 return false; 552 } 553 } 554 } 555 return true; 556 } 557 558 boolean allResumedActivitiesComplete() { 559 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 560 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 561 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 562 final ActivityStack stack = stacks.get(stackNdx); 563 if (isFrontStack(stack)) { 564 final ActivityRecord r = stack.mResumedActivity; 565 if (r != null && r.state != ActivityState.RESUMED) { 566 return false; 567 } 568 } 569 } 570 } 571 // TODO: Not sure if this should check if all Paused are complete too. 572 if (DEBUG_STACK) Slog.d(TAG, 573 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 574 mLastFocusedStack + " to=" + mFocusedStack); 575 mLastFocusedStack = mFocusedStack; 576 return true; 577 } 578 579 boolean allResumedActivitiesVisible() { 580 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 581 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 582 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 583 final ActivityStack stack = stacks.get(stackNdx); 584 final ActivityRecord r = stack.mResumedActivity; 585 if (r != null && (!r.nowVisible || r.waitingVisible)) { 586 return false; 587 } 588 } 589 } 590 return true; 591 } 592 593 /** 594 * Pause all activities in either all of the stacks or just the back stacks. 595 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 596 * @return true if any activity was paused as a result of this call. 597 */ 598 boolean pauseBackStacks(boolean userLeaving) { 599 boolean someActivityPaused = false; 600 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 601 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 602 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 603 final ActivityStack stack = stacks.get(stackNdx); 604 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 605 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + 606 " mResumedActivity=" + stack.mResumedActivity); 607 stack.startPausingLocked(userLeaving, false); 608 someActivityPaused = true; 609 } 610 } 611 } 612 return someActivityPaused; 613 } 614 615 boolean allPausedActivitiesComplete() { 616 boolean pausing = true; 617 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 618 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 619 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 620 final ActivityStack stack = stacks.get(stackNdx); 621 final ActivityRecord r = stack.mPausingActivity; 622 if (r != null && r.state != ActivityState.PAUSED 623 && r.state != ActivityState.STOPPED 624 && r.state != ActivityState.STOPPING) { 625 if (DEBUG_STATES) { 626 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 627 pausing = false; 628 } else { 629 return false; 630 } 631 } 632 } 633 } 634 return pausing; 635 } 636 637 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) { 638 // TODO: Put all stacks in supervisor and iterate through them instead. 639 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 640 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 641 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 642 final ActivityStack stack = stacks.get(stackNdx); 643 if (stack.mResumedActivity != null && 644 stack.mActivityContainer.mParentActivity == parent) { 645 stack.startPausingLocked(userLeaving, uiSleeping); 646 } 647 } 648 } 649 } 650 651 void reportActivityVisibleLocked(ActivityRecord r) { 652 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 653 WaitResult w = mWaitingActivityVisible.get(i); 654 w.timeout = false; 655 if (r != null) { 656 w.who = new ComponentName(r.info.packageName, r.info.name); 657 } 658 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 659 w.thisTime = w.totalTime; 660 } 661 mService.notifyAll(); 662 dismissKeyguard(); 663 } 664 665 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 666 long thisTime, long totalTime) { 667 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 668 WaitResult w = mWaitingActivityLaunched.remove(i); 669 w.timeout = timeout; 670 if (r != null) { 671 w.who = new ComponentName(r.info.packageName, r.info.name); 672 } 673 w.thisTime = thisTime; 674 w.totalTime = totalTime; 675 } 676 mService.notifyAll(); 677 } 678 679 ActivityRecord topRunningActivityLocked() { 680 final ActivityStack focusedStack = getFocusedStack(); 681 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 682 if (r != null) { 683 return r; 684 } 685 686 // Return to the home stack. 687 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 688 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 689 final ActivityStack stack = stacks.get(stackNdx); 690 if (stack != focusedStack && isFrontStack(stack)) { 691 r = stack.topRunningActivityLocked(null); 692 if (r != null) { 693 return r; 694 } 695 } 696 } 697 return null; 698 } 699 700 void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) { 701 // Gather all of the running tasks for each stack into runningTaskLists. 702 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = 703 new ArrayList<ArrayList<RunningTaskInfo>>(); 704 final int numDisplays = mActivityDisplays.size(); 705 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 706 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 707 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 708 final ActivityStack stack = stacks.get(stackNdx); 709 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>(); 710 runningTaskLists.add(stackTaskList); 711 stack.getTasksLocked(stackTaskList, callingUid, allowed); 712 } 713 } 714 715 // The lists are already sorted from most recent to oldest. Just pull the most recent off 716 // each list and add it to list. Stop when all lists are empty or maxNum reached. 717 while (maxNum > 0) { 718 long mostRecentActiveTime = Long.MIN_VALUE; 719 ArrayList<RunningTaskInfo> selectedStackList = null; 720 final int numTaskLists = runningTaskLists.size(); 721 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { 722 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); 723 if (!stackTaskList.isEmpty()) { 724 final long lastActiveTime = stackTaskList.get(0).lastActiveTime; 725 if (lastActiveTime > mostRecentActiveTime) { 726 mostRecentActiveTime = lastActiveTime; 727 selectedStackList = stackTaskList; 728 } 729 } 730 } 731 if (selectedStackList != null) { 732 list.add(selectedStackList.remove(0)); 733 --maxNum; 734 } else { 735 break; 736 } 737 } 738 } 739 740 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 741 String profileFile, ParcelFileDescriptor profileFd, int userId) { 742 // Collect information about the target of the Intent. 743 ActivityInfo aInfo; 744 try { 745 ResolveInfo rInfo = 746 AppGlobals.getPackageManager().resolveIntent( 747 intent, resolvedType, 748 PackageManager.MATCH_DEFAULT_ONLY 749 | ActivityManagerService.STOCK_PM_FLAGS, userId); 750 aInfo = rInfo != null ? rInfo.activityInfo : null; 751 } catch (RemoteException e) { 752 aInfo = null; 753 } 754 755 if (aInfo != null) { 756 // Store the found target back into the intent, because now that 757 // we have it we never want to do this again. For example, if the 758 // user navigates back to this point in the history, we should 759 // always restart the exact same activity. 760 intent.setComponent(new ComponentName( 761 aInfo.applicationInfo.packageName, aInfo.name)); 762 763 // Don't debug things in the system process 764 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 765 if (!aInfo.processName.equals("system")) { 766 mService.setDebugApp(aInfo.processName, true, false); 767 } 768 } 769 770 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 771 if (!aInfo.processName.equals("system")) { 772 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 773 } 774 } 775 776 if (profileFile != null) { 777 if (!aInfo.processName.equals("system")) { 778 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 779 profileFile, profileFd, 780 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 781 } 782 } 783 } 784 return aInfo; 785 } 786 787 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 788 moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE); 789 startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0, 790 null, false, null, null); 791 } 792 793 final int startActivityMayWait(IApplicationThread caller, int callingUid, 794 String callingPackage, Intent intent, String resolvedType, 795 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 796 IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, 797 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 798 Bundle options, int userId, IActivityContainer iContainer) { 799 // Refuse possible leaked file descriptors 800 if (intent != null && intent.hasFileDescriptors()) { 801 throw new IllegalArgumentException("File descriptors passed in Intent"); 802 } 803 boolean componentSpecified = intent.getComponent() != null; 804 805 // Don't modify the client's object! 806 intent = new Intent(intent); 807 808 // Collect information about the target of the Intent. 809 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 810 profileFile, profileFd, userId); 811 812 ActivityContainer container = (ActivityContainer)iContainer; 813 synchronized (mService) { 814 int callingPid; 815 if (callingUid >= 0) { 816 callingPid = -1; 817 } else if (caller == null) { 818 callingPid = Binder.getCallingPid(); 819 callingUid = Binder.getCallingUid(); 820 } else { 821 callingPid = callingUid = -1; 822 } 823 824 final ActivityStack stack; 825 if (container == null || container.mStack.isOnHomeDisplay()) { 826 stack = getFocusedStack(); 827 } else { 828 stack = container.mStack; 829 } 830 stack.mConfigWillChange = config != null 831 && mService.mConfiguration.diff(config) != 0; 832 if (DEBUG_CONFIGURATION) Slog.v(TAG, 833 "Starting activity when config will change = " + stack.mConfigWillChange); 834 835 final long origId = Binder.clearCallingIdentity(); 836 837 if (aInfo != null && 838 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 839 // This may be a heavy-weight process! Check to see if we already 840 // have another, different heavy-weight process running. 841 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 842 if (mService.mHeavyWeightProcess != null && 843 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 844 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 845 int realCallingUid = callingUid; 846 if (caller != null) { 847 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 848 if (callerApp != null) { 849 realCallingUid = callerApp.info.uid; 850 } else { 851 Slog.w(TAG, "Unable to find app for caller " + caller 852 + " (pid=" + callingPid + ") when starting: " 853 + intent.toString()); 854 ActivityOptions.abort(options); 855 return ActivityManager.START_PERMISSION_DENIED; 856 } 857 } 858 859 IIntentSender target = mService.getIntentSenderLocked( 860 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 861 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 862 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 863 | PendingIntent.FLAG_ONE_SHOT, null); 864 865 Intent newIntent = new Intent(); 866 if (requestCode >= 0) { 867 // Caller is requesting a result. 868 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 869 } 870 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 871 new IntentSender(target)); 872 if (mService.mHeavyWeightProcess.activities.size() > 0) { 873 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 874 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 875 hist.packageName); 876 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 877 hist.task.taskId); 878 } 879 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 880 aInfo.packageName); 881 newIntent.setFlags(intent.getFlags()); 882 newIntent.setClassName("android", 883 HeavyWeightSwitcherActivity.class.getName()); 884 intent = newIntent; 885 resolvedType = null; 886 caller = null; 887 callingUid = Binder.getCallingUid(); 888 callingPid = Binder.getCallingPid(); 889 componentSpecified = true; 890 try { 891 ResolveInfo rInfo = 892 AppGlobals.getPackageManager().resolveIntent( 893 intent, null, 894 PackageManager.MATCH_DEFAULT_ONLY 895 | ActivityManagerService.STOCK_PM_FLAGS, userId); 896 aInfo = rInfo != null ? rInfo.activityInfo : null; 897 aInfo = mService.getActivityInfoForUser(aInfo, userId); 898 } catch (RemoteException e) { 899 aInfo = null; 900 } 901 } 902 } 903 } 904 905 int res = startActivityLocked(caller, intent, resolvedType, aInfo, 906 voiceSession, voiceInteractor, resultTo, resultWho, 907 requestCode, callingPid, callingUid, callingPackage, startFlags, options, 908 componentSpecified, null, container); 909 910 Binder.restoreCallingIdentity(origId); 911 912 if (stack.mConfigWillChange) { 913 // If the caller also wants to switch to a new configuration, 914 // do so now. This allows a clean switch, as we are waiting 915 // for the current activity to pause (so we will not destroy 916 // it), and have not yet started the next activity. 917 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 918 "updateConfiguration()"); 919 stack.mConfigWillChange = false; 920 if (DEBUG_CONFIGURATION) Slog.v(TAG, 921 "Updating to new configuration after starting activity."); 922 mService.updateConfigurationLocked(config, null, false, false); 923 } 924 925 if (outResult != null) { 926 outResult.result = res; 927 if (res == ActivityManager.START_SUCCESS) { 928 mWaitingActivityLaunched.add(outResult); 929 do { 930 try { 931 mService.wait(); 932 } catch (InterruptedException e) { 933 } 934 } while (!outResult.timeout && outResult.who == null); 935 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 936 ActivityRecord r = stack.topRunningActivityLocked(null); 937 if (r.nowVisible) { 938 outResult.timeout = false; 939 outResult.who = new ComponentName(r.info.packageName, r.info.name); 940 outResult.totalTime = 0; 941 outResult.thisTime = 0; 942 } else { 943 outResult.thisTime = SystemClock.uptimeMillis(); 944 mWaitingActivityVisible.add(outResult); 945 do { 946 try { 947 mService.wait(); 948 } catch (InterruptedException e) { 949 } 950 } while (!outResult.timeout && outResult.who == null); 951 } 952 } 953 } 954 955 return res; 956 } 957 } 958 959 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 960 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 961 Bundle options, int userId) { 962 if (intents == null) { 963 throw new NullPointerException("intents is null"); 964 } 965 if (resolvedTypes == null) { 966 throw new NullPointerException("resolvedTypes is null"); 967 } 968 if (intents.length != resolvedTypes.length) { 969 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 970 } 971 972 973 int callingPid; 974 if (callingUid >= 0) { 975 callingPid = -1; 976 } else if (caller == null) { 977 callingPid = Binder.getCallingPid(); 978 callingUid = Binder.getCallingUid(); 979 } else { 980 callingPid = callingUid = -1; 981 } 982 final long origId = Binder.clearCallingIdentity(); 983 try { 984 synchronized (mService) { 985 ActivityRecord[] outActivity = new ActivityRecord[1]; 986 for (int i=0; i<intents.length; i++) { 987 Intent intent = intents[i]; 988 if (intent == null) { 989 continue; 990 } 991 992 // Refuse possible leaked file descriptors 993 if (intent != null && intent.hasFileDescriptors()) { 994 throw new IllegalArgumentException("File descriptors passed in Intent"); 995 } 996 997 boolean componentSpecified = intent.getComponent() != null; 998 999 // Don't modify the client's object! 1000 intent = new Intent(intent); 1001 1002 // Collect information about the target of the Intent. 1003 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 1004 0, null, null, userId); 1005 // TODO: New, check if this is correct 1006 aInfo = mService.getActivityInfoForUser(aInfo, userId); 1007 1008 if (aInfo != null && 1009 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 1010 != 0) { 1011 throw new IllegalArgumentException( 1012 "FLAG_CANT_SAVE_STATE not supported here"); 1013 } 1014 1015 Bundle theseOptions; 1016 if (options != null && i == intents.length-1) { 1017 theseOptions = options; 1018 } else { 1019 theseOptions = null; 1020 } 1021 int res = startActivityLocked(caller, intent, resolvedTypes[i], 1022 aInfo, null, null, resultTo, null, -1, callingPid, callingUid, callingPackage, 1023 0, theseOptions, componentSpecified, outActivity, null); 1024 if (res < 0) { 1025 return res; 1026 } 1027 1028 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 1029 } 1030 } 1031 } finally { 1032 Binder.restoreCallingIdentity(origId); 1033 } 1034 1035 return ActivityManager.START_SUCCESS; 1036 } 1037 1038 final boolean realStartActivityLocked(ActivityRecord r, 1039 ProcessRecord app, boolean andResume, boolean checkConfig) 1040 throws RemoteException { 1041 1042 r.startFreezingScreenLocked(app, 0); 1043 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true"); 1044 mWindowManager.setAppVisibility(r.appToken, true); 1045 1046 // schedule launch ticks to collect information about slow apps. 1047 r.startLaunchTickingLocked(); 1048 1049 // Have the window manager re-evaluate the orientation of 1050 // the screen based on the new activity order. Note that 1051 // as a result of this, it can call back into the activity 1052 // manager with a new orientation. We don't care about that, 1053 // because the activity is not currently running so we are 1054 // just restarting it anyway. 1055 if (checkConfig) { 1056 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1057 mService.mConfiguration, 1058 r.mayFreezeScreenLocked(app) ? r.appToken : null); 1059 mService.updateConfigurationLocked(config, r, false, false); 1060 } 1061 1062 r.app = app; 1063 app.waitingToKill = null; 1064 r.launchCount++; 1065 r.lastLaunchTime = SystemClock.uptimeMillis(); 1066 1067 if (localLOGV) Slog.v(TAG, "Launching: " + r); 1068 1069 int idx = app.activities.indexOf(r); 1070 if (idx < 0) { 1071 app.activities.add(r); 1072 } 1073 mService.updateLruProcessLocked(app, true, null); 1074 mService.updateOomAdjLocked(); 1075 1076 final ActivityStack stack = r.task.stack; 1077 try { 1078 if (app.thread == null) { 1079 throw new RemoteException(); 1080 } 1081 List<ResultInfo> results = null; 1082 List<Intent> newIntents = null; 1083 if (andResume) { 1084 results = r.results; 1085 newIntents = r.newIntents; 1086 } 1087 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 1088 + " icicle=" + r.icicle 1089 + " with results=" + results + " newIntents=" + newIntents 1090 + " andResume=" + andResume); 1091 if (andResume) { 1092 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1093 r.userId, System.identityHashCode(r), 1094 r.task.taskId, r.shortComponentName); 1095 } 1096 if (r.isHomeActivity() && r.isNotResolverActivity()) { 1097 // Home process is the root process of the task. 1098 mService.mHomeProcess = r.task.mActivities.get(0).app; 1099 } 1100 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1101 r.sleeping = false; 1102 r.forceNewConfig = false; 1103 mService.showAskCompatModeDialogLocked(r); 1104 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1105 String profileFile = null; 1106 ParcelFileDescriptor profileFd = null; 1107 boolean profileAutoStop = false; 1108 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1109 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1110 mService.mProfileProc = app; 1111 profileFile = mService.mProfileFile; 1112 profileFd = mService.mProfileFd; 1113 profileAutoStop = mService.mAutoStopProfiler; 1114 } 1115 } 1116 app.hasShownUi = true; 1117 app.pendingUiClean = true; 1118 if (profileFd != null) { 1119 try { 1120 profileFd = profileFd.dup(); 1121 } catch (IOException e) { 1122 if (profileFd != null) { 1123 try { 1124 profileFd.close(); 1125 } catch (IOException o) { 1126 } 1127 profileFd = null; 1128 } 1129 } 1130 } 1131 1132 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 1133 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1134 System.identityHashCode(r), r.info, 1135 new Configuration(mService.mConfiguration), r.compat, r.task.voiceInteractor, 1136 app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, 1137 mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop 1138 ); 1139 1140 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 1141 // This may be a heavy-weight process! Note that the package 1142 // manager will ensure that only activity can run in the main 1143 // process of the .apk, which is the only thing that will be 1144 // considered heavy-weight. 1145 if (app.processName.equals(app.info.packageName)) { 1146 if (mService.mHeavyWeightProcess != null 1147 && mService.mHeavyWeightProcess != app) { 1148 Slog.w(TAG, "Starting new heavy weight process " + app 1149 + " when already running " 1150 + mService.mHeavyWeightProcess); 1151 } 1152 mService.mHeavyWeightProcess = app; 1153 Message msg = mService.mHandler.obtainMessage( 1154 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1155 msg.obj = r; 1156 mService.mHandler.sendMessage(msg); 1157 } 1158 } 1159 1160 } catch (RemoteException e) { 1161 if (r.launchFailed) { 1162 // This is the second time we failed -- finish activity 1163 // and give up. 1164 Slog.e(TAG, "Second failure launching " 1165 + r.intent.getComponent().flattenToShortString() 1166 + ", giving up", e); 1167 mService.appDiedLocked(app, app.pid, app.thread); 1168 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1169 "2nd-crash", false); 1170 return false; 1171 } 1172 1173 // This is the first time we failed -- restart process and 1174 // retry. 1175 app.activities.remove(r); 1176 throw e; 1177 } 1178 1179 r.launchFailed = false; 1180 if (stack.updateLRUListLocked(r)) { 1181 Slog.w(TAG, "Activity " + r 1182 + " being launched, but already in LRU list"); 1183 } 1184 1185 if (andResume) { 1186 // As part of the process of launching, ActivityThread also performs 1187 // a resume. 1188 stack.minimalResumeActivityLocked(r); 1189 } else { 1190 // This activity is not starting in the resumed state... which 1191 // should look like we asked it to pause+stop (but remain visible), 1192 // and it has done so and reported back the current icicle and 1193 // other state. 1194 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1195 + " (starting in stopped state)"); 1196 r.state = ActivityState.STOPPED; 1197 r.stopped = true; 1198 } 1199 1200 // Launch the new version setup screen if needed. We do this -after- 1201 // launching the initial activity (that is, home), so that it can have 1202 // a chance to initialize itself while in the background, making the 1203 // switch back to it faster and look better. 1204 if (isFrontStack(stack)) { 1205 mService.startSetupActivityLocked(); 1206 } 1207 1208 return true; 1209 } 1210 1211 void startSpecificActivityLocked(ActivityRecord r, 1212 boolean andResume, boolean checkConfig) { 1213 // Is this activity's application already running? 1214 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1215 r.info.applicationInfo.uid, true); 1216 1217 r.task.stack.setLaunchTime(r); 1218 1219 if (app != null && app.thread != null) { 1220 try { 1221 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1222 || !"android".equals(r.info.packageName)) { 1223 // Don't add this if it is a platform component that is marked 1224 // to run in multiple processes, because this is actually 1225 // part of the framework so doesn't make sense to track as a 1226 // separate apk in the process. 1227 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1228 mService.mProcessStats); 1229 } 1230 realStartActivityLocked(r, app, andResume, checkConfig); 1231 return; 1232 } catch (RemoteException e) { 1233 Slog.w(TAG, "Exception when starting activity " 1234 + r.intent.getComponent().flattenToShortString(), e); 1235 } 1236 1237 // If a dead object exception was thrown -- fall through to 1238 // restart the application. 1239 } 1240 1241 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1242 "activity", r.intent.getComponent(), false, false, true); 1243 } 1244 1245 final int startActivityLocked(IApplicationThread caller, 1246 Intent intent, String resolvedType, ActivityInfo aInfo, 1247 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1248 IBinder resultTo, String resultWho, int requestCode, 1249 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1250 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { 1251 int err = ActivityManager.START_SUCCESS; 1252 1253 ProcessRecord callerApp = null; 1254 if (caller != null) { 1255 callerApp = mService.getRecordForAppLocked(caller); 1256 if (callerApp != null) { 1257 callingPid = callerApp.pid; 1258 callingUid = callerApp.info.uid; 1259 } else { 1260 Slog.w(TAG, "Unable to find app for caller " + caller 1261 + " (pid=" + callingPid + ") when starting: " 1262 + intent.toString()); 1263 err = ActivityManager.START_PERMISSION_DENIED; 1264 } 1265 } 1266 1267 if (err == ActivityManager.START_SUCCESS) { 1268 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1269 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1270 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) 1271 + " on display " + (container == null ? (mFocusedStack == null ? 1272 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1273 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1274 container.mActivityDisplay.mDisplayId))); 1275 } 1276 1277 ActivityRecord sourceRecord = null; 1278 ActivityRecord resultRecord = null; 1279 if (resultTo != null) { 1280 sourceRecord = isInAnyStackLocked(resultTo); 1281 if (DEBUG_RESULTS) Slog.v( 1282 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1283 if (sourceRecord != null) { 1284 if (requestCode >= 0 && !sourceRecord.finishing) { 1285 resultRecord = sourceRecord; 1286 } 1287 } 1288 } 1289 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1290 1291 final int launchFlags = intent.getFlags(); 1292 1293 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1294 && sourceRecord != null) { 1295 // Transfer the result target from the source activity to the new 1296 // one being started, including any failures. 1297 if (requestCode >= 0) { 1298 ActivityOptions.abort(options); 1299 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1300 } 1301 resultRecord = sourceRecord.resultTo; 1302 resultWho = sourceRecord.resultWho; 1303 requestCode = sourceRecord.requestCode; 1304 sourceRecord.resultTo = null; 1305 if (resultRecord != null) { 1306 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 1307 } 1308 if (sourceRecord.launchedFromUid == callingUid) { 1309 // The new activity is being launched from the same uid as the previous 1310 // activity in the flow, and asking to forward its result back to the 1311 // previous. In this case the activity is serving as a trampoline between 1312 // the two, so we also want to update its launchedFromPackage to be the 1313 // same as the previous activity. Note that this is safe, since we know 1314 // these two packages come from the same uid; the caller could just as 1315 // well have supplied that same package name itself. This specifially 1316 // deals with the case of an intent picker/chooser being launched in the app 1317 // flow to redirect to an activity picked by the user, where we want the final 1318 // activity to consider it to have been launched by the previous app activity. 1319 callingPackage = sourceRecord.launchedFromPackage; 1320 } 1321 } 1322 1323 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1324 // We couldn't find a class that can handle the given Intent. 1325 // That's the end of that! 1326 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1327 } 1328 1329 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1330 // We couldn't find the specific class specified in the Intent. 1331 // Also the end of the line. 1332 err = ActivityManager.START_CLASS_NOT_FOUND; 1333 } 1334 1335 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1336 && sourceRecord.task.voiceSession != null) { 1337 // If this activity is being launched as part of a voice session, we need 1338 // to ensure that it is safe to do so. If the upcoming activity will also 1339 // be part of the voice session, we can only launch it if it has explicitly 1340 // said it supports the VOICE category, or it is a part of the calling app. 1341 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1342 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1343 try { 1344 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1345 intent, resolvedType)) { 1346 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1347 } 1348 } catch (RemoteException e) { 1349 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1350 } 1351 } 1352 } 1353 1354 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1355 // If the caller is starting a new voice session, just make sure the target 1356 // is actually allowing it to run this way. 1357 try { 1358 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1359 intent, resolvedType)) { 1360 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1361 } 1362 } catch (RemoteException e) { 1363 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1364 } 1365 } 1366 1367 if (err != ActivityManager.START_SUCCESS) { 1368 if (resultRecord != null) { 1369 resultStack.sendActivityResultLocked(-1, 1370 resultRecord, resultWho, requestCode, 1371 Activity.RESULT_CANCELED, null); 1372 } 1373 setDismissKeyguard(false); 1374 ActivityOptions.abort(options); 1375 return err; 1376 } 1377 1378 final int startAnyPerm = mService.checkPermission( 1379 START_ANY_ACTIVITY, callingPid, callingUid); 1380 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1381 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1382 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1383 if (resultRecord != null) { 1384 resultStack.sendActivityResultLocked(-1, 1385 resultRecord, resultWho, requestCode, 1386 Activity.RESULT_CANCELED, null); 1387 } 1388 setDismissKeyguard(false); 1389 String msg; 1390 if (!aInfo.exported) { 1391 msg = "Permission Denial: starting " + intent.toString() 1392 + " from " + callerApp + " (pid=" + callingPid 1393 + ", uid=" + callingUid + ")" 1394 + " not exported from uid " + aInfo.applicationInfo.uid; 1395 } else { 1396 msg = "Permission Denial: starting " + intent.toString() 1397 + " from " + callerApp + " (pid=" + callingPid 1398 + ", uid=" + callingUid + ")" 1399 + " requires " + aInfo.permission; 1400 } 1401 Slog.w(TAG, msg); 1402 throw new SecurityException(msg); 1403 } 1404 1405 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1406 callingPid, resolvedType, aInfo.applicationInfo); 1407 1408 if (mService.mController != null) { 1409 try { 1410 // The Intent we give to the watcher has the extra data 1411 // stripped off, since it can contain private information. 1412 Intent watchIntent = intent.cloneFilter(); 1413 abort |= !mService.mController.activityStarting(watchIntent, 1414 aInfo.applicationInfo.packageName); 1415 } catch (RemoteException e) { 1416 mService.mController = null; 1417 } 1418 } 1419 1420 if (abort) { 1421 if (resultRecord != null) { 1422 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1423 Activity.RESULT_CANCELED, null); 1424 } 1425 // We pretend to the caller that it was really started, but 1426 // they will just get a cancel result. 1427 setDismissKeyguard(false); 1428 ActivityOptions.abort(options); 1429 return ActivityManager.START_SUCCESS; 1430 } 1431 1432 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1433 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1434 requestCode, componentSpecified, this, container, options); 1435 if (outActivity != null) { 1436 outActivity[0] = r; 1437 } 1438 1439 final ActivityStack stack = getFocusedStack(); 1440 if (voiceSession == null && (stack.mResumedActivity == null 1441 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1442 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1443 PendingActivityLaunch pal = 1444 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1445 mPendingActivityLaunches.add(pal); 1446 setDismissKeyguard(false); 1447 ActivityOptions.abort(options); 1448 return ActivityManager.START_SWITCHES_CANCELED; 1449 } 1450 } 1451 1452 if (mService.mDidAppSwitch) { 1453 // This is the second allowed switch since we stopped switches, 1454 // so now just generally allow switches. Use case: user presses 1455 // home (switches disabled, switch to home, mDidAppSwitch now true); 1456 // user taps a home icon (coming from home so allowed, we hit here 1457 // and now allow anyone to switch again). 1458 mService.mAppSwitchesAllowedTime = 0; 1459 } else { 1460 mService.mDidAppSwitch = true; 1461 } 1462 1463 doPendingActivityLaunchesLocked(false); 1464 1465 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1466 startFlags, true, options); 1467 1468 if (allPausedActivitiesComplete()) { 1469 // If someone asked to have the keyguard dismissed on the next 1470 // activity start, but we are not actually doing an activity 1471 // switch... just dismiss the keyguard now, because we 1472 // probably want to see whatever is behind it. 1473 dismissKeyguard(); 1474 } 1475 return err; 1476 } 1477 1478 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1479 final TaskRecord task = r.task; 1480 1481 // On leanback only devices we should keep all activities in the same stack. 1482 if (!mLeanbackOnlyDevice && 1483 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1484 if (task != null) { 1485 final ActivityStack taskStack = task.stack; 1486 if (taskStack.isOnHomeDisplay()) { 1487 if (mFocusedStack != taskStack) { 1488 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1489 "focused stack to r=" + r + " task=" + task); 1490 mFocusedStack = taskStack; 1491 } else { 1492 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1493 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1494 } 1495 } 1496 return taskStack; 1497 } 1498 1499 final ActivityContainer container = r.mInitialActivityContainer; 1500 if (container != null) { 1501 // The first time put it on the desired stack, after this put on task stack. 1502 r.mInitialActivityContainer = null; 1503 return container.mStack; 1504 } 1505 1506 if (mFocusedStack != mHomeStack && (!newTask || 1507 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1508 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1509 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1510 return mFocusedStack; 1511 } 1512 1513 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1514 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1515 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1516 if (!stack.isHomeStack()) { 1517 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1518 "adjustStackFocus: Setting focused stack=" + stack); 1519 mFocusedStack = stack; 1520 return mFocusedStack; 1521 } 1522 } 1523 1524 // Need to create an app stack for this user. 1525 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1526 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1527 " stackId=" + stackId); 1528 mFocusedStack = getStack(stackId); 1529 return mFocusedStack; 1530 } 1531 return mHomeStack; 1532 } 1533 1534 void setFocusedStack(ActivityRecord r) { 1535 if (r != null) { 1536 final TaskRecord task = r.task; 1537 boolean isHomeActivity = !r.isApplicationActivity(); 1538 if (!isHomeActivity && task != null) { 1539 isHomeActivity = !task.isApplicationTask(); 1540 } 1541 if (!isHomeActivity && task != null) { 1542 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1543 isHomeActivity = parent != null && parent.isHomeActivity(); 1544 } 1545 moveHomeStack(isHomeActivity); 1546 } 1547 } 1548 1549 final int startActivityUncheckedLocked(ActivityRecord r, 1550 ActivityRecord sourceRecord, 1551 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 1552 boolean doResume, Bundle options) { 1553 final Intent intent = r.intent; 1554 final int callingUid = r.launchedFromUid; 1555 1556 final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; 1557 final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; 1558 1559 int launchFlags = intent.getFlags(); 1560 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 1561 (launchSingleInstance || launchSingleTask)) { 1562 // We have a conflict between the Intent and the Activity manifest, manifest wins. 1563 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 1564 "\"singleInstance\" or \"singleTask\""); 1565 launchFlags &= 1566 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1567 } else { 1568 switch (r.info.documentLaunchMode) { 1569 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1570 break; 1571 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1572 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1573 break; 1574 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1575 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1576 break; 1577 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 1578 launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1579 break; 1580 } 1581 } 1582 1583 final boolean launchTaskBehind = r.mLaunchTaskBehind && 1584 (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 1585 1586 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1587 // For whatever reason this activity is being launched into a new 1588 // task... yet the caller has requested a result back. Well, that 1589 // is pretty messed up, so instead immediately send back a cancel 1590 // and let the new task continue launched as normal without a 1591 // dependency on its originator. 1592 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1593 r.resultTo.task.stack.sendActivityResultLocked(-1, 1594 r.resultTo, r.resultWho, r.requestCode, 1595 Activity.RESULT_CANCELED, null); 1596 r.resultTo = null; 1597 } 1598 1599 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 1600 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1601 } 1602 1603 // We'll invoke onUserLeaving before onPause only if the launching 1604 // activity did not explicitly state that this is an automated launch. 1605 mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1606 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1607 1608 // If the caller has asked not to resume at this point, we make note 1609 // of this in the record so that we can skip it when trying to find 1610 // the top running activity. 1611 if (!doResume) { 1612 r.delayedResume = true; 1613 } 1614 1615 ActivityRecord notTop = 1616 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1617 1618 // If the onlyIfNeeded flag is set, then we can do this if the activity 1619 // being launched is the same as the one making the call... or, as 1620 // a special case, if we do not know the caller then we count the 1621 // current top activity as the caller. 1622 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1623 ActivityRecord checkedCaller = sourceRecord; 1624 if (checkedCaller == null) { 1625 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1626 } 1627 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1628 // Caller is not the same as launcher, so always needed. 1629 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1630 } 1631 } 1632 1633 if (sourceRecord == null) { 1634 // This activity is not being started from another... in this 1635 // case we -always- start a new task. 1636 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1637 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1638 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1639 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1640 } 1641 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1642 // The original activity who is starting us is running as a single 1643 // instance... this new activity it is starting must go on its 1644 // own task. 1645 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1646 } else if (launchSingleInstance || launchSingleTask) { 1647 // The activity being started is a single instance... it always 1648 // gets launched into its own task. 1649 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1650 } 1651 1652 ActivityInfo newTaskInfo = null; 1653 Intent newTaskIntent = null; 1654 final ActivityStack sourceStack; 1655 if (sourceRecord != null) { 1656 if (sourceRecord.finishing) { 1657 // If the source is finishing, we can't further count it as our source. This 1658 // is because the task it is associated with may now be empty and on its way out, 1659 // so we don't want to blindly throw it in to that task. Instead we will take 1660 // the NEW_TASK flow and try to find a task for it. But save the task information 1661 // so it can be used when creating the new task. 1662 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1663 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1664 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1665 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1666 newTaskInfo = sourceRecord.info; 1667 newTaskIntent = sourceRecord.task.intent; 1668 } 1669 sourceRecord = null; 1670 sourceStack = null; 1671 } else { 1672 sourceStack = sourceRecord.task.stack; 1673 } 1674 } else { 1675 sourceStack = null; 1676 } 1677 1678 intent.setFlags(launchFlags); 1679 1680 boolean addingToTask = false; 1681 boolean movedHome = false; 1682 TaskRecord reuseTask = null; 1683 ActivityStack targetStack; 1684 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1685 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1686 || launchSingleInstance || launchSingleTask) { 1687 // If bring to front is requested, and no result is requested, and 1688 // we can find a task that was started with this same 1689 // component, then instead of launching bring that one to the front. 1690 if (r.resultTo == null) { 1691 // See if there is a task to bring to the front. If this is 1692 // a SINGLE_INSTANCE activity, there can be one and only one 1693 // instance of it in the history, and it is always in its own 1694 // unique task, so we do a special search. 1695 ActivityRecord intentActivity = !launchSingleInstance ? 1696 findTaskLocked(r) : findActivityLocked(intent, r.info); 1697 if (intentActivity != null) { 1698 if (isLockTaskModeViolation(intentActivity.task)) { 1699 showLockTaskToast(); 1700 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1701 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1702 } 1703 if (r.task == null) { 1704 r.task = intentActivity.task; 1705 } 1706 targetStack = intentActivity.task.stack; 1707 targetStack.mLastPausedActivity = null; 1708 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1709 + " from " + intentActivity); 1710 targetStack.moveToFront(); 1711 if (intentActivity.task.intent == null) { 1712 // This task was started because of movement of 1713 // the activity based on affinity... now that we 1714 // are actually launching it, we can assign the 1715 // base intent. 1716 intentActivity.task.setIntent(intent, r.info); 1717 } 1718 // If the target task is not in the front, then we need 1719 // to bring it to the front... except... well, with 1720 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1721 // to have the same behavior as if a new instance was 1722 // being started, which means not bringing it to the front 1723 // if the caller is not itself in the front. 1724 final ActivityStack lastStack = getLastStack(); 1725 ActivityRecord curTop = lastStack == null? 1726 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1727 if (curTop != null && (curTop.task != intentActivity.task || 1728 curTop.task != lastStack.topTask())) { 1729 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1730 if (sourceRecord == null || (sourceStack.topActivity() != null && 1731 sourceStack.topActivity().task == sourceRecord.task)) { 1732 // We really do want to push this one into the 1733 // user's face, right now. 1734 if (launchTaskBehind && sourceRecord != null) { 1735 intentActivity.setTaskToAffiliateWith(sourceRecord.task); 1736 } 1737 movedHome = true; 1738 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1739 if ((launchFlags & 1740 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1741 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1742 // Caller wants to appear on home activity. 1743 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1744 } 1745 options = null; 1746 } 1747 } 1748 // If the caller has requested that the target task be 1749 // reset, then do so. 1750 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1751 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1752 } 1753 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1754 // We don't need to start a new activity, and 1755 // the client said not to do anything if that 1756 // is the case, so this is it! And for paranoia, make 1757 // sure we have correctly resumed the top activity. 1758 if (doResume) { 1759 resumeTopActivitiesLocked(targetStack, null, options); 1760 } else { 1761 ActivityOptions.abort(options); 1762 } 1763 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1764 } 1765 if ((launchFlags & 1766 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1767 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1768 // The caller has requested to completely replace any 1769 // existing task with its new activity. Well that should 1770 // not be too hard... 1771 reuseTask = intentActivity.task; 1772 reuseTask.performClearTaskLocked(); 1773 reuseTask.setIntent(r.intent, r.info); 1774 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1775 || launchSingleInstance || launchSingleTask) { 1776 // In this situation we want to remove all activities 1777 // from the task up to the one being started. In most 1778 // cases this means we are resetting the task to its 1779 // initial state. 1780 ActivityRecord top = 1781 intentActivity.task.performClearTaskLocked(r, launchFlags); 1782 if (top != null) { 1783 if (top.frontOfTask) { 1784 // Activity aliases may mean we use different 1785 // intents for the top activity, so make sure 1786 // the task now has the identity of the new 1787 // intent. 1788 top.task.setIntent(r.intent, r.info); 1789 } 1790 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1791 r, top.task); 1792 top.deliverNewIntentLocked(callingUid, r.intent); 1793 } else { 1794 // A special case: we need to 1795 // start the activity because it is not currently 1796 // running, and the caller has asked to clear the 1797 // current task to have this activity at the top. 1798 addingToTask = true; 1799 // Now pretend like this activity is being started 1800 // by the top of its task, so it is put in the 1801 // right place. 1802 sourceRecord = intentActivity; 1803 } 1804 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1805 // In this case the top activity on the task is the 1806 // same as the one being launched, so we take that 1807 // as a request to bring the task to the foreground. 1808 // If the top activity in the task is the root 1809 // activity, deliver this new intent to it if it 1810 // desires. 1811 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1812 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1813 && intentActivity.realActivity.equals(r.realActivity)) { 1814 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1815 intentActivity.task); 1816 if (intentActivity.frontOfTask) { 1817 intentActivity.task.setIntent(r.intent, r.info); 1818 } 1819 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1820 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1821 // In this case we are launching the root activity 1822 // of the task, but with a different intent. We 1823 // should start a new instance on top. 1824 addingToTask = true; 1825 sourceRecord = intentActivity; 1826 } 1827 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1828 // In this case an activity is being launched in to an 1829 // existing task, without resetting that task. This 1830 // is typically the situation of launching an activity 1831 // from a notification or shortcut. We want to place 1832 // the new activity on top of the current task. 1833 addingToTask = true; 1834 sourceRecord = intentActivity; 1835 } else if (!intentActivity.task.rootWasReset) { 1836 // In this case we are launching in to an existing task 1837 // that has not yet been started from its front door. 1838 // The current task has been brought to the front. 1839 // Ideally, we'd probably like to place this new task 1840 // at the bottom of its stack, but that's a little hard 1841 // to do with the current organization of the code so 1842 // for now we'll just drop it. 1843 intentActivity.task.setIntent(r.intent, r.info); 1844 } 1845 if (!addingToTask && reuseTask == null) { 1846 // We didn't do anything... but it was needed (a.k.a., client 1847 // don't use that intent!) And for paranoia, make 1848 // sure we have correctly resumed the top activity. 1849 if (doResume) { 1850 targetStack.resumeTopActivityLocked(null, options); 1851 } else { 1852 ActivityOptions.abort(options); 1853 } 1854 return ActivityManager.START_TASK_TO_FRONT; 1855 } 1856 } 1857 } 1858 } 1859 1860 //String uri = r.intent.toURI(); 1861 //Intent intent2 = new Intent(uri); 1862 //Slog.i(TAG, "Given intent: " + r.intent); 1863 //Slog.i(TAG, "URI is: " + uri); 1864 //Slog.i(TAG, "To intent: " + intent2); 1865 1866 if (r.packageName != null) { 1867 // If the activity being launched is the same as the one currently 1868 // at the top, then we need to check if it should only be launched 1869 // once. 1870 ActivityStack topStack = getFocusedStack(); 1871 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1872 if (top != null && r.resultTo == null) { 1873 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1874 if (top.app != null && top.app.thread != null) { 1875 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1876 || launchSingleInstance || launchSingleTask) { 1877 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1878 top.task); 1879 // For paranoia, make sure we have correctly 1880 // resumed the top activity. 1881 topStack.mLastPausedActivity = null; 1882 if (doResume) { 1883 resumeTopActivitiesLocked(); 1884 } 1885 ActivityOptions.abort(options); 1886 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1887 // We don't need to start a new activity, and 1888 // the client said not to do anything if that 1889 // is the case, so this is it! 1890 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1891 } 1892 top.deliverNewIntentLocked(callingUid, r.intent); 1893 return ActivityManager.START_DELIVERED_TO_TOP; 1894 } 1895 } 1896 } 1897 } 1898 1899 } else { 1900 if (r.resultTo != null) { 1901 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1902 r.requestCode, Activity.RESULT_CANCELED, null); 1903 } 1904 ActivityOptions.abort(options); 1905 return ActivityManager.START_CLASS_NOT_FOUND; 1906 } 1907 1908 boolean newTask = false; 1909 boolean keepCurTransition = false; 1910 1911 TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ? 1912 sourceRecord.task : null; 1913 1914 // Should this be considered a new task? 1915 if (r.resultTo == null && !addingToTask 1916 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1917 if (isLockTaskModeViolation(reuseTask)) { 1918 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1919 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1920 } 1921 newTask = true; 1922 targetStack = adjustStackFocus(r, newTask); 1923 if (!launchTaskBehind) { 1924 targetStack.moveToFront(); 1925 } 1926 if (reuseTask == null) { 1927 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1928 newTaskInfo != null ? newTaskInfo : r.info, 1929 newTaskIntent != null ? newTaskIntent : intent, 1930 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */), 1931 taskToAffiliate); 1932 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1933 r.task); 1934 } else { 1935 r.setTask(reuseTask, taskToAffiliate); 1936 } 1937 if (!movedHome) { 1938 if ((launchFlags & 1939 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1940 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1941 // Caller wants to appear on home activity, so before starting 1942 // their own activity we will bring home to the front. 1943 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1944 } 1945 } 1946 } else if (sourceRecord != null) { 1947 final TaskRecord sourceTask = sourceRecord.task; 1948 if (isLockTaskModeViolation(sourceTask)) { 1949 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1950 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1951 } 1952 targetStack = sourceTask.stack; 1953 targetStack.moveToFront(); 1954 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 1955 if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1956 // In this case, we are adding the activity to an existing 1957 // task, but the caller has asked to clear that task if the 1958 // activity is already running. 1959 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1960 keepCurTransition = true; 1961 if (top != null) { 1962 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1963 top.deliverNewIntentLocked(callingUid, r.intent); 1964 // For paranoia, make sure we have correctly 1965 // resumed the top activity. 1966 targetStack.mLastPausedActivity = null; 1967 if (doResume) { 1968 targetStack.resumeTopActivityLocked(null); 1969 } 1970 ActivityOptions.abort(options); 1971 return ActivityManager.START_DELIVERED_TO_TOP; 1972 } 1973 } else if (!addingToTask && 1974 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1975 // In this case, we are launching an activity in our own task 1976 // that may already be running somewhere in the history, and 1977 // we want to shuffle it to the front of the stack if so. 1978 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1979 if (top != null) { 1980 final TaskRecord task = top.task; 1981 task.moveActivityToFrontLocked(top); 1982 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1983 top.updateOptionsLocked(options); 1984 top.deliverNewIntentLocked(callingUid, r.intent); 1985 targetStack.mLastPausedActivity = null; 1986 if (doResume) { 1987 targetStack.resumeTopActivityLocked(null); 1988 } 1989 return ActivityManager.START_DELIVERED_TO_TOP; 1990 } 1991 } 1992 // An existing activity is starting this new activity, so we want 1993 // to keep the new one in the same task as the one that is starting 1994 // it. 1995 r.setTask(sourceTask, null); 1996 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1997 + " in existing task " + r.task + " from source " + sourceRecord); 1998 1999 } else { 2000 // This not being started from an existing activity, and not part 2001 // of a new task... just put it in the top task, though these days 2002 // this case should never happen. 2003 targetStack = adjustStackFocus(r, newTask); 2004 targetStack.moveToFront(); 2005 ActivityRecord prev = targetStack.topActivity(); 2006 r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), 2007 r.info, intent, null, null, true), null); 2008 mWindowManager.moveTaskToTop(r.task.taskId); 2009 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2010 + " in new guessed " + r.task); 2011 } 2012 2013 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 2014 intent, r.getUriPermissionsLocked(), r.userId); 2015 2016 if (sourceRecord != null && sourceRecord.isRecentsActivity()) { 2017 r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE); 2018 } 2019 if (newTask) { 2020 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 2021 } 2022 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 2023 targetStack.mLastPausedActivity = null; 2024 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 2025 if (!launchTaskBehind) { 2026 // Don't set focus on an activity that's going to the back. 2027 mService.setFocusedActivityLocked(r); 2028 } 2029 return ActivityManager.START_SUCCESS; 2030 } 2031 2032 final void doPendingActivityLaunchesLocked(boolean doResume) { 2033 while (!mPendingActivityLaunches.isEmpty()) { 2034 PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); 2035 startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 2036 doResume && mPendingActivityLaunches.isEmpty(), null); 2037 } 2038 } 2039 2040 void removePendingActivityLaunchesLocked(ActivityRecord r) { 2041 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) { 2042 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx); 2043 if (pal.r == r) { 2044 mPendingActivityLaunches.remove(palNdx); 2045 } 2046 } 2047 } 2048 2049 void acquireLaunchWakelock() { 2050 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2051 throw new IllegalStateException("Calling must be system uid"); 2052 } 2053 mLaunchingActivity.acquire(); 2054 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2055 // To be safe, don't allow the wake lock to be held for too long. 2056 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2057 } 2058 } 2059 2060 // Checked. 2061 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 2062 Configuration config) { 2063 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 2064 2065 ArrayList<ActivityRecord> stops = null; 2066 ArrayList<ActivityRecord> finishes = null; 2067 ArrayList<UserStartedState> startingUsers = null; 2068 int NS = 0; 2069 int NF = 0; 2070 boolean booting = false; 2071 boolean enableScreen = false; 2072 boolean activityRemoved = false; 2073 2074 ActivityRecord r = ActivityRecord.forToken(token); 2075 if (r != null) { 2076 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 2077 Debug.getCallers(4)); 2078 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2079 r.finishLaunchTickingLocked(); 2080 if (fromTimeout) { 2081 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2082 } 2083 2084 // This is a hack to semi-deal with a race condition 2085 // in the client where it can be constructed with a 2086 // newer configuration from when we asked it to launch. 2087 // We'll update with whatever configuration it now says 2088 // it used to launch. 2089 if (config != null) { 2090 r.configuration = config; 2091 } 2092 2093 // We are now idle. If someone is waiting for a thumbnail from 2094 // us, we can now deliver. 2095 r.idle = true; 2096 2097 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2098 if (!mService.mBooted && isFrontStack(r.task.stack)) { 2099 mService.mBooted = true; 2100 enableScreen = true; 2101 } 2102 } 2103 2104 if (allResumedActivitiesIdle()) { 2105 if (r != null) { 2106 mService.scheduleAppGcsLocked(); 2107 } 2108 2109 if (mLaunchingActivity.isHeld()) { 2110 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2111 if (VALIDATE_WAKE_LOCK_CALLER && 2112 Binder.getCallingUid() != Process.myUid()) { 2113 throw new IllegalStateException("Calling must be system uid"); 2114 } 2115 mLaunchingActivity.release(); 2116 } 2117 ensureActivitiesVisibleLocked(null, 0); 2118 } 2119 2120 // Atomically retrieve all of the other things to do. 2121 stops = processStoppingActivitiesLocked(true); 2122 NS = stops != null ? stops.size() : 0; 2123 if ((NF=mFinishingActivities.size()) > 0) { 2124 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 2125 mFinishingActivities.clear(); 2126 } 2127 2128 booting = mService.mBooting; 2129 mService.mBooting = false; 2130 2131 if (mStartingUsers.size() > 0) { 2132 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 2133 mStartingUsers.clear(); 2134 } 2135 2136 // Stop any activities that are scheduled to do so but have been 2137 // waiting for the next one to start. 2138 for (int i = 0; i < NS; i++) { 2139 r = stops.get(i); 2140 final ActivityStack stack = r.task.stack; 2141 if (r.finishing) { 2142 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2143 } else { 2144 stack.stopActivityLocked(r); 2145 } 2146 } 2147 2148 // Finish any activities that are scheduled to do so but have been 2149 // waiting for the next one to start. 2150 for (int i = 0; i < NF; i++) { 2151 r = finishes.get(i); 2152 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle"); 2153 } 2154 2155 if (booting) { 2156 mService.finishBooting(); 2157 } else { 2158 // Complete user switch 2159 if (startingUsers != null) { 2160 for (int i = 0; i < startingUsers.size(); i++) { 2161 mService.finishUserSwitch(startingUsers.get(i)); 2162 } 2163 } 2164 // Complete starting up of background users 2165 if (mStartingBackgroundUsers.size() > 0) { 2166 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2167 mStartingBackgroundUsers.clear(); 2168 for (int i = 0; i < startingUsers.size(); i++) { 2169 mService.finishUserBoot(startingUsers.get(i)); 2170 } 2171 } 2172 } 2173 2174 mService.trimApplications(); 2175 //dump(); 2176 //mWindowManager.dump(); 2177 2178 if (enableScreen) { 2179 mService.enableScreenAfterBoot(); 2180 } 2181 2182 if (activityRemoved) { 2183 resumeTopActivitiesLocked(); 2184 } 2185 2186 return r; 2187 } 2188 2189 boolean handleAppDiedLocked(ProcessRecord app) { 2190 boolean hasVisibleActivities = false; 2191 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2192 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2193 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2194 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2195 } 2196 } 2197 return hasVisibleActivities; 2198 } 2199 2200 void closeSystemDialogsLocked() { 2201 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2202 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2203 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2204 stacks.get(stackNdx).closeSystemDialogsLocked(); 2205 } 2206 } 2207 } 2208 2209 void removeUserLocked(int userId) { 2210 mUserStackInFront.delete(userId); 2211 } 2212 2213 /** 2214 * @return true if some activity was finished (or would have finished if doit were true). 2215 */ 2216 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2217 boolean didSomething = false; 2218 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2219 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2220 final int numStacks = stacks.size(); 2221 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2222 final ActivityStack stack = stacks.get(stackNdx); 2223 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2224 didSomething = true; 2225 } 2226 } 2227 } 2228 return didSomething; 2229 } 2230 2231 void updatePreviousProcessLocked(ActivityRecord r) { 2232 // Now that this process has stopped, we may want to consider 2233 // it to be the previous app to try to keep around in case 2234 // the user wants to return to it. 2235 2236 // First, found out what is currently the foreground app, so that 2237 // we don't blow away the previous app if this activity is being 2238 // hosted by the process that is actually still the foreground. 2239 ProcessRecord fgApp = null; 2240 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2241 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2242 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2243 final ActivityStack stack = stacks.get(stackNdx); 2244 if (isFrontStack(stack)) { 2245 if (stack.mResumedActivity != null) { 2246 fgApp = stack.mResumedActivity.app; 2247 } else if (stack.mPausingActivity != null) { 2248 fgApp = stack.mPausingActivity.app; 2249 } 2250 break; 2251 } 2252 } 2253 } 2254 2255 // Now set this one as the previous process, only if that really 2256 // makes sense to. 2257 if (r.app != null && fgApp != null && r.app != fgApp 2258 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2259 && r.app != mService.mHomeProcess) { 2260 mService.mPreviousProcess = r.app; 2261 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2262 } 2263 } 2264 2265 boolean resumeTopActivitiesLocked() { 2266 return resumeTopActivitiesLocked(null, null, null); 2267 } 2268 2269 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2270 Bundle targetOptions) { 2271 if (targetStack == null) { 2272 targetStack = getFocusedStack(); 2273 } 2274 // Do targetStack first. 2275 boolean result = false; 2276 if (isFrontStack(targetStack)) { 2277 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2278 } 2279 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2280 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2281 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2282 final ActivityStack stack = stacks.get(stackNdx); 2283 if (stack == targetStack) { 2284 // Already started above. 2285 continue; 2286 } 2287 if (isFrontStack(stack)) { 2288 stack.resumeTopActivityLocked(null); 2289 } 2290 } 2291 } 2292 return result; 2293 } 2294 2295 void finishTopRunningActivityLocked(ProcessRecord app) { 2296 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2297 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2298 final int numStacks = stacks.size(); 2299 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2300 final ActivityStack stack = stacks.get(stackNdx); 2301 stack.finishTopRunningActivityLocked(app); 2302 } 2303 } 2304 } 2305 2306 void finishVoiceTask(IVoiceInteractionSession session) { 2307 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2308 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2309 final int numStacks = stacks.size(); 2310 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2311 final ActivityStack stack = stacks.get(stackNdx); 2312 stack.finishVoiceTask(session); 2313 } 2314 } 2315 } 2316 2317 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2318 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2319 mUserLeaving = true; 2320 } 2321 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2322 // Caller wants the home activity moved with it. To accomplish this, 2323 // we'll just indicate that this task returns to the home task. 2324 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2325 } 2326 task.stack.moveTaskToFrontLocked(task, null, options); 2327 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2328 + task.stack); 2329 } 2330 2331 ActivityStack getStack(int stackId) { 2332 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2333 if (activityContainer != null) { 2334 return activityContainer.mStack; 2335 } 2336 return null; 2337 } 2338 2339 ArrayList<ActivityStack> getStacks() { 2340 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2341 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2342 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2343 } 2344 return allStacks; 2345 } 2346 2347 IBinder getHomeActivityToken() { 2348 ActivityRecord homeActivity = getHomeActivity(); 2349 if (homeActivity != null) { 2350 return homeActivity.appToken; 2351 } 2352 return null; 2353 } 2354 2355 ActivityRecord getHomeActivity() { 2356 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2357 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2358 final TaskRecord task = tasks.get(taskNdx); 2359 if (task.isHomeTask()) { 2360 final ArrayList<ActivityRecord> activities = task.mActivities; 2361 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2362 final ActivityRecord r = activities.get(activityNdx); 2363 if (r.isHomeActivity()) { 2364 return r; 2365 } 2366 } 2367 } 2368 } 2369 return null; 2370 } 2371 2372 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2373 IActivityContainerCallback callback) { 2374 ActivityContainer activityContainer = 2375 new VirtualActivityContainer(parentActivity, callback); 2376 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2377 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer); 2378 parentActivity.mChildContainers.add(activityContainer); 2379 return activityContainer; 2380 } 2381 2382 void removeChildActivityContainers(ActivityRecord parentActivity) { 2383 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2384 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2385 ActivityContainer container = childStacks.remove(containerNdx); 2386 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " + 2387 container); 2388 container.release(); 2389 } 2390 } 2391 2392 void deleteActivityContainer(IActivityContainer container) { 2393 ActivityContainer activityContainer = (ActivityContainer)container; 2394 if (activityContainer != null) { 2395 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ", 2396 new RuntimeException("here").fillInStackTrace()); 2397 final int stackId = activityContainer.mStackId; 2398 mActivityContainers.remove(stackId); 2399 mWindowManager.removeStack(stackId); 2400 } 2401 } 2402 2403 private int createStackOnDisplay(int stackId, int displayId) { 2404 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2405 if (activityDisplay == null) { 2406 return -1; 2407 } 2408 2409 ActivityContainer activityContainer = new ActivityContainer(stackId); 2410 mActivityContainers.put(stackId, activityContainer); 2411 activityContainer.attachToDisplayLocked(activityDisplay); 2412 return stackId; 2413 } 2414 2415 int getNextStackId() { 2416 while (true) { 2417 if (++mLastStackId <= HOME_STACK_ID) { 2418 mLastStackId = HOME_STACK_ID + 1; 2419 } 2420 if (getStack(mLastStackId) == null) { 2421 break; 2422 } 2423 } 2424 return mLastStackId; 2425 } 2426 2427 void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { 2428 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2429 final ActivityStack stack = getStack(stackId); 2430 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2431 final TaskRecord task = tasks.get(taskNdx); 2432 stack.addTask(task, false, false); 2433 final int taskId = task.taskId; 2434 final ArrayList<ActivityRecord> activities = task.mActivities; 2435 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2436 final ActivityRecord r = activities.get(activityNdx); 2437 mWindowManager.addAppToken(0, r.appToken, taskId, stackId, 2438 r.info.screenOrientation, r.fullscreen, 2439 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, 2440 r.userId, r.info.configChanges, task.voiceSession != null, 2441 r.mLaunchTaskBehind); 2442 } 2443 mWindowManager.addTask(taskId, stackId, false); 2444 } 2445 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2446 } 2447 2448 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2449 final TaskRecord task = anyTaskForIdLocked(taskId); 2450 if (task == null) { 2451 return; 2452 } 2453 final ActivityStack stack = getStack(stackId); 2454 if (stack == null) { 2455 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2456 return; 2457 } 2458 task.stack.removeTask(task); 2459 stack.addTask(task, toTop, true); 2460 mWindowManager.addTask(taskId, stackId, toTop); 2461 resumeTopActivitiesLocked(); 2462 } 2463 2464 ActivityRecord findTaskLocked(ActivityRecord r) { 2465 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2466 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2467 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2468 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2469 final ActivityStack stack = stacks.get(stackNdx); 2470 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2471 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2472 continue; 2473 } 2474 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2475 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2476 stack); 2477 continue; 2478 } 2479 final ActivityRecord ar = stack.findTaskLocked(r); 2480 if (ar != null) { 2481 return ar; 2482 } 2483 } 2484 } 2485 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2486 return null; 2487 } 2488 2489 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2490 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2491 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2492 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2493 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2494 if (ar != null) { 2495 return ar; 2496 } 2497 } 2498 } 2499 return null; 2500 } 2501 2502 void goingToSleepLocked() { 2503 scheduleSleepTimeout(); 2504 if (!mGoingToSleep.isHeld()) { 2505 mGoingToSleep.acquire(); 2506 if (mLaunchingActivity.isHeld()) { 2507 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2508 throw new IllegalStateException("Calling must be system uid"); 2509 } 2510 mLaunchingActivity.release(); 2511 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2512 } 2513 } 2514 checkReadyForSleepLocked(); 2515 } 2516 2517 boolean shutdownLocked(int timeout) { 2518 goingToSleepLocked(); 2519 2520 boolean timedout = false; 2521 final long endTime = System.currentTimeMillis() + timeout; 2522 while (true) { 2523 boolean cantShutdown = false; 2524 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2525 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2526 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2527 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2528 } 2529 } 2530 if (cantShutdown) { 2531 long timeRemaining = endTime - System.currentTimeMillis(); 2532 if (timeRemaining > 0) { 2533 try { 2534 mService.wait(timeRemaining); 2535 } catch (InterruptedException e) { 2536 } 2537 } else { 2538 Slog.w(TAG, "Activity manager shutdown timed out"); 2539 timedout = true; 2540 break; 2541 } 2542 } else { 2543 break; 2544 } 2545 } 2546 2547 // Force checkReadyForSleep to complete. 2548 mSleepTimeout = true; 2549 checkReadyForSleepLocked(); 2550 2551 return timedout; 2552 } 2553 2554 void comeOutOfSleepIfNeededLocked() { 2555 removeSleepTimeouts(); 2556 if (mGoingToSleep.isHeld()) { 2557 mGoingToSleep.release(); 2558 } 2559 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2560 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2561 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2562 final ActivityStack stack = stacks.get(stackNdx); 2563 stack.awakeFromSleepingLocked(); 2564 if (isFrontStack(stack)) { 2565 resumeTopActivitiesLocked(); 2566 } 2567 } 2568 } 2569 mGoingToSleepActivities.clear(); 2570 } 2571 2572 void activitySleptLocked(ActivityRecord r) { 2573 mGoingToSleepActivities.remove(r); 2574 checkReadyForSleepLocked(); 2575 } 2576 2577 void checkReadyForSleepLocked() { 2578 if (!mService.isSleepingOrShuttingDown()) { 2579 // Do not care. 2580 return; 2581 } 2582 2583 if (!mSleepTimeout) { 2584 boolean dontSleep = false; 2585 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2586 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2587 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2588 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2589 } 2590 } 2591 2592 if (mStoppingActivities.size() > 0) { 2593 // Still need to tell some activities to stop; can't sleep yet. 2594 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2595 + mStoppingActivities.size() + " activities"); 2596 scheduleIdleLocked(); 2597 dontSleep = true; 2598 } 2599 2600 if (mGoingToSleepActivities.size() > 0) { 2601 // Still need to tell some activities to sleep; can't sleep yet. 2602 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2603 + mGoingToSleepActivities.size() + " activities"); 2604 dontSleep = true; 2605 } 2606 2607 if (dontSleep) { 2608 return; 2609 } 2610 } 2611 2612 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2613 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2614 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2615 stacks.get(stackNdx).goToSleep(); 2616 } 2617 } 2618 2619 removeSleepTimeouts(); 2620 2621 if (mGoingToSleep.isHeld()) { 2622 mGoingToSleep.release(); 2623 } 2624 if (mService.mShuttingDown) { 2625 mService.notifyAll(); 2626 } 2627 } 2628 2629 boolean reportResumedActivityLocked(ActivityRecord r) { 2630 final ActivityStack stack = r.task.stack; 2631 if (isFrontStack(stack)) { 2632 mService.updateUsageStats(r, true); 2633 } 2634 if (allResumedActivitiesComplete()) { 2635 ensureActivitiesVisibleLocked(null, 0); 2636 mWindowManager.executeAppTransition(); 2637 return true; 2638 } 2639 return false; 2640 } 2641 2642 void handleAppCrashLocked(ProcessRecord app) { 2643 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2644 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2645 final int numStacks = stacks.size(); 2646 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2647 final ActivityStack stack = stacks.get(stackNdx); 2648 stack.handleAppCrashLocked(app); 2649 } 2650 } 2651 } 2652 2653 boolean setMediaPlayingLocked(ActivityRecord r, boolean playing) { 2654 final ActivityStack stack = r.task.stack; 2655 if (stack == null) { 2656 if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: r=" + r + " playing=" + 2657 playing + " stack is null"); 2658 return false; 2659 } 2660 final boolean isPlaying = stack.isMediaPlaying(); 2661 if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlayer: r=" + r + " playing=" + 2662 playing + " isPlaying=" + isPlaying); 2663 2664 final ActivityRecord top = topRunningActivityLocked(); 2665 if (top == null || top == r || (playing == isPlaying)) { 2666 if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: quick return"); 2667 stack.setMediaPlayer(playing ? r : null); 2668 return true; 2669 } 2670 2671 // A non-top activity is reporting a visibility change. 2672 if (top.fullscreen || top.state != ActivityState.RESUMED || top.app == null || 2673 top.app.thread == null) { 2674 // Can't carry out this request. 2675 if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: returning top.fullscreen=" + 2676 top.fullscreen+ " top.state=" + top.state + " top.app=" + top.app + 2677 " top.app.thread=" + top.app.thread); 2678 return false; 2679 } 2680 2681 stack.setMediaPlayer(playing ? r : null); 2682 try { 2683 top.app.thread.scheduleBackgroundMediaPlayingChanged(top.appToken, playing); 2684 } catch (RemoteException e) { 2685 } 2686 return true; 2687 } 2688 2689 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2690 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2691 r.mLaunchTaskBehind = false; 2692 final TaskRecord task = r.task; 2693 task.setLastThumbnail(task.stack.screenshotActivities(r)); 2694 mService.addRecentTaskLocked(task); 2695 mWindowManager.setAppVisibility(r.appToken, false); 2696 } 2697 2698 void scheduleLaunchTaskBehindComplete(IBinder token) { 2699 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2700 } 2701 2702 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2703 // First the front stacks. In case any are not fullscreen and are in front of home. 2704 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2705 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2706 final int topStackNdx = stacks.size() - 1; 2707 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2708 final ActivityStack stack = stacks.get(stackNdx); 2709 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2710 } 2711 } 2712 } 2713 2714 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2715 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2716 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2717 final int numStacks = stacks.size(); 2718 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2719 final ActivityStack stack = stacks.get(stackNdx); 2720 stack.scheduleDestroyActivities(app, reason); 2721 } 2722 } 2723 } 2724 2725 boolean switchUserLocked(int userId, UserStartedState uss) { 2726 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2727 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2728 mCurrentUser = userId; 2729 2730 mStartingUsers.add(uss); 2731 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2732 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2733 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2734 final ActivityStack stack = stacks.get(stackNdx); 2735 stack.switchUserLocked(userId); 2736 TaskRecord task = stack.topTask(); 2737 if (task != null) { 2738 mWindowManager.moveTaskToTop(task.taskId); 2739 } 2740 } 2741 } 2742 2743 ActivityStack stack = getStack(restoreStackId); 2744 if (stack == null) { 2745 stack = mHomeStack; 2746 } 2747 final boolean homeInFront = stack.isHomeStack(); 2748 if (stack.isOnHomeDisplay()) { 2749 moveHomeStack(homeInFront); 2750 TaskRecord task = stack.topTask(); 2751 if (task != null) { 2752 mWindowManager.moveTaskToTop(task.taskId); 2753 } 2754 } else { 2755 // Stack was moved to another display while user was swapped out. 2756 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2757 } 2758 return homeInFront; 2759 } 2760 2761 /** 2762 * Add background users to send boot completed events to. 2763 * @param userId The user being started in the background 2764 * @param uss The state object for the user. 2765 */ 2766 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 2767 mStartingBackgroundUsers.add(uss); 2768 } 2769 2770 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2771 int N = mStoppingActivities.size(); 2772 if (N <= 0) return null; 2773 2774 ArrayList<ActivityRecord> stops = null; 2775 2776 final boolean nowVisible = allResumedActivitiesVisible(); 2777 for (int i=0; i<N; i++) { 2778 ActivityRecord s = mStoppingActivities.get(i); 2779 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2780 + nowVisible + " waitingVisible=" + s.waitingVisible 2781 + " finishing=" + s.finishing); 2782 if (s.waitingVisible && nowVisible) { 2783 mWaitingVisibleActivities.remove(s); 2784 s.waitingVisible = false; 2785 if (s.finishing) { 2786 // If this activity is finishing, it is sitting on top of 2787 // everyone else but we now know it is no longer needed... 2788 // so get rid of it. Otherwise, we need to go through the 2789 // normal flow and hide it once we determine that it is 2790 // hidden by the activities in front of it. 2791 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2792 mWindowManager.setAppVisibility(s.appToken, false); 2793 } 2794 } 2795 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2796 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2797 if (stops == null) { 2798 stops = new ArrayList<ActivityRecord>(); 2799 } 2800 stops.add(s); 2801 mStoppingActivities.remove(i); 2802 N--; 2803 i--; 2804 } 2805 } 2806 2807 return stops; 2808 } 2809 2810 void validateTopActivitiesLocked() { 2811 // FIXME 2812/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2813 final ActivityStack stack = stacks.get(stackNdx); 2814 final ActivityRecord r = stack.topRunningActivityLocked(null); 2815 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2816 if (isFrontStack(stack)) { 2817 if (r == null) { 2818 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2819 } else { 2820 final ActivityRecord pausing = stack.mPausingActivity; 2821 if (pausing != null && pausing == r) { 2822 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2823 " state=" + state); 2824 } 2825 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2826 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2827 " state=" + state); 2828 } 2829 } 2830 } else { 2831 final ActivityRecord resumed = stack.mResumedActivity; 2832 if (resumed != null && resumed == r) { 2833 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2834 " state=" + state); 2835 } 2836 if (r != null && (state == ActivityState.INITIALIZING 2837 || state == ActivityState.RESUMED)) { 2838 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2839 " state=" + state); 2840 } 2841 } 2842 } 2843*/ 2844 } 2845 2846 public void dump(PrintWriter pw, String prefix) { 2847 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2848 pw.println(mDismissKeyguardOnNextActivity); 2849 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2850 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2851 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2852 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2853 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2854 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2855 } 2856 2857 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2858 return getFocusedStack().getDumpActivitiesLocked(name); 2859 } 2860 2861 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2862 boolean needSep, String prefix) { 2863 if (activity != null) { 2864 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2865 if (needSep) { 2866 pw.println(); 2867 } 2868 pw.print(prefix); 2869 pw.println(activity); 2870 return true; 2871 } 2872 } 2873 return false; 2874 } 2875 2876 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2877 boolean dumpClient, String dumpPackage) { 2878 boolean printed = false; 2879 boolean needSep = false; 2880 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2881 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2882 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 2883 pw.println(" (activities from bottom to top):"); 2884 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2885 final int numStacks = stacks.size(); 2886 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2887 final ActivityStack stack = stacks.get(stackNdx); 2888 StringBuilder stackHeader = new StringBuilder(128); 2889 stackHeader.append(" Stack #"); 2890 stackHeader.append(stack.mStackId); 2891 stackHeader.append(":"); 2892 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2893 needSep, stackHeader.toString()); 2894 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2895 !dumpAll, false, dumpPackage, true, 2896 " Running activities (most recent first):", null); 2897 2898 needSep = printed; 2899 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2900 " mPausingActivity: "); 2901 if (pr) { 2902 printed = true; 2903 needSep = false; 2904 } 2905 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2906 " mResumedActivity: "); 2907 if (pr) { 2908 printed = true; 2909 needSep = false; 2910 } 2911 if (dumpAll) { 2912 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2913 " mLastPausedActivity: "); 2914 if (pr) { 2915 printed = true; 2916 needSep = true; 2917 } 2918 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2919 needSep, " mLastNoHistoryActivity: "); 2920 } 2921 needSep = printed; 2922 } 2923 } 2924 2925 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2926 false, dumpPackage, true, " Activities waiting to finish:", null); 2927 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2928 false, dumpPackage, true, " Activities waiting to stop:", null); 2929 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2930 false, dumpPackage, true, " Activities waiting for another to become visible:", 2931 null); 2932 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2933 false, dumpPackage, true, " Activities waiting to sleep:", null); 2934 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2935 false, dumpPackage, true, " Activities waiting to sleep:", null); 2936 2937 return printed; 2938 } 2939 2940 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2941 String prefix, String label, boolean complete, boolean brief, boolean client, 2942 String dumpPackage, boolean needNL, String header1, String header2) { 2943 TaskRecord lastTask = null; 2944 String innerPrefix = null; 2945 String[] args = null; 2946 boolean printed = false; 2947 for (int i=list.size()-1; i>=0; i--) { 2948 final ActivityRecord r = list.get(i); 2949 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2950 continue; 2951 } 2952 if (innerPrefix == null) { 2953 innerPrefix = prefix + " "; 2954 args = new String[0]; 2955 } 2956 printed = true; 2957 final boolean full = !brief && (complete || !r.isInHistory()); 2958 if (needNL) { 2959 pw.println(""); 2960 needNL = false; 2961 } 2962 if (header1 != null) { 2963 pw.println(header1); 2964 header1 = null; 2965 } 2966 if (header2 != null) { 2967 pw.println(header2); 2968 header2 = null; 2969 } 2970 if (lastTask != r.task) { 2971 lastTask = r.task; 2972 pw.print(prefix); 2973 pw.print(full ? "* " : " "); 2974 pw.println(lastTask); 2975 if (full) { 2976 lastTask.dump(pw, prefix + " "); 2977 } else if (complete) { 2978 // Complete + brief == give a summary. Isn't that obvious?!? 2979 if (lastTask.intent != null) { 2980 pw.print(prefix); pw.print(" "); 2981 pw.println(lastTask.intent.toInsecureStringWithClip()); 2982 } 2983 } 2984 } 2985 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2986 pw.print(" #"); pw.print(i); pw.print(": "); 2987 pw.println(r); 2988 if (full) { 2989 r.dump(pw, innerPrefix); 2990 } else if (complete) { 2991 // Complete + brief == give a summary. Isn't that obvious?!? 2992 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2993 if (r.app != null) { 2994 pw.print(innerPrefix); pw.println(r.app); 2995 } 2996 } 2997 if (client && r.app != null && r.app.thread != null) { 2998 // flush anything that is already in the PrintWriter since the thread is going 2999 // to write to the file descriptor directly 3000 pw.flush(); 3001 try { 3002 TransferPipe tp = new TransferPipe(); 3003 try { 3004 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3005 r.appToken, innerPrefix, args); 3006 // Short timeout, since blocking here can 3007 // deadlock with the application. 3008 tp.go(fd, 2000); 3009 } finally { 3010 tp.kill(); 3011 } 3012 } catch (IOException e) { 3013 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3014 } catch (RemoteException e) { 3015 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3016 } 3017 needNL = true; 3018 } 3019 } 3020 return printed; 3021 } 3022 3023 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3024 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3025 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3026 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3027 } 3028 3029 final void scheduleIdleLocked() { 3030 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3031 } 3032 3033 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3034 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 3035 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3036 } 3037 3038 final void scheduleResumeTopActivities() { 3039 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3040 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3041 } 3042 } 3043 3044 void removeSleepTimeouts() { 3045 mSleepTimeout = false; 3046 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3047 } 3048 3049 final void scheduleSleepTimeout() { 3050 removeSleepTimeouts(); 3051 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3052 } 3053 3054 @Override 3055 public void onDisplayAdded(int displayId) { 3056 Slog.v(TAG, "Display added displayId=" + displayId); 3057 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3058 } 3059 3060 @Override 3061 public void onDisplayRemoved(int displayId) { 3062 Slog.v(TAG, "Display removed displayId=" + displayId); 3063 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3064 } 3065 3066 @Override 3067 public void onDisplayChanged(int displayId) { 3068 Slog.v(TAG, "Display changed displayId=" + displayId); 3069 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3070 } 3071 3072 public void handleDisplayAddedLocked(int displayId) { 3073 boolean newDisplay; 3074 synchronized (mService) { 3075 newDisplay = mActivityDisplays.get(displayId) == null; 3076 if (newDisplay) { 3077 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3078 mActivityDisplays.put(displayId, activityDisplay); 3079 } 3080 } 3081 if (newDisplay) { 3082 mWindowManager.onDisplayAdded(displayId); 3083 } 3084 } 3085 3086 public void handleDisplayRemovedLocked(int displayId) { 3087 synchronized (mService) { 3088 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3089 if (activityDisplay != null) { 3090 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3091 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3092 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3093 } 3094 mActivityDisplays.remove(displayId); 3095 } 3096 } 3097 mWindowManager.onDisplayRemoved(displayId); 3098 } 3099 3100 public void handleDisplayChangedLocked(int displayId) { 3101 synchronized (mService) { 3102 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3103 if (activityDisplay != null) { 3104 // TODO: Update the bounds. 3105 } 3106 } 3107 mWindowManager.onDisplayChanged(displayId); 3108 } 3109 3110 StackInfo getStackInfo(ActivityStack stack) { 3111 StackInfo info = new StackInfo(); 3112 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3113 info.displayId = Display.DEFAULT_DISPLAY; 3114 info.stackId = stack.mStackId; 3115 3116 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3117 final int numTasks = tasks.size(); 3118 int[] taskIds = new int[numTasks]; 3119 String[] taskNames = new String[numTasks]; 3120 for (int i = 0; i < numTasks; ++i) { 3121 final TaskRecord task = tasks.get(i); 3122 taskIds[i] = task.taskId; 3123 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3124 : task.realActivity != null ? task.realActivity.flattenToString() 3125 : task.getTopActivity() != null ? task.getTopActivity().packageName 3126 : "unknown"; 3127 } 3128 info.taskIds = taskIds; 3129 info.taskNames = taskNames; 3130 return info; 3131 } 3132 3133 StackInfo getStackInfoLocked(int stackId) { 3134 ActivityStack stack = getStack(stackId); 3135 if (stack != null) { 3136 return getStackInfo(stack); 3137 } 3138 return null; 3139 } 3140 3141 ArrayList<StackInfo> getAllStackInfosLocked() { 3142 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 3143 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3144 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3145 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3146 list.add(getStackInfo(stacks.get(ndx))); 3147 } 3148 } 3149 return list; 3150 } 3151 3152 void showLockTaskToast() { 3153 mLockTaskNotify.showToast(mLockTaskIsLocked); 3154 } 3155 3156 void setLockTaskModeLocked(TaskRecord task, boolean isLocked) { 3157 if (task == null) { 3158 // Take out of lock task mode if necessary 3159 if (mLockTaskModeTask != null) { 3160 final Message lockTaskMsg = Message.obtain(); 3161 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3162 lockTaskMsg.what = LOCK_TASK_END_MSG; 3163 mLockTaskModeTask = null; 3164 mHandler.sendMessage(lockTaskMsg); 3165 } 3166 return; 3167 } 3168 if (isLockTaskModeViolation(task)) { 3169 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 3170 return; 3171 } 3172 mLockTaskModeTask = task; 3173 findTaskToMoveToFrontLocked(task, 0, null); 3174 resumeTopActivitiesLocked(); 3175 3176 final Message lockTaskMsg = Message.obtain(); 3177 lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName(); 3178 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3179 lockTaskMsg.what = LOCK_TASK_START_MSG; 3180 lockTaskMsg.arg2 = !isLocked ? 1 : 0; 3181 mHandler.sendMessage(lockTaskMsg); 3182 } 3183 3184 boolean isLockTaskModeViolation(TaskRecord task) { 3185 return mLockTaskModeTask != null && mLockTaskModeTask != task; 3186 } 3187 3188 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3189 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3190 mLockTaskModeTask = null; 3191 } 3192 } 3193 3194 boolean isInLockTaskMode() { 3195 return mLockTaskModeTask != null; 3196 } 3197 3198 private final class ActivityStackSupervisorHandler extends Handler { 3199 3200 public ActivityStackSupervisorHandler(Looper looper) { 3201 super(looper); 3202 } 3203 3204 void activityIdleInternal(ActivityRecord r) { 3205 synchronized (mService) { 3206 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3207 } 3208 } 3209 3210 @Override 3211 public void handleMessage(Message msg) { 3212 switch (msg.what) { 3213 case IDLE_TIMEOUT_MSG: { 3214 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3215 if (mService.mDidDexOpt) { 3216 mService.mDidDexOpt = false; 3217 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3218 nmsg.obj = msg.obj; 3219 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3220 return; 3221 } 3222 // We don't at this point know if the activity is fullscreen, 3223 // so we need to be conservative and assume it isn't. 3224 activityIdleInternal((ActivityRecord)msg.obj); 3225 } break; 3226 case IDLE_NOW_MSG: { 3227 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3228 activityIdleInternal((ActivityRecord)msg.obj); 3229 } break; 3230 case RESUME_TOP_ACTIVITY_MSG: { 3231 synchronized (mService) { 3232 resumeTopActivitiesLocked(); 3233 } 3234 } break; 3235 case SLEEP_TIMEOUT_MSG: { 3236 synchronized (mService) { 3237 if (mService.isSleepingOrShuttingDown()) { 3238 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3239 mSleepTimeout = true; 3240 checkReadyForSleepLocked(); 3241 } 3242 } 3243 } break; 3244 case LAUNCH_TIMEOUT_MSG: { 3245 if (mService.mDidDexOpt) { 3246 mService.mDidDexOpt = false; 3247 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3248 return; 3249 } 3250 synchronized (mService) { 3251 if (mLaunchingActivity.isHeld()) { 3252 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3253 if (VALIDATE_WAKE_LOCK_CALLER 3254 && Binder.getCallingUid() != Process.myUid()) { 3255 throw new IllegalStateException("Calling must be system uid"); 3256 } 3257 mLaunchingActivity.release(); 3258 } 3259 } 3260 } break; 3261 case HANDLE_DISPLAY_ADDED: { 3262 handleDisplayAddedLocked(msg.arg1); 3263 } break; 3264 case HANDLE_DISPLAY_CHANGED: { 3265 handleDisplayChangedLocked(msg.arg1); 3266 } break; 3267 case HANDLE_DISPLAY_REMOVED: { 3268 handleDisplayRemovedLocked(msg.arg1); 3269 } break; 3270 case CONTAINER_CALLBACK_VISIBILITY: { 3271 final ActivityContainer container = (ActivityContainer) msg.obj; 3272 final IActivityContainerCallback callback = container.mCallback; 3273 if (callback != null) { 3274 try { 3275 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3276 } catch (RemoteException e) { 3277 } 3278 } 3279 } break; 3280 case LOCK_TASK_START_MSG: { 3281 // When lock task starts, we disable the status bars. 3282 try { 3283 if (mLockTaskNotify == null) { 3284 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3285 } 3286 mLockTaskNotify.show(true); 3287 mLockTaskIsLocked = msg.arg2 == 0; 3288 if (getStatusBarService() != null) { 3289 int flags = 3290 StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK; 3291 if (!mLockTaskIsLocked) { 3292 flags ^= StatusBarManager.DISABLE_HOME 3293 | StatusBarManager.DISABLE_RECENT; 3294 } 3295 getStatusBarService().disable(flags, mToken, 3296 mService.mContext.getPackageName()); 3297 } 3298 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3299 if (getDevicePolicyManager() != null) { 3300 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3301 (String)msg.obj, msg.arg1); 3302 } 3303 } catch (RemoteException ex) { 3304 throw new RuntimeException(ex); 3305 } 3306 } break; 3307 case LOCK_TASK_END_MSG: { 3308 // When lock task ends, we enable the status bars. 3309 try { 3310 if (getStatusBarService() != null) { 3311 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3312 mService.mContext.getPackageName()); 3313 } 3314 mWindowManager.reenableKeyguard(mToken); 3315 if (getDevicePolicyManager() != null) { 3316 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3317 msg.arg1); 3318 } 3319 if (mLockTaskNotify == null) { 3320 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3321 } 3322 mLockTaskNotify.show(false); 3323 try { 3324 boolean shouldLockKeyguard = Settings.System.getInt( 3325 mService.mContext.getContentResolver(), 3326 Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0; 3327 if (!mLockTaskIsLocked && shouldLockKeyguard) { 3328 mWindowManager.lockNow(null); 3329 mWindowManager.dismissKeyguard(); 3330 } 3331 } catch (SettingNotFoundException e) { 3332 // No setting, don't lock. 3333 } 3334 } catch (RemoteException ex) { 3335 throw new RuntimeException(ex); 3336 } 3337 } break; 3338 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3339 final ActivityContainer container = (ActivityContainer) msg.obj; 3340 final IActivityContainerCallback callback = container.mCallback; 3341 if (callback != null) { 3342 try { 3343 callback.onAllActivitiesComplete(container.asBinder()); 3344 } catch (RemoteException e) { 3345 } 3346 } 3347 } break; 3348 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 3349 synchronized (mService) { 3350 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 3351 msg.obj); 3352 final ActivityContainer container = (ActivityContainer) msg.obj; 3353 container.mStack.finishAllActivitiesLocked(true); 3354 container.onTaskListEmptyLocked(); 3355 } 3356 } break; 3357 case LAUNCH_TASK_BEHIND_COMPLETE: { 3358 synchronized (mService) { 3359 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 3360 if (r != null) { 3361 handleLaunchTaskBehindCompleteLocked(r); 3362 } 3363 } 3364 } break; 3365 } 3366 } 3367 } 3368 3369 class ActivityContainer extends android.app.IActivityContainer.Stub { 3370 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3371 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3372 final int mStackId; 3373 IActivityContainerCallback mCallback = null; 3374 final ActivityStack mStack; 3375 ActivityRecord mParentActivity = null; 3376 String mIdString; 3377 3378 boolean mVisible = true; 3379 3380 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3381 ActivityDisplay mActivityDisplay; 3382 3383 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3384 final static int CONTAINER_STATE_NO_SURFACE = 1; 3385 final static int CONTAINER_STATE_FINISHING = 2; 3386 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3387 3388 ActivityContainer(int stackId) { 3389 synchronized (mService) { 3390 mStackId = stackId; 3391 mStack = new ActivityStack(this); 3392 mIdString = "ActivtyContainer{" + mStackId + "}"; 3393 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3394 } 3395 } 3396 3397 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3398 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3399 + " to display=" + activityDisplay); 3400 mActivityDisplay = activityDisplay; 3401 mStack.mDisplayId = activityDisplay.mDisplayId; 3402 mStack.mStacks = activityDisplay.mStacks; 3403 3404 activityDisplay.attachActivities(mStack); 3405 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3406 } 3407 3408 @Override 3409 public void attachToDisplay(int displayId) { 3410 synchronized (mService) { 3411 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3412 if (activityDisplay == null) { 3413 return; 3414 } 3415 attachToDisplayLocked(activityDisplay); 3416 } 3417 } 3418 3419 @Override 3420 public int getDisplayId() { 3421 synchronized (mService) { 3422 if (mActivityDisplay != null) { 3423 return mActivityDisplay.mDisplayId; 3424 } 3425 } 3426 return -1; 3427 } 3428 3429 @Override 3430 public boolean injectEvent(InputEvent event) { 3431 final long origId = Binder.clearCallingIdentity(); 3432 try { 3433 synchronized (mService) { 3434 if (mActivityDisplay != null) { 3435 return mInputManagerInternal.injectInputEvent(event, 3436 mActivityDisplay.mDisplayId, 3437 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3438 } 3439 } 3440 return false; 3441 } finally { 3442 Binder.restoreCallingIdentity(origId); 3443 } 3444 } 3445 3446 @Override 3447 public void release() { 3448 synchronized (mService) { 3449 if (mContainerState == CONTAINER_STATE_FINISHING) { 3450 return; 3451 } 3452 mContainerState = CONTAINER_STATE_FINISHING; 3453 3454 final Message msg = 3455 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3456 mHandler.sendMessageDelayed(msg, 2000); 3457 3458 long origId = Binder.clearCallingIdentity(); 3459 try { 3460 mStack.finishAllActivitiesLocked(false); 3461 } finally { 3462 Binder.restoreCallingIdentity(origId); 3463 } 3464 } 3465 } 3466 3467 private void detachLocked() { 3468 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3469 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3470 if (mActivityDisplay != null) { 3471 mActivityDisplay.detachActivitiesLocked(mStack); 3472 mActivityDisplay = null; 3473 mStack.mDisplayId = -1; 3474 mStack.mStacks = null; 3475 mWindowManager.detachStack(mStackId); 3476 } 3477 } 3478 3479 @Override 3480 public final int startActivity(Intent intent) { 3481 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3482 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3483 Binder.getCallingUid(), mCurrentUser, false, 3484 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3485 // TODO: Switch to user app stacks here. 3486 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3487 String mimeType = intent.getType(); 3488 if (mimeType == null && intent.getData() != null 3489 && "content".equals(intent.getData().getScheme())) { 3490 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3491 } 3492 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null, 3493 null, null, null, null, userId, this); 3494 } 3495 3496 @Override 3497 public final int startActivityIntentSender(IIntentSender intentSender) { 3498 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3499 3500 if (!(intentSender instanceof PendingIntentRecord)) { 3501 throw new IllegalArgumentException("Bad PendingIntent object"); 3502 } 3503 3504 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3505 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3506 } 3507 3508 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3509 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3510 Binder.getCallingUid(), mCurrentUser, false, 3511 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3512 if (resolvedType == null) { 3513 resolvedType = intent.getType(); 3514 if (resolvedType == null && intent.getData() != null 3515 && "content".equals(intent.getData().getScheme())) { 3516 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3517 } 3518 } 3519 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3520 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3521 throw new SecurityException( 3522 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3523 } 3524 } 3525 3526 /** Throw a SecurityException if allowEmbedded is not true */ 3527 @Override 3528 public final void checkEmbeddedAllowed(Intent intent) { 3529 checkEmbeddedAllowedInner(intent, null); 3530 } 3531 3532 /** Throw a SecurityException if allowEmbedded is not true */ 3533 @Override 3534 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3535 if (!(intentSender instanceof PendingIntentRecord)) { 3536 throw new IllegalArgumentException("Bad PendingIntent object"); 3537 } 3538 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3539 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3540 pendingIntent.key.requestResolvedType); 3541 } 3542 3543 @Override 3544 public IBinder asBinder() { 3545 return this; 3546 } 3547 3548 @Override 3549 public void setSurface(Surface surface, int width, int height, int density) { 3550 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3551 } 3552 3553 ActivityStackSupervisor getOuter() { 3554 return ActivityStackSupervisor.this; 3555 } 3556 3557 boolean isAttachedLocked() { 3558 return mActivityDisplay != null; 3559 } 3560 3561 void getBounds(Point outBounds) { 3562 synchronized (mService) { 3563 if (mActivityDisplay != null) { 3564 mActivityDisplay.getBounds(outBounds); 3565 } else { 3566 outBounds.set(0, 0); 3567 } 3568 } 3569 } 3570 3571 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3572 void setVisible(boolean visible) { 3573 if (mVisible != visible) { 3574 mVisible = visible; 3575 if (mCallback != null) { 3576 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3577 0 /* unused */, this).sendToTarget(); 3578 } 3579 } 3580 } 3581 3582 void setDrawn() { 3583 } 3584 3585 // You can always start a new task on a regular ActivityStack. 3586 boolean isEligibleForNewTasks() { 3587 return true; 3588 } 3589 3590 void onTaskListEmptyLocked() { 3591 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3592 if (!mStack.isHomeStack()) { 3593 detachLocked(); 3594 deleteActivityContainer(this); 3595 } 3596 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3597 } 3598 3599 @Override 3600 public String toString() { 3601 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3602 } 3603 } 3604 3605 private class VirtualActivityContainer extends ActivityContainer { 3606 Surface mSurface; 3607 boolean mDrawn = false; 3608 3609 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3610 super(getNextStackId()); 3611 mParentActivity = parent; 3612 mCallback = callback; 3613 mContainerState = CONTAINER_STATE_NO_SURFACE; 3614 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3615 } 3616 3617 @Override 3618 public void setSurface(Surface surface, int width, int height, int density) { 3619 super.setSurface(surface, width, height, density); 3620 3621 synchronized (mService) { 3622 final long origId = Binder.clearCallingIdentity(); 3623 try { 3624 setSurfaceLocked(surface, width, height, density); 3625 } finally { 3626 Binder.restoreCallingIdentity(origId); 3627 } 3628 } 3629 } 3630 3631 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3632 if (mContainerState == CONTAINER_STATE_FINISHING) { 3633 return; 3634 } 3635 VirtualActivityDisplay virtualActivityDisplay = 3636 (VirtualActivityDisplay) mActivityDisplay; 3637 if (virtualActivityDisplay == null) { 3638 virtualActivityDisplay = 3639 new VirtualActivityDisplay(width, height, density); 3640 mActivityDisplay = virtualActivityDisplay; 3641 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3642 attachToDisplayLocked(virtualActivityDisplay); 3643 } 3644 3645 if (mSurface != null) { 3646 mSurface.release(); 3647 } 3648 3649 mSurface = surface; 3650 if (surface != null) { 3651 mStack.resumeTopActivityLocked(null); 3652 } else { 3653 mContainerState = CONTAINER_STATE_NO_SURFACE; 3654 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3655 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3656 mStack.startPausingLocked(false, true); 3657 } 3658 } 3659 3660 setSurfaceIfReadyLocked(); 3661 3662 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3663 + virtualActivityDisplay); 3664 } 3665 3666 @Override 3667 boolean isAttachedLocked() { 3668 return mSurface != null && super.isAttachedLocked(); 3669 } 3670 3671 @Override 3672 void setDrawn() { 3673 synchronized (mService) { 3674 mDrawn = true; 3675 setSurfaceIfReadyLocked(); 3676 } 3677 } 3678 3679 // Never start a new task on an ActivityView if it isn't explicitly specified. 3680 @Override 3681 boolean isEligibleForNewTasks() { 3682 return false; 3683 } 3684 3685 private void setSurfaceIfReadyLocked() { 3686 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3687 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3688 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3689 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3690 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3691 } 3692 } 3693 } 3694 3695 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3696 * attached {@link ActivityStack}s */ 3697 class ActivityDisplay { 3698 /** Actual Display this object tracks. */ 3699 int mDisplayId; 3700 Display mDisplay; 3701 DisplayInfo mDisplayInfo = new DisplayInfo(); 3702 3703 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3704 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3705 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3706 3707 ActivityRecord mMediaPlayingActivity; 3708 3709 ActivityDisplay() { 3710 } 3711 3712 ActivityDisplay(int displayId) { 3713 init(mDisplayManager.getDisplay(displayId)); 3714 } 3715 3716 void init(Display display) { 3717 mDisplay = display; 3718 mDisplayId = display.getDisplayId(); 3719 mDisplay.getDisplayInfo(mDisplayInfo); 3720 } 3721 3722 void attachActivities(ActivityStack stack) { 3723 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3724 + mDisplayId); 3725 mStacks.add(stack); 3726 } 3727 3728 void detachActivitiesLocked(ActivityStack stack) { 3729 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3730 + " from displayId=" + mDisplayId); 3731 mStacks.remove(stack); 3732 } 3733 3734 void getBounds(Point bounds) { 3735 mDisplay.getDisplayInfo(mDisplayInfo); 3736 bounds.x = mDisplayInfo.appWidth; 3737 bounds.y = mDisplayInfo.appHeight; 3738 } 3739 3740 void setMediaPlaying(ActivityRecord r) { 3741 mMediaPlayingActivity = r; 3742 } 3743 3744 boolean isMediaPlaying() { 3745 return mMediaPlayingActivity != null; 3746 } 3747 3748 @Override 3749 public String toString() { 3750 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3751 } 3752 } 3753 3754 class VirtualActivityDisplay extends ActivityDisplay { 3755 VirtualDisplay mVirtualDisplay; 3756 3757 VirtualActivityDisplay(int width, int height, int density) { 3758 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3759 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 3760 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 3761 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3762 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 3763 3764 init(mVirtualDisplay.getDisplay()); 3765 3766 mWindowManager.handleDisplayAdded(mDisplayId); 3767 } 3768 3769 void setSurface(Surface surface) { 3770 if (mVirtualDisplay != null) { 3771 mVirtualDisplay.setSurface(surface); 3772 } 3773 } 3774 3775 @Override 3776 void detachActivitiesLocked(ActivityStack stack) { 3777 super.detachActivitiesLocked(stack); 3778 if (mVirtualDisplay != null) { 3779 mVirtualDisplay.release(); 3780 mVirtualDisplay = null; 3781 } 3782 } 3783 3784 @Override 3785 public String toString() { 3786 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3787 } 3788 } 3789 3790 private boolean isLeanbackOnlyDevice() { 3791 boolean onLeanbackOnly = false; 3792 try { 3793 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 3794 PackageManager.FEATURE_LEANBACK_ONLY); 3795 } catch (RemoteException e) { 3796 // noop 3797 } 3798 3799 return onLeanbackOnly; 3800 } 3801} 3802