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