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