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