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