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