ActivityStackSupervisor.java revision 962d535464eb79b11c346236f6889ad76a966e56
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 addingToTask = true; 1733 1734 // If the task is not empty and the caller is asking to start it as the root 1735 // of a new task, then we don't actually want to start this on the task. We 1736 // will bring the task to the front, and possibly give it a new intent. 1737 } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1738 addingToTask = false; 1739 1740 } else { 1741 addingToTask = true; 1742 } 1743 1744 reuseTask = inTask; 1745 } else { 1746 inTask = null; 1747 } 1748 1749 // We may want to try to place the new activity in to an existing task. We always 1750 // do this if the target activity is singleTask or singleInstance; we will also do 1751 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 1752 // us to still place it in a new task: multi task, always doc mode, or being asked to 1753 // launch this as a new task behind the current one. 1754 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1755 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1756 || launchSingleInstance || launchSingleTask) { 1757 // If bring to front is requested, and no result is requested and we have not 1758 // been given an explicit task to launch in to, and 1759 // we can find a task that was started with this same 1760 // component, then instead of launching bring that one to the front. 1761 if (inTask == null && r.resultTo == null) { 1762 // See if there is a task to bring to the front. If this is 1763 // a SINGLE_INSTANCE activity, there can be one and only one 1764 // instance of it in the history, and it is always in its own 1765 // unique task, so we do a special search. 1766 ActivityRecord intentActivity = !launchSingleInstance ? 1767 findTaskLocked(r) : findActivityLocked(intent, r.info); 1768 if (intentActivity != null) { 1769 if (isLockTaskModeViolation(intentActivity.task)) { 1770 showLockTaskToast(); 1771 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1772 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1773 } 1774 if (r.task == null) { 1775 r.task = intentActivity.task; 1776 } 1777 targetStack = intentActivity.task.stack; 1778 targetStack.mLastPausedActivity = null; 1779 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1780 + " from " + intentActivity); 1781 targetStack.moveToFront(); 1782 if (intentActivity.task.intent == null) { 1783 // This task was started because of movement of 1784 // the activity based on affinity... now that we 1785 // are actually launching it, we can assign the 1786 // base intent. 1787 intentActivity.task.setIntent(r); 1788 } 1789 // If the target task is not in the front, then we need 1790 // to bring it to the front... except... well, with 1791 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1792 // to have the same behavior as if a new instance was 1793 // being started, which means not bringing it to the front 1794 // if the caller is not itself in the front. 1795 final ActivityStack lastStack = getLastStack(); 1796 ActivityRecord curTop = lastStack == null? 1797 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1798 if (curTop != null && (curTop.task != intentActivity.task || 1799 curTop.task != lastStack.topTask())) { 1800 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1801 if (sourceRecord == null || (sourceStack.topActivity() != null && 1802 sourceStack.topActivity().task == sourceRecord.task)) { 1803 // We really do want to push this one into the 1804 // user's face, right now. 1805 if (launchTaskBehind && sourceRecord != null) { 1806 intentActivity.setTaskToAffiliateWith(sourceRecord.task); 1807 } 1808 movedHome = true; 1809 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1810 if ((launchFlags & 1811 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1812 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1813 // Caller wants to appear on home activity. 1814 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1815 } 1816 options = null; 1817 } 1818 } 1819 // If the caller has requested that the target task be 1820 // reset, then do so. 1821 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1822 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1823 } 1824 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1825 // We don't need to start a new activity, and 1826 // the client said not to do anything if that 1827 // is the case, so this is it! And for paranoia, make 1828 // sure we have correctly resumed the top activity. 1829 if (doResume) { 1830 resumeTopActivitiesLocked(targetStack, null, options); 1831 } else { 1832 ActivityOptions.abort(options); 1833 } 1834 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1835 } 1836 if ((launchFlags & 1837 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1838 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1839 // The caller has requested to completely replace any 1840 // existing task with its new activity. Well that should 1841 // not be too hard... 1842 reuseTask = intentActivity.task; 1843 reuseTask.performClearTaskLocked(); 1844 reuseTask.setIntent(r); 1845 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1846 || launchSingleInstance || launchSingleTask) { 1847 // In this situation we want to remove all activities 1848 // from the task up to the one being started. In most 1849 // cases this means we are resetting the task to its 1850 // initial state. 1851 ActivityRecord top = 1852 intentActivity.task.performClearTaskLocked(r, launchFlags); 1853 if (top != null) { 1854 if (top.frontOfTask) { 1855 // Activity aliases may mean we use different 1856 // intents for the top activity, so make sure 1857 // the task now has the identity of the new 1858 // intent. 1859 top.task.setIntent(r); 1860 } 1861 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1862 r, top.task); 1863 top.deliverNewIntentLocked(callingUid, r.intent); 1864 } else { 1865 // A special case: we need to 1866 // start the activity because it is not currently 1867 // running, and the caller has asked to clear the 1868 // current task to have this activity at the top. 1869 addingToTask = true; 1870 // Now pretend like this activity is being started 1871 // by the top of its task, so it is put in the 1872 // right place. 1873 sourceRecord = intentActivity; 1874 } 1875 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1876 // In this case the top activity on the task is the 1877 // same as the one being launched, so we take that 1878 // as a request to bring the task to the foreground. 1879 // If the top activity in the task is the root 1880 // activity, deliver this new intent to it if it 1881 // desires. 1882 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop) 1883 && intentActivity.realActivity.equals(r.realActivity)) { 1884 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1885 intentActivity.task); 1886 if (intentActivity.frontOfTask) { 1887 intentActivity.task.setIntent(r); 1888 } 1889 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1890 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1891 // In this case we are launching the root activity 1892 // of the task, but with a different intent. We 1893 // should start a new instance on top. 1894 addingToTask = true; 1895 sourceRecord = intentActivity; 1896 } 1897 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1898 // In this case an activity is being launched in to an 1899 // existing task, without resetting that task. This 1900 // is typically the situation of launching an activity 1901 // from a notification or shortcut. We want to place 1902 // the new activity on top of the current task. 1903 addingToTask = true; 1904 sourceRecord = intentActivity; 1905 } else if (!intentActivity.task.rootWasReset) { 1906 // In this case we are launching in to an existing task 1907 // that has not yet been started from its front door. 1908 // The current task has been brought to the front. 1909 // Ideally, we'd probably like to place this new task 1910 // at the bottom of its stack, but that's a little hard 1911 // to do with the current organization of the code so 1912 // for now we'll just drop it. 1913 intentActivity.task.setIntent(r); 1914 } 1915 if (!addingToTask && reuseTask == null) { 1916 // We didn't do anything... but it was needed (a.k.a., client 1917 // don't use that intent!) And for paranoia, make 1918 // sure we have correctly resumed the top activity. 1919 if (doResume) { 1920 targetStack.resumeTopActivityLocked(null, options); 1921 } else { 1922 ActivityOptions.abort(options); 1923 } 1924 return ActivityManager.START_TASK_TO_FRONT; 1925 } 1926 } 1927 } 1928 } 1929 1930 //String uri = r.intent.toURI(); 1931 //Intent intent2 = new Intent(uri); 1932 //Slog.i(TAG, "Given intent: " + r.intent); 1933 //Slog.i(TAG, "URI is: " + uri); 1934 //Slog.i(TAG, "To intent: " + intent2); 1935 1936 if (r.packageName != null) { 1937 // If the activity being launched is the same as the one currently 1938 // at the top, then we need to check if it should only be launched 1939 // once. 1940 ActivityStack topStack = getFocusedStack(); 1941 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1942 if (top != null && r.resultTo == null) { 1943 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1944 if (top.app != null && top.app.thread != null) { 1945 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1946 || launchSingleTop || launchSingleTask) { 1947 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1948 top.task); 1949 // For paranoia, make sure we have correctly 1950 // resumed the top activity. 1951 topStack.mLastPausedActivity = null; 1952 if (doResume) { 1953 resumeTopActivitiesLocked(); 1954 } 1955 ActivityOptions.abort(options); 1956 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1957 // We don't need to start a new activity, and 1958 // the client said not to do anything if that 1959 // is the case, so this is it! 1960 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1961 } 1962 top.deliverNewIntentLocked(callingUid, r.intent); 1963 return ActivityManager.START_DELIVERED_TO_TOP; 1964 } 1965 } 1966 } 1967 } 1968 1969 } else { 1970 if (r.resultTo != null) { 1971 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1972 r.requestCode, Activity.RESULT_CANCELED, null); 1973 } 1974 ActivityOptions.abort(options); 1975 return ActivityManager.START_CLASS_NOT_FOUND; 1976 } 1977 1978 boolean newTask = false; 1979 boolean keepCurTransition = false; 1980 1981 TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ? 1982 sourceRecord.task : null; 1983 1984 // Should this be considered a new task? 1985 if (r.resultTo == null && inTask == null && !addingToTask 1986 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1987 if (isLockTaskModeViolation(reuseTask)) { 1988 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1989 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1990 } 1991 newTask = true; 1992 targetStack = adjustStackFocus(r, newTask); 1993 if (!launchTaskBehind) { 1994 targetStack.moveToFront(); 1995 } 1996 if (reuseTask == null) { 1997 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1998 newTaskInfo != null ? newTaskInfo : r.info, 1999 newTaskIntent != null ? newTaskIntent : intent, 2000 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */), 2001 taskToAffiliate); 2002 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 2003 r.task); 2004 } else { 2005 r.setTask(reuseTask, taskToAffiliate); 2006 } 2007 if (!movedHome) { 2008 if ((launchFlags & 2009 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 2010 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 2011 // Caller wants to appear on home activity, so before starting 2012 // their own activity we will bring home to the front. 2013 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2014 } 2015 } 2016 } else if (sourceRecord != null) { 2017 final TaskRecord sourceTask = sourceRecord.task; 2018 if (isLockTaskModeViolation(sourceTask)) { 2019 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2020 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2021 } 2022 targetStack = sourceTask.stack; 2023 targetStack.moveToFront(); 2024 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 2025 if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 2026 // In this case, we are adding the activity to an existing 2027 // task, but the caller has asked to clear that task if the 2028 // activity is already running. 2029 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 2030 keepCurTransition = true; 2031 if (top != null) { 2032 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 2033 top.deliverNewIntentLocked(callingUid, r.intent); 2034 // For paranoia, make sure we have correctly 2035 // resumed the top activity. 2036 targetStack.mLastPausedActivity = null; 2037 if (doResume) { 2038 targetStack.resumeTopActivityLocked(null); 2039 } 2040 ActivityOptions.abort(options); 2041 return ActivityManager.START_DELIVERED_TO_TOP; 2042 } 2043 } else if (!addingToTask && 2044 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 2045 // In this case, we are launching an activity in our own task 2046 // that may already be running somewhere in the history, and 2047 // we want to shuffle it to the front of the stack if so. 2048 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 2049 if (top != null) { 2050 final TaskRecord task = top.task; 2051 task.moveActivityToFrontLocked(top); 2052 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 2053 top.updateOptionsLocked(options); 2054 top.deliverNewIntentLocked(callingUid, r.intent); 2055 targetStack.mLastPausedActivity = null; 2056 if (doResume) { 2057 targetStack.resumeTopActivityLocked(null); 2058 } 2059 return ActivityManager.START_DELIVERED_TO_TOP; 2060 } 2061 } 2062 // An existing activity is starting this new activity, so we want 2063 // to keep the new one in the same task as the one that is starting 2064 // it. 2065 r.setTask(sourceTask, null); 2066 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2067 + " in existing task " + r.task + " from source " + sourceRecord); 2068 2069 } else if (inTask != null) { 2070 // The calling is asking that the new activity be started in an explicit 2071 // task it has provided to us. 2072 if (isLockTaskModeViolation(inTask)) { 2073 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2074 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2075 } 2076 targetStack = inTask.stack; 2077 targetStack.moveTaskToFrontLocked(inTask, r, options); 2078 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 2079 2080 // Check whether we should actually launch the new activity in to the task, 2081 // or just reuse the current activity on top. 2082 ActivityRecord top = inTask.getTopActivity(); 2083 if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 2084 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 2085 || launchSingleTop || launchSingleTask) { 2086 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 2087 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2088 // We don't need to start a new activity, and 2089 // the client said not to do anything if that 2090 // is the case, so this is it! 2091 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2092 } 2093 top.deliverNewIntentLocked(callingUid, r.intent); 2094 return ActivityManager.START_DELIVERED_TO_TOP; 2095 } 2096 } 2097 2098 if (!addingToTask) { 2099 // We don't actually want to have this activity added to the task, so just 2100 // stop here but still tell the caller that we consumed the intent. 2101 ActivityOptions.abort(options); 2102 return ActivityManager.START_TASK_TO_FRONT; 2103 } 2104 2105 r.setTask(inTask, null); 2106 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2107 + " in explicit task " + r.task); 2108 2109 } else { 2110 // This not being started from an existing activity, and not part 2111 // of a new task... just put it in the top task, though these days 2112 // this case should never happen. 2113 targetStack = adjustStackFocus(r, newTask); 2114 targetStack.moveToFront(); 2115 ActivityRecord prev = targetStack.topActivity(); 2116 r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), 2117 r.info, intent, null, null, true), null); 2118 mWindowManager.moveTaskToTop(r.task.taskId); 2119 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 2120 + " in new guessed " + r.task); 2121 } 2122 2123 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 2124 intent, r.getUriPermissionsLocked(), r.userId); 2125 2126 if (sourceRecord != null && sourceRecord.isRecentsActivity()) { 2127 r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE); 2128 } 2129 if (newTask) { 2130 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 2131 } 2132 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 2133 targetStack.mLastPausedActivity = null; 2134 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 2135 if (!launchTaskBehind) { 2136 // Don't set focus on an activity that's going to the back. 2137 mService.setFocusedActivityLocked(r); 2138 } 2139 return ActivityManager.START_SUCCESS; 2140 } 2141 2142 final void doPendingActivityLaunchesLocked(boolean doResume) { 2143 while (!mPendingActivityLaunches.isEmpty()) { 2144 PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); 2145 startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 2146 doResume && mPendingActivityLaunches.isEmpty(), null, null); 2147 } 2148 } 2149 2150 void removePendingActivityLaunchesLocked(ActivityStack stack) { 2151 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) { 2152 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx); 2153 if (pal.stack == stack) { 2154 mPendingActivityLaunches.remove(palNdx); 2155 } 2156 } 2157 } 2158 2159 void acquireLaunchWakelock() { 2160 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2161 throw new IllegalStateException("Calling must be system uid"); 2162 } 2163 mLaunchingActivity.acquire(); 2164 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2165 // To be safe, don't allow the wake lock to be held for too long. 2166 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2167 } 2168 } 2169 2170 // Checked. 2171 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 2172 Configuration config) { 2173 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 2174 2175 ArrayList<ActivityRecord> stops = null; 2176 ArrayList<ActivityRecord> finishes = null; 2177 ArrayList<UserStartedState> startingUsers = null; 2178 int NS = 0; 2179 int NF = 0; 2180 boolean booting = false; 2181 boolean enableScreen = false; 2182 boolean activityRemoved = false; 2183 2184 ActivityRecord r = ActivityRecord.forToken(token); 2185 if (r != null) { 2186 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 2187 Debug.getCallers(4)); 2188 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2189 r.finishLaunchTickingLocked(); 2190 if (fromTimeout) { 2191 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2192 } 2193 2194 // This is a hack to semi-deal with a race condition 2195 // in the client where it can be constructed with a 2196 // newer configuration from when we asked it to launch. 2197 // We'll update with whatever configuration it now says 2198 // it used to launch. 2199 if (config != null) { 2200 r.configuration = config; 2201 } 2202 2203 // We are now idle. If someone is waiting for a thumbnail from 2204 // us, we can now deliver. 2205 r.idle = true; 2206 2207 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2208 if (!mService.mBooted && isFrontStack(r.task.stack)) { 2209 mService.mBooted = true; 2210 enableScreen = true; 2211 } 2212 } 2213 2214 if (allResumedActivitiesIdle()) { 2215 if (r != null) { 2216 mService.scheduleAppGcsLocked(); 2217 } 2218 2219 if (mLaunchingActivity.isHeld()) { 2220 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2221 if (VALIDATE_WAKE_LOCK_CALLER && 2222 Binder.getCallingUid() != Process.myUid()) { 2223 throw new IllegalStateException("Calling must be system uid"); 2224 } 2225 mLaunchingActivity.release(); 2226 } 2227 ensureActivitiesVisibleLocked(null, 0); 2228 } 2229 2230 // Atomically retrieve all of the other things to do. 2231 stops = processStoppingActivitiesLocked(true); 2232 NS = stops != null ? stops.size() : 0; 2233 if ((NF=mFinishingActivities.size()) > 0) { 2234 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 2235 mFinishingActivities.clear(); 2236 } 2237 2238 booting = mService.mBooting; 2239 mService.mBooting = false; 2240 2241 if (mStartingUsers.size() > 0) { 2242 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 2243 mStartingUsers.clear(); 2244 } 2245 2246 // Stop any activities that are scheduled to do so but have been 2247 // waiting for the next one to start. 2248 for (int i = 0; i < NS; i++) { 2249 r = stops.get(i); 2250 final ActivityStack stack = r.task.stack; 2251 if (r.finishing) { 2252 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2253 } else { 2254 stack.stopActivityLocked(r); 2255 } 2256 } 2257 2258 // Finish any activities that are scheduled to do so but have been 2259 // waiting for the next one to start. 2260 for (int i = 0; i < NF; i++) { 2261 r = finishes.get(i); 2262 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle"); 2263 } 2264 2265 if (booting) { 2266 mService.finishBooting(); 2267 } else { 2268 // Complete user switch 2269 if (startingUsers != null) { 2270 for (int i = 0; i < startingUsers.size(); i++) { 2271 mService.finishUserSwitch(startingUsers.get(i)); 2272 } 2273 } 2274 // Complete starting up of background users 2275 if (mStartingBackgroundUsers.size() > 0) { 2276 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2277 mStartingBackgroundUsers.clear(); 2278 for (int i = 0; i < startingUsers.size(); i++) { 2279 mService.finishUserBoot(startingUsers.get(i)); 2280 } 2281 } 2282 } 2283 2284 mService.trimApplications(); 2285 //dump(); 2286 //mWindowManager.dump(); 2287 2288 if (enableScreen) { 2289 mService.postEnableScreenAfterBootLocked(); 2290 } 2291 2292 if (activityRemoved) { 2293 resumeTopActivitiesLocked(); 2294 } 2295 2296 return r; 2297 } 2298 2299 boolean handleAppDiedLocked(ProcessRecord app) { 2300 boolean hasVisibleActivities = false; 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 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2305 } 2306 } 2307 return hasVisibleActivities; 2308 } 2309 2310 void closeSystemDialogsLocked() { 2311 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2312 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2313 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2314 stacks.get(stackNdx).closeSystemDialogsLocked(); 2315 } 2316 } 2317 } 2318 2319 void removeUserLocked(int userId) { 2320 mUserStackInFront.delete(userId); 2321 } 2322 2323 /** 2324 * @return true if some activity was finished (or would have finished if doit were true). 2325 */ 2326 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2327 boolean didSomething = false; 2328 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2329 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2330 final int numStacks = stacks.size(); 2331 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2332 final ActivityStack stack = stacks.get(stackNdx); 2333 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2334 didSomething = true; 2335 } 2336 } 2337 } 2338 return didSomething; 2339 } 2340 2341 void updatePreviousProcessLocked(ActivityRecord r) { 2342 // Now that this process has stopped, we may want to consider 2343 // it to be the previous app to try to keep around in case 2344 // the user wants to return to it. 2345 2346 // First, found out what is currently the foreground app, so that 2347 // we don't blow away the previous app if this activity is being 2348 // hosted by the process that is actually still the foreground. 2349 ProcessRecord fgApp = null; 2350 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2351 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2352 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2353 final ActivityStack stack = stacks.get(stackNdx); 2354 if (isFrontStack(stack)) { 2355 if (stack.mResumedActivity != null) { 2356 fgApp = stack.mResumedActivity.app; 2357 } else if (stack.mPausingActivity != null) { 2358 fgApp = stack.mPausingActivity.app; 2359 } 2360 break; 2361 } 2362 } 2363 } 2364 2365 // Now set this one as the previous process, only if that really 2366 // makes sense to. 2367 if (r.app != null && fgApp != null && r.app != fgApp 2368 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2369 && r.app != mService.mHomeProcess) { 2370 mService.mPreviousProcess = r.app; 2371 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2372 } 2373 } 2374 2375 boolean resumeTopActivitiesLocked() { 2376 return resumeTopActivitiesLocked(null, null, null); 2377 } 2378 2379 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2380 Bundle targetOptions) { 2381 if (targetStack == null) { 2382 targetStack = getFocusedStack(); 2383 } 2384 // Do targetStack first. 2385 boolean result = false; 2386 if (isFrontStack(targetStack)) { 2387 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2388 } 2389 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2390 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2391 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2392 final ActivityStack stack = stacks.get(stackNdx); 2393 if (stack == targetStack) { 2394 // Already started above. 2395 continue; 2396 } 2397 if (isFrontStack(stack)) { 2398 stack.resumeTopActivityLocked(null); 2399 } 2400 } 2401 } 2402 return result; 2403 } 2404 2405 void finishTopRunningActivityLocked(ProcessRecord app) { 2406 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2407 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2408 final int numStacks = stacks.size(); 2409 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2410 final ActivityStack stack = stacks.get(stackNdx); 2411 stack.finishTopRunningActivityLocked(app); 2412 } 2413 } 2414 } 2415 2416 void finishVoiceTask(IVoiceInteractionSession session) { 2417 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2418 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2419 final int numStacks = stacks.size(); 2420 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2421 final ActivityStack stack = stacks.get(stackNdx); 2422 stack.finishVoiceTask(session); 2423 } 2424 } 2425 } 2426 2427 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2428 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2429 mUserLeaving = true; 2430 } 2431 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2432 // Caller wants the home activity moved with it. To accomplish this, 2433 // we'll just indicate that this task returns to the home task. 2434 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2435 } 2436 task.stack.moveTaskToFrontLocked(task, null, options); 2437 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2438 + task.stack); 2439 } 2440 2441 ActivityStack getStack(int stackId) { 2442 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2443 if (activityContainer != null) { 2444 return activityContainer.mStack; 2445 } 2446 return null; 2447 } 2448 2449 ArrayList<ActivityStack> getStacks() { 2450 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2451 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2452 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2453 } 2454 return allStacks; 2455 } 2456 2457 IBinder getHomeActivityToken() { 2458 ActivityRecord homeActivity = getHomeActivity(); 2459 if (homeActivity != null) { 2460 return homeActivity.appToken; 2461 } 2462 return null; 2463 } 2464 2465 ActivityRecord getHomeActivity() { 2466 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2467 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2468 final TaskRecord task = tasks.get(taskNdx); 2469 if (task.isHomeTask()) { 2470 final ArrayList<ActivityRecord> activities = task.mActivities; 2471 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2472 final ActivityRecord r = activities.get(activityNdx); 2473 if (r.isHomeActivity()) { 2474 return r; 2475 } 2476 } 2477 } 2478 } 2479 return null; 2480 } 2481 2482 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2483 IActivityContainerCallback callback) { 2484 ActivityContainer activityContainer = 2485 new VirtualActivityContainer(parentActivity, callback); 2486 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2487 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer); 2488 parentActivity.mChildContainers.add(activityContainer); 2489 return activityContainer; 2490 } 2491 2492 void removeChildActivityContainers(ActivityRecord parentActivity) { 2493 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2494 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2495 ActivityContainer container = childStacks.remove(containerNdx); 2496 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " + 2497 container); 2498 container.release(); 2499 } 2500 } 2501 2502 void deleteActivityContainer(IActivityContainer container) { 2503 ActivityContainer activityContainer = (ActivityContainer)container; 2504 if (activityContainer != null) { 2505 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ", 2506 new RuntimeException("here").fillInStackTrace()); 2507 final int stackId = activityContainer.mStackId; 2508 mActivityContainers.remove(stackId); 2509 mWindowManager.removeStack(stackId); 2510 } 2511 } 2512 2513 private int createStackOnDisplay(int stackId, int displayId) { 2514 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2515 if (activityDisplay == null) { 2516 return -1; 2517 } 2518 2519 ActivityContainer activityContainer = new ActivityContainer(stackId); 2520 mActivityContainers.put(stackId, activityContainer); 2521 activityContainer.attachToDisplayLocked(activityDisplay); 2522 return stackId; 2523 } 2524 2525 int getNextStackId() { 2526 while (true) { 2527 if (++mLastStackId <= HOME_STACK_ID) { 2528 mLastStackId = HOME_STACK_ID + 1; 2529 } 2530 if (getStack(mLastStackId) == null) { 2531 break; 2532 } 2533 } 2534 return mLastStackId; 2535 } 2536 2537 void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { 2538 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2539 final ActivityStack stack = getStack(stackId); 2540 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2541 final TaskRecord task = tasks.get(taskNdx); 2542 stack.addTask(task, false, false); 2543 final int taskId = task.taskId; 2544 final ArrayList<ActivityRecord> activities = task.mActivities; 2545 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2546 final ActivityRecord r = activities.get(activityNdx); 2547 mWindowManager.addAppToken(0, r.appToken, taskId, stackId, 2548 r.info.screenOrientation, r.fullscreen, 2549 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, 2550 r.userId, r.info.configChanges, task.voiceSession != null, 2551 r.mLaunchTaskBehind); 2552 } 2553 } 2554 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2555 } 2556 2557 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2558 final TaskRecord task = anyTaskForIdLocked(taskId); 2559 if (task == null) { 2560 return; 2561 } 2562 final ActivityStack stack = getStack(stackId); 2563 if (stack == null) { 2564 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2565 return; 2566 } 2567 task.stack.removeTask(task); 2568 stack.addTask(task, toTop, true); 2569 mWindowManager.addTask(taskId, stackId, toTop); 2570 resumeTopActivitiesLocked(); 2571 } 2572 2573 ActivityRecord findTaskLocked(ActivityRecord r) { 2574 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2575 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2576 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2577 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2578 final ActivityStack stack = stacks.get(stackNdx); 2579 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2580 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2581 continue; 2582 } 2583 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2584 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2585 stack); 2586 continue; 2587 } 2588 final ActivityRecord ar = stack.findTaskLocked(r); 2589 if (ar != null) { 2590 return ar; 2591 } 2592 } 2593 } 2594 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2595 return null; 2596 } 2597 2598 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2599 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2600 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2601 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2602 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2603 if (ar != null) { 2604 return ar; 2605 } 2606 } 2607 } 2608 return null; 2609 } 2610 2611 void goingToSleepLocked() { 2612 scheduleSleepTimeout(); 2613 if (!mGoingToSleep.isHeld()) { 2614 mGoingToSleep.acquire(); 2615 if (mLaunchingActivity.isHeld()) { 2616 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2617 throw new IllegalStateException("Calling must be system uid"); 2618 } 2619 mLaunchingActivity.release(); 2620 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2621 } 2622 } 2623 checkReadyForSleepLocked(); 2624 } 2625 2626 boolean shutdownLocked(int timeout) { 2627 goingToSleepLocked(); 2628 2629 boolean timedout = false; 2630 final long endTime = System.currentTimeMillis() + timeout; 2631 while (true) { 2632 boolean cantShutdown = false; 2633 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2634 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2635 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2636 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2637 } 2638 } 2639 if (cantShutdown) { 2640 long timeRemaining = endTime - System.currentTimeMillis(); 2641 if (timeRemaining > 0) { 2642 try { 2643 mService.wait(timeRemaining); 2644 } catch (InterruptedException e) { 2645 } 2646 } else { 2647 Slog.w(TAG, "Activity manager shutdown timed out"); 2648 timedout = true; 2649 break; 2650 } 2651 } else { 2652 break; 2653 } 2654 } 2655 2656 // Force checkReadyForSleep to complete. 2657 mSleepTimeout = true; 2658 checkReadyForSleepLocked(); 2659 2660 return timedout; 2661 } 2662 2663 void comeOutOfSleepIfNeededLocked() { 2664 removeSleepTimeouts(); 2665 if (mGoingToSleep.isHeld()) { 2666 mGoingToSleep.release(); 2667 } 2668 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2669 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2670 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2671 final ActivityStack stack = stacks.get(stackNdx); 2672 stack.awakeFromSleepingLocked(); 2673 if (isFrontStack(stack)) { 2674 resumeTopActivitiesLocked(); 2675 } 2676 } 2677 } 2678 mGoingToSleepActivities.clear(); 2679 } 2680 2681 void activitySleptLocked(ActivityRecord r) { 2682 mGoingToSleepActivities.remove(r); 2683 checkReadyForSleepLocked(); 2684 } 2685 2686 void checkReadyForSleepLocked() { 2687 if (!mService.isSleepingOrShuttingDown()) { 2688 // Do not care. 2689 return; 2690 } 2691 2692 if (!mSleepTimeout) { 2693 boolean dontSleep = false; 2694 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2695 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2696 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2697 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2698 } 2699 } 2700 2701 if (mStoppingActivities.size() > 0) { 2702 // Still need to tell some activities to stop; can't sleep yet. 2703 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2704 + mStoppingActivities.size() + " activities"); 2705 scheduleIdleLocked(); 2706 dontSleep = true; 2707 } 2708 2709 if (mGoingToSleepActivities.size() > 0) { 2710 // Still need to tell some activities to sleep; can't sleep yet. 2711 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2712 + mGoingToSleepActivities.size() + " activities"); 2713 dontSleep = true; 2714 } 2715 2716 if (dontSleep) { 2717 return; 2718 } 2719 } 2720 2721 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2722 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2723 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2724 stacks.get(stackNdx).goToSleep(); 2725 } 2726 } 2727 2728 removeSleepTimeouts(); 2729 2730 if (mGoingToSleep.isHeld()) { 2731 mGoingToSleep.release(); 2732 } 2733 if (mService.mShuttingDown) { 2734 mService.notifyAll(); 2735 } 2736 } 2737 2738 boolean reportResumedActivityLocked(ActivityRecord r) { 2739 final ActivityStack stack = r.task.stack; 2740 if (isFrontStack(stack)) { 2741 mService.updateUsageStats(r, true); 2742 } 2743 if (allResumedActivitiesComplete()) { 2744 ensureActivitiesVisibleLocked(null, 0); 2745 mWindowManager.executeAppTransition(); 2746 return true; 2747 } 2748 return false; 2749 } 2750 2751 void handleAppCrashLocked(ProcessRecord app) { 2752 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2753 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2754 final int numStacks = stacks.size(); 2755 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2756 final ActivityStack stack = stacks.get(stackNdx); 2757 stack.handleAppCrashLocked(app); 2758 } 2759 } 2760 } 2761 2762 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 2763 final ActivityStack stack = r.task.stack; 2764 if (stack == null) { 2765 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" + 2766 visible + " stack is null"); 2767 return false; 2768 } 2769 final boolean isVisible = stack.hasVisibleBehindActivity(); 2770 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" + 2771 visible + " isVisible=" + isVisible); 2772 2773 final ActivityRecord top = topRunningActivityLocked(); 2774 if (top == null || top == r || (visible == isVisible)) { 2775 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return"); 2776 stack.setVisibleBehindActivity(visible ? r : null); 2777 return true; 2778 } 2779 2780 // A non-top activity is reporting a visibility change. 2781 if ((visible && (top.fullscreen || top.state != ActivityState.RESUMED)) || 2782 top.app == null || top.app.thread == null) { 2783 // Can't carry out this request. 2784 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen=" 2785 + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app + 2786 " top.app.thread=" + top.app.thread); 2787 return false; 2788 } else if (!visible && stack.getVisibleBehindActivity() != r) { 2789 // Only the activity set as currently visible behind should actively reset its 2790 // visible behind state. 2791 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning visible=" 2792 + visible + " stack.getVisibleBehindActivity()=" + 2793 stack.getVisibleBehindActivity() + " r=" + r); 2794 return false; 2795 } 2796 2797 stack.setVisibleBehindActivity(visible ? r : null); 2798 if (!visible) { 2799 // Make the activity immediately above r opaque. 2800 final ActivityRecord next = stack.findNextTranslucentActivity(r); 2801 if (next != null) { 2802 mService.convertFromTranslucent(next.appToken); 2803 } 2804 } 2805 try { 2806 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 2807 } catch (RemoteException e) { 2808 } 2809 return true; 2810 } 2811 2812 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2813 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2814 r.mLaunchTaskBehind = false; 2815 final TaskRecord task = r.task; 2816 task.setLastThumbnail(task.stack.screenshotActivities(r)); 2817 mService.addRecentTaskLocked(task); 2818 mWindowManager.setAppVisibility(r.appToken, false); 2819 } 2820 2821 void scheduleLaunchTaskBehindComplete(IBinder token) { 2822 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2823 } 2824 2825 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2826 // First the front stacks. In case any are not fullscreen and are in front of home. 2827 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2828 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2829 final int topStackNdx = stacks.size() - 1; 2830 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2831 final ActivityStack stack = stacks.get(stackNdx); 2832 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2833 } 2834 } 2835 } 2836 2837 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2838 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2839 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2840 final int numStacks = stacks.size(); 2841 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2842 final ActivityStack stack = stacks.get(stackNdx); 2843 stack.scheduleDestroyActivities(app, reason); 2844 } 2845 } 2846 } 2847 2848 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 2849 // Examine all activities currently running in the process. 2850 TaskRecord firstTask = null; 2851 // Tasks is non-null only if two or more tasks are found. 2852 ArraySet<TaskRecord> tasks = null; 2853 if (DEBUG_RELEASE) Slog.d(TAG, "Trying to release some activities in " + app); 2854 for (int i=0; i<app.activities.size(); i++) { 2855 ActivityRecord r = app.activities.get(i); 2856 // First, if we find an activity that is in the process of being destroyed, 2857 // then we just aren't going to do anything for now; we want things to settle 2858 // down before we try to prune more activities. 2859 if (r.finishing || r.state == ActivityState.DESTROYING 2860 || r.state == ActivityState.DESTROYED) { 2861 if (DEBUG_RELEASE) Slog.d(TAG, "Abort release; already destroying: " + r); 2862 return; 2863 } 2864 // Don't consider any activies that are currently not in a state where they 2865 // can be destroyed. 2866 if (r.visible || !r.stopped || !r.haveState 2867 || r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING 2868 || r.state == ActivityState.PAUSED || r.state == ActivityState.STOPPING) { 2869 if (DEBUG_RELEASE) Slog.d(TAG, "Not releasing in-use activity: " + r); 2870 continue; 2871 } 2872 if (r.task != null) { 2873 if (DEBUG_RELEASE) Slog.d(TAG, "Collecting release task " + r.task 2874 + " from " + r); 2875 if (firstTask == null) { 2876 firstTask = r.task; 2877 } else if (firstTask != r.task) { 2878 if (tasks == null) { 2879 tasks = new ArraySet<>(); 2880 tasks.add(firstTask); 2881 } 2882 tasks.add(r.task); 2883 } 2884 } 2885 } 2886 if (tasks == null) { 2887 if (DEBUG_RELEASE) Slog.d(TAG, "Didn't find two or more tasks to release"); 2888 return; 2889 } 2890 // If we have activities in multiple tasks that are in a position to be destroyed, 2891 // let's iterate through the tasks and release the oldest one. 2892 final int numDisplays = mActivityDisplays.size(); 2893 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2894 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2895 // Step through all stacks starting from behind, to hit the oldest things first. 2896 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 2897 final ActivityStack stack = stacks.get(stackNdx); 2898 // Try to release activities in this stack; if we manage to, we are done. 2899 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 2900 return; 2901 } 2902 } 2903 } 2904 } 2905 2906 boolean switchUserLocked(int userId, UserStartedState uss) { 2907 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2908 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2909 mCurrentUser = userId; 2910 2911 mStartingUsers.add(uss); 2912 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2913 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2914 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2915 final ActivityStack stack = stacks.get(stackNdx); 2916 stack.switchUserLocked(userId); 2917 TaskRecord task = stack.topTask(); 2918 if (task != null) { 2919 mWindowManager.moveTaskToTop(task.taskId); 2920 } 2921 } 2922 } 2923 2924 ActivityStack stack = getStack(restoreStackId); 2925 if (stack == null) { 2926 stack = mHomeStack; 2927 } 2928 final boolean homeInFront = stack.isHomeStack(); 2929 if (stack.isOnHomeDisplay()) { 2930 moveHomeStack(homeInFront); 2931 TaskRecord task = stack.topTask(); 2932 if (task != null) { 2933 mWindowManager.moveTaskToTop(task.taskId); 2934 } 2935 } else { 2936 // Stack was moved to another display while user was swapped out. 2937 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2938 } 2939 return homeInFront; 2940 } 2941 2942 /** 2943 * Add background users to send boot completed events to. 2944 * @param userId The user being started in the background 2945 * @param uss The state object for the user. 2946 */ 2947 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 2948 mStartingBackgroundUsers.add(uss); 2949 } 2950 2951 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2952 int N = mStoppingActivities.size(); 2953 if (N <= 0) return null; 2954 2955 ArrayList<ActivityRecord> stops = null; 2956 2957 final boolean nowVisible = allResumedActivitiesVisible(); 2958 for (int i=0; i<N; i++) { 2959 ActivityRecord s = mStoppingActivities.get(i); 2960 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2961 + nowVisible + " waitingVisible=" + s.waitingVisible 2962 + " finishing=" + s.finishing); 2963 if (s.waitingVisible && nowVisible) { 2964 mWaitingVisibleActivities.remove(s); 2965 s.waitingVisible = false; 2966 if (s.finishing) { 2967 // If this activity is finishing, it is sitting on top of 2968 // everyone else but we now know it is no longer needed... 2969 // so get rid of it. Otherwise, we need to go through the 2970 // normal flow and hide it once we determine that it is 2971 // hidden by the activities in front of it. 2972 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2973 mWindowManager.setAppVisibility(s.appToken, false); 2974 } 2975 } 2976 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2977 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2978 if (stops == null) { 2979 stops = new ArrayList<ActivityRecord>(); 2980 } 2981 stops.add(s); 2982 mStoppingActivities.remove(i); 2983 N--; 2984 i--; 2985 } 2986 } 2987 2988 return stops; 2989 } 2990 2991 void validateTopActivitiesLocked() { 2992 // FIXME 2993/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2994 final ActivityStack stack = stacks.get(stackNdx); 2995 final ActivityRecord r = stack.topRunningActivityLocked(null); 2996 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2997 if (isFrontStack(stack)) { 2998 if (r == null) { 2999 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 3000 } else { 3001 final ActivityRecord pausing = stack.mPausingActivity; 3002 if (pausing != null && pausing == r) { 3003 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 3004 " state=" + state); 3005 } 3006 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 3007 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 3008 " state=" + state); 3009 } 3010 } 3011 } else { 3012 final ActivityRecord resumed = stack.mResumedActivity; 3013 if (resumed != null && resumed == r) { 3014 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 3015 " state=" + state); 3016 } 3017 if (r != null && (state == ActivityState.INITIALIZING 3018 || state == ActivityState.RESUMED)) { 3019 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 3020 " state=" + state); 3021 } 3022 } 3023 } 3024*/ 3025 } 3026 3027 public void dump(PrintWriter pw, String prefix) { 3028 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3029 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3030 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3031 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 3032 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3033 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3034 } 3035 3036 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3037 return getFocusedStack().getDumpActivitiesLocked(name); 3038 } 3039 3040 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3041 boolean needSep, String prefix) { 3042 if (activity != null) { 3043 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3044 if (needSep) { 3045 pw.println(); 3046 } 3047 pw.print(prefix); 3048 pw.println(activity); 3049 return true; 3050 } 3051 } 3052 return false; 3053 } 3054 3055 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3056 boolean dumpClient, String dumpPackage) { 3057 boolean printed = false; 3058 boolean needSep = false; 3059 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3060 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3061 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3062 pw.println(" (activities from bottom to top):"); 3063 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3064 final int numStacks = stacks.size(); 3065 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 3066 final ActivityStack stack = stacks.get(stackNdx); 3067 StringBuilder stackHeader = new StringBuilder(128); 3068 stackHeader.append(" Stack #"); 3069 stackHeader.append(stack.mStackId); 3070 stackHeader.append(":"); 3071 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3072 needSep, stackHeader.toString()); 3073 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3074 !dumpAll, false, dumpPackage, true, 3075 " Running activities (most recent first):", null); 3076 3077 needSep = printed; 3078 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3079 " mPausingActivity: "); 3080 if (pr) { 3081 printed = true; 3082 needSep = false; 3083 } 3084 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3085 " mResumedActivity: "); 3086 if (pr) { 3087 printed = true; 3088 needSep = false; 3089 } 3090 if (dumpAll) { 3091 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3092 " mLastPausedActivity: "); 3093 if (pr) { 3094 printed = true; 3095 needSep = true; 3096 } 3097 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3098 needSep, " mLastNoHistoryActivity: "); 3099 } 3100 needSep = printed; 3101 } 3102 } 3103 3104 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3105 false, dumpPackage, true, " Activities waiting to finish:", null); 3106 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3107 false, dumpPackage, true, " Activities waiting to stop:", null); 3108 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3109 false, dumpPackage, true, " Activities waiting for another to become visible:", 3110 null); 3111 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3112 false, dumpPackage, true, " Activities waiting to sleep:", null); 3113 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3114 false, dumpPackage, true, " Activities waiting to sleep:", null); 3115 3116 return printed; 3117 } 3118 3119 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3120 String prefix, String label, boolean complete, boolean brief, boolean client, 3121 String dumpPackage, boolean needNL, String header1, String header2) { 3122 TaskRecord lastTask = null; 3123 String innerPrefix = null; 3124 String[] args = null; 3125 boolean printed = false; 3126 for (int i=list.size()-1; i>=0; i--) { 3127 final ActivityRecord r = list.get(i); 3128 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3129 continue; 3130 } 3131 if (innerPrefix == null) { 3132 innerPrefix = prefix + " "; 3133 args = new String[0]; 3134 } 3135 printed = true; 3136 final boolean full = !brief && (complete || !r.isInHistory()); 3137 if (needNL) { 3138 pw.println(""); 3139 needNL = false; 3140 } 3141 if (header1 != null) { 3142 pw.println(header1); 3143 header1 = null; 3144 } 3145 if (header2 != null) { 3146 pw.println(header2); 3147 header2 = null; 3148 } 3149 if (lastTask != r.task) { 3150 lastTask = r.task; 3151 pw.print(prefix); 3152 pw.print(full ? "* " : " "); 3153 pw.println(lastTask); 3154 if (full) { 3155 lastTask.dump(pw, prefix + " "); 3156 } else if (complete) { 3157 // Complete + brief == give a summary. Isn't that obvious?!? 3158 if (lastTask.intent != null) { 3159 pw.print(prefix); pw.print(" "); 3160 pw.println(lastTask.intent.toInsecureStringWithClip()); 3161 } 3162 } 3163 } 3164 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3165 pw.print(" #"); pw.print(i); pw.print(": "); 3166 pw.println(r); 3167 if (full) { 3168 r.dump(pw, innerPrefix); 3169 } else if (complete) { 3170 // Complete + brief == give a summary. Isn't that obvious?!? 3171 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3172 if (r.app != null) { 3173 pw.print(innerPrefix); pw.println(r.app); 3174 } 3175 } 3176 if (client && r.app != null && r.app.thread != null) { 3177 // flush anything that is already in the PrintWriter since the thread is going 3178 // to write to the file descriptor directly 3179 pw.flush(); 3180 try { 3181 TransferPipe tp = new TransferPipe(); 3182 try { 3183 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3184 r.appToken, innerPrefix, args); 3185 // Short timeout, since blocking here can 3186 // deadlock with the application. 3187 tp.go(fd, 2000); 3188 } finally { 3189 tp.kill(); 3190 } 3191 } catch (IOException e) { 3192 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3193 } catch (RemoteException e) { 3194 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3195 } 3196 needNL = true; 3197 } 3198 } 3199 return printed; 3200 } 3201 3202 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3203 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3204 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3205 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3206 } 3207 3208 final void scheduleIdleLocked() { 3209 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3210 } 3211 3212 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3213 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 3214 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3215 } 3216 3217 final void scheduleResumeTopActivities() { 3218 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3219 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3220 } 3221 } 3222 3223 void removeSleepTimeouts() { 3224 mSleepTimeout = false; 3225 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3226 } 3227 3228 final void scheduleSleepTimeout() { 3229 removeSleepTimeouts(); 3230 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3231 } 3232 3233 @Override 3234 public void onDisplayAdded(int displayId) { 3235 Slog.v(TAG, "Display added displayId=" + displayId); 3236 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3237 } 3238 3239 @Override 3240 public void onDisplayRemoved(int displayId) { 3241 Slog.v(TAG, "Display removed displayId=" + displayId); 3242 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3243 } 3244 3245 @Override 3246 public void onDisplayChanged(int displayId) { 3247 Slog.v(TAG, "Display changed displayId=" + displayId); 3248 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3249 } 3250 3251 public void handleDisplayAddedLocked(int displayId) { 3252 boolean newDisplay; 3253 synchronized (mService) { 3254 newDisplay = mActivityDisplays.get(displayId) == null; 3255 if (newDisplay) { 3256 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3257 mActivityDisplays.put(displayId, activityDisplay); 3258 } 3259 } 3260 if (newDisplay) { 3261 mWindowManager.onDisplayAdded(displayId); 3262 } 3263 } 3264 3265 public void handleDisplayRemovedLocked(int displayId) { 3266 synchronized (mService) { 3267 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3268 if (activityDisplay != null) { 3269 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3270 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3271 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3272 } 3273 mActivityDisplays.remove(displayId); 3274 } 3275 } 3276 mWindowManager.onDisplayRemoved(displayId); 3277 } 3278 3279 public void handleDisplayChangedLocked(int displayId) { 3280 synchronized (mService) { 3281 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3282 if (activityDisplay != null) { 3283 // TODO: Update the bounds. 3284 } 3285 } 3286 mWindowManager.onDisplayChanged(displayId); 3287 } 3288 3289 StackInfo getStackInfo(ActivityStack stack) { 3290 StackInfo info = new StackInfo(); 3291 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3292 info.displayId = Display.DEFAULT_DISPLAY; 3293 info.stackId = stack.mStackId; 3294 3295 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3296 final int numTasks = tasks.size(); 3297 int[] taskIds = new int[numTasks]; 3298 String[] taskNames = new String[numTasks]; 3299 for (int i = 0; i < numTasks; ++i) { 3300 final TaskRecord task = tasks.get(i); 3301 taskIds[i] = task.taskId; 3302 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3303 : task.realActivity != null ? task.realActivity.flattenToString() 3304 : task.getTopActivity() != null ? task.getTopActivity().packageName 3305 : "unknown"; 3306 } 3307 info.taskIds = taskIds; 3308 info.taskNames = taskNames; 3309 return info; 3310 } 3311 3312 StackInfo getStackInfoLocked(int stackId) { 3313 ActivityStack stack = getStack(stackId); 3314 if (stack != null) { 3315 return getStackInfo(stack); 3316 } 3317 return null; 3318 } 3319 3320 ArrayList<StackInfo> getAllStackInfosLocked() { 3321 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 3322 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3323 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3324 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3325 list.add(getStackInfo(stacks.get(ndx))); 3326 } 3327 } 3328 return list; 3329 } 3330 3331 void showLockTaskToast() { 3332 mLockTaskNotify.showToast(mLockTaskIsLocked); 3333 } 3334 3335 void setLockTaskModeLocked(TaskRecord task, boolean isLocked) { 3336 if (task == null) { 3337 // Take out of lock task mode if necessary 3338 if (mLockTaskModeTask != null) { 3339 final Message lockTaskMsg = Message.obtain(); 3340 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3341 lockTaskMsg.what = LOCK_TASK_END_MSG; 3342 mLockTaskModeTask = null; 3343 mHandler.sendMessage(lockTaskMsg); 3344 } 3345 return; 3346 } 3347 if (isLockTaskModeViolation(task)) { 3348 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 3349 return; 3350 } 3351 mLockTaskModeTask = task; 3352 findTaskToMoveToFrontLocked(task, 0, null); 3353 resumeTopActivitiesLocked(); 3354 3355 final Message lockTaskMsg = Message.obtain(); 3356 lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName(); 3357 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3358 lockTaskMsg.what = LOCK_TASK_START_MSG; 3359 lockTaskMsg.arg2 = !isLocked ? 1 : 0; 3360 mHandler.sendMessage(lockTaskMsg); 3361 } 3362 3363 boolean isLockTaskModeViolation(TaskRecord task) { 3364 return mLockTaskModeTask != null && mLockTaskModeTask != task; 3365 } 3366 3367 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3368 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3369 final Message lockTaskMsg = Message.obtain(); 3370 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3371 lockTaskMsg.what = LOCK_TASK_END_MSG; 3372 mLockTaskModeTask = null; 3373 mHandler.sendMessage(lockTaskMsg); 3374 } 3375 } 3376 3377 boolean isInLockTaskMode() { 3378 return mLockTaskModeTask != null; 3379 } 3380 3381 private final class ActivityStackSupervisorHandler extends Handler { 3382 3383 public ActivityStackSupervisorHandler(Looper looper) { 3384 super(looper); 3385 } 3386 3387 void activityIdleInternal(ActivityRecord r) { 3388 synchronized (mService) { 3389 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3390 } 3391 } 3392 3393 @Override 3394 public void handleMessage(Message msg) { 3395 switch (msg.what) { 3396 case IDLE_TIMEOUT_MSG: { 3397 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3398 if (mService.mDidDexOpt) { 3399 mService.mDidDexOpt = false; 3400 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3401 nmsg.obj = msg.obj; 3402 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3403 return; 3404 } 3405 // We don't at this point know if the activity is fullscreen, 3406 // so we need to be conservative and assume it isn't. 3407 activityIdleInternal((ActivityRecord)msg.obj); 3408 } break; 3409 case IDLE_NOW_MSG: { 3410 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3411 activityIdleInternal((ActivityRecord)msg.obj); 3412 } break; 3413 case RESUME_TOP_ACTIVITY_MSG: { 3414 synchronized (mService) { 3415 resumeTopActivitiesLocked(); 3416 } 3417 } break; 3418 case SLEEP_TIMEOUT_MSG: { 3419 synchronized (mService) { 3420 if (mService.isSleepingOrShuttingDown()) { 3421 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3422 mSleepTimeout = true; 3423 checkReadyForSleepLocked(); 3424 } 3425 } 3426 } break; 3427 case LAUNCH_TIMEOUT_MSG: { 3428 if (mService.mDidDexOpt) { 3429 mService.mDidDexOpt = false; 3430 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3431 return; 3432 } 3433 synchronized (mService) { 3434 if (mLaunchingActivity.isHeld()) { 3435 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3436 if (VALIDATE_WAKE_LOCK_CALLER 3437 && Binder.getCallingUid() != Process.myUid()) { 3438 throw new IllegalStateException("Calling must be system uid"); 3439 } 3440 mLaunchingActivity.release(); 3441 } 3442 } 3443 } break; 3444 case HANDLE_DISPLAY_ADDED: { 3445 handleDisplayAddedLocked(msg.arg1); 3446 } break; 3447 case HANDLE_DISPLAY_CHANGED: { 3448 handleDisplayChangedLocked(msg.arg1); 3449 } break; 3450 case HANDLE_DISPLAY_REMOVED: { 3451 handleDisplayRemovedLocked(msg.arg1); 3452 } break; 3453 case CONTAINER_CALLBACK_VISIBILITY: { 3454 final ActivityContainer container = (ActivityContainer) msg.obj; 3455 final IActivityContainerCallback callback = container.mCallback; 3456 if (callback != null) { 3457 try { 3458 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3459 } catch (RemoteException e) { 3460 } 3461 } 3462 } break; 3463 case LOCK_TASK_START_MSG: { 3464 // When lock task starts, we disable the status bars. 3465 try { 3466 if (mLockTaskNotify == null) { 3467 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3468 } 3469 mLockTaskNotify.show(true); 3470 mLockTaskIsLocked = msg.arg2 == 0; 3471 if (getStatusBarService() != null) { 3472 int flags = 3473 StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK; 3474 if (!mLockTaskIsLocked) { 3475 flags ^= StatusBarManager.DISABLE_HOME 3476 | StatusBarManager.DISABLE_RECENT; 3477 } 3478 getStatusBarService().disable(flags, mToken, 3479 mService.mContext.getPackageName()); 3480 } 3481 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3482 if (getDevicePolicyManager() != null) { 3483 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3484 (String)msg.obj, msg.arg1); 3485 } 3486 } catch (RemoteException ex) { 3487 throw new RuntimeException(ex); 3488 } 3489 } break; 3490 case LOCK_TASK_END_MSG: { 3491 // When lock task ends, we enable the status bars. 3492 try { 3493 if (getStatusBarService() != null) { 3494 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3495 mService.mContext.getPackageName()); 3496 } 3497 mWindowManager.reenableKeyguard(mToken); 3498 if (getDevicePolicyManager() != null) { 3499 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3500 msg.arg1); 3501 } 3502 if (mLockTaskNotify == null) { 3503 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3504 } 3505 mLockTaskNotify.show(false); 3506 try { 3507 boolean shouldLockKeyguard = Settings.System.getInt( 3508 mService.mContext.getContentResolver(), 3509 Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0; 3510 if (!mLockTaskIsLocked && shouldLockKeyguard) { 3511 mWindowManager.lockNow(null); 3512 mWindowManager.dismissKeyguard(); 3513 new LockPatternUtils(mService.mContext) 3514 .requireCredentialEntry(UserHandle.USER_ALL); 3515 } 3516 } catch (SettingNotFoundException e) { 3517 // No setting, don't lock. 3518 } 3519 } catch (RemoteException ex) { 3520 throw new RuntimeException(ex); 3521 } 3522 } break; 3523 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3524 final ActivityContainer container = (ActivityContainer) msg.obj; 3525 final IActivityContainerCallback callback = container.mCallback; 3526 if (callback != null) { 3527 try { 3528 callback.onAllActivitiesComplete(container.asBinder()); 3529 } catch (RemoteException e) { 3530 } 3531 } 3532 } break; 3533 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 3534 synchronized (mService) { 3535 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 3536 msg.obj); 3537 final ActivityContainer container = (ActivityContainer) msg.obj; 3538 container.mStack.finishAllActivitiesLocked(true); 3539 container.onTaskListEmptyLocked(); 3540 } 3541 } break; 3542 case LAUNCH_TASK_BEHIND_COMPLETE: { 3543 synchronized (mService) { 3544 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 3545 if (r != null) { 3546 handleLaunchTaskBehindCompleteLocked(r); 3547 } 3548 } 3549 } break; 3550 } 3551 } 3552 } 3553 3554 class ActivityContainer extends android.app.IActivityContainer.Stub { 3555 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3556 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3557 final int mStackId; 3558 IActivityContainerCallback mCallback = null; 3559 final ActivityStack mStack; 3560 ActivityRecord mParentActivity = null; 3561 String mIdString; 3562 3563 boolean mVisible = true; 3564 3565 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3566 ActivityDisplay mActivityDisplay; 3567 3568 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3569 final static int CONTAINER_STATE_NO_SURFACE = 1; 3570 final static int CONTAINER_STATE_FINISHING = 2; 3571 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3572 3573 ActivityContainer(int stackId) { 3574 synchronized (mService) { 3575 mStackId = stackId; 3576 mStack = new ActivityStack(this); 3577 mIdString = "ActivtyContainer{" + mStackId + "}"; 3578 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3579 } 3580 } 3581 3582 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3583 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3584 + " to display=" + activityDisplay); 3585 mActivityDisplay = activityDisplay; 3586 mStack.mDisplayId = activityDisplay.mDisplayId; 3587 mStack.mStacks = activityDisplay.mStacks; 3588 3589 activityDisplay.attachActivities(mStack); 3590 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3591 } 3592 3593 @Override 3594 public void attachToDisplay(int displayId) { 3595 synchronized (mService) { 3596 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3597 if (activityDisplay == null) { 3598 return; 3599 } 3600 attachToDisplayLocked(activityDisplay); 3601 } 3602 } 3603 3604 @Override 3605 public int getDisplayId() { 3606 synchronized (mService) { 3607 if (mActivityDisplay != null) { 3608 return mActivityDisplay.mDisplayId; 3609 } 3610 } 3611 return -1; 3612 } 3613 3614 @Override 3615 public boolean injectEvent(InputEvent event) { 3616 final long origId = Binder.clearCallingIdentity(); 3617 try { 3618 synchronized (mService) { 3619 if (mActivityDisplay != null) { 3620 return mInputManagerInternal.injectInputEvent(event, 3621 mActivityDisplay.mDisplayId, 3622 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3623 } 3624 } 3625 return false; 3626 } finally { 3627 Binder.restoreCallingIdentity(origId); 3628 } 3629 } 3630 3631 @Override 3632 public void release() { 3633 synchronized (mService) { 3634 if (mContainerState == CONTAINER_STATE_FINISHING) { 3635 return; 3636 } 3637 mContainerState = CONTAINER_STATE_FINISHING; 3638 3639 final Message msg = 3640 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3641 mHandler.sendMessageDelayed(msg, 2000); 3642 3643 long origId = Binder.clearCallingIdentity(); 3644 try { 3645 mStack.finishAllActivitiesLocked(false); 3646 removePendingActivityLaunchesLocked(mStack); 3647 } finally { 3648 Binder.restoreCallingIdentity(origId); 3649 } 3650 } 3651 } 3652 3653 private void detachLocked() { 3654 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3655 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3656 if (mActivityDisplay != null) { 3657 mActivityDisplay.detachActivitiesLocked(mStack); 3658 mActivityDisplay = null; 3659 mStack.mDisplayId = -1; 3660 mStack.mStacks = null; 3661 mWindowManager.detachStack(mStackId); 3662 } 3663 } 3664 3665 @Override 3666 public final int startActivity(Intent intent) { 3667 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3668 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3669 Binder.getCallingUid(), mCurrentUser, false, 3670 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3671 // TODO: Switch to user app stacks here. 3672 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3673 String mimeType = intent.getType(); 3674 if (mimeType == null && intent.getData() != null 3675 && "content".equals(intent.getData().getScheme())) { 3676 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3677 } 3678 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 3679 0, null, null, null, null, userId, this, null); 3680 } 3681 3682 @Override 3683 public final int startActivityIntentSender(IIntentSender intentSender) { 3684 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3685 3686 if (!(intentSender instanceof PendingIntentRecord)) { 3687 throw new IllegalArgumentException("Bad PendingIntent object"); 3688 } 3689 3690 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3691 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3692 } 3693 3694 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3695 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3696 Binder.getCallingUid(), mCurrentUser, false, 3697 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3698 if (resolvedType == null) { 3699 resolvedType = intent.getType(); 3700 if (resolvedType == null && intent.getData() != null 3701 && "content".equals(intent.getData().getScheme())) { 3702 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3703 } 3704 } 3705 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 3706 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3707 throw new SecurityException( 3708 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3709 } 3710 } 3711 3712 /** Throw a SecurityException if allowEmbedded is not true */ 3713 @Override 3714 public final void checkEmbeddedAllowed(Intent intent) { 3715 checkEmbeddedAllowedInner(intent, null); 3716 } 3717 3718 /** Throw a SecurityException if allowEmbedded is not true */ 3719 @Override 3720 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3721 if (!(intentSender instanceof PendingIntentRecord)) { 3722 throw new IllegalArgumentException("Bad PendingIntent object"); 3723 } 3724 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3725 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3726 pendingIntent.key.requestResolvedType); 3727 } 3728 3729 @Override 3730 public IBinder asBinder() { 3731 return this; 3732 } 3733 3734 @Override 3735 public void setSurface(Surface surface, int width, int height, int density) { 3736 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3737 } 3738 3739 ActivityStackSupervisor getOuter() { 3740 return ActivityStackSupervisor.this; 3741 } 3742 3743 boolean isAttachedLocked() { 3744 return mActivityDisplay != null; 3745 } 3746 3747 void getBounds(Point outBounds) { 3748 synchronized (mService) { 3749 if (mActivityDisplay != null) { 3750 mActivityDisplay.getBounds(outBounds); 3751 } else { 3752 outBounds.set(0, 0); 3753 } 3754 } 3755 } 3756 3757 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3758 void setVisible(boolean visible) { 3759 if (mVisible != visible) { 3760 mVisible = visible; 3761 if (mCallback != null) { 3762 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3763 0 /* unused */, this).sendToTarget(); 3764 } 3765 } 3766 } 3767 3768 void setDrawn() { 3769 } 3770 3771 // You can always start a new task on a regular ActivityStack. 3772 boolean isEligibleForNewTasks() { 3773 return true; 3774 } 3775 3776 void onTaskListEmptyLocked() { 3777 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3778 if (!mStack.isHomeStack()) { 3779 detachLocked(); 3780 deleteActivityContainer(this); 3781 } 3782 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3783 } 3784 3785 @Override 3786 public String toString() { 3787 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3788 } 3789 } 3790 3791 private class VirtualActivityContainer extends ActivityContainer { 3792 Surface mSurface; 3793 boolean mDrawn = false; 3794 3795 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3796 super(getNextStackId()); 3797 mParentActivity = parent; 3798 mCallback = callback; 3799 mContainerState = CONTAINER_STATE_NO_SURFACE; 3800 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3801 } 3802 3803 @Override 3804 public void setSurface(Surface surface, int width, int height, int density) { 3805 super.setSurface(surface, width, height, density); 3806 3807 synchronized (mService) { 3808 final long origId = Binder.clearCallingIdentity(); 3809 try { 3810 setSurfaceLocked(surface, width, height, density); 3811 } finally { 3812 Binder.restoreCallingIdentity(origId); 3813 } 3814 } 3815 } 3816 3817 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3818 if (mContainerState == CONTAINER_STATE_FINISHING) { 3819 return; 3820 } 3821 VirtualActivityDisplay virtualActivityDisplay = 3822 (VirtualActivityDisplay) mActivityDisplay; 3823 if (virtualActivityDisplay == null) { 3824 virtualActivityDisplay = 3825 new VirtualActivityDisplay(width, height, density); 3826 mActivityDisplay = virtualActivityDisplay; 3827 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3828 attachToDisplayLocked(virtualActivityDisplay); 3829 } 3830 3831 if (mSurface != null) { 3832 mSurface.release(); 3833 } 3834 3835 mSurface = surface; 3836 if (surface != null) { 3837 mStack.resumeTopActivityLocked(null); 3838 } else { 3839 mContainerState = CONTAINER_STATE_NO_SURFACE; 3840 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3841 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3842 mStack.startPausingLocked(false, true); 3843 } 3844 } 3845 3846 setSurfaceIfReadyLocked(); 3847 3848 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3849 + virtualActivityDisplay); 3850 } 3851 3852 @Override 3853 boolean isAttachedLocked() { 3854 return mSurface != null && super.isAttachedLocked(); 3855 } 3856 3857 @Override 3858 void setDrawn() { 3859 synchronized (mService) { 3860 mDrawn = true; 3861 setSurfaceIfReadyLocked(); 3862 } 3863 } 3864 3865 // Never start a new task on an ActivityView if it isn't explicitly specified. 3866 @Override 3867 boolean isEligibleForNewTasks() { 3868 return false; 3869 } 3870 3871 private void setSurfaceIfReadyLocked() { 3872 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3873 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3874 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3875 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3876 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3877 } 3878 } 3879 } 3880 3881 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3882 * attached {@link ActivityStack}s */ 3883 class ActivityDisplay { 3884 /** Actual Display this object tracks. */ 3885 int mDisplayId; 3886 Display mDisplay; 3887 DisplayInfo mDisplayInfo = new DisplayInfo(); 3888 3889 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3890 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3891 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3892 3893 ActivityRecord mVisibleBehindActivity; 3894 3895 ActivityDisplay() { 3896 } 3897 3898 ActivityDisplay(int displayId) { 3899 init(mDisplayManager.getDisplay(displayId)); 3900 } 3901 3902 void init(Display display) { 3903 mDisplay = display; 3904 mDisplayId = display.getDisplayId(); 3905 mDisplay.getDisplayInfo(mDisplayInfo); 3906 } 3907 3908 void attachActivities(ActivityStack stack) { 3909 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3910 + mDisplayId); 3911 mStacks.add(stack); 3912 } 3913 3914 void detachActivitiesLocked(ActivityStack stack) { 3915 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3916 + " from displayId=" + mDisplayId); 3917 mStacks.remove(stack); 3918 } 3919 3920 void getBounds(Point bounds) { 3921 mDisplay.getDisplayInfo(mDisplayInfo); 3922 bounds.x = mDisplayInfo.appWidth; 3923 bounds.y = mDisplayInfo.appHeight; 3924 } 3925 3926 void setVisibleBehindActivity(ActivityRecord r) { 3927 mVisibleBehindActivity = r; 3928 } 3929 3930 boolean hasVisibleBehindActivity() { 3931 return mVisibleBehindActivity != null; 3932 } 3933 3934 @Override 3935 public String toString() { 3936 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3937 } 3938 } 3939 3940 class VirtualActivityDisplay extends ActivityDisplay { 3941 VirtualDisplay mVirtualDisplay; 3942 3943 VirtualActivityDisplay(int width, int height, int density) { 3944 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3945 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 3946 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 3947 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3948 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 3949 3950 init(mVirtualDisplay.getDisplay()); 3951 3952 mWindowManager.handleDisplayAdded(mDisplayId); 3953 } 3954 3955 void setSurface(Surface surface) { 3956 if (mVirtualDisplay != null) { 3957 mVirtualDisplay.setSurface(surface); 3958 } 3959 } 3960 3961 @Override 3962 void detachActivitiesLocked(ActivityStack stack) { 3963 super.detachActivitiesLocked(stack); 3964 if (mVirtualDisplay != null) { 3965 mVirtualDisplay.release(); 3966 mVirtualDisplay = null; 3967 } 3968 } 3969 3970 @Override 3971 public String toString() { 3972 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3973 } 3974 } 3975 3976 private boolean isLeanbackOnlyDevice() { 3977 boolean onLeanbackOnly = false; 3978 try { 3979 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 3980 PackageManager.FEATURE_LEANBACK_ONLY); 3981 } catch (RemoteException e) { 3982 // noop 3983 } 3984 3985 return onLeanbackOnly; 3986 } 3987} 3988