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