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