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