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