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