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