ActivityStackSupervisor.java revision d31c16457a7360bc892d71c308c7ab76cdb45af1
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 private final RecentTasks mRecentTasks; 170 171 final ActivityStackSupervisorHandler mHandler; 172 173 /** Short cut */ 174 WindowManagerService mWindowManager; 175 DisplayManager mDisplayManager; 176 177 /** Identifier counter for all ActivityStacks */ 178 private int mLastStackId = HOME_STACK_ID; 179 180 /** Task identifier that activities are currently being started in. Incremented each time a 181 * new task is created. */ 182 private int mCurTaskId = 0; 183 184 /** The current user */ 185 private int mCurrentUser; 186 187 /** The stack containing the launcher app. Assumed to always be attached to 188 * Display.DEFAULT_DISPLAY. */ 189 private ActivityStack mHomeStack; 190 191 /** The stack currently receiving input or launching the next activity. */ 192 private ActivityStack mFocusedStack; 193 194 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 195 * been resumed. If stacks are changing position this will hold the old stack until the new 196 * stack becomes resumed after which it will be set to mFocusedStack. */ 197 private ActivityStack mLastFocusedStack; 198 199 /** List of activities that are waiting for a new activity to become visible before completing 200 * whatever operation they are supposed to do. */ 201 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>(); 202 203 /** List of processes waiting to find out about the next visible activity. */ 204 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>(); 205 206 /** List of processes waiting to find out about the next launched activity. */ 207 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>(); 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<>(); 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<>(); 216 217 /** List of activities that are in the process of going to sleep. */ 218 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>(); 219 220 /** Used on user changes */ 221 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<>(); 222 223 /** Used to queue up any background users being started */ 224 final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<>(); 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, RecentTasks recentTasks) { 302 mService = service; 303 mRecentTasks = recentTasks; 304 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); 305 } 306 307 /** 308 * At the time when the constructor runs, the power manager has not yet been 309 * initialized. So we initialize our wakelocks afterwards. 310 */ 311 void initPowerManagement() { 312 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 313 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 314 mLaunchingActivity = 315 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 316 mLaunchingActivity.setReferenceCounted(false); 317 } 318 319 // This function returns a IStatusBarService. The value is from ServiceManager. 320 // getService and is cached. 321 private IStatusBarService getStatusBarService() { 322 synchronized (mService) { 323 if (mStatusBarService == null) { 324 mStatusBarService = IStatusBarService.Stub.asInterface( 325 ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); 326 if (mStatusBarService == null) { 327 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 328 } 329 } 330 return mStatusBarService; 331 } 332 } 333 334 private IDevicePolicyManager getDevicePolicyManager() { 335 synchronized (mService) { 336 if (mDevicePolicyManager == null) { 337 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 338 ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE)); 339 if (mDevicePolicyManager == null) { 340 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 341 } 342 } 343 return mDevicePolicyManager; 344 } 345 } 346 347 void setWindowManager(WindowManagerService wm) { 348 synchronized (mService) { 349 mWindowManager = wm; 350 351 mDisplayManager = 352 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 353 mDisplayManager.registerDisplayListener(this, null); 354 355 Display[] displays = mDisplayManager.getDisplays(); 356 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 357 final int displayId = displays[displayNdx].getDisplayId(); 358 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 359 if (activityDisplay.mDisplay == null) { 360 throw new IllegalStateException("Default Display does not exist"); 361 } 362 mActivityDisplays.put(displayId, activityDisplay); 363 } 364 365 createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY); 366 mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID); 367 368 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 369 370 // Initialize this here, now that we can get a valid reference to PackageManager. 371 mLeanbackOnlyDevice = isLeanbackOnlyDevice(); 372 } 373 } 374 375 void notifyActivityDrawnForKeyguard() { 376 if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); 377 mWindowManager.notifyActivityDrawnForKeyguard(); 378 } 379 380 ActivityStack getFocusedStack() { 381 return mFocusedStack; 382 } 383 384 ActivityStack getLastStack() { 385 return mLastFocusedStack; 386 } 387 388 // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the 389 // top of all visible stacks. 390 boolean isFrontStack(ActivityStack stack) { 391 final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 392 if (parent != null) { 393 stack = parent.task.stack; 394 } 395 ArrayList<ActivityStack> stacks = stack.mStacks; 396 if (stacks != null && !stacks.isEmpty()) { 397 return stack == stacks.get(stacks.size() - 1); 398 } 399 return false; 400 } 401 402 void moveHomeStack(boolean toFront) { 403 ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 404 final int topNdx = stacks.size() - 1; 405 if (topNdx <= 0) { 406 return; 407 } 408 ActivityStack topStack = stacks.get(topNdx); 409 final boolean homeInFront = topStack == mHomeStack; 410 if (homeInFront != toFront) { 411 mLastFocusedStack = topStack; 412 stacks.remove(mHomeStack); 413 stacks.add(toFront ? topNdx : 0, mHomeStack); 414 mFocusedStack = stacks.get(topNdx); 415 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new=" 416 + mFocusedStack); 417 } 418 EventLog.writeEvent(EventLogTags.AM_HOME_STACK_MOVED, 419 mCurrentUser, toFront ? 1 : 0, stacks.get(topNdx).getStackId(), 420 mFocusedStack == null ? -1 : mFocusedStack.getStackId()); 421 422 if (mService.mBooting || !mService.mBooted) { 423 final ActivityRecord r = topRunningActivityLocked(); 424 if (r != null && r.idle) { 425 checkFinishBootingLocked(); 426 } 427 } 428 } 429 430 void moveHomeStackTaskToTop(int homeStackTaskType) { 431 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 432 mWindowManager.showRecentApps(); 433 return; 434 } 435 moveHomeStack(true); 436 mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); 437 } 438 439 boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) { 440 if (!mService.mBooting && !mService.mBooted) { 441 // Not ready yet! 442 return false; 443 } 444 445 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 446 mWindowManager.showRecentApps(); 447 return false; 448 } 449 moveHomeStackTaskToTop(homeStackTaskType); 450 if (prev != null) { 451 prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 452 } 453 454 ActivityRecord r = mHomeStack.topRunningActivityLocked(null); 455 // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) { 456 if (r != null && r.isHomeActivity()) { 457 mService.setFocusedActivityLocked(r); 458 return resumeTopActivitiesLocked(mHomeStack, prev, null); 459 } 460 return mService.startHomeActivityLocked(mCurrentUser); 461 } 462 463 TaskRecord anyTaskForIdLocked(int id) { 464 int numDisplays = mActivityDisplays.size(); 465 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 466 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 467 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 468 ActivityStack stack = stacks.get(stackNdx); 469 TaskRecord task = stack.taskForIdLocked(id); 470 if (task != null) { 471 return task; 472 } 473 } 474 } 475 476 // Don't give up! Look in recents. 477 if (DEBUG_RECENTS) Slog.v(TAG, "Looking for task id=" + id + " in recents"); 478 TaskRecord task = mRecentTasks.taskForIdLocked(id); 479 if (task == null) { 480 if (DEBUG_RECENTS) Slog.d(TAG, "\tDidn't find task id=" + id + " in recents"); 481 return null; 482 } 483 484 if (!restoreRecentTaskLocked(task)) { 485 if (DEBUG_RECENTS) Slog.w(TAG, "Couldn't restore task id=" + id + " found in recents"); 486 return null; 487 } 488 if (DEBUG_RECENTS) Slog.w(TAG, "Restored task id=" + id + " from in recents"); 489 return task; 490 } 491 492 ActivityRecord isInAnyStackLocked(IBinder token) { 493 int numDisplays = mActivityDisplays.size(); 494 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 495 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 496 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 497 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); 498 if (r != null) { 499 return r; 500 } 501 } 502 } 503 return null; 504 } 505 506 void setNextTaskId(int taskId) { 507 if (taskId > mCurTaskId) { 508 mCurTaskId = taskId; 509 } 510 } 511 512 int getNextTaskId() { 513 do { 514 mCurTaskId++; 515 if (mCurTaskId <= 0) { 516 mCurTaskId = 1; 517 } 518 } while (anyTaskForIdLocked(mCurTaskId) != null); 519 return mCurTaskId; 520 } 521 522 ActivityRecord resumedAppLocked() { 523 ActivityStack stack = getFocusedStack(); 524 if (stack == null) { 525 return null; 526 } 527 ActivityRecord resumedActivity = stack.mResumedActivity; 528 if (resumedActivity == null || resumedActivity.app == null) { 529 resumedActivity = stack.mPausingActivity; 530 if (resumedActivity == null || resumedActivity.app == null) { 531 resumedActivity = stack.topRunningActivityLocked(null); 532 } 533 } 534 return resumedActivity; 535 } 536 537 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { 538 final String processName = app.processName; 539 boolean didSomething = false; 540 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 541 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 542 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 543 final ActivityStack stack = stacks.get(stackNdx); 544 if (!isFrontStack(stack)) { 545 continue; 546 } 547 ActivityRecord hr = stack.topRunningActivityLocked(null); 548 if (hr != null) { 549 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 550 && processName.equals(hr.processName)) { 551 try { 552 if (realStartActivityLocked(hr, app, true, true)) { 553 didSomething = true; 554 } 555 } catch (RemoteException e) { 556 Slog.w(TAG, "Exception in new application when starting activity " 557 + hr.intent.getComponent().flattenToShortString(), e); 558 throw e; 559 } 560 } 561 } 562 } 563 } 564 if (!didSomething) { 565 ensureActivitiesVisibleLocked(null, 0); 566 } 567 return didSomething; 568 } 569 570 boolean allResumedActivitiesIdle() { 571 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 572 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 573 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 574 final ActivityStack stack = stacks.get(stackNdx); 575 if (!isFrontStack(stack) || stack.numActivities() == 0) { 576 continue; 577 } 578 final ActivityRecord resumedActivity = stack.mResumedActivity; 579 if (resumedActivity == null || !resumedActivity.idle) { 580 if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack=" 581 + stack.mStackId + " " + resumedActivity + " not idle"); 582 return false; 583 } 584 } 585 } 586 return true; 587 } 588 589 boolean allResumedActivitiesComplete() { 590 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 591 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 592 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 593 final ActivityStack stack = stacks.get(stackNdx); 594 if (isFrontStack(stack)) { 595 final ActivityRecord r = stack.mResumedActivity; 596 if (r != null && r.state != ActivityState.RESUMED) { 597 return false; 598 } 599 } 600 } 601 } 602 // TODO: Not sure if this should check if all Paused are complete too. 603 if (DEBUG_STACK) Slog.d(TAG, 604 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 605 mLastFocusedStack + " to=" + mFocusedStack); 606 mLastFocusedStack = mFocusedStack; 607 return true; 608 } 609 610 boolean allResumedActivitiesVisible() { 611 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 612 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 613 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 614 final ActivityStack stack = stacks.get(stackNdx); 615 final ActivityRecord r = stack.mResumedActivity; 616 if (r != null && (!r.nowVisible || mWaitingVisibleActivities.contains(r))) { 617 return false; 618 } 619 } 620 } 621 return true; 622 } 623 624 /** 625 * Pause all activities in either all of the stacks or just the back stacks. 626 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 627 * @return true if any activity was paused as a result of this call. 628 */ 629 boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) { 630 boolean someActivityPaused = false; 631 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 632 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 633 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 634 final ActivityStack stack = stacks.get(stackNdx); 635 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 636 if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + 637 " mResumedActivity=" + stack.mResumedActivity); 638 someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, 639 dontWait); 640 } 641 } 642 } 643 return someActivityPaused; 644 } 645 646 boolean allPausedActivitiesComplete() { 647 boolean pausing = true; 648 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 649 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 650 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 651 final ActivityStack stack = stacks.get(stackNdx); 652 final ActivityRecord r = stack.mPausingActivity; 653 if (r != null && r.state != ActivityState.PAUSED 654 && r.state != ActivityState.STOPPED 655 && r.state != ActivityState.STOPPING) { 656 if (DEBUG_STATES) { 657 Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 658 pausing = false; 659 } else { 660 return false; 661 } 662 } 663 } 664 } 665 return pausing; 666 } 667 668 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping, 669 boolean resuming, boolean dontWait) { 670 // TODO: Put all stacks in supervisor and iterate through them instead. 671 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 672 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 673 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 674 final ActivityStack stack = stacks.get(stackNdx); 675 if (stack.mResumedActivity != null && 676 stack.mActivityContainer.mParentActivity == parent) { 677 stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait); 678 } 679 } 680 } 681 } 682 683 void reportActivityVisibleLocked(ActivityRecord r) { 684 sendWaitingVisibleReportLocked(r); 685 } 686 687 void sendWaitingVisibleReportLocked(ActivityRecord r) { 688 boolean changed = false; 689 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 690 WaitResult w = mWaitingActivityVisible.get(i); 691 if (w.who == null) { 692 changed = true; 693 w.timeout = false; 694 if (r != null) { 695 w.who = new ComponentName(r.info.packageName, r.info.name); 696 } 697 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 698 w.thisTime = w.totalTime; 699 } 700 } 701 if (changed) { 702 mService.notifyAll(); 703 } 704 } 705 706 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 707 long thisTime, long totalTime) { 708 boolean changed = false; 709 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 710 WaitResult w = mWaitingActivityLaunched.remove(i); 711 if (w.who == null) { 712 changed = true; 713 w.timeout = timeout; 714 if (r != null) { 715 w.who = new ComponentName(r.info.packageName, r.info.name); 716 } 717 w.thisTime = thisTime; 718 w.totalTime = totalTime; 719 } 720 } 721 if (changed) { 722 mService.notifyAll(); 723 } 724 } 725 726 ActivityRecord topRunningActivityLocked() { 727 final ActivityStack focusedStack = getFocusedStack(); 728 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 729 if (r != null) { 730 return r; 731 } 732 733 // Return to the home stack. 734 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 735 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 736 final ActivityStack stack = stacks.get(stackNdx); 737 if (stack != focusedStack && isFrontStack(stack)) { 738 r = stack.topRunningActivityLocked(null); 739 if (r != null) { 740 return r; 741 } 742 } 743 } 744 return null; 745 } 746 747 void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) { 748 // Gather all of the running tasks for each stack into runningTaskLists. 749 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = 750 new ArrayList<ArrayList<RunningTaskInfo>>(); 751 final int numDisplays = mActivityDisplays.size(); 752 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 753 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 754 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 755 final ActivityStack stack = stacks.get(stackNdx); 756 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>(); 757 runningTaskLists.add(stackTaskList); 758 stack.getTasksLocked(stackTaskList, callingUid, allowed); 759 } 760 } 761 762 // The lists are already sorted from most recent to oldest. Just pull the most recent off 763 // each list and add it to list. Stop when all lists are empty or maxNum reached. 764 while (maxNum > 0) { 765 long mostRecentActiveTime = Long.MIN_VALUE; 766 ArrayList<RunningTaskInfo> selectedStackList = null; 767 final int numTaskLists = runningTaskLists.size(); 768 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { 769 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); 770 if (!stackTaskList.isEmpty()) { 771 final long lastActiveTime = stackTaskList.get(0).lastActiveTime; 772 if (lastActiveTime > mostRecentActiveTime) { 773 mostRecentActiveTime = lastActiveTime; 774 selectedStackList = stackTaskList; 775 } 776 } 777 } 778 if (selectedStackList != null) { 779 list.add(selectedStackList.remove(0)); 780 --maxNum; 781 } else { 782 break; 783 } 784 } 785 } 786 787 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 788 ProfilerInfo profilerInfo, int userId) { 789 // Collect information about the target of the Intent. 790 ActivityInfo aInfo; 791 try { 792 ResolveInfo rInfo = 793 AppGlobals.getPackageManager().resolveIntent( 794 intent, resolvedType, 795 PackageManager.MATCH_DEFAULT_ONLY 796 | ActivityManagerService.STOCK_PM_FLAGS, userId); 797 aInfo = rInfo != null ? rInfo.activityInfo : null; 798 } catch (RemoteException e) { 799 aInfo = null; 800 } 801 802 if (aInfo != null) { 803 // Store the found target back into the intent, because now that 804 // we have it we never want to do this again. For example, if the 805 // user navigates back to this point in the history, we should 806 // always restart the exact same activity. 807 intent.setComponent(new ComponentName( 808 aInfo.applicationInfo.packageName, aInfo.name)); 809 810 // Don't debug things in the system process 811 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 812 if (!aInfo.processName.equals("system")) { 813 mService.setDebugApp(aInfo.processName, true, false); 814 } 815 } 816 817 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 818 if (!aInfo.processName.equals("system")) { 819 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 820 } 821 } 822 823 if (profilerInfo != null) { 824 if (!aInfo.processName.equals("system")) { 825 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo); 826 } 827 } 828 } 829 return aInfo; 830 } 831 832 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 833 moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE); 834 startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 835 0, 0, 0, null, false, null, null, null); 836 } 837 838 final int startActivityMayWait(IApplicationThread caller, int callingUid, 839 String callingPackage, Intent intent, String resolvedType, 840 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 841 IBinder resultTo, String resultWho, int requestCode, int startFlags, 842 ProfilerInfo profilerInfo, WaitResult outResult, Configuration config, 843 Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) { 844 // Refuse possible leaked file descriptors 845 if (intent != null && intent.hasFileDescriptors()) { 846 throw new IllegalArgumentException("File descriptors passed in Intent"); 847 } 848 boolean componentSpecified = intent.getComponent() != null; 849 850 // Don't modify the client's object! 851 intent = new Intent(intent); 852 853 // Collect information about the target of the Intent. 854 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 855 profilerInfo, userId); 856 857 ActivityContainer container = (ActivityContainer)iContainer; 858 synchronized (mService) { 859 final int realCallingPid = Binder.getCallingPid(); 860 final int realCallingUid = Binder.getCallingUid(); 861 int callingPid; 862 if (callingUid >= 0) { 863 callingPid = -1; 864 } else if (caller == null) { 865 callingPid = realCallingPid; 866 callingUid = realCallingUid; 867 } else { 868 callingPid = callingUid = -1; 869 } 870 871 final ActivityStack stack; 872 if (container == null || container.mStack.isOnHomeDisplay()) { 873 stack = getFocusedStack(); 874 } else { 875 stack = container.mStack; 876 } 877 stack.mConfigWillChange = config != null 878 && mService.mConfiguration.diff(config) != 0; 879 if (DEBUG_CONFIGURATION) Slog.v(TAG, 880 "Starting activity when config will change = " + stack.mConfigWillChange); 881 882 final long origId = Binder.clearCallingIdentity(); 883 884 if (aInfo != null && 885 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 886 // This may be a heavy-weight process! Check to see if we already 887 // have another, different heavy-weight process running. 888 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 889 if (mService.mHeavyWeightProcess != null && 890 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 891 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 892 int appCallingUid = callingUid; 893 if (caller != null) { 894 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 895 if (callerApp != null) { 896 appCallingUid = callerApp.info.uid; 897 } else { 898 Slog.w(TAG, "Unable to find app for caller " + caller 899 + " (pid=" + callingPid + ") when starting: " 900 + intent.toString()); 901 ActivityOptions.abort(options); 902 return ActivityManager.START_PERMISSION_DENIED; 903 } 904 } 905 906 IIntentSender target = mService.getIntentSenderLocked( 907 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 908 appCallingUid, userId, null, null, 0, new Intent[] { intent }, 909 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 910 | PendingIntent.FLAG_ONE_SHOT, null); 911 912 Intent newIntent = new Intent(); 913 if (requestCode >= 0) { 914 // Caller is requesting a result. 915 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 916 } 917 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 918 new IntentSender(target)); 919 if (mService.mHeavyWeightProcess.activities.size() > 0) { 920 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 921 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 922 hist.packageName); 923 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 924 hist.task.taskId); 925 } 926 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 927 aInfo.packageName); 928 newIntent.setFlags(intent.getFlags()); 929 newIntent.setClassName("android", 930 HeavyWeightSwitcherActivity.class.getName()); 931 intent = newIntent; 932 resolvedType = null; 933 caller = null; 934 callingUid = Binder.getCallingUid(); 935 callingPid = Binder.getCallingPid(); 936 componentSpecified = true; 937 try { 938 ResolveInfo rInfo = 939 AppGlobals.getPackageManager().resolveIntent( 940 intent, null, 941 PackageManager.MATCH_DEFAULT_ONLY 942 | ActivityManagerService.STOCK_PM_FLAGS, userId); 943 aInfo = rInfo != null ? rInfo.activityInfo : null; 944 aInfo = mService.getActivityInfoForUser(aInfo, userId); 945 } catch (RemoteException e) { 946 aInfo = null; 947 } 948 } 949 } 950 } 951 952 int res = startActivityLocked(caller, intent, resolvedType, aInfo, 953 voiceSession, voiceInteractor, resultTo, resultWho, 954 requestCode, callingPid, callingUid, callingPackage, 955 realCallingPid, realCallingUid, startFlags, options, 956 componentSpecified, null, container, inTask); 957 958 Binder.restoreCallingIdentity(origId); 959 960 if (stack.mConfigWillChange) { 961 // If the caller also wants to switch to a new configuration, 962 // do so now. This allows a clean switch, as we are waiting 963 // for the current activity to pause (so we will not destroy 964 // it), and have not yet started the next activity. 965 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 966 "updateConfiguration()"); 967 stack.mConfigWillChange = false; 968 if (DEBUG_CONFIGURATION) Slog.v(TAG, 969 "Updating to new configuration after starting activity."); 970 mService.updateConfigurationLocked(config, null, false, false); 971 } 972 973 if (outResult != null) { 974 outResult.result = res; 975 if (res == ActivityManager.START_SUCCESS) { 976 mWaitingActivityLaunched.add(outResult); 977 do { 978 try { 979 mService.wait(); 980 } catch (InterruptedException e) { 981 } 982 } while (!outResult.timeout && outResult.who == null); 983 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 984 ActivityRecord r = stack.topRunningActivityLocked(null); 985 if (r.nowVisible && r.state == ActivityState.RESUMED) { 986 outResult.timeout = false; 987 outResult.who = new ComponentName(r.info.packageName, r.info.name); 988 outResult.totalTime = 0; 989 outResult.thisTime = 0; 990 } else { 991 outResult.thisTime = SystemClock.uptimeMillis(); 992 mWaitingActivityVisible.add(outResult); 993 do { 994 try { 995 mService.wait(); 996 } catch (InterruptedException e) { 997 } 998 } while (!outResult.timeout && outResult.who == null); 999 } 1000 } 1001 } 1002 1003 return res; 1004 } 1005 } 1006 1007 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 1008 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 1009 Bundle options, int userId) { 1010 if (intents == null) { 1011 throw new NullPointerException("intents is null"); 1012 } 1013 if (resolvedTypes == null) { 1014 throw new NullPointerException("resolvedTypes is null"); 1015 } 1016 if (intents.length != resolvedTypes.length) { 1017 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 1018 } 1019 1020 1021 int callingPid; 1022 if (callingUid >= 0) { 1023 callingPid = -1; 1024 } else if (caller == null) { 1025 callingPid = Binder.getCallingPid(); 1026 callingUid = Binder.getCallingUid(); 1027 } else { 1028 callingPid = callingUid = -1; 1029 } 1030 final long origId = Binder.clearCallingIdentity(); 1031 try { 1032 synchronized (mService) { 1033 ActivityRecord[] outActivity = new ActivityRecord[1]; 1034 for (int i=0; i<intents.length; i++) { 1035 Intent intent = intents[i]; 1036 if (intent == null) { 1037 continue; 1038 } 1039 1040 // Refuse possible leaked file descriptors 1041 if (intent != null && intent.hasFileDescriptors()) { 1042 throw new IllegalArgumentException("File descriptors passed in Intent"); 1043 } 1044 1045 boolean componentSpecified = intent.getComponent() != null; 1046 1047 // Don't modify the client's object! 1048 intent = new Intent(intent); 1049 1050 // Collect information about the target of the Intent. 1051 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 0, null, userId); 1052 // TODO: New, check if this is correct 1053 aInfo = mService.getActivityInfoForUser(aInfo, userId); 1054 1055 if (aInfo != null && 1056 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 1057 != 0) { 1058 throw new IllegalArgumentException( 1059 "FLAG_CANT_SAVE_STATE not supported here"); 1060 } 1061 1062 Bundle theseOptions; 1063 if (options != null && i == intents.length-1) { 1064 theseOptions = options; 1065 } else { 1066 theseOptions = null; 1067 } 1068 int res = startActivityLocked(caller, intent, resolvedTypes[i], 1069 aInfo, null, null, resultTo, null, -1, callingPid, callingUid, 1070 callingPackage, callingPid, callingUid, 1071 0, theseOptions, componentSpecified, outActivity, null, null); 1072 if (res < 0) { 1073 return res; 1074 } 1075 1076 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 1077 } 1078 } 1079 } finally { 1080 Binder.restoreCallingIdentity(origId); 1081 } 1082 1083 return ActivityManager.START_SUCCESS; 1084 } 1085 1086 final boolean realStartActivityLocked(ActivityRecord r, 1087 ProcessRecord app, boolean andResume, boolean checkConfig) 1088 throws RemoteException { 1089 1090 r.startFreezingScreenLocked(app, 0); 1091 if (false) Slog.d(TAG, "realStartActivity: setting app visibility true"); 1092 mWindowManager.setAppVisibility(r.appToken, true); 1093 1094 // schedule launch ticks to collect information about slow apps. 1095 r.startLaunchTickingLocked(); 1096 1097 // Have the window manager re-evaluate the orientation of 1098 // the screen based on the new activity order. Note that 1099 // as a result of this, it can call back into the activity 1100 // manager with a new orientation. We don't care about that, 1101 // because the activity is not currently running so we are 1102 // just restarting it anyway. 1103 if (checkConfig) { 1104 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1105 mService.mConfiguration, 1106 r.mayFreezeScreenLocked(app) ? r.appToken : null); 1107 mService.updateConfigurationLocked(config, r, false, false); 1108 } 1109 1110 r.app = app; 1111 app.waitingToKill = null; 1112 r.launchCount++; 1113 r.lastLaunchTime = SystemClock.uptimeMillis(); 1114 1115 if (localLOGV) Slog.v(TAG, "Launching: " + r); 1116 1117 int idx = app.activities.indexOf(r); 1118 if (idx < 0) { 1119 app.activities.add(r); 1120 } 1121 mService.updateLruProcessLocked(app, true, null); 1122 mService.updateOomAdjLocked(); 1123 1124 final ActivityStack stack = r.task.stack; 1125 try { 1126 if (app.thread == null) { 1127 throw new RemoteException(); 1128 } 1129 List<ResultInfo> results = null; 1130 List<ReferrerIntent> newIntents = null; 1131 if (andResume) { 1132 results = r.results; 1133 newIntents = r.newIntents; 1134 } 1135 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 1136 + " icicle=" + r.icicle 1137 + " with results=" + results + " newIntents=" + newIntents 1138 + " andResume=" + andResume); 1139 if (andResume) { 1140 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1141 r.userId, System.identityHashCode(r), 1142 r.task.taskId, r.shortComponentName); 1143 } 1144 if (r.isHomeActivity() && r.isNotResolverActivity()) { 1145 // Home process is the root process of the task. 1146 mService.mHomeProcess = r.task.mActivities.get(0).app; 1147 } 1148 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1149 r.sleeping = false; 1150 r.forceNewConfig = false; 1151 mService.showAskCompatModeDialogLocked(r); 1152 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1153 String profileFile = null; 1154 ParcelFileDescriptor profileFd = null; 1155 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1156 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1157 mService.mProfileProc = app; 1158 profileFile = mService.mProfileFile; 1159 profileFd = mService.mProfileFd; 1160 } 1161 } 1162 app.hasShownUi = true; 1163 app.pendingUiClean = true; 1164 if (profileFd != null) { 1165 try { 1166 profileFd = profileFd.dup(); 1167 } catch (IOException e) { 1168 if (profileFd != null) { 1169 try { 1170 profileFd.close(); 1171 } catch (IOException o) { 1172 } 1173 profileFd = null; 1174 } 1175 } 1176 } 1177 1178 ProfilerInfo profilerInfo = profileFile != null 1179 ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval, 1180 mService.mAutoStopProfiler) : null; 1181 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 1182 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1183 System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), 1184 r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState, 1185 r.icicle, r.persistentState, results, newIntents, !andResume, 1186 mService.isNextTransitionForward(), profilerInfo); 1187 1188 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 1189 // This may be a heavy-weight process! Note that the package 1190 // manager will ensure that only activity can run in the main 1191 // process of the .apk, which is the only thing that will be 1192 // considered heavy-weight. 1193 if (app.processName.equals(app.info.packageName)) { 1194 if (mService.mHeavyWeightProcess != null 1195 && mService.mHeavyWeightProcess != app) { 1196 Slog.w(TAG, "Starting new heavy weight process " + app 1197 + " when already running " 1198 + mService.mHeavyWeightProcess); 1199 } 1200 mService.mHeavyWeightProcess = app; 1201 Message msg = mService.mHandler.obtainMessage( 1202 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1203 msg.obj = r; 1204 mService.mHandler.sendMessage(msg); 1205 } 1206 } 1207 1208 } catch (RemoteException e) { 1209 if (r.launchFailed) { 1210 // This is the second time we failed -- finish activity 1211 // and give up. 1212 Slog.e(TAG, "Second failure launching " 1213 + r.intent.getComponent().flattenToShortString() 1214 + ", giving up", e); 1215 mService.appDiedLocked(app); 1216 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1217 "2nd-crash", false); 1218 return false; 1219 } 1220 1221 // This is the first time we failed -- restart process and 1222 // retry. 1223 app.activities.remove(r); 1224 throw e; 1225 } 1226 1227 r.launchFailed = false; 1228 if (stack.updateLRUListLocked(r)) { 1229 Slog.w(TAG, "Activity " + r 1230 + " being launched, but already in LRU list"); 1231 } 1232 1233 if (andResume) { 1234 // As part of the process of launching, ActivityThread also performs 1235 // a resume. 1236 stack.minimalResumeActivityLocked(r); 1237 } else { 1238 // This activity is not starting in the resumed state... which 1239 // should look like we asked it to pause+stop (but remain visible), 1240 // and it has done so and reported back the current icicle and 1241 // other state. 1242 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1243 + " (starting in stopped state)"); 1244 r.state = ActivityState.STOPPED; 1245 r.stopped = true; 1246 } 1247 1248 // Launch the new version setup screen if needed. We do this -after- 1249 // launching the initial activity (that is, home), so that it can have 1250 // a chance to initialize itself while in the background, making the 1251 // switch back to it faster and look better. 1252 if (isFrontStack(stack)) { 1253 mService.startSetupActivityLocked(); 1254 } 1255 1256 // Update any services we are bound to that might care about whether 1257 // their client may have activities. 1258 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 1259 1260 return true; 1261 } 1262 1263 void startSpecificActivityLocked(ActivityRecord r, 1264 boolean andResume, boolean checkConfig) { 1265 // Is this activity's application already running? 1266 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1267 r.info.applicationInfo.uid, true); 1268 1269 r.task.stack.setLaunchTime(r); 1270 1271 if (app != null && app.thread != null) { 1272 try { 1273 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1274 || !"android".equals(r.info.packageName)) { 1275 // Don't add this if it is a platform component that is marked 1276 // to run in multiple processes, because this is actually 1277 // part of the framework so doesn't make sense to track as a 1278 // separate apk in the process. 1279 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1280 mService.mProcessStats); 1281 } 1282 realStartActivityLocked(r, app, andResume, checkConfig); 1283 return; 1284 } catch (RemoteException e) { 1285 Slog.w(TAG, "Exception when starting activity " 1286 + r.intent.getComponent().flattenToShortString(), e); 1287 } 1288 1289 // If a dead object exception was thrown -- fall through to 1290 // restart the application. 1291 } 1292 1293 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1294 "activity", r.intent.getComponent(), false, false, true); 1295 } 1296 1297 final int startActivityLocked(IApplicationThread caller, 1298 Intent intent, String resolvedType, ActivityInfo aInfo, 1299 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1300 IBinder resultTo, String resultWho, int requestCode, 1301 int callingPid, int callingUid, String callingPackage, 1302 int realCallingPid, int realCallingUid, int startFlags, Bundle options, 1303 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container, 1304 TaskRecord inTask) { 1305 int err = ActivityManager.START_SUCCESS; 1306 1307 ProcessRecord callerApp = null; 1308 if (caller != null) { 1309 callerApp = mService.getRecordForAppLocked(caller); 1310 if (callerApp != null) { 1311 callingPid = callerApp.pid; 1312 callingUid = callerApp.info.uid; 1313 } else { 1314 Slog.w(TAG, "Unable to find app for caller " + caller 1315 + " (pid=" + callingPid + ") when starting: " 1316 + intent.toString()); 1317 err = ActivityManager.START_PERMISSION_DENIED; 1318 } 1319 } 1320 1321 if (err == ActivityManager.START_SUCCESS) { 1322 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1323 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1324 + "} from uid " + callingUid 1325 + " on display " + (container == null ? (mFocusedStack == null ? 1326 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1327 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1328 container.mActivityDisplay.mDisplayId))); 1329 } 1330 1331 ActivityRecord sourceRecord = null; 1332 ActivityRecord resultRecord = null; 1333 if (resultTo != null) { 1334 sourceRecord = isInAnyStackLocked(resultTo); 1335 if (DEBUG_RESULTS) Slog.v( 1336 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1337 if (sourceRecord != null) { 1338 if (requestCode >= 0 && !sourceRecord.finishing) { 1339 resultRecord = sourceRecord; 1340 } 1341 } 1342 } 1343 1344 final int launchFlags = intent.getFlags(); 1345 1346 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { 1347 // Transfer the result target from the source activity to the new 1348 // one being started, including any failures. 1349 if (requestCode >= 0) { 1350 ActivityOptions.abort(options); 1351 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1352 } 1353 resultRecord = sourceRecord.resultTo; 1354 resultWho = sourceRecord.resultWho; 1355 requestCode = sourceRecord.requestCode; 1356 sourceRecord.resultTo = null; 1357 if (resultRecord != null) { 1358 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 1359 } 1360 if (sourceRecord.launchedFromUid == callingUid) { 1361 // The new activity is being launched from the same uid as the previous 1362 // activity in the flow, and asking to forward its result back to the 1363 // previous. In this case the activity is serving as a trampoline between 1364 // the two, so we also want to update its launchedFromPackage to be the 1365 // same as the previous activity. Note that this is safe, since we know 1366 // these two packages come from the same uid; the caller could just as 1367 // well have supplied that same package name itself. This specifially 1368 // deals with the case of an intent picker/chooser being launched in the app 1369 // flow to redirect to an activity picked by the user, where we want the final 1370 // activity to consider it to have been launched by the previous app activity. 1371 callingPackage = sourceRecord.launchedFromPackage; 1372 } 1373 } 1374 1375 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1376 // We couldn't find a class that can handle the given Intent. 1377 // That's the end of that! 1378 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1379 } 1380 1381 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1382 // We couldn't find the specific class specified in the Intent. 1383 // Also the end of the line. 1384 err = ActivityManager.START_CLASS_NOT_FOUND; 1385 } 1386 1387 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1388 && sourceRecord.task.voiceSession != null) { 1389 // If this activity is being launched as part of a voice session, we need 1390 // to ensure that it is safe to do so. If the upcoming activity will also 1391 // be part of the voice session, we can only launch it if it has explicitly 1392 // said it supports the VOICE category, or it is a part of the calling app. 1393 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1394 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1395 try { 1396 if (!AppGlobals.getPackageManager().activitySupportsIntent( 1397 intent.getComponent(), intent, resolvedType)) { 1398 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1399 } 1400 } catch (RemoteException e) { 1401 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1402 } 1403 } 1404 } 1405 1406 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1407 // If the caller is starting a new voice session, just make sure the target 1408 // is actually allowing it to run this way. 1409 try { 1410 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1411 intent, resolvedType)) { 1412 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1413 } 1414 } catch (RemoteException e) { 1415 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1416 } 1417 } 1418 1419 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1420 1421 if (err != ActivityManager.START_SUCCESS) { 1422 if (resultRecord != null) { 1423 resultStack.sendActivityResultLocked(-1, 1424 resultRecord, resultWho, requestCode, 1425 Activity.RESULT_CANCELED, null); 1426 } 1427 ActivityOptions.abort(options); 1428 return err; 1429 } 1430 1431 final int startAnyPerm = mService.checkPermission( 1432 START_ANY_ACTIVITY, callingPid, callingUid); 1433 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1434 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1435 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1436 if (resultRecord != null) { 1437 resultStack.sendActivityResultLocked(-1, 1438 resultRecord, resultWho, requestCode, 1439 Activity.RESULT_CANCELED, null); 1440 } 1441 String msg; 1442 if (!aInfo.exported) { 1443 msg = "Permission Denial: starting " + intent.toString() 1444 + " from " + callerApp + " (pid=" + callingPid 1445 + ", uid=" + callingUid + ")" 1446 + " not exported from uid " + aInfo.applicationInfo.uid; 1447 } else { 1448 msg = "Permission Denial: starting " + intent.toString() 1449 + " from " + callerApp + " (pid=" + callingPid 1450 + ", uid=" + callingUid + ")" 1451 + " requires " + aInfo.permission; 1452 } 1453 Slog.w(TAG, msg); 1454 throw new SecurityException(msg); 1455 } 1456 1457 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1458 callingPid, resolvedType, aInfo.applicationInfo); 1459 1460 if (mService.mController != null) { 1461 try { 1462 // The Intent we give to the watcher has the extra data 1463 // stripped off, since it can contain private information. 1464 Intent watchIntent = intent.cloneFilter(); 1465 abort |= !mService.mController.activityStarting(watchIntent, 1466 aInfo.applicationInfo.packageName); 1467 } catch (RemoteException e) { 1468 mService.mController = null; 1469 } 1470 } 1471 1472 if (abort) { 1473 if (resultRecord != null) { 1474 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1475 Activity.RESULT_CANCELED, null); 1476 } 1477 // We pretend to the caller that it was really started, but 1478 // they will just get a cancel result. 1479 ActivityOptions.abort(options); 1480 return ActivityManager.START_SUCCESS; 1481 } 1482 1483 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1484 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1485 requestCode, componentSpecified, this, container, options); 1486 if (outActivity != null) { 1487 outActivity[0] = r; 1488 } 1489 1490 final ActivityStack stack = getFocusedStack(); 1491 if (voiceSession == null && (stack.mResumedActivity == null 1492 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1493 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, 1494 realCallingPid, realCallingUid, "Activity start")) { 1495 PendingActivityLaunch pal = 1496 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1497 mPendingActivityLaunches.add(pal); 1498 ActivityOptions.abort(options); 1499 return ActivityManager.START_SWITCHES_CANCELED; 1500 } 1501 } 1502 1503 if (mService.mDidAppSwitch) { 1504 // This is the second allowed switch since we stopped switches, 1505 // so now just generally allow switches. Use case: user presses 1506 // home (switches disabled, switch to home, mDidAppSwitch now true); 1507 // user taps a home icon (coming from home so allowed, we hit here 1508 // and now allow anyone to switch again). 1509 mService.mAppSwitchesAllowedTime = 0; 1510 } else { 1511 mService.mDidAppSwitch = true; 1512 } 1513 1514 doPendingActivityLaunchesLocked(false); 1515 1516 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1517 startFlags, true, options, inTask); 1518 1519 if (err < 0) { 1520 // If someone asked to have the keyguard dismissed on the next 1521 // activity start, but we are not actually doing an activity 1522 // switch... just dismiss the keyguard now, because we 1523 // probably want to see whatever is behind it. 1524 notifyActivityDrawnForKeyguard(); 1525 } 1526 return err; 1527 } 1528 1529 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1530 final TaskRecord task = r.task; 1531 1532 // On leanback only devices we should keep all activities in the same stack. 1533 if (!mLeanbackOnlyDevice && 1534 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1535 if (task != null) { 1536 final ActivityStack taskStack = task.stack; 1537 if (taskStack.isOnHomeDisplay()) { 1538 if (mFocusedStack != taskStack) { 1539 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1540 "focused stack to r=" + r + " task=" + task); 1541 mFocusedStack = taskStack; 1542 } else { 1543 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1544 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1545 } 1546 } 1547 return taskStack; 1548 } 1549 1550 final ActivityContainer container = r.mInitialActivityContainer; 1551 if (container != null) { 1552 // The first time put it on the desired stack, after this put on task stack. 1553 r.mInitialActivityContainer = null; 1554 return container.mStack; 1555 } 1556 1557 if (mFocusedStack != mHomeStack && (!newTask || 1558 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1559 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1560 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1561 return mFocusedStack; 1562 } 1563 1564 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1565 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1566 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1567 if (!stack.isHomeStack()) { 1568 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1569 "adjustStackFocus: Setting focused stack=" + stack); 1570 mFocusedStack = stack; 1571 return mFocusedStack; 1572 } 1573 } 1574 1575 // Need to create an app stack for this user. 1576 mFocusedStack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1577 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1578 " stackId=" + mFocusedStack.mStackId); 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, String reason) { 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, reason); 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 createVirtualActivityContainer(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 ActivityStack createStackOnDisplay(int stackId, int displayId) { 2599 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2600 if (activityDisplay == null) { 2601 return null; 2602 } 2603 2604 ActivityContainer activityContainer = new ActivityContainer(stackId); 2605 mActivityContainers.put(stackId, activityContainer); 2606 activityContainer.attachToDisplayLocked(activityDisplay); 2607 return activityContainer.mStack; 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 = 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 mRecentTasks.addLocked(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 ArrayList<ActivityRecord> stops = null; 3072 3073 final boolean nowVisible = allResumedActivitiesVisible(); 3074 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3075 ActivityRecord s = mStoppingActivities.get(activityNdx); 3076 final boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3077 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3078 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3079 if (waitingVisible && nowVisible) { 3080 mWaitingVisibleActivities.remove(s); 3081 if (s.finishing) { 3082 // If this activity is finishing, it is sitting on top of 3083 // everyone else but we now know it is no longer needed... 3084 // so get rid of it. Otherwise, we need to go through the 3085 // normal flow and hide it once we determine that it is 3086 // hidden by the activities in front of it. 3087 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 3088 mWindowManager.setAppVisibility(s.appToken, false); 3089 } 3090 } 3091 if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3092 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 3093 if (stops == null) { 3094 stops = new ArrayList<>(); 3095 } 3096 stops.add(s); 3097 mStoppingActivities.remove(activityNdx); 3098 } 3099 } 3100 3101 return stops; 3102 } 3103 3104 void validateTopActivitiesLocked() { 3105 // FIXME 3106/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3107 final ActivityStack stack = stacks.get(stackNdx); 3108 final ActivityRecord r = stack.topRunningActivityLocked(null); 3109 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 3110 if (isFrontStack(stack)) { 3111 if (r == null) { 3112 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 3113 } else { 3114 final ActivityRecord pausing = stack.mPausingActivity; 3115 if (pausing != null && pausing == r) { 3116 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 3117 " state=" + state); 3118 } 3119 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 3120 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 3121 " state=" + state); 3122 } 3123 } 3124 } else { 3125 final ActivityRecord resumed = stack.mResumedActivity; 3126 if (resumed != null && resumed == r) { 3127 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 3128 " state=" + state); 3129 } 3130 if (r != null && (state == ActivityState.INITIALIZING 3131 || state == ActivityState.RESUMED)) { 3132 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 3133 " state=" + state); 3134 } 3135 } 3136 } 3137*/ 3138 } 3139 3140 public void dump(PrintWriter pw, String prefix) { 3141 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3142 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3143 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3144 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 3145 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3146 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3147 } 3148 3149 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3150 return getFocusedStack().getDumpActivitiesLocked(name); 3151 } 3152 3153 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3154 boolean needSep, String prefix) { 3155 if (activity != null) { 3156 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3157 if (needSep) { 3158 pw.println(); 3159 } 3160 pw.print(prefix); 3161 pw.println(activity); 3162 return true; 3163 } 3164 } 3165 return false; 3166 } 3167 3168 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3169 boolean dumpClient, String dumpPackage) { 3170 boolean printed = false; 3171 boolean needSep = false; 3172 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3173 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3174 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3175 pw.println(" (activities from top to bottom):"); 3176 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3177 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3178 final ActivityStack stack = stacks.get(stackNdx); 3179 StringBuilder stackHeader = new StringBuilder(128); 3180 stackHeader.append(" Stack #"); 3181 stackHeader.append(stack.mStackId); 3182 stackHeader.append(":"); 3183 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3184 needSep, stackHeader.toString()); 3185 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3186 !dumpAll, false, dumpPackage, true, 3187 " Running activities (most recent first):", null); 3188 3189 needSep = printed; 3190 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3191 " mPausingActivity: "); 3192 if (pr) { 3193 printed = true; 3194 needSep = false; 3195 } 3196 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3197 " mResumedActivity: "); 3198 if (pr) { 3199 printed = true; 3200 needSep = false; 3201 } 3202 if (dumpAll) { 3203 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3204 " mLastPausedActivity: "); 3205 if (pr) { 3206 printed = true; 3207 needSep = true; 3208 } 3209 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3210 needSep, " mLastNoHistoryActivity: "); 3211 } 3212 needSep = printed; 3213 } 3214 } 3215 3216 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3217 false, dumpPackage, true, " Activities waiting to finish:", null); 3218 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3219 false, dumpPackage, true, " Activities waiting to stop:", null); 3220 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3221 false, dumpPackage, true, " Activities waiting for another to become visible:", 3222 null); 3223 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3224 false, dumpPackage, true, " Activities waiting to sleep:", null); 3225 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3226 false, dumpPackage, true, " Activities waiting to sleep:", null); 3227 3228 return printed; 3229 } 3230 3231 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3232 String prefix, String label, boolean complete, boolean brief, boolean client, 3233 String dumpPackage, boolean needNL, String header1, String header2) { 3234 TaskRecord lastTask = null; 3235 String innerPrefix = null; 3236 String[] args = null; 3237 boolean printed = false; 3238 for (int i=list.size()-1; i>=0; i--) { 3239 final ActivityRecord r = list.get(i); 3240 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3241 continue; 3242 } 3243 if (innerPrefix == null) { 3244 innerPrefix = prefix + " "; 3245 args = new String[0]; 3246 } 3247 printed = true; 3248 final boolean full = !brief && (complete || !r.isInHistory()); 3249 if (needNL) { 3250 pw.println(""); 3251 needNL = false; 3252 } 3253 if (header1 != null) { 3254 pw.println(header1); 3255 header1 = null; 3256 } 3257 if (header2 != null) { 3258 pw.println(header2); 3259 header2 = null; 3260 } 3261 if (lastTask != r.task) { 3262 lastTask = r.task; 3263 pw.print(prefix); 3264 pw.print(full ? "* " : " "); 3265 pw.println(lastTask); 3266 if (full) { 3267 lastTask.dump(pw, prefix + " "); 3268 } else if (complete) { 3269 // Complete + brief == give a summary. Isn't that obvious?!? 3270 if (lastTask.intent != null) { 3271 pw.print(prefix); pw.print(" "); 3272 pw.println(lastTask.intent.toInsecureStringWithClip()); 3273 } 3274 } 3275 } 3276 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3277 pw.print(" #"); pw.print(i); pw.print(": "); 3278 pw.println(r); 3279 if (full) { 3280 r.dump(pw, innerPrefix); 3281 } else if (complete) { 3282 // Complete + brief == give a summary. Isn't that obvious?!? 3283 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3284 if (r.app != null) { 3285 pw.print(innerPrefix); pw.println(r.app); 3286 } 3287 } 3288 if (client && r.app != null && r.app.thread != null) { 3289 // flush anything that is already in the PrintWriter since the thread is going 3290 // to write to the file descriptor directly 3291 pw.flush(); 3292 try { 3293 TransferPipe tp = new TransferPipe(); 3294 try { 3295 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3296 r.appToken, innerPrefix, args); 3297 // Short timeout, since blocking here can 3298 // deadlock with the application. 3299 tp.go(fd, 2000); 3300 } finally { 3301 tp.kill(); 3302 } 3303 } catch (IOException e) { 3304 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3305 } catch (RemoteException e) { 3306 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3307 } 3308 needNL = true; 3309 } 3310 } 3311 return printed; 3312 } 3313 3314 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3315 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3316 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3317 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3318 } 3319 3320 final void scheduleIdleLocked() { 3321 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3322 } 3323 3324 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3325 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 3326 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3327 } 3328 3329 final void scheduleResumeTopActivities() { 3330 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3331 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3332 } 3333 } 3334 3335 void removeSleepTimeouts() { 3336 mSleepTimeout = false; 3337 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3338 } 3339 3340 final void scheduleSleepTimeout() { 3341 removeSleepTimeouts(); 3342 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3343 } 3344 3345 @Override 3346 public void onDisplayAdded(int displayId) { 3347 Slog.v(TAG, "Display added displayId=" + displayId); 3348 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3349 } 3350 3351 @Override 3352 public void onDisplayRemoved(int displayId) { 3353 Slog.v(TAG, "Display removed displayId=" + displayId); 3354 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3355 } 3356 3357 @Override 3358 public void onDisplayChanged(int displayId) { 3359 Slog.v(TAG, "Display changed displayId=" + displayId); 3360 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3361 } 3362 3363 public void handleDisplayAddedLocked(int displayId) { 3364 boolean newDisplay; 3365 synchronized (mService) { 3366 newDisplay = mActivityDisplays.get(displayId) == null; 3367 if (newDisplay) { 3368 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3369 if (activityDisplay.mDisplay == null) { 3370 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3371 return; 3372 } 3373 mActivityDisplays.put(displayId, activityDisplay); 3374 } 3375 } 3376 if (newDisplay) { 3377 mWindowManager.onDisplayAdded(displayId); 3378 } 3379 } 3380 3381 public void handleDisplayRemovedLocked(int displayId) { 3382 synchronized (mService) { 3383 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3384 if (activityDisplay != null) { 3385 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3386 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3387 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3388 } 3389 mActivityDisplays.remove(displayId); 3390 } 3391 } 3392 mWindowManager.onDisplayRemoved(displayId); 3393 } 3394 3395 public void handleDisplayChangedLocked(int displayId) { 3396 synchronized (mService) { 3397 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3398 if (activityDisplay != null) { 3399 // TODO: Update the bounds. 3400 } 3401 } 3402 mWindowManager.onDisplayChanged(displayId); 3403 } 3404 3405 StackInfo getStackInfo(ActivityStack stack) { 3406 StackInfo info = new StackInfo(); 3407 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3408 info.displayId = Display.DEFAULT_DISPLAY; 3409 info.stackId = stack.mStackId; 3410 3411 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3412 final int numTasks = tasks.size(); 3413 int[] taskIds = new int[numTasks]; 3414 String[] taskNames = new String[numTasks]; 3415 for (int i = 0; i < numTasks; ++i) { 3416 final TaskRecord task = tasks.get(i); 3417 taskIds[i] = task.taskId; 3418 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3419 : task.realActivity != null ? task.realActivity.flattenToString() 3420 : task.getTopActivity() != null ? task.getTopActivity().packageName 3421 : "unknown"; 3422 } 3423 info.taskIds = taskIds; 3424 info.taskNames = taskNames; 3425 return info; 3426 } 3427 3428 StackInfo getStackInfoLocked(int stackId) { 3429 ActivityStack stack = getStack(stackId); 3430 if (stack != null) { 3431 return getStackInfo(stack); 3432 } 3433 return null; 3434 } 3435 3436 ArrayList<StackInfo> getAllStackInfosLocked() { 3437 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 3438 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3439 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3440 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3441 list.add(getStackInfo(stacks.get(ndx))); 3442 } 3443 } 3444 return list; 3445 } 3446 3447 void showLockTaskToast() { 3448 mLockTaskNotify.showToast(mLockTaskIsLocked); 3449 } 3450 3451 void setLockTaskModeLocked(TaskRecord task, boolean isLocked) { 3452 if (task == null) { 3453 // Take out of lock task mode if necessary 3454 if (mLockTaskModeTask != null) { 3455 final Message lockTaskMsg = Message.obtain(); 3456 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3457 lockTaskMsg.what = LOCK_TASK_END_MSG; 3458 mLockTaskModeTask = null; 3459 mHandler.sendMessage(lockTaskMsg); 3460 } 3461 return; 3462 } 3463 if (isLockTaskModeViolation(task)) { 3464 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 3465 return; 3466 } 3467 mLockTaskModeTask = task; 3468 findTaskToMoveToFrontLocked(task, 0, null); 3469 resumeTopActivitiesLocked(); 3470 3471 final Message lockTaskMsg = Message.obtain(); 3472 lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName(); 3473 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3474 lockTaskMsg.what = LOCK_TASK_START_MSG; 3475 lockTaskMsg.arg2 = !isLocked ? 1 : 0; 3476 mHandler.sendMessage(lockTaskMsg); 3477 } 3478 3479 boolean isLockTaskModeViolation(TaskRecord task) { 3480 return mLockTaskModeTask != null && mLockTaskModeTask != task; 3481 } 3482 3483 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3484 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3485 final Message lockTaskMsg = Message.obtain(); 3486 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3487 lockTaskMsg.what = LOCK_TASK_END_MSG; 3488 mLockTaskModeTask = null; 3489 mHandler.sendMessage(lockTaskMsg); 3490 } 3491 } 3492 3493 boolean isInLockTaskMode() { 3494 return mLockTaskModeTask != null; 3495 } 3496 3497 private final class ActivityStackSupervisorHandler extends Handler { 3498 3499 public ActivityStackSupervisorHandler(Looper looper) { 3500 super(looper); 3501 } 3502 3503 void activityIdleInternal(ActivityRecord r) { 3504 synchronized (mService) { 3505 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3506 } 3507 } 3508 3509 @Override 3510 public void handleMessage(Message msg) { 3511 switch (msg.what) { 3512 case IDLE_TIMEOUT_MSG: { 3513 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3514 if (mService.mDidDexOpt) { 3515 mService.mDidDexOpt = false; 3516 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3517 nmsg.obj = msg.obj; 3518 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3519 return; 3520 } 3521 // We don't at this point know if the activity is fullscreen, 3522 // so we need to be conservative and assume it isn't. 3523 activityIdleInternal((ActivityRecord)msg.obj); 3524 } break; 3525 case IDLE_NOW_MSG: { 3526 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3527 activityIdleInternal((ActivityRecord)msg.obj); 3528 } break; 3529 case RESUME_TOP_ACTIVITY_MSG: { 3530 synchronized (mService) { 3531 resumeTopActivitiesLocked(); 3532 } 3533 } break; 3534 case SLEEP_TIMEOUT_MSG: { 3535 synchronized (mService) { 3536 if (mService.isSleepingOrShuttingDown()) { 3537 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3538 mSleepTimeout = true; 3539 checkReadyForSleepLocked(); 3540 } 3541 } 3542 } break; 3543 case LAUNCH_TIMEOUT_MSG: { 3544 if (mService.mDidDexOpt) { 3545 mService.mDidDexOpt = false; 3546 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3547 return; 3548 } 3549 synchronized (mService) { 3550 if (mLaunchingActivity.isHeld()) { 3551 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3552 if (VALIDATE_WAKE_LOCK_CALLER 3553 && Binder.getCallingUid() != Process.myUid()) { 3554 throw new IllegalStateException("Calling must be system uid"); 3555 } 3556 mLaunchingActivity.release(); 3557 } 3558 } 3559 } break; 3560 case HANDLE_DISPLAY_ADDED: { 3561 handleDisplayAddedLocked(msg.arg1); 3562 } break; 3563 case HANDLE_DISPLAY_CHANGED: { 3564 handleDisplayChangedLocked(msg.arg1); 3565 } break; 3566 case HANDLE_DISPLAY_REMOVED: { 3567 handleDisplayRemovedLocked(msg.arg1); 3568 } break; 3569 case CONTAINER_CALLBACK_VISIBILITY: { 3570 final ActivityContainer container = (ActivityContainer) msg.obj; 3571 final IActivityContainerCallback callback = container.mCallback; 3572 if (callback != null) { 3573 try { 3574 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3575 } catch (RemoteException e) { 3576 } 3577 } 3578 } break; 3579 case LOCK_TASK_START_MSG: { 3580 // When lock task starts, we disable the status bars. 3581 try { 3582 if (mLockTaskNotify == null) { 3583 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3584 } 3585 mLockTaskNotify.show(true); 3586 mLockTaskIsLocked = msg.arg2 == 0; 3587 if (getStatusBarService() != null) { 3588 int flags = 3589 StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK; 3590 if (!mLockTaskIsLocked) { 3591 flags ^= StatusBarManager.DISABLE_HOME 3592 | StatusBarManager.DISABLE_RECENT; 3593 } 3594 getStatusBarService().disable(flags, mToken, 3595 mService.mContext.getPackageName()); 3596 } 3597 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3598 if (getDevicePolicyManager() != null) { 3599 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3600 (String)msg.obj, msg.arg1); 3601 } 3602 } catch (RemoteException ex) { 3603 throw new RuntimeException(ex); 3604 } 3605 } break; 3606 case LOCK_TASK_END_MSG: { 3607 // When lock task ends, we enable the status bars. 3608 try { 3609 if (getStatusBarService() != null) { 3610 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3611 mService.mContext.getPackageName()); 3612 } 3613 mWindowManager.reenableKeyguard(mToken); 3614 if (getDevicePolicyManager() != null) { 3615 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3616 msg.arg1); 3617 } 3618 if (mLockTaskNotify == null) { 3619 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3620 } 3621 mLockTaskNotify.show(false); 3622 try { 3623 boolean shouldLockKeyguard = Settings.Secure.getInt( 3624 mService.mContext.getContentResolver(), 3625 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3626 if (!mLockTaskIsLocked && shouldLockKeyguard) { 3627 mWindowManager.lockNow(null); 3628 mWindowManager.dismissKeyguard(); 3629 new LockPatternUtils(mService.mContext) 3630 .requireCredentialEntry(UserHandle.USER_ALL); 3631 } 3632 } catch (SettingNotFoundException e) { 3633 // No setting, don't lock. 3634 } 3635 } catch (RemoteException ex) { 3636 throw new RuntimeException(ex); 3637 } 3638 } break; 3639 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3640 final ActivityContainer container = (ActivityContainer) msg.obj; 3641 final IActivityContainerCallback callback = container.mCallback; 3642 if (callback != null) { 3643 try { 3644 callback.onAllActivitiesComplete(container.asBinder()); 3645 } catch (RemoteException e) { 3646 } 3647 } 3648 } break; 3649 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 3650 synchronized (mService) { 3651 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 3652 msg.obj); 3653 final ActivityContainer container = (ActivityContainer) msg.obj; 3654 container.mStack.finishAllActivitiesLocked(true); 3655 container.onTaskListEmptyLocked(); 3656 } 3657 } break; 3658 case LAUNCH_TASK_BEHIND_COMPLETE: { 3659 synchronized (mService) { 3660 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 3661 if (r != null) { 3662 handleLaunchTaskBehindCompleteLocked(r); 3663 } 3664 } 3665 } break; 3666 } 3667 } 3668 } 3669 3670 class ActivityContainer extends android.app.IActivityContainer.Stub { 3671 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3672 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3673 final int mStackId; 3674 IActivityContainerCallback mCallback = null; 3675 final ActivityStack mStack; 3676 ActivityRecord mParentActivity = null; 3677 String mIdString; 3678 3679 boolean mVisible = true; 3680 3681 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3682 ActivityDisplay mActivityDisplay; 3683 3684 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3685 final static int CONTAINER_STATE_NO_SURFACE = 1; 3686 final static int CONTAINER_STATE_FINISHING = 2; 3687 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3688 3689 ActivityContainer(int stackId) { 3690 synchronized (mService) { 3691 mStackId = stackId; 3692 mStack = new ActivityStack(this, mRecentTasks); 3693 mIdString = "ActivtyContainer{" + mStackId + "}"; 3694 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3695 } 3696 } 3697 3698 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3699 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3700 + " to display=" + activityDisplay); 3701 mActivityDisplay = activityDisplay; 3702 mStack.mDisplayId = activityDisplay.mDisplayId; 3703 mStack.mStacks = activityDisplay.mStacks; 3704 3705 activityDisplay.attachActivities(mStack); 3706 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3707 } 3708 3709 @Override 3710 public void attachToDisplay(int displayId) { 3711 synchronized (mService) { 3712 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3713 if (activityDisplay == null) { 3714 return; 3715 } 3716 attachToDisplayLocked(activityDisplay); 3717 } 3718 } 3719 3720 @Override 3721 public int getDisplayId() { 3722 synchronized (mService) { 3723 if (mActivityDisplay != null) { 3724 return mActivityDisplay.mDisplayId; 3725 } 3726 } 3727 return -1; 3728 } 3729 3730 @Override 3731 public boolean injectEvent(InputEvent event) { 3732 final long origId = Binder.clearCallingIdentity(); 3733 try { 3734 synchronized (mService) { 3735 if (mActivityDisplay != null) { 3736 return mInputManagerInternal.injectInputEvent(event, 3737 mActivityDisplay.mDisplayId, 3738 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3739 } 3740 } 3741 return false; 3742 } finally { 3743 Binder.restoreCallingIdentity(origId); 3744 } 3745 } 3746 3747 @Override 3748 public void release() { 3749 synchronized (mService) { 3750 if (mContainerState == CONTAINER_STATE_FINISHING) { 3751 return; 3752 } 3753 mContainerState = CONTAINER_STATE_FINISHING; 3754 3755 final Message msg = 3756 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3757 mHandler.sendMessageDelayed(msg, 2000); 3758 3759 long origId = Binder.clearCallingIdentity(); 3760 try { 3761 mStack.finishAllActivitiesLocked(false); 3762 removePendingActivityLaunchesLocked(mStack); 3763 } finally { 3764 Binder.restoreCallingIdentity(origId); 3765 } 3766 } 3767 } 3768 3769 protected void detachLocked() { 3770 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3771 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3772 if (mActivityDisplay != null) { 3773 mActivityDisplay.detachActivitiesLocked(mStack); 3774 mActivityDisplay = null; 3775 mStack.mDisplayId = -1; 3776 mStack.mStacks = null; 3777 mWindowManager.detachStack(mStackId); 3778 } 3779 } 3780 3781 @Override 3782 public final int startActivity(Intent intent) { 3783 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3784 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3785 Binder.getCallingUid(), mCurrentUser, false, 3786 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3787 // TODO: Switch to user app stacks here. 3788 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3789 String mimeType = intent.getType(); 3790 if (mimeType == null && intent.getData() != null 3791 && "content".equals(intent.getData().getScheme())) { 3792 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3793 } 3794 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 3795 0, null, null, null, null, userId, this, null); 3796 } 3797 3798 @Override 3799 public final int startActivityIntentSender(IIntentSender intentSender) { 3800 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3801 3802 if (!(intentSender instanceof PendingIntentRecord)) { 3803 throw new IllegalArgumentException("Bad PendingIntent object"); 3804 } 3805 3806 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3807 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3808 } 3809 3810 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3811 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3812 Binder.getCallingUid(), mCurrentUser, false, 3813 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 3814 if (resolvedType == null) { 3815 resolvedType = intent.getType(); 3816 if (resolvedType == null && intent.getData() != null 3817 && "content".equals(intent.getData().getScheme())) { 3818 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3819 } 3820 } 3821 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 3822 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3823 throw new SecurityException( 3824 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3825 } 3826 } 3827 3828 /** Throw a SecurityException if allowEmbedded is not true */ 3829 @Override 3830 public final void checkEmbeddedAllowed(Intent intent) { 3831 checkEmbeddedAllowedInner(intent, null); 3832 } 3833 3834 /** Throw a SecurityException if allowEmbedded is not true */ 3835 @Override 3836 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3837 if (!(intentSender instanceof PendingIntentRecord)) { 3838 throw new IllegalArgumentException("Bad PendingIntent object"); 3839 } 3840 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3841 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3842 pendingIntent.key.requestResolvedType); 3843 } 3844 3845 @Override 3846 public IBinder asBinder() { 3847 return this; 3848 } 3849 3850 @Override 3851 public void setSurface(Surface surface, int width, int height, int density) { 3852 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3853 } 3854 3855 ActivityStackSupervisor getOuter() { 3856 return ActivityStackSupervisor.this; 3857 } 3858 3859 boolean isAttachedLocked() { 3860 return mActivityDisplay != null; 3861 } 3862 3863 void getBounds(Point outBounds) { 3864 synchronized (mService) { 3865 if (mActivityDisplay != null) { 3866 mActivityDisplay.getBounds(outBounds); 3867 } else { 3868 outBounds.set(0, 0); 3869 } 3870 } 3871 } 3872 3873 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3874 void setVisible(boolean visible) { 3875 if (mVisible != visible) { 3876 mVisible = visible; 3877 if (mCallback != null) { 3878 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3879 0 /* unused */, this).sendToTarget(); 3880 } 3881 } 3882 } 3883 3884 void setDrawn() { 3885 } 3886 3887 // You can always start a new task on a regular ActivityStack. 3888 boolean isEligibleForNewTasks() { 3889 return true; 3890 } 3891 3892 void onTaskListEmptyLocked() { 3893 } 3894 3895 @Override 3896 public String toString() { 3897 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3898 } 3899 } 3900 3901 private class VirtualActivityContainer extends ActivityContainer { 3902 Surface mSurface; 3903 boolean mDrawn = false; 3904 3905 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3906 super(getNextStackId()); 3907 mParentActivity = parent; 3908 mCallback = callback; 3909 mContainerState = CONTAINER_STATE_NO_SURFACE; 3910 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3911 } 3912 3913 @Override 3914 public void setSurface(Surface surface, int width, int height, int density) { 3915 super.setSurface(surface, width, height, density); 3916 3917 synchronized (mService) { 3918 final long origId = Binder.clearCallingIdentity(); 3919 try { 3920 setSurfaceLocked(surface, width, height, density); 3921 } finally { 3922 Binder.restoreCallingIdentity(origId); 3923 } 3924 } 3925 } 3926 3927 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3928 if (mContainerState == CONTAINER_STATE_FINISHING) { 3929 return; 3930 } 3931 VirtualActivityDisplay virtualActivityDisplay = 3932 (VirtualActivityDisplay) mActivityDisplay; 3933 if (virtualActivityDisplay == null) { 3934 virtualActivityDisplay = 3935 new VirtualActivityDisplay(width, height, density); 3936 mActivityDisplay = virtualActivityDisplay; 3937 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3938 attachToDisplayLocked(virtualActivityDisplay); 3939 } 3940 3941 if (mSurface != null) { 3942 mSurface.release(); 3943 } 3944 3945 mSurface = surface; 3946 if (surface != null) { 3947 mStack.resumeTopActivityLocked(null); 3948 } else { 3949 mContainerState = CONTAINER_STATE_NO_SURFACE; 3950 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3951 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3952 mStack.startPausingLocked(false, true, false, false); 3953 } 3954 } 3955 3956 setSurfaceIfReadyLocked(); 3957 3958 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3959 + virtualActivityDisplay); 3960 } 3961 3962 @Override 3963 boolean isAttachedLocked() { 3964 return mSurface != null && super.isAttachedLocked(); 3965 } 3966 3967 @Override 3968 void setDrawn() { 3969 synchronized (mService) { 3970 mDrawn = true; 3971 setSurfaceIfReadyLocked(); 3972 } 3973 } 3974 3975 // Never start a new task on an ActivityView if it isn't explicitly specified. 3976 @Override 3977 boolean isEligibleForNewTasks() { 3978 return false; 3979 } 3980 3981 void onTaskListEmptyLocked() { 3982 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3983 detachLocked(); 3984 deleteActivityContainer(this); 3985 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3986 } 3987 3988 private void setSurfaceIfReadyLocked() { 3989 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3990 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3991 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3992 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3993 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3994 } 3995 } 3996 } 3997 3998 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3999 * attached {@link ActivityStack}s */ 4000 class ActivityDisplay { 4001 /** Actual Display this object tracks. */ 4002 int mDisplayId; 4003 Display mDisplay; 4004 DisplayInfo mDisplayInfo = new DisplayInfo(); 4005 4006 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4007 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4008 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 4009 4010 ActivityRecord mVisibleBehindActivity; 4011 4012 ActivityDisplay() { 4013 } 4014 4015 // After instantiation, check that mDisplay is not null before using this. The alternative 4016 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4017 ActivityDisplay(int displayId) { 4018 final Display display = mDisplayManager.getDisplay(displayId); 4019 if (display == null) { 4020 return; 4021 } 4022 init(display); 4023 } 4024 4025 void init(Display display) { 4026 mDisplay = display; 4027 mDisplayId = display.getDisplayId(); 4028 mDisplay.getDisplayInfo(mDisplayInfo); 4029 } 4030 4031 void attachActivities(ActivityStack stack) { 4032 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 4033 + mDisplayId); 4034 mStacks.add(stack); 4035 } 4036 4037 void detachActivitiesLocked(ActivityStack stack) { 4038 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 4039 + " from displayId=" + mDisplayId); 4040 mStacks.remove(stack); 4041 } 4042 4043 void getBounds(Point bounds) { 4044 mDisplay.getDisplayInfo(mDisplayInfo); 4045 bounds.x = mDisplayInfo.appWidth; 4046 bounds.y = mDisplayInfo.appHeight; 4047 } 4048 4049 void setVisibleBehindActivity(ActivityRecord r) { 4050 mVisibleBehindActivity = r; 4051 } 4052 4053 boolean hasVisibleBehindActivity() { 4054 return mVisibleBehindActivity != null; 4055 } 4056 4057 @Override 4058 public String toString() { 4059 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4060 } 4061 } 4062 4063 class VirtualActivityDisplay extends ActivityDisplay { 4064 VirtualDisplay mVirtualDisplay; 4065 4066 VirtualActivityDisplay(int width, int height, int density) { 4067 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4068 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4069 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4070 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4071 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4072 4073 init(mVirtualDisplay.getDisplay()); 4074 4075 mWindowManager.handleDisplayAdded(mDisplayId); 4076 } 4077 4078 void setSurface(Surface surface) { 4079 if (mVirtualDisplay != null) { 4080 mVirtualDisplay.setSurface(surface); 4081 } 4082 } 4083 4084 @Override 4085 void detachActivitiesLocked(ActivityStack stack) { 4086 super.detachActivitiesLocked(stack); 4087 if (mVirtualDisplay != null) { 4088 mVirtualDisplay.release(); 4089 mVirtualDisplay = null; 4090 } 4091 } 4092 4093 @Override 4094 public String toString() { 4095 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4096 } 4097 } 4098 4099 private boolean isLeanbackOnlyDevice() { 4100 boolean onLeanbackOnly = false; 4101 try { 4102 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 4103 PackageManager.FEATURE_LEANBACK_ONLY); 4104 } catch (RemoteException e) { 4105 // noop 4106 } 4107 4108 return onLeanbackOnly; 4109 } 4110} 4111