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