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