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