ActivityStackSupervisor.java revision 6b904ef4741321dcb01caee9795c2a044018706c
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 1318 final int launchFlags = intent.getFlags(); 1319 1320 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { 1321 // Transfer the result target from the source activity to the new 1322 // one being started, including any failures. 1323 if (requestCode >= 0) { 1324 ActivityOptions.abort(options); 1325 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1326 } 1327 resultRecord = sourceRecord.resultTo; 1328 resultWho = sourceRecord.resultWho; 1329 requestCode = sourceRecord.requestCode; 1330 sourceRecord.resultTo = null; 1331 if (resultRecord != null) { 1332 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 1333 } 1334 if (sourceRecord.launchedFromUid == callingUid) { 1335 // The new activity is being launched from the same uid as the previous 1336 // activity in the flow, and asking to forward its result back to the 1337 // previous. In this case the activity is serving as a trampoline between 1338 // the two, so we also want to update its launchedFromPackage to be the 1339 // same as the previous activity. Note that this is safe, since we know 1340 // these two packages come from the same uid; the caller could just as 1341 // well have supplied that same package name itself. This specifially 1342 // deals with the case of an intent picker/chooser being launched in the app 1343 // flow to redirect to an activity picked by the user, where we want the final 1344 // activity to consider it to have been launched by the previous app activity. 1345 callingPackage = sourceRecord.launchedFromPackage; 1346 } 1347 } 1348 1349 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1350 // We couldn't find a class that can handle the given Intent. 1351 // That's the end of that! 1352 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1353 } 1354 1355 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1356 // We couldn't find the specific class specified in the Intent. 1357 // Also the end of the line. 1358 err = ActivityManager.START_CLASS_NOT_FOUND; 1359 } 1360 1361 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1362 && sourceRecord.task.voiceSession != null) { 1363 // If this activity is being launched as part of a voice session, we need 1364 // to ensure that it is safe to do so. If the upcoming activity will also 1365 // be part of the voice session, we can only launch it if it has explicitly 1366 // said it supports the VOICE category, or it is a part of the calling app. 1367 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1368 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1369 try { 1370 if (!AppGlobals.getPackageManager().activitySupportsIntent( 1371 intent.getComponent(), intent, resolvedType)) { 1372 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1373 } 1374 } catch (RemoteException e) { 1375 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1376 } 1377 } 1378 } 1379 1380 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1381 // If the caller is starting a new voice session, just make sure the target 1382 // is actually allowing it to run this way. 1383 try { 1384 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1385 intent, resolvedType)) { 1386 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1387 } 1388 } catch (RemoteException e) { 1389 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1390 } 1391 } 1392 1393 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1394 1395 if (err != ActivityManager.START_SUCCESS) { 1396 if (resultRecord != null) { 1397 resultStack.sendActivityResultLocked(-1, 1398 resultRecord, resultWho, requestCode, 1399 Activity.RESULT_CANCELED, null); 1400 } 1401 ActivityOptions.abort(options); 1402 return err; 1403 } 1404 1405 final int startAnyPerm = mService.checkPermission( 1406 START_ANY_ACTIVITY, callingPid, callingUid); 1407 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1408 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1409 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1410 if (resultRecord != null) { 1411 resultStack.sendActivityResultLocked(-1, 1412 resultRecord, resultWho, requestCode, 1413 Activity.RESULT_CANCELED, null); 1414 } 1415 String msg; 1416 if (!aInfo.exported) { 1417 msg = "Permission Denial: starting " + intent.toString() 1418 + " from " + callerApp + " (pid=" + callingPid 1419 + ", uid=" + callingUid + ")" 1420 + " not exported from uid " + aInfo.applicationInfo.uid; 1421 } else { 1422 msg = "Permission Denial: starting " + intent.toString() 1423 + " from " + callerApp + " (pid=" + callingPid 1424 + ", uid=" + callingUid + ")" 1425 + " requires " + aInfo.permission; 1426 } 1427 Slog.w(TAG, msg); 1428 throw new SecurityException(msg); 1429 } 1430 1431 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1432 callingPid, resolvedType, aInfo.applicationInfo); 1433 1434 if (mService.mController != null) { 1435 try { 1436 // The Intent we give to the watcher has the extra data 1437 // stripped off, since it can contain private information. 1438 Intent watchIntent = intent.cloneFilter(); 1439 abort |= !mService.mController.activityStarting(watchIntent, 1440 aInfo.applicationInfo.packageName); 1441 } catch (RemoteException e) { 1442 mService.mController = null; 1443 } 1444 } 1445 1446 if (abort) { 1447 if (resultRecord != null) { 1448 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1449 Activity.RESULT_CANCELED, null); 1450 } 1451 // We pretend to the caller that it was really started, but 1452 // they will just get a cancel result. 1453 ActivityOptions.abort(options); 1454 return ActivityManager.START_SUCCESS; 1455 } 1456 1457 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1458 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1459 requestCode, componentSpecified, this, container, options); 1460 if (outActivity != null) { 1461 outActivity[0] = r; 1462 } 1463 1464 final ActivityStack stack = getFocusedStack(); 1465 if (voiceSession == null && (stack.mResumedActivity == null 1466 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1467 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, 1468 realCallingPid, realCallingUid, "Activity start")) { 1469 PendingActivityLaunch pal = 1470 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1471 mPendingActivityLaunches.add(pal); 1472 ActivityOptions.abort(options); 1473 return ActivityManager.START_SWITCHES_CANCELED; 1474 } 1475 } 1476 1477 if (mService.mDidAppSwitch) { 1478 // This is the second allowed switch since we stopped switches, 1479 // so now just generally allow switches. Use case: user presses 1480 // home (switches disabled, switch to home, mDidAppSwitch now true); 1481 // user taps a home icon (coming from home so allowed, we hit here 1482 // and now allow anyone to switch again). 1483 mService.mAppSwitchesAllowedTime = 0; 1484 } else { 1485 mService.mDidAppSwitch = true; 1486 } 1487 1488 doPendingActivityLaunchesLocked(false); 1489 1490 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1491 startFlags, true, options, inTask); 1492 1493 if (err < 0) { 1494 // If someone asked to have the keyguard dismissed on the next 1495 // activity start, but we are not actually doing an activity 1496 // switch... just dismiss the keyguard now, because we 1497 // probably want to see whatever is behind it. 1498 notifyActivityDrawnForKeyguard(); 1499 } 1500 return err; 1501 } 1502 1503 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1504 final TaskRecord task = r.task; 1505 1506 // On leanback only devices we should keep all activities in the same stack. 1507 if (!mLeanbackOnlyDevice && 1508 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1509 if (task != null) { 1510 final ActivityStack taskStack = task.stack; 1511 if (taskStack.isOnHomeDisplay()) { 1512 if (mFocusedStack != taskStack) { 1513 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1514 "focused stack to r=" + r + " task=" + task); 1515 mFocusedStack = taskStack; 1516 } else { 1517 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1518 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1519 } 1520 } 1521 return taskStack; 1522 } 1523 1524 final ActivityContainer container = r.mInitialActivityContainer; 1525 if (container != null) { 1526 // The first time put it on the desired stack, after this put on task stack. 1527 r.mInitialActivityContainer = null; 1528 return container.mStack; 1529 } 1530 1531 if (mFocusedStack != mHomeStack && (!newTask || 1532 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1533 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1534 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1535 return mFocusedStack; 1536 } 1537 1538 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1539 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1540 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1541 if (!stack.isHomeStack()) { 1542 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1543 "adjustStackFocus: Setting focused stack=" + stack); 1544 mFocusedStack = stack; 1545 return mFocusedStack; 1546 } 1547 } 1548 1549 // Need to create an app stack for this user. 1550 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1551 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1552 " stackId=" + stackId); 1553 mFocusedStack = getStack(stackId); 1554 return mFocusedStack; 1555 } 1556 return mHomeStack; 1557 } 1558 1559 void setFocusedStack(ActivityRecord r) { 1560 if (r != null) { 1561 final TaskRecord task = r.task; 1562 boolean isHomeActivity = !r.isApplicationActivity(); 1563 if (!isHomeActivity && task != null) { 1564 isHomeActivity = !task.isApplicationTask(); 1565 } 1566 if (!isHomeActivity && task != null) { 1567 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1568 isHomeActivity = parent != null && parent.isHomeActivity(); 1569 } 1570 moveHomeStack(isHomeActivity); 1571 } 1572 } 1573 1574 final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, 1575 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 1576 boolean doResume, Bundle options, TaskRecord inTask) { 1577 final Intent intent = r.intent; 1578 final int callingUid = r.launchedFromUid; 1579 1580 // In some flows in to this function, we retrieve the task record and hold on to it 1581 // without a lock before calling back in to here... so the task at this point may 1582 // not actually be in recents. Check for that, and if it isn't in recents just 1583 // consider it invalid. 1584 if (inTask != null && !inTask.inRecents) { 1585 Slog.w(TAG, "Starting activity in task not in recents: " + inTask); 1586 inTask = null; 1587 } 1588 1589 final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP; 1590 final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; 1591 final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; 1592 1593 int launchFlags = intent.getFlags(); 1594 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 1595 (launchSingleInstance || launchSingleTask)) { 1596 // We have a conflict between the Intent and the Activity manifest, manifest wins. 1597 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 1598 "\"singleInstance\" or \"singleTask\""); 1599 launchFlags &= 1600 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1601 } else { 1602 switch (r.info.documentLaunchMode) { 1603 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1604 break; 1605 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1606 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1607 break; 1608 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1609 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1610 break; 1611 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 1612 launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1613 break; 1614 } 1615 } 1616 1617 final boolean launchTaskBehind = r.mLaunchTaskBehind 1618 && !launchSingleTask && !launchSingleInstance 1619 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 1620 1621 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1622 // For whatever reason this activity is being launched into a new 1623 // task... yet the caller has requested a result back. Well, that 1624 // is pretty messed up, so instead immediately send back a cancel 1625 // and let the new task continue launched as normal without a 1626 // dependency on its originator. 1627 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1628 r.resultTo.task.stack.sendActivityResultLocked(-1, 1629 r.resultTo, r.resultWho, r.requestCode, 1630 Activity.RESULT_CANCELED, null); 1631 r.resultTo = null; 1632 } 1633 1634 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 1635 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1636 } 1637 1638 // If we are actually going to launch in to a new task, there are some cases where 1639 // we further want to do multiple task. 1640 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1641 if (launchTaskBehind 1642 || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) { 1643 launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1644 } 1645 } 1646 1647 // We'll invoke onUserLeaving before onPause only if the launching 1648 // activity did not explicitly state that this is an automated launch. 1649 mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1650 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1651 1652 // If the caller has asked not to resume at this point, we make note 1653 // of this in the record so that we can skip it when trying to find 1654 // the top running activity. 1655 if (!doResume) { 1656 r.delayedResume = true; 1657 } 1658 1659 ActivityRecord notTop = 1660 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1661 1662 // If the onlyIfNeeded flag is set, then we can do this if the activity 1663 // being launched is the same as the one making the call... or, as 1664 // a special case, if we do not know the caller then we count the 1665 // current top activity as the caller. 1666 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1667 ActivityRecord checkedCaller = sourceRecord; 1668 if (checkedCaller == null) { 1669 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1670 } 1671 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1672 // Caller is not the same as launcher, so always needed. 1673 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1674 } 1675 } 1676 1677 boolean addingToTask = false; 1678 TaskRecord reuseTask = null; 1679 1680 // If the caller is not coming from another activity, but has given us an 1681 // explicit task into which they would like us to launch the new activity, 1682 // then let's see about doing that. 1683 if (sourceRecord == null && inTask != null && inTask.stack != null) { 1684 final Intent baseIntent = inTask.getBaseIntent(); 1685 final ActivityRecord root = inTask.getRootActivity(); 1686 if (baseIntent == null) { 1687 ActivityOptions.abort(options); 1688 throw new IllegalArgumentException("Launching into task without base intent: " 1689 + inTask); 1690 } 1691 1692 // If this task is empty, then we are adding the first activity -- it 1693 // determines the root, and must be launching as a NEW_TASK. 1694 if (launchSingleInstance || launchSingleTask) { 1695 if (!baseIntent.getComponent().equals(r.intent.getComponent())) { 1696 ActivityOptions.abort(options); 1697 throw new IllegalArgumentException("Trying to launch singleInstance/Task " 1698 + r + " into different task " + inTask); 1699 } 1700 if (root != null) { 1701 ActivityOptions.abort(options); 1702 throw new IllegalArgumentException("Caller with inTask " + inTask 1703 + " has root " + root + " but target is singleInstance/Task"); 1704 } 1705 } 1706 1707 // If task is empty, then adopt the interesting intent launch flags in to the 1708 // activity being started. 1709 if (root == null) { 1710 final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK 1711 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT 1712 | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; 1713 launchFlags = (launchFlags&~flagsOfInterest) 1714 | (baseIntent.getFlags()&flagsOfInterest); 1715 intent.setFlags(launchFlags); 1716 inTask.setIntent(r); 1717 addingToTask = true; 1718 1719 // If the task is not empty and the caller is asking to start it as the root 1720 // of a new task, then we don't actually want to start this on the task. We 1721 // will bring the task to the front, and possibly give it a new intent. 1722 } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1723 addingToTask = false; 1724 1725 } else { 1726 addingToTask = true; 1727 } 1728 1729 reuseTask = inTask; 1730 } else { 1731 inTask = null; 1732 } 1733 1734 if (inTask == null) { 1735 if (sourceRecord == null) { 1736 // This activity is not being started from another... in this 1737 // case we -always- start a new task. 1738 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) { 1739 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1740 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1741 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1742 } 1743 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1744 // The original activity who is starting us is running as a single 1745 // instance... this new activity it is starting must go on its 1746 // own task. 1747 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1748 } else if (launchSingleInstance || launchSingleTask) { 1749 // The activity being started is a single instance... it always 1750 // gets launched into its own task. 1751 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1752 } 1753 } 1754 1755 ActivityInfo newTaskInfo = null; 1756 Intent newTaskIntent = null; 1757 ActivityStack sourceStack; 1758 if (sourceRecord != null) { 1759 if (sourceRecord.finishing) { 1760 // If the source is finishing, we can't further count it as our source. This 1761 // is because the task it is associated with may now be empty and on its way out, 1762 // so we don't want to blindly throw it in to that task. Instead we will take 1763 // the NEW_TASK flow and try to find a task for it. But save the task information 1764 // so it can be used when creating the new task. 1765 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1766 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1767 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1768 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1769 newTaskInfo = sourceRecord.info; 1770 newTaskIntent = sourceRecord.task.intent; 1771 } 1772 sourceRecord = null; 1773 sourceStack = null; 1774 } else { 1775 sourceStack = sourceRecord.task.stack; 1776 } 1777 } else { 1778 sourceStack = null; 1779 } 1780 1781 boolean movedHome = false; 1782 ActivityStack targetStack; 1783 1784 intent.setFlags(launchFlags); 1785 1786 // We may want to try to place the new activity in to an existing task. We always 1787 // do this if the target activity is singleTask or singleInstance; we will also do 1788 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 1789 // us to still place it in a new task: multi task, always doc mode, or being asked to 1790 // launch this as a new task behind the current one. 1791 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1792 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1793 || launchSingleInstance || launchSingleTask) { 1794 // If bring to front is requested, and no result is requested and we have not 1795 // been given an explicit task to launch in to, and 1796 // we can find a task that was started with this same 1797 // component, then instead of launching bring that one to the front. 1798 if (inTask == null && r.resultTo == null) { 1799 // See if there is a task to bring to the front. If this is 1800 // a SINGLE_INSTANCE activity, there can be one and only one 1801 // instance of it in the history, and it is always in its own 1802 // unique task, so we do a special search. 1803 ActivityRecord intentActivity = !launchSingleInstance ? 1804 findTaskLocked(r) : findActivityLocked(intent, r.info); 1805 if (intentActivity != null) { 1806 if (isLockTaskModeViolation(intentActivity.task)) { 1807 showLockTaskToast(); 1808 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); 1809 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1810 } 1811 if (r.task == null) { 1812 r.task = intentActivity.task; 1813 } 1814 targetStack = intentActivity.task.stack; 1815 targetStack.mLastPausedActivity = null; 1816 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1817 + " from " + intentActivity); 1818 targetStack.moveToFront(); 1819 if (intentActivity.task.intent == null) { 1820 // This task was started because of movement of 1821 // the activity based on affinity... now that we 1822 // are actually launching it, we can assign the 1823 // base intent. 1824 intentActivity.task.setIntent(r); 1825 } 1826 // If the target task is not in the front, then we need 1827 // to bring it to the front... except... well, with 1828 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1829 // to have the same behavior as if a new instance was 1830 // being started, which means not bringing it to the front 1831 // if the caller is not itself in the front. 1832 final ActivityStack lastStack = getLastStack(); 1833 ActivityRecord curTop = lastStack == null? 1834 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1835 boolean movedToFront = false; 1836 if (curTop != null && (curTop.task != intentActivity.task || 1837 curTop.task != lastStack.topTask())) { 1838 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1839 if (sourceRecord == null || (sourceStack.topActivity() != null && 1840 sourceStack.topActivity().task == sourceRecord.task)) { 1841 // We really do want to push this one into the 1842 // user's face, right now. 1843 if (launchTaskBehind && sourceRecord != null) { 1844 intentActivity.setTaskToAffiliateWith(sourceRecord.task); 1845 } 1846 movedHome = true; 1847 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1848 if ((launchFlags & 1849 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1850 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1851 // Caller wants to appear on home activity. 1852 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1853 } 1854 options = null; 1855 movedToFront = true; 1856 } 1857 } 1858 // If the caller has requested that the target task be 1859 // reset, then do so. 1860 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1861 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1862 } 1863 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1864 // We don't need to start a new activity, and 1865 // the client said not to do anything if that 1866 // is the case, so this is it! And for paranoia, make 1867 // sure we have correctly resumed the top activity. 1868 if (doResume) { 1869 resumeTopActivitiesLocked(targetStack, null, options); 1870 1871 // Make sure to notify Keyguard as well if we are not running an app 1872 // transition later. 1873 if (!movedToFront) { 1874 notifyActivityDrawnForKeyguard(); 1875 } 1876 } else { 1877 ActivityOptions.abort(options); 1878 } 1879 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1880 } 1881 if ((launchFlags & 1882 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1883 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1884 // The caller has requested to completely replace any 1885 // existing task with its new activity. Well that should 1886 // not be too hard... 1887 reuseTask = intentActivity.task; 1888 reuseTask.performClearTaskLocked(); 1889 reuseTask.setIntent(r); 1890 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1891 || launchSingleInstance || launchSingleTask) { 1892 // In this situation we want to remove all activities 1893 // from the task up to the one being started. In most 1894 // cases this means we are resetting the task to its 1895 // initial state. 1896 ActivityRecord top = 1897 intentActivity.task.performClearTaskLocked(r, launchFlags); 1898 if (top != null) { 1899 if (top.frontOfTask) { 1900 // Activity aliases may mean we use different 1901 // intents for the top activity, so make sure 1902 // the task now has the identity of the new 1903 // intent. 1904 top.task.setIntent(r); 1905 } 1906 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1907 r, top.task); 1908 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 1909 } else { 1910 // A special case: we need to 1911 // start the activity because it is not currently 1912 // running, and the caller has asked to clear the 1913 // current task to have this activity at the top. 1914 addingToTask = true; 1915 // Now pretend like this activity is being started 1916 // by the top of its task, so it is put in the 1917 // right place. 1918 sourceRecord = intentActivity; 1919 } 1920 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1921 // In this case the top activity on the task is the 1922 // same as the one being launched, so we take that 1923 // as a request to bring the task to the foreground. 1924 // If the top activity in the task is the root 1925 // activity, deliver this new intent to it if it 1926 // desires. 1927 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop) 1928 && intentActivity.realActivity.equals(r.realActivity)) { 1929 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1930 intentActivity.task); 1931 if (intentActivity.frontOfTask) { 1932 intentActivity.task.setIntent(r); 1933 } 1934 intentActivity.deliverNewIntentLocked(callingUid, r.intent, 1935 r.launchedFromPackage); 1936 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1937 // In this case we are launching the root activity 1938 // of the task, but with a different intent. We 1939 // should start a new instance on top. 1940 addingToTask = true; 1941 sourceRecord = intentActivity; 1942 } 1943 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1944 // In this case an activity is being launched in to an 1945 // existing task, without resetting that task. This 1946 // is typically the situation of launching an activity 1947 // from a notification or shortcut. We want to place 1948 // the new activity on top of the current task. 1949 addingToTask = true; 1950 sourceRecord = intentActivity; 1951 } else if (!intentActivity.task.rootWasReset) { 1952 // In this case we are launching in to an existing task 1953 // that has not yet been started from its front door. 1954 // The current task has been brought to the front. 1955 // Ideally, we'd probably like to place this new task 1956 // at the bottom of its stack, but that's a little hard 1957 // to do with the current organization of the code so 1958 // for now we'll just drop it. 1959 intentActivity.task.setIntent(r); 1960 } 1961 if (!addingToTask && reuseTask == null) { 1962 // We didn't do anything... but it was needed (a.k.a., client 1963 // don't use that intent!) And for paranoia, make 1964 // sure we have correctly resumed the top activity. 1965 if (doResume) { 1966 targetStack.resumeTopActivityLocked(null, options); 1967 if (!movedToFront) { 1968 // Make sure to notify Keyguard as well if we are not running an app 1969 // transition later. 1970 notifyActivityDrawnForKeyguard(); 1971 } 1972 } else { 1973 ActivityOptions.abort(options); 1974 } 1975 return ActivityManager.START_TASK_TO_FRONT; 1976 } 1977 } 1978 } 1979 } 1980 1981 //String uri = r.intent.toURI(); 1982 //Intent intent2 = new Intent(uri); 1983 //Slog.i(TAG, "Given intent: " + r.intent); 1984 //Slog.i(TAG, "URI is: " + uri); 1985 //Slog.i(TAG, "To intent: " + intent2); 1986 1987 if (r.packageName != null) { 1988 // If the activity being launched is the same as the one currently 1989 // at the top, then we need to check if it should only be launched 1990 // once. 1991 ActivityStack topStack = getFocusedStack(); 1992 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1993 if (top != null && r.resultTo == null) { 1994 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1995 if (top.app != null && top.app.thread != null) { 1996 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1997 || launchSingleTop || launchSingleTask) { 1998 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1999 top.task); 2000 // For paranoia, make sure we have correctly 2001 // resumed the top activity. 2002 topStack.mLastPausedActivity = null; 2003 if (doResume) { 2004 resumeTopActivitiesLocked(); 2005 } 2006 ActivityOptions.abort(options); 2007 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2008 // We don't need to start a new activity, and 2009 // the client said not to do anything if that 2010 // is the case, so this is it! 2011 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2012 } 2013 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2014 return ActivityManager.START_DELIVERED_TO_TOP; 2015 } 2016 } 2017 } 2018 } 2019 2020 } else { 2021 if (r.resultTo != null) { 2022 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 2023 r.requestCode, Activity.RESULT_CANCELED, null); 2024 } 2025 ActivityOptions.abort(options); 2026 return ActivityManager.START_CLASS_NOT_FOUND; 2027 } 2028 2029 boolean newTask = false; 2030 boolean keepCurTransition = false; 2031 2032 TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ? 2033 sourceRecord.task : null; 2034 2035 // Should this be considered a new task? 2036 if (r.resultTo == null && inTask == null && !addingToTask 2037 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 2038 if (isLockTaskModeViolation(reuseTask)) { 2039 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2040 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2041 } 2042 newTask = true; 2043 targetStack = adjustStackFocus(r, newTask); 2044 if (!launchTaskBehind) { 2045 targetStack.moveToFront(); 2046 } 2047 if (reuseTask == null) { 2048 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 2049 newTaskInfo != null ? newTaskInfo : r.info, 2050 newTaskIntent != null ? newTaskIntent : intent, 2051 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */), 2052 taskToAffiliate); 2053 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 2054 r.task); 2055 } else { 2056 r.setTask(reuseTask, taskToAffiliate); 2057 } 2058 if (!movedHome) { 2059 if ((launchFlags & 2060 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 2061 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 2062 // Caller wants to appear on home activity, so before starting 2063 // their own activity we will bring home to the front. 2064 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2065 } 2066 } 2067 } else if (sourceRecord != null) { 2068 final TaskRecord sourceTask = sourceRecord.task; 2069 if (isLockTaskModeViolation(sourceTask)) { 2070 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2071 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2072 } 2073 targetStack = sourceTask.stack; 2074 targetStack.moveToFront(); 2075 final TaskRecord topTask = targetStack.topTask(); 2076 if (topTask != sourceTask) { 2077 targetStack.moveTaskToFrontLocked(sourceTask, r, options); 2078 } 2079 if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 2080 // In this case, we are adding the activity to an existing 2081 // task, but the caller has asked to clear that task if the 2082 // activity is already running. 2083 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 2084 keepCurTransition = true; 2085 if (top != null) { 2086 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 2087 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2088 // For paranoia, make sure we have correctly 2089 // resumed the top activity. 2090 targetStack.mLastPausedActivity = null; 2091 if (doResume) { 2092 targetStack.resumeTopActivityLocked(null); 2093 } 2094 ActivityOptions.abort(options); 2095 return ActivityManager.START_DELIVERED_TO_TOP; 2096 } 2097 } else if (!addingToTask && 2098 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 2099 // In this case, we are launching an activity in our own task 2100 // that may already be running somewhere in the history, and 2101 // we want to shuffle it to the front of the stack if so. 2102 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 2103 if (top != null) { 2104 final TaskRecord task = top.task; 2105 task.moveActivityToFrontLocked(top); 2106 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 2107 top.updateOptionsLocked(options); 2108 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2109 targetStack.mLastPausedActivity = null; 2110 if (doResume) { 2111 targetStack.resumeTopActivityLocked(null); 2112 } 2113 return ActivityManager.START_DELIVERED_TO_TOP; 2114 } 2115 } 2116 // An existing activity is starting this new activity, so we want 2117 // to keep the new one in the same task as the one that is starting 2118 // it. 2119 r.setTask(sourceTask, null); 2120 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2121 + " in existing task " + r.task + " from source " + sourceRecord); 2122 2123 } else if (inTask != null) { 2124 // The calling is asking that the new activity be started in an explicit 2125 // task it has provided to us. 2126 if (isLockTaskModeViolation(inTask)) { 2127 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2128 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2129 } 2130 targetStack = inTask.stack; 2131 targetStack.moveTaskToFrontLocked(inTask, r, options); 2132 2133 // Check whether we should actually launch the new activity in to the task, 2134 // or just reuse the current activity on top. 2135 ActivityRecord top = inTask.getTopActivity(); 2136 if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 2137 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 2138 || launchSingleTop || launchSingleTask) { 2139 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 2140 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2141 // We don't need to start a new activity, and 2142 // the client said not to do anything if that 2143 // is the case, so this is it! 2144 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2145 } 2146 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2147 return ActivityManager.START_DELIVERED_TO_TOP; 2148 } 2149 } 2150 2151 if (!addingToTask) { 2152 // We don't actually want to have this activity added to the task, so just 2153 // stop here but still tell the caller that we consumed the intent. 2154 ActivityOptions.abort(options); 2155 return ActivityManager.START_TASK_TO_FRONT; 2156 } 2157 2158 r.setTask(inTask, null); 2159 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2160 + " in explicit task " + r.task); 2161 2162 } else { 2163 // This not being started from an existing activity, and not part 2164 // of a new task... just put it in the top task, though these days 2165 // this case should never happen. 2166 targetStack = adjustStackFocus(r, newTask); 2167 targetStack.moveToFront(); 2168 ActivityRecord prev = targetStack.topActivity(); 2169 r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), 2170 r.info, intent, null, null, true), null); 2171 mWindowManager.moveTaskToTop(r.task.taskId); 2172 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2173 + " in new guessed " + r.task); 2174 } 2175 2176 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 2177 intent, r.getUriPermissionsLocked(), r.userId); 2178 2179 if (sourceRecord != null && sourceRecord.isRecentsActivity()) { 2180 r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE); 2181 } 2182 if (newTask) { 2183 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 2184 } 2185 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 2186 targetStack.mLastPausedActivity = null; 2187 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 2188 if (!launchTaskBehind) { 2189 // Don't set focus on an activity that's going to the back. 2190 mService.setFocusedActivityLocked(r); 2191 } 2192 return ActivityManager.START_SUCCESS; 2193 } 2194 2195 final void doPendingActivityLaunchesLocked(boolean doResume) { 2196 while (!mPendingActivityLaunches.isEmpty()) { 2197 PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); 2198 startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 2199 doResume && mPendingActivityLaunches.isEmpty(), null, null); 2200 } 2201 } 2202 2203 void removePendingActivityLaunchesLocked(ActivityStack stack) { 2204 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) { 2205 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx); 2206 if (pal.stack == stack) { 2207 mPendingActivityLaunches.remove(palNdx); 2208 } 2209 } 2210 } 2211 2212 void acquireLaunchWakelock() { 2213 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2214 throw new IllegalStateException("Calling must be system uid"); 2215 } 2216 mLaunchingActivity.acquire(); 2217 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2218 // To be safe, don't allow the wake lock to be held for too long. 2219 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2220 } 2221 } 2222 2223 // Checked. 2224 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 2225 Configuration config) { 2226 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 2227 2228 ArrayList<ActivityRecord> stops = null; 2229 ArrayList<ActivityRecord> finishes = null; 2230 ArrayList<UserStartedState> startingUsers = null; 2231 int NS = 0; 2232 int NF = 0; 2233 boolean booting = false; 2234 boolean enableScreen = false; 2235 boolean activityRemoved = false; 2236 2237 ActivityRecord r = ActivityRecord.forToken(token); 2238 if (r != null) { 2239 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 2240 Debug.getCallers(4)); 2241 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2242 r.finishLaunchTickingLocked(); 2243 if (fromTimeout) { 2244 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2245 } 2246 2247 // This is a hack to semi-deal with a race condition 2248 // in the client where it can be constructed with a 2249 // newer configuration from when we asked it to launch. 2250 // We'll update with whatever configuration it now says 2251 // it used to launch. 2252 if (config != null) { 2253 r.configuration = config; 2254 } 2255 2256 // We are now idle. If someone is waiting for a thumbnail from 2257 // us, we can now deliver. 2258 r.idle = true; 2259 2260 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2261 if (isFrontStack(r.task.stack) || fromTimeout) { 2262 booting = mService.mBooting; 2263 mService.mBooting = false; 2264 if (!mService.mBooted) { 2265 mService.mBooted = true; 2266 enableScreen = true; 2267 } 2268 } 2269 } 2270 2271 if (allResumedActivitiesIdle()) { 2272 if (r != null) { 2273 mService.scheduleAppGcsLocked(); 2274 } 2275 2276 if (mLaunchingActivity.isHeld()) { 2277 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2278 if (VALIDATE_WAKE_LOCK_CALLER && 2279 Binder.getCallingUid() != Process.myUid()) { 2280 throw new IllegalStateException("Calling must be system uid"); 2281 } 2282 mLaunchingActivity.release(); 2283 } 2284 ensureActivitiesVisibleLocked(null, 0); 2285 } 2286 2287 // Atomically retrieve all of the other things to do. 2288 stops = processStoppingActivitiesLocked(true); 2289 NS = stops != null ? stops.size() : 0; 2290 if ((NF=mFinishingActivities.size()) > 0) { 2291 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 2292 mFinishingActivities.clear(); 2293 } 2294 2295 if (mStartingUsers.size() > 0) { 2296 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 2297 mStartingUsers.clear(); 2298 } 2299 2300 // Stop any activities that are scheduled to do so but have been 2301 // waiting for the next one to start. 2302 for (int i = 0; i < NS; i++) { 2303 r = stops.get(i); 2304 final ActivityStack stack = r.task.stack; 2305 if (r.finishing) { 2306 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2307 } else { 2308 stack.stopActivityLocked(r); 2309 } 2310 } 2311 2312 // Finish any activities that are scheduled to do so but have been 2313 // waiting for the next one to start. 2314 for (int i = 0; i < NF; i++) { 2315 r = finishes.get(i); 2316 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle"); 2317 } 2318 2319 if (!booting) { 2320 // Complete user switch 2321 if (startingUsers != null) { 2322 for (int i = 0; i < startingUsers.size(); i++) { 2323 mService.finishUserSwitch(startingUsers.get(i)); 2324 } 2325 } 2326 // Complete starting up of background users 2327 if (mStartingBackgroundUsers.size() > 0) { 2328 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2329 mStartingBackgroundUsers.clear(); 2330 for (int i = 0; i < startingUsers.size(); i++) { 2331 mService.finishUserBoot(startingUsers.get(i)); 2332 } 2333 } 2334 } 2335 2336 mService.trimApplications(); 2337 //dump(); 2338 //mWindowManager.dump(); 2339 2340 if (booting || enableScreen) { 2341 mService.postFinishBooting(booting, enableScreen); 2342 } 2343 2344 if (activityRemoved) { 2345 resumeTopActivitiesLocked(); 2346 } 2347 2348 return r; 2349 } 2350 2351 boolean handleAppDiedLocked(ProcessRecord app) { 2352 boolean hasVisibleActivities = false; 2353 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2354 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2355 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2356 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2357 } 2358 } 2359 return hasVisibleActivities; 2360 } 2361 2362 void closeSystemDialogsLocked() { 2363 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2364 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2365 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2366 stacks.get(stackNdx).closeSystemDialogsLocked(); 2367 } 2368 } 2369 } 2370 2371 void removeUserLocked(int userId) { 2372 mUserStackInFront.delete(userId); 2373 } 2374 2375 /** 2376 * @return true if some activity was finished (or would have finished if doit were true). 2377 */ 2378 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2379 boolean didSomething = false; 2380 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2381 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2382 final int numStacks = stacks.size(); 2383 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2384 final ActivityStack stack = stacks.get(stackNdx); 2385 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2386 didSomething = true; 2387 } 2388 } 2389 } 2390 return didSomething; 2391 } 2392 2393 void updatePreviousProcessLocked(ActivityRecord r) { 2394 // Now that this process has stopped, we may want to consider 2395 // it to be the previous app to try to keep around in case 2396 // the user wants to return to it. 2397 2398 // First, found out what is currently the foreground app, so that 2399 // we don't blow away the previous app if this activity is being 2400 // hosted by the process that is actually still the foreground. 2401 ProcessRecord fgApp = null; 2402 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2403 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2404 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2405 final ActivityStack stack = stacks.get(stackNdx); 2406 if (isFrontStack(stack)) { 2407 if (stack.mResumedActivity != null) { 2408 fgApp = stack.mResumedActivity.app; 2409 } else if (stack.mPausingActivity != null) { 2410 fgApp = stack.mPausingActivity.app; 2411 } 2412 break; 2413 } 2414 } 2415 } 2416 2417 // Now set this one as the previous process, only if that really 2418 // makes sense to. 2419 if (r.app != null && fgApp != null && r.app != fgApp 2420 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2421 && r.app != mService.mHomeProcess) { 2422 mService.mPreviousProcess = r.app; 2423 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2424 } 2425 } 2426 2427 boolean resumeTopActivitiesLocked() { 2428 return resumeTopActivitiesLocked(null, null, null); 2429 } 2430 2431 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2432 Bundle targetOptions) { 2433 if (targetStack == null) { 2434 targetStack = getFocusedStack(); 2435 } 2436 // Do targetStack first. 2437 boolean result = false; 2438 if (isFrontStack(targetStack)) { 2439 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2440 } 2441 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2442 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2443 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2444 final ActivityStack stack = stacks.get(stackNdx); 2445 if (stack == targetStack) { 2446 // Already started above. 2447 continue; 2448 } 2449 if (isFrontStack(stack)) { 2450 stack.resumeTopActivityLocked(null); 2451 } 2452 } 2453 } 2454 return result; 2455 } 2456 2457 void finishTopRunningActivityLocked(ProcessRecord app) { 2458 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2459 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2460 final int numStacks = stacks.size(); 2461 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2462 final ActivityStack stack = stacks.get(stackNdx); 2463 stack.finishTopRunningActivityLocked(app); 2464 } 2465 } 2466 } 2467 2468 void finishVoiceTask(IVoiceInteractionSession session) { 2469 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2470 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2471 final int numStacks = stacks.size(); 2472 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2473 final ActivityStack stack = stacks.get(stackNdx); 2474 stack.finishVoiceTask(session); 2475 } 2476 } 2477 } 2478 2479 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2480 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2481 mUserLeaving = true; 2482 } 2483 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2484 // Caller wants the home activity moved with it. To accomplish this, 2485 // we'll just indicate that this task returns to the home task. 2486 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2487 } 2488 task.stack.moveTaskToFrontLocked(task, null, options); 2489 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2490 + task.stack); 2491 } 2492 2493 ActivityStack getStack(int stackId) { 2494 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2495 if (activityContainer != null) { 2496 return activityContainer.mStack; 2497 } 2498 return null; 2499 } 2500 2501 ArrayList<ActivityStack> getStacks() { 2502 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2503 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2504 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2505 } 2506 return allStacks; 2507 } 2508 2509 IBinder getHomeActivityToken() { 2510 ActivityRecord homeActivity = getHomeActivity(); 2511 if (homeActivity != null) { 2512 return homeActivity.appToken; 2513 } 2514 return null; 2515 } 2516 2517 ActivityRecord getHomeActivity() { 2518 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2519 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2520 final TaskRecord task = tasks.get(taskNdx); 2521 if (task.isHomeTask()) { 2522 final ArrayList<ActivityRecord> activities = task.mActivities; 2523 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2524 final ActivityRecord r = activities.get(activityNdx); 2525 if (r.isHomeActivity()) { 2526 return r; 2527 } 2528 } 2529 } 2530 } 2531 return null; 2532 } 2533 2534 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2535 IActivityContainerCallback callback) { 2536 ActivityContainer activityContainer = 2537 new VirtualActivityContainer(parentActivity, callback); 2538 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2539 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer); 2540 parentActivity.mChildContainers.add(activityContainer); 2541 return activityContainer; 2542 } 2543 2544 void removeChildActivityContainers(ActivityRecord parentActivity) { 2545 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2546 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2547 ActivityContainer container = childStacks.remove(containerNdx); 2548 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " + 2549 container); 2550 container.release(); 2551 } 2552 } 2553 2554 void deleteActivityContainer(IActivityContainer container) { 2555 ActivityContainer activityContainer = (ActivityContainer)container; 2556 if (activityContainer != null) { 2557 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ", 2558 new RuntimeException("here").fillInStackTrace()); 2559 final int stackId = activityContainer.mStackId; 2560 mActivityContainers.remove(stackId); 2561 mWindowManager.removeStack(stackId); 2562 } 2563 } 2564 2565 private int createStackOnDisplay(int stackId, int displayId) { 2566 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2567 if (activityDisplay == null) { 2568 return -1; 2569 } 2570 2571 ActivityContainer activityContainer = new ActivityContainer(stackId); 2572 mActivityContainers.put(stackId, activityContainer); 2573 activityContainer.attachToDisplayLocked(activityDisplay); 2574 return stackId; 2575 } 2576 2577 int getNextStackId() { 2578 while (true) { 2579 if (++mLastStackId <= HOME_STACK_ID) { 2580 mLastStackId = HOME_STACK_ID + 1; 2581 } 2582 if (getStack(mLastStackId) == null) { 2583 break; 2584 } 2585 } 2586 return mLastStackId; 2587 } 2588 2589 void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { 2590 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2591 final ActivityStack stack = getStack(stackId); 2592 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2593 final TaskRecord task = tasks.get(taskNdx); 2594 stack.addTask(task, false, false); 2595 final int taskId = task.taskId; 2596 final ArrayList<ActivityRecord> activities = task.mActivities; 2597 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2598 final ActivityRecord r = activities.get(activityNdx); 2599 mWindowManager.addAppToken(0, r.appToken, taskId, stackId, 2600 r.info.screenOrientation, r.fullscreen, 2601 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, 2602 r.userId, r.info.configChanges, task.voiceSession != null, 2603 r.mLaunchTaskBehind); 2604 } 2605 } 2606 } 2607 2608 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2609 final TaskRecord task = anyTaskForIdLocked(taskId); 2610 if (task == null) { 2611 return; 2612 } 2613 final ActivityStack stack = getStack(stackId); 2614 if (stack == null) { 2615 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2616 return; 2617 } 2618 task.stack.removeTask(task); 2619 stack.addTask(task, toTop, true); 2620 mWindowManager.addTask(taskId, stackId, toTop); 2621 resumeTopActivitiesLocked(); 2622 } 2623 2624 ActivityRecord findTaskLocked(ActivityRecord r) { 2625 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2626 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2627 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2628 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2629 final ActivityStack stack = stacks.get(stackNdx); 2630 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2631 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2632 continue; 2633 } 2634 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2635 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2636 stack); 2637 continue; 2638 } 2639 final ActivityRecord ar = stack.findTaskLocked(r); 2640 if (ar != null) { 2641 return ar; 2642 } 2643 } 2644 } 2645 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2646 return null; 2647 } 2648 2649 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2650 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2651 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2652 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2653 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2654 if (ar != null) { 2655 return ar; 2656 } 2657 } 2658 } 2659 return null; 2660 } 2661 2662 void goingToSleepLocked() { 2663 scheduleSleepTimeout(); 2664 if (!mGoingToSleep.isHeld()) { 2665 mGoingToSleep.acquire(); 2666 if (mLaunchingActivity.isHeld()) { 2667 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2668 throw new IllegalStateException("Calling must be system uid"); 2669 } 2670 mLaunchingActivity.release(); 2671 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2672 } 2673 } 2674 checkReadyForSleepLocked(); 2675 } 2676 2677 boolean shutdownLocked(int timeout) { 2678 goingToSleepLocked(); 2679 2680 boolean timedout = false; 2681 final long endTime = System.currentTimeMillis() + timeout; 2682 while (true) { 2683 boolean cantShutdown = false; 2684 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2685 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2686 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2687 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2688 } 2689 } 2690 if (cantShutdown) { 2691 long timeRemaining = endTime - System.currentTimeMillis(); 2692 if (timeRemaining > 0) { 2693 try { 2694 mService.wait(timeRemaining); 2695 } catch (InterruptedException e) { 2696 } 2697 } else { 2698 Slog.w(TAG, "Activity manager shutdown timed out"); 2699 timedout = true; 2700 break; 2701 } 2702 } else { 2703 break; 2704 } 2705 } 2706 2707 // Force checkReadyForSleep to complete. 2708 mSleepTimeout = true; 2709 checkReadyForSleepLocked(); 2710 2711 return timedout; 2712 } 2713 2714 void comeOutOfSleepIfNeededLocked() { 2715 removeSleepTimeouts(); 2716 if (mGoingToSleep.isHeld()) { 2717 mGoingToSleep.release(); 2718 } 2719 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2720 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2721 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2722 final ActivityStack stack = stacks.get(stackNdx); 2723 stack.awakeFromSleepingLocked(); 2724 if (isFrontStack(stack)) { 2725 resumeTopActivitiesLocked(); 2726 } 2727 } 2728 } 2729 mGoingToSleepActivities.clear(); 2730 } 2731 2732 void activitySleptLocked(ActivityRecord r) { 2733 mGoingToSleepActivities.remove(r); 2734 checkReadyForSleepLocked(); 2735 } 2736 2737 void checkReadyForSleepLocked() { 2738 if (!mService.isSleepingOrShuttingDown()) { 2739 // Do not care. 2740 return; 2741 } 2742 2743 if (!mSleepTimeout) { 2744 boolean dontSleep = false; 2745 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2746 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2747 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2748 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2749 } 2750 } 2751 2752 if (mStoppingActivities.size() > 0) { 2753 // Still need to tell some activities to stop; can't sleep yet. 2754 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2755 + mStoppingActivities.size() + " activities"); 2756 scheduleIdleLocked(); 2757 dontSleep = true; 2758 } 2759 2760 if (mGoingToSleepActivities.size() > 0) { 2761 // Still need to tell some activities to sleep; can't sleep yet. 2762 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2763 + mGoingToSleepActivities.size() + " activities"); 2764 dontSleep = true; 2765 } 2766 2767 if (dontSleep) { 2768 return; 2769 } 2770 } 2771 2772 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2773 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2774 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2775 stacks.get(stackNdx).goToSleep(); 2776 } 2777 } 2778 2779 removeSleepTimeouts(); 2780 2781 if (mGoingToSleep.isHeld()) { 2782 mGoingToSleep.release(); 2783 } 2784 if (mService.mShuttingDown) { 2785 mService.notifyAll(); 2786 } 2787 } 2788 2789 boolean reportResumedActivityLocked(ActivityRecord r) { 2790 final ActivityStack stack = r.task.stack; 2791 if (isFrontStack(stack)) { 2792 mService.updateUsageStats(r, true); 2793 } 2794 if (allResumedActivitiesComplete()) { 2795 ensureActivitiesVisibleLocked(null, 0); 2796 mWindowManager.executeAppTransition(); 2797 return true; 2798 } 2799 return false; 2800 } 2801 2802 void handleAppCrashLocked(ProcessRecord app) { 2803 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2804 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2805 final int numStacks = stacks.size(); 2806 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2807 final ActivityStack stack = stacks.get(stackNdx); 2808 stack.handleAppCrashLocked(app); 2809 } 2810 } 2811 } 2812 2813 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 2814 final ActivityStack stack = r.task.stack; 2815 if (stack == null) { 2816 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" + 2817 visible + " stack is null"); 2818 return false; 2819 } 2820 final boolean isVisible = stack.hasVisibleBehindActivity(); 2821 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" + 2822 visible + " isVisible=" + isVisible); 2823 2824 final ActivityRecord top = topRunningActivityLocked(); 2825 if (top == null || top == r || (visible == isVisible)) { 2826 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return"); 2827 stack.setVisibleBehindActivity(visible ? r : null); 2828 return true; 2829 } 2830 2831 // A non-top activity is reporting a visibility change. 2832 if (visible && top.fullscreen) { 2833 // Let the caller know that it can't be seen. 2834 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen=" 2835 + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app + 2836 " top.app.thread=" + top.app.thread); 2837 return false; 2838 } else if (!visible && stack.getVisibleBehindActivity() != r) { 2839 // Only the activity set as currently visible behind should actively reset its 2840 // visible behind state. 2841 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible=" 2842 + visible + " stack.getVisibleBehindActivity()=" + 2843 stack.getVisibleBehindActivity() + " r=" + r); 2844 return false; 2845 } 2846 2847 stack.setVisibleBehindActivity(visible ? r : null); 2848 if (!visible) { 2849 // Make the activity immediately above r opaque. 2850 final ActivityRecord next = stack.findNextTranslucentActivity(r); 2851 if (next != null) { 2852 mService.convertFromTranslucent(next.appToken); 2853 } 2854 } 2855 if (top.app != null && top.app.thread != null) { 2856 // Notify the top app of the change. 2857 try { 2858 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 2859 } catch (RemoteException e) { 2860 } 2861 } 2862 return true; 2863 } 2864 2865 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2866 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2867 r.mLaunchTaskBehind = false; 2868 final TaskRecord task = r.task; 2869 task.setLastThumbnail(task.stack.screenshotActivities(r)); 2870 mService.addRecentTaskLocked(task); 2871 mService.notifyTaskStackChangedLocked(); 2872 mWindowManager.setAppVisibility(r.appToken, false); 2873 } 2874 2875 void scheduleLaunchTaskBehindComplete(IBinder token) { 2876 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2877 } 2878 2879 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2880 // First the front stacks. In case any are not fullscreen and are in front of home. 2881 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2882 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2883 final int topStackNdx = stacks.size() - 1; 2884 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2885 final ActivityStack stack = stacks.get(stackNdx); 2886 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2887 } 2888 } 2889 } 2890 2891 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2892 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2893 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2894 final int numStacks = stacks.size(); 2895 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2896 final ActivityStack stack = stacks.get(stackNdx); 2897 stack.scheduleDestroyActivities(app, reason); 2898 } 2899 } 2900 } 2901 2902 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 2903 // Examine all activities currently running in the process. 2904 TaskRecord firstTask = null; 2905 // Tasks is non-null only if two or more tasks are found. 2906 ArraySet<TaskRecord> tasks = null; 2907 if (DEBUG_RELEASE) Slog.d(TAG, "Trying to release some activities in " + app); 2908 for (int i=0; i<app.activities.size(); i++) { 2909 ActivityRecord r = app.activities.get(i); 2910 // First, if we find an activity that is in the process of being destroyed, 2911 // then we just aren't going to do anything for now; we want things to settle 2912 // down before we try to prune more activities. 2913 if (r.finishing || r.state == ActivityState.DESTROYING 2914 || r.state == ActivityState.DESTROYED) { 2915 if (DEBUG_RELEASE) Slog.d(TAG, "Abort release; already destroying: " + r); 2916 return; 2917 } 2918 // Don't consider any activies that are currently not in a state where they 2919 // can be destroyed. 2920 if (r.visible || !r.stopped || !r.haveState 2921 || r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING 2922 || r.state == ActivityState.PAUSED || r.state == ActivityState.STOPPING) { 2923 if (DEBUG_RELEASE) Slog.d(TAG, "Not releasing in-use activity: " + r); 2924 continue; 2925 } 2926 if (r.task != null) { 2927 if (DEBUG_RELEASE) Slog.d(TAG, "Collecting release task " + r.task 2928 + " from " + r); 2929 if (firstTask == null) { 2930 firstTask = r.task; 2931 } else if (firstTask != r.task) { 2932 if (tasks == null) { 2933 tasks = new ArraySet<>(); 2934 tasks.add(firstTask); 2935 } 2936 tasks.add(r.task); 2937 } 2938 } 2939 } 2940 if (tasks == null) { 2941 if (DEBUG_RELEASE) Slog.d(TAG, "Didn't find two or more tasks to release"); 2942 return; 2943 } 2944 // If we have activities in multiple tasks that are in a position to be destroyed, 2945 // let's iterate through the tasks and release the oldest one. 2946 final int numDisplays = mActivityDisplays.size(); 2947 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2948 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2949 // Step through all stacks starting from behind, to hit the oldest things first. 2950 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 2951 final ActivityStack stack = stacks.get(stackNdx); 2952 // Try to release activities in this stack; if we manage to, we are done. 2953 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 2954 return; 2955 } 2956 } 2957 } 2958 } 2959 2960 boolean switchUserLocked(int userId, UserStartedState uss) { 2961 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2962 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2963 mCurrentUser = userId; 2964 2965 mStartingUsers.add(uss); 2966 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2967 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2968 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2969 final ActivityStack stack = stacks.get(stackNdx); 2970 stack.switchUserLocked(userId); 2971 TaskRecord task = stack.topTask(); 2972 if (task != null) { 2973 mWindowManager.moveTaskToTop(task.taskId); 2974 } 2975 } 2976 } 2977 2978 ActivityStack stack = getStack(restoreStackId); 2979 if (stack == null) { 2980 stack = mHomeStack; 2981 } 2982 final boolean homeInFront = stack.isHomeStack(); 2983 if (stack.isOnHomeDisplay()) { 2984 moveHomeStack(homeInFront); 2985 TaskRecord task = stack.topTask(); 2986 if (task != null) { 2987 mWindowManager.moveTaskToTop(task.taskId); 2988 } 2989 } else { 2990 // Stack was moved to another display while user was swapped out. 2991 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2992 } 2993 return homeInFront; 2994 } 2995 2996 /** 2997 * Add background users to send boot completed events to. 2998 * @param userId The user being started in the background 2999 * @param uss The state object for the user. 3000 */ 3001 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 3002 mStartingBackgroundUsers.add(uss); 3003 } 3004 3005 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 3006 int N = mStoppingActivities.size(); 3007 if (N <= 0) return null; 3008 3009 ArrayList<ActivityRecord> stops = null; 3010 3011 final boolean nowVisible = allResumedActivitiesVisible(); 3012 for (int i=0; i<N; i++) { 3013 ActivityRecord s = mStoppingActivities.get(i); 3014 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 3015 + nowVisible + " waitingVisible=" + s.waitingVisible 3016 + " finishing=" + s.finishing); 3017 if (s.waitingVisible && nowVisible) { 3018 mWaitingVisibleActivities.remove(s); 3019 s.waitingVisible = false; 3020 if (s.finishing) { 3021 // If this activity is finishing, it is sitting on top of 3022 // everyone else but we now know it is no longer needed... 3023 // so get rid of it. Otherwise, we need to go through the 3024 // normal flow and hide it once we determine that it is 3025 // hidden by the activities in front of it. 3026 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 3027 mWindowManager.setAppVisibility(s.appToken, false); 3028 } 3029 } 3030 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3031 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 3032 if (stops == null) { 3033 stops = new ArrayList<ActivityRecord>(); 3034 } 3035 stops.add(s); 3036 mStoppingActivities.remove(i); 3037 N--; 3038 i--; 3039 } 3040 } 3041 3042 return stops; 3043 } 3044 3045 void validateTopActivitiesLocked() { 3046 // FIXME 3047/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3048 final ActivityStack stack = stacks.get(stackNdx); 3049 final ActivityRecord r = stack.topRunningActivityLocked(null); 3050 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 3051 if (isFrontStack(stack)) { 3052 if (r == null) { 3053 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 3054 } else { 3055 final ActivityRecord pausing = stack.mPausingActivity; 3056 if (pausing != null && pausing == r) { 3057 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 3058 " state=" + state); 3059 } 3060 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 3061 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 3062 " state=" + state); 3063 } 3064 } 3065 } else { 3066 final ActivityRecord resumed = stack.mResumedActivity; 3067 if (resumed != null && resumed == r) { 3068 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 3069 " state=" + state); 3070 } 3071 if (r != null && (state == ActivityState.INITIALIZING 3072 || state == ActivityState.RESUMED)) { 3073 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 3074 " state=" + state); 3075 } 3076 } 3077 } 3078*/ 3079 } 3080 3081 public void dump(PrintWriter pw, String prefix) { 3082 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3083 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3084 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3085 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 3086 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3087 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3088 } 3089 3090 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3091 return getFocusedStack().getDumpActivitiesLocked(name); 3092 } 3093 3094 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3095 boolean needSep, String prefix) { 3096 if (activity != null) { 3097 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3098 if (needSep) { 3099 pw.println(); 3100 } 3101 pw.print(prefix); 3102 pw.println(activity); 3103 return true; 3104 } 3105 } 3106 return false; 3107 } 3108 3109 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3110 boolean dumpClient, String dumpPackage) { 3111 boolean printed = false; 3112 boolean needSep = false; 3113 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3114 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3115 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3116 pw.println(" (activities from top to bottom):"); 3117 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3118 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3119 final ActivityStack stack = stacks.get(stackNdx); 3120 StringBuilder stackHeader = new StringBuilder(128); 3121 stackHeader.append(" Stack #"); 3122 stackHeader.append(stack.mStackId); 3123 stackHeader.append(":"); 3124 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3125 needSep, stackHeader.toString()); 3126 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3127 !dumpAll, false, dumpPackage, true, 3128 " Running activities (most recent first):", null); 3129 3130 needSep = printed; 3131 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3132 " mPausingActivity: "); 3133 if (pr) { 3134 printed = true; 3135 needSep = false; 3136 } 3137 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3138 " mResumedActivity: "); 3139 if (pr) { 3140 printed = true; 3141 needSep = false; 3142 } 3143 if (dumpAll) { 3144 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3145 " mLastPausedActivity: "); 3146 if (pr) { 3147 printed = true; 3148 needSep = true; 3149 } 3150 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3151 needSep, " mLastNoHistoryActivity: "); 3152 } 3153 needSep = printed; 3154 } 3155 } 3156 3157 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3158 false, dumpPackage, true, " Activities waiting to finish:", null); 3159 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3160 false, dumpPackage, true, " Activities waiting to stop:", null); 3161 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3162 false, dumpPackage, true, " Activities waiting for another to become visible:", 3163 null); 3164 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3165 false, dumpPackage, true, " Activities waiting to sleep:", null); 3166 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3167 false, dumpPackage, true, " Activities waiting to sleep:", null); 3168 3169 return printed; 3170 } 3171 3172 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3173 String prefix, String label, boolean complete, boolean brief, boolean client, 3174 String dumpPackage, boolean needNL, String header1, String header2) { 3175 TaskRecord lastTask = null; 3176 String innerPrefix = null; 3177 String[] args = null; 3178 boolean printed = false; 3179 for (int i=list.size()-1; i>=0; i--) { 3180 final ActivityRecord r = list.get(i); 3181 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3182 continue; 3183 } 3184 if (innerPrefix == null) { 3185 innerPrefix = prefix + " "; 3186 args = new String[0]; 3187 } 3188 printed = true; 3189 final boolean full = !brief && (complete || !r.isInHistory()); 3190 if (needNL) { 3191 pw.println(""); 3192 needNL = false; 3193 } 3194 if (header1 != null) { 3195 pw.println(header1); 3196 header1 = null; 3197 } 3198 if (header2 != null) { 3199 pw.println(header2); 3200 header2 = null; 3201 } 3202 if (lastTask != r.task) { 3203 lastTask = r.task; 3204 pw.print(prefix); 3205 pw.print(full ? "* " : " "); 3206 pw.println(lastTask); 3207 if (full) { 3208 lastTask.dump(pw, prefix + " "); 3209 } else if (complete) { 3210 // Complete + brief == give a summary. Isn't that obvious?!? 3211 if (lastTask.intent != null) { 3212 pw.print(prefix); pw.print(" "); 3213 pw.println(lastTask.intent.toInsecureStringWithClip()); 3214 } 3215 } 3216 } 3217 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3218 pw.print(" #"); pw.print(i); pw.print(": "); 3219 pw.println(r); 3220 if (full) { 3221 r.dump(pw, innerPrefix); 3222 } else if (complete) { 3223 // Complete + brief == give a summary. Isn't that obvious?!? 3224 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3225 if (r.app != null) { 3226 pw.print(innerPrefix); pw.println(r.app); 3227 } 3228 } 3229 if (client && r.app != null && r.app.thread != null) { 3230 // flush anything that is already in the PrintWriter since the thread is going 3231 // to write to the file descriptor directly 3232 pw.flush(); 3233 try { 3234 TransferPipe tp = new TransferPipe(); 3235 try { 3236 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3237 r.appToken, innerPrefix, args); 3238 // Short timeout, since blocking here can 3239 // deadlock with the application. 3240 tp.go(fd, 2000); 3241 } finally { 3242 tp.kill(); 3243 } 3244 } catch (IOException e) { 3245 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3246 } catch (RemoteException e) { 3247 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3248 } 3249 needNL = true; 3250 } 3251 } 3252 return printed; 3253 } 3254 3255 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3256 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3257 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3258 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3259 } 3260 3261 final void scheduleIdleLocked() { 3262 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3263 } 3264 3265 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3266 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 3267 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3268 } 3269 3270 final void scheduleResumeTopActivities() { 3271 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3272 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3273 } 3274 } 3275 3276 void removeSleepTimeouts() { 3277 mSleepTimeout = false; 3278 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3279 } 3280 3281 final void scheduleSleepTimeout() { 3282 removeSleepTimeouts(); 3283 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3284 } 3285 3286 @Override 3287 public void onDisplayAdded(int displayId) { 3288 Slog.v(TAG, "Display added displayId=" + displayId); 3289 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3290 } 3291 3292 @Override 3293 public void onDisplayRemoved(int displayId) { 3294 Slog.v(TAG, "Display removed displayId=" + displayId); 3295 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3296 } 3297 3298 @Override 3299 public void onDisplayChanged(int displayId) { 3300 Slog.v(TAG, "Display changed displayId=" + displayId); 3301 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3302 } 3303 3304 public void handleDisplayAddedLocked(int displayId) { 3305 boolean newDisplay; 3306 synchronized (mService) { 3307 newDisplay = mActivityDisplays.get(displayId) == null; 3308 if (newDisplay) { 3309 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3310 if (activityDisplay.mDisplay == null) { 3311 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3312 return; 3313 } 3314 mActivityDisplays.put(displayId, activityDisplay); 3315 } 3316 } 3317 if (newDisplay) { 3318 mWindowManager.onDisplayAdded(displayId); 3319 } 3320 } 3321 3322 public void handleDisplayRemovedLocked(int displayId) { 3323 synchronized (mService) { 3324 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3325 if (activityDisplay != null) { 3326 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3327 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3328 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3329 } 3330 mActivityDisplays.remove(displayId); 3331 } 3332 } 3333 mWindowManager.onDisplayRemoved(displayId); 3334 } 3335 3336 public void handleDisplayChangedLocked(int displayId) { 3337 synchronized (mService) { 3338 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3339 if (activityDisplay != null) { 3340 // TODO: Update the bounds. 3341 } 3342 } 3343 mWindowManager.onDisplayChanged(displayId); 3344 } 3345 3346 StackInfo getStackInfo(ActivityStack stack) { 3347 StackInfo info = new StackInfo(); 3348 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3349 info.displayId = Display.DEFAULT_DISPLAY; 3350 info.stackId = stack.mStackId; 3351 3352 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3353 final int numTasks = tasks.size(); 3354 int[] taskIds = new int[numTasks]; 3355 String[] taskNames = new String[numTasks]; 3356 for (int i = 0; i < numTasks; ++i) { 3357 final TaskRecord task = tasks.get(i); 3358 taskIds[i] = task.taskId; 3359 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3360 : task.realActivity != null ? task.realActivity.flattenToString() 3361 : task.getTopActivity() != null ? task.getTopActivity().packageName 3362 : "unknown"; 3363 } 3364 info.taskIds = taskIds; 3365 info.taskNames = taskNames; 3366 return info; 3367 } 3368 3369 StackInfo getStackInfoLocked(int stackId) { 3370 ActivityStack stack = getStack(stackId); 3371 if (stack != null) { 3372 return getStackInfo(stack); 3373 } 3374 return null; 3375 } 3376 3377 ArrayList<StackInfo> getAllStackInfosLocked() { 3378 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 3379 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3380 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3381 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3382 list.add(getStackInfo(stacks.get(ndx))); 3383 } 3384 } 3385 return list; 3386 } 3387 3388 void showLockTaskToast() { 3389 mLockTaskNotify.showToast(mLockTaskIsLocked); 3390 } 3391 3392 void setLockTaskModeLocked(TaskRecord task, boolean isLocked) { 3393 if (task == null) { 3394 // Take out of lock task mode if necessary 3395 if (mLockTaskModeTask != null) { 3396 final Message lockTaskMsg = Message.obtain(); 3397 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3398 lockTaskMsg.what = LOCK_TASK_END_MSG; 3399 mLockTaskModeTask = null; 3400 mHandler.sendMessage(lockTaskMsg); 3401 } 3402 return; 3403 } 3404 if (isLockTaskModeViolation(task)) { 3405 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 3406 return; 3407 } 3408 mLockTaskModeTask = task; 3409 findTaskToMoveToFrontLocked(task, 0, null); 3410 resumeTopActivitiesLocked(); 3411 3412 final Message lockTaskMsg = Message.obtain(); 3413 lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName(); 3414 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3415 lockTaskMsg.what = LOCK_TASK_START_MSG; 3416 lockTaskMsg.arg2 = !isLocked ? 1 : 0; 3417 mHandler.sendMessage(lockTaskMsg); 3418 } 3419 3420 boolean isLockTaskModeViolation(TaskRecord task) { 3421 return mLockTaskModeTask != null && mLockTaskModeTask != task; 3422 } 3423 3424 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3425 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3426 final Message lockTaskMsg = Message.obtain(); 3427 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3428 lockTaskMsg.what = LOCK_TASK_END_MSG; 3429 mLockTaskModeTask = null; 3430 mHandler.sendMessage(lockTaskMsg); 3431 } 3432 } 3433 3434 boolean isInLockTaskMode() { 3435 return mLockTaskModeTask != null; 3436 } 3437 3438 private final class ActivityStackSupervisorHandler extends Handler { 3439 3440 public ActivityStackSupervisorHandler(Looper looper) { 3441 super(looper); 3442 } 3443 3444 void activityIdleInternal(ActivityRecord r) { 3445 synchronized (mService) { 3446 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3447 } 3448 } 3449 3450 @Override 3451 public void handleMessage(Message msg) { 3452 switch (msg.what) { 3453 case IDLE_TIMEOUT_MSG: { 3454 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3455 if (mService.mDidDexOpt) { 3456 mService.mDidDexOpt = false; 3457 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3458 nmsg.obj = msg.obj; 3459 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3460 return; 3461 } 3462 // We don't at this point know if the activity is fullscreen, 3463 // so we need to be conservative and assume it isn't. 3464 activityIdleInternal((ActivityRecord)msg.obj); 3465 } break; 3466 case IDLE_NOW_MSG: { 3467 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3468 activityIdleInternal((ActivityRecord)msg.obj); 3469 } break; 3470 case RESUME_TOP_ACTIVITY_MSG: { 3471 synchronized (mService) { 3472 resumeTopActivitiesLocked(); 3473 } 3474 } break; 3475 case SLEEP_TIMEOUT_MSG: { 3476 synchronized (mService) { 3477 if (mService.isSleepingOrShuttingDown()) { 3478 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3479 mSleepTimeout = true; 3480 checkReadyForSleepLocked(); 3481 } 3482 } 3483 } break; 3484 case LAUNCH_TIMEOUT_MSG: { 3485 if (mService.mDidDexOpt) { 3486 mService.mDidDexOpt = false; 3487 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3488 return; 3489 } 3490 synchronized (mService) { 3491 if (mLaunchingActivity.isHeld()) { 3492 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3493 if (VALIDATE_WAKE_LOCK_CALLER 3494 && Binder.getCallingUid() != Process.myUid()) { 3495 throw new IllegalStateException("Calling must be system uid"); 3496 } 3497 mLaunchingActivity.release(); 3498 } 3499 } 3500 } break; 3501 case HANDLE_DISPLAY_ADDED: { 3502 handleDisplayAddedLocked(msg.arg1); 3503 } break; 3504 case HANDLE_DISPLAY_CHANGED: { 3505 handleDisplayChangedLocked(msg.arg1); 3506 } break; 3507 case HANDLE_DISPLAY_REMOVED: { 3508 handleDisplayRemovedLocked(msg.arg1); 3509 } break; 3510 case CONTAINER_CALLBACK_VISIBILITY: { 3511 final ActivityContainer container = (ActivityContainer) msg.obj; 3512 final IActivityContainerCallback callback = container.mCallback; 3513 if (callback != null) { 3514 try { 3515 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3516 } catch (RemoteException e) { 3517 } 3518 } 3519 } break; 3520 case LOCK_TASK_START_MSG: { 3521 // When lock task starts, we disable the status bars. 3522 try { 3523 if (mLockTaskNotify == null) { 3524 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3525 } 3526 mLockTaskNotify.show(true); 3527 mLockTaskIsLocked = msg.arg2 == 0; 3528 if (getStatusBarService() != null) { 3529 int flags = 3530 StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK; 3531 if (!mLockTaskIsLocked) { 3532 flags ^= StatusBarManager.DISABLE_HOME 3533 | StatusBarManager.DISABLE_RECENT; 3534 } 3535 getStatusBarService().disable(flags, mToken, 3536 mService.mContext.getPackageName()); 3537 } 3538 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3539 if (getDevicePolicyManager() != null) { 3540 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3541 (String)msg.obj, msg.arg1); 3542 } 3543 } catch (RemoteException ex) { 3544 throw new RuntimeException(ex); 3545 } 3546 } break; 3547 case LOCK_TASK_END_MSG: { 3548 // When lock task ends, we enable the status bars. 3549 try { 3550 if (getStatusBarService() != null) { 3551 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3552 mService.mContext.getPackageName()); 3553 } 3554 mWindowManager.reenableKeyguard(mToken); 3555 if (getDevicePolicyManager() != null) { 3556 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3557 msg.arg1); 3558 } 3559 if (mLockTaskNotify == null) { 3560 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3561 } 3562 mLockTaskNotify.show(false); 3563 try { 3564 boolean shouldLockKeyguard = Settings.Secure.getInt( 3565 mService.mContext.getContentResolver(), 3566 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3567 if (!mLockTaskIsLocked && shouldLockKeyguard) { 3568 mWindowManager.lockNow(null); 3569 mWindowManager.dismissKeyguard(); 3570 new LockPatternUtils(mService.mContext) 3571 .requireCredentialEntry(UserHandle.USER_ALL); 3572 } 3573 } catch (SettingNotFoundException e) { 3574 // No setting, don't lock. 3575 } 3576 } catch (RemoteException ex) { 3577 throw new RuntimeException(ex); 3578 } 3579 } break; 3580 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3581 final ActivityContainer container = (ActivityContainer) msg.obj; 3582 final IActivityContainerCallback callback = container.mCallback; 3583 if (callback != null) { 3584 try { 3585 callback.onAllActivitiesComplete(container.asBinder()); 3586 } catch (RemoteException e) { 3587 } 3588 } 3589 } break; 3590 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 3591 synchronized (mService) { 3592 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 3593 msg.obj); 3594 final ActivityContainer container = (ActivityContainer) msg.obj; 3595 container.mStack.finishAllActivitiesLocked(true); 3596 container.onTaskListEmptyLocked(); 3597 } 3598 } break; 3599 case LAUNCH_TASK_BEHIND_COMPLETE: { 3600 synchronized (mService) { 3601 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 3602 if (r != null) { 3603 handleLaunchTaskBehindCompleteLocked(r); 3604 } 3605 } 3606 } break; 3607 } 3608 } 3609 } 3610 3611 class ActivityContainer extends android.app.IActivityContainer.Stub { 3612 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3613 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3614 final int mStackId; 3615 IActivityContainerCallback mCallback = null; 3616 final ActivityStack mStack; 3617 ActivityRecord mParentActivity = null; 3618 String mIdString; 3619 3620 boolean mVisible = true; 3621 3622 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3623 ActivityDisplay mActivityDisplay; 3624 3625 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3626 final static int CONTAINER_STATE_NO_SURFACE = 1; 3627 final static int CONTAINER_STATE_FINISHING = 2; 3628 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3629 3630 ActivityContainer(int stackId) { 3631 synchronized (mService) { 3632 mStackId = stackId; 3633 mStack = new ActivityStack(this); 3634 mIdString = "ActivtyContainer{" + mStackId + "}"; 3635 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3636 } 3637 } 3638 3639 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3640 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3641 + " to display=" + activityDisplay); 3642 mActivityDisplay = activityDisplay; 3643 mStack.mDisplayId = activityDisplay.mDisplayId; 3644 mStack.mStacks = activityDisplay.mStacks; 3645 3646 activityDisplay.attachActivities(mStack); 3647 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3648 } 3649 3650 @Override 3651 public void attachToDisplay(int displayId) { 3652 synchronized (mService) { 3653 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3654 if (activityDisplay == null) { 3655 return; 3656 } 3657 attachToDisplayLocked(activityDisplay); 3658 } 3659 } 3660 3661 @Override 3662 public int getDisplayId() { 3663 synchronized (mService) { 3664 if (mActivityDisplay != null) { 3665 return mActivityDisplay.mDisplayId; 3666 } 3667 } 3668 return -1; 3669 } 3670 3671 @Override 3672 public boolean injectEvent(InputEvent event) { 3673 final long origId = Binder.clearCallingIdentity(); 3674 try { 3675 synchronized (mService) { 3676 if (mActivityDisplay != null) { 3677 return mInputManagerInternal.injectInputEvent(event, 3678 mActivityDisplay.mDisplayId, 3679 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3680 } 3681 } 3682 return false; 3683 } finally { 3684 Binder.restoreCallingIdentity(origId); 3685 } 3686 } 3687 3688 @Override 3689 public void release() { 3690 synchronized (mService) { 3691 if (mContainerState == CONTAINER_STATE_FINISHING) { 3692 return; 3693 } 3694 mContainerState = CONTAINER_STATE_FINISHING; 3695 3696 final Message msg = 3697 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3698 mHandler.sendMessageDelayed(msg, 2000); 3699 3700 long origId = Binder.clearCallingIdentity(); 3701 try { 3702 mStack.finishAllActivitiesLocked(false); 3703 removePendingActivityLaunchesLocked(mStack); 3704 } finally { 3705 Binder.restoreCallingIdentity(origId); 3706 } 3707 } 3708 } 3709 3710 protected void detachLocked() { 3711 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3712 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3713 if (mActivityDisplay != null) { 3714 mActivityDisplay.detachActivitiesLocked(mStack); 3715 mActivityDisplay = null; 3716 mStack.mDisplayId = -1; 3717 mStack.mStacks = null; 3718 mWindowManager.detachStack(mStackId); 3719 } 3720 } 3721 3722 @Override 3723 public final int startActivity(Intent intent) { 3724 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3725 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3726 Binder.getCallingUid(), mCurrentUser, false, 3727 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3728 // TODO: Switch to user app stacks here. 3729 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3730 String mimeType = intent.getType(); 3731 if (mimeType == null && intent.getData() != null 3732 && "content".equals(intent.getData().getScheme())) { 3733 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3734 } 3735 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 3736 0, null, null, null, null, userId, this, null); 3737 } 3738 3739 @Override 3740 public final int startActivityIntentSender(IIntentSender intentSender) { 3741 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3742 3743 if (!(intentSender instanceof PendingIntentRecord)) { 3744 throw new IllegalArgumentException("Bad PendingIntent object"); 3745 } 3746 3747 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3748 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3749 } 3750 3751 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3752 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3753 Binder.getCallingUid(), mCurrentUser, false, 3754 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3755 if (resolvedType == null) { 3756 resolvedType = intent.getType(); 3757 if (resolvedType == null && intent.getData() != null 3758 && "content".equals(intent.getData().getScheme())) { 3759 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3760 } 3761 } 3762 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 3763 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3764 throw new SecurityException( 3765 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3766 } 3767 } 3768 3769 /** Throw a SecurityException if allowEmbedded is not true */ 3770 @Override 3771 public final void checkEmbeddedAllowed(Intent intent) { 3772 checkEmbeddedAllowedInner(intent, null); 3773 } 3774 3775 /** Throw a SecurityException if allowEmbedded is not true */ 3776 @Override 3777 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3778 if (!(intentSender instanceof PendingIntentRecord)) { 3779 throw new IllegalArgumentException("Bad PendingIntent object"); 3780 } 3781 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3782 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3783 pendingIntent.key.requestResolvedType); 3784 } 3785 3786 @Override 3787 public IBinder asBinder() { 3788 return this; 3789 } 3790 3791 @Override 3792 public void setSurface(Surface surface, int width, int height, int density) { 3793 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3794 } 3795 3796 ActivityStackSupervisor getOuter() { 3797 return ActivityStackSupervisor.this; 3798 } 3799 3800 boolean isAttachedLocked() { 3801 return mActivityDisplay != null; 3802 } 3803 3804 void getBounds(Point outBounds) { 3805 synchronized (mService) { 3806 if (mActivityDisplay != null) { 3807 mActivityDisplay.getBounds(outBounds); 3808 } else { 3809 outBounds.set(0, 0); 3810 } 3811 } 3812 } 3813 3814 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3815 void setVisible(boolean visible) { 3816 if (mVisible != visible) { 3817 mVisible = visible; 3818 if (mCallback != null) { 3819 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3820 0 /* unused */, this).sendToTarget(); 3821 } 3822 } 3823 } 3824 3825 void setDrawn() { 3826 } 3827 3828 // You can always start a new task on a regular ActivityStack. 3829 boolean isEligibleForNewTasks() { 3830 return true; 3831 } 3832 3833 void onTaskListEmptyLocked() { 3834 } 3835 3836 @Override 3837 public String toString() { 3838 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3839 } 3840 } 3841 3842 private class VirtualActivityContainer extends ActivityContainer { 3843 Surface mSurface; 3844 boolean mDrawn = false; 3845 3846 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3847 super(getNextStackId()); 3848 mParentActivity = parent; 3849 mCallback = callback; 3850 mContainerState = CONTAINER_STATE_NO_SURFACE; 3851 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3852 } 3853 3854 @Override 3855 public void setSurface(Surface surface, int width, int height, int density) { 3856 super.setSurface(surface, width, height, density); 3857 3858 synchronized (mService) { 3859 final long origId = Binder.clearCallingIdentity(); 3860 try { 3861 setSurfaceLocked(surface, width, height, density); 3862 } finally { 3863 Binder.restoreCallingIdentity(origId); 3864 } 3865 } 3866 } 3867 3868 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3869 if (mContainerState == CONTAINER_STATE_FINISHING) { 3870 return; 3871 } 3872 VirtualActivityDisplay virtualActivityDisplay = 3873 (VirtualActivityDisplay) mActivityDisplay; 3874 if (virtualActivityDisplay == null) { 3875 virtualActivityDisplay = 3876 new VirtualActivityDisplay(width, height, density); 3877 mActivityDisplay = virtualActivityDisplay; 3878 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3879 attachToDisplayLocked(virtualActivityDisplay); 3880 } 3881 3882 if (mSurface != null) { 3883 mSurface.release(); 3884 } 3885 3886 mSurface = surface; 3887 if (surface != null) { 3888 mStack.resumeTopActivityLocked(null); 3889 } else { 3890 mContainerState = CONTAINER_STATE_NO_SURFACE; 3891 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3892 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3893 mStack.startPausingLocked(false, true, false, false); 3894 } 3895 } 3896 3897 setSurfaceIfReadyLocked(); 3898 3899 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3900 + virtualActivityDisplay); 3901 } 3902 3903 @Override 3904 boolean isAttachedLocked() { 3905 return mSurface != null && super.isAttachedLocked(); 3906 } 3907 3908 @Override 3909 void setDrawn() { 3910 synchronized (mService) { 3911 mDrawn = true; 3912 setSurfaceIfReadyLocked(); 3913 } 3914 } 3915 3916 // Never start a new task on an ActivityView if it isn't explicitly specified. 3917 @Override 3918 boolean isEligibleForNewTasks() { 3919 return false; 3920 } 3921 3922 void onTaskListEmptyLocked() { 3923 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3924 detachLocked(); 3925 deleteActivityContainer(this); 3926 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3927 } 3928 3929 private void setSurfaceIfReadyLocked() { 3930 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3931 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3932 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3933 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3934 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3935 } 3936 } 3937 } 3938 3939 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3940 * attached {@link ActivityStack}s */ 3941 class ActivityDisplay { 3942 /** Actual Display this object tracks. */ 3943 int mDisplayId; 3944 Display mDisplay; 3945 DisplayInfo mDisplayInfo = new DisplayInfo(); 3946 3947 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3948 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3949 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3950 3951 ActivityRecord mVisibleBehindActivity; 3952 3953 ActivityDisplay() { 3954 } 3955 3956 // After instantiation, check that mDisplay is not null before using this. The alternative 3957 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 3958 ActivityDisplay(int displayId) { 3959 final Display display = mDisplayManager.getDisplay(displayId); 3960 if (display == null) { 3961 return; 3962 } 3963 init(display); 3964 } 3965 3966 void init(Display display) { 3967 mDisplay = display; 3968 mDisplayId = display.getDisplayId(); 3969 mDisplay.getDisplayInfo(mDisplayInfo); 3970 } 3971 3972 void attachActivities(ActivityStack stack) { 3973 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3974 + mDisplayId); 3975 mStacks.add(stack); 3976 } 3977 3978 void detachActivitiesLocked(ActivityStack stack) { 3979 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3980 + " from displayId=" + mDisplayId); 3981 mStacks.remove(stack); 3982 } 3983 3984 void getBounds(Point bounds) { 3985 mDisplay.getDisplayInfo(mDisplayInfo); 3986 bounds.x = mDisplayInfo.appWidth; 3987 bounds.y = mDisplayInfo.appHeight; 3988 } 3989 3990 void setVisibleBehindActivity(ActivityRecord r) { 3991 mVisibleBehindActivity = r; 3992 } 3993 3994 boolean hasVisibleBehindActivity() { 3995 return mVisibleBehindActivity != null; 3996 } 3997 3998 @Override 3999 public String toString() { 4000 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4001 } 4002 } 4003 4004 class VirtualActivityDisplay extends ActivityDisplay { 4005 VirtualDisplay mVirtualDisplay; 4006 4007 VirtualActivityDisplay(int width, int height, int density) { 4008 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4009 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4010 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4011 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4012 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4013 4014 init(mVirtualDisplay.getDisplay()); 4015 4016 mWindowManager.handleDisplayAdded(mDisplayId); 4017 } 4018 4019 void setSurface(Surface surface) { 4020 if (mVirtualDisplay != null) { 4021 mVirtualDisplay.setSurface(surface); 4022 } 4023 } 4024 4025 @Override 4026 void detachActivitiesLocked(ActivityStack stack) { 4027 super.detachActivitiesLocked(stack); 4028 if (mVirtualDisplay != null) { 4029 mVirtualDisplay.release(); 4030 mVirtualDisplay = null; 4031 } 4032 } 4033 4034 @Override 4035 public String toString() { 4036 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4037 } 4038 } 4039 4040 private boolean isLeanbackOnlyDevice() { 4041 boolean onLeanbackOnly = false; 4042 try { 4043 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 4044 PackageManager.FEATURE_LEANBACK_ONLY); 4045 } catch (RemoteException e) { 4046 // noop 4047 } 4048 4049 return onLeanbackOnly; 4050 } 4051} 4052