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