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