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