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