ActivityStackSupervisor.java revision f329d050b8e72ba6daf67edc1b1b64b0035a6050
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, r.info.applicationInfo.versionCode, 1182 mService.mProcessStats); 1183 } 1184 realStartActivityLocked(r, app, andResume, checkConfig); 1185 return; 1186 } catch (RemoteException e) { 1187 Slog.w(TAG, "Exception when starting activity " 1188 + r.intent.getComponent().flattenToShortString(), e); 1189 } 1190 1191 // If a dead object exception was thrown -- fall through to 1192 // restart the application. 1193 } 1194 1195 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1196 "activity", r.intent.getComponent(), false, false, true); 1197 } 1198 1199 final int startActivityLocked(IApplicationThread caller, 1200 Intent intent, String resolvedType, ActivityInfo aInfo, 1201 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1202 IBinder resultTo, String resultWho, int requestCode, 1203 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1204 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { 1205 int err = ActivityManager.START_SUCCESS; 1206 1207 ProcessRecord callerApp = null; 1208 if (caller != null) { 1209 callerApp = mService.getRecordForAppLocked(caller); 1210 if (callerApp != null) { 1211 callingPid = callerApp.pid; 1212 callingUid = callerApp.info.uid; 1213 } else { 1214 Slog.w(TAG, "Unable to find app for caller " + caller 1215 + " (pid=" + callingPid + ") when starting: " 1216 + intent.toString()); 1217 err = ActivityManager.START_PERMISSION_DENIED; 1218 } 1219 } 1220 1221 if (err == ActivityManager.START_SUCCESS) { 1222 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1223 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1224 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) 1225 + " on display " + (container == null ? (mFocusedStack == null ? 1226 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1227 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1228 container.mActivityDisplay.mDisplayId))); 1229 } 1230 1231 ActivityRecord sourceRecord = null; 1232 ActivityRecord resultRecord = null; 1233 if (resultTo != null) { 1234 sourceRecord = isInAnyStackLocked(resultTo); 1235 if (DEBUG_RESULTS) Slog.v( 1236 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1237 if (sourceRecord != null) { 1238 if (requestCode >= 0 && !sourceRecord.finishing) { 1239 resultRecord = sourceRecord; 1240 } 1241 } 1242 } 1243 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1244 1245 final int launchFlags = intent.getFlags(); 1246 1247 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1248 && sourceRecord != null) { 1249 // Transfer the result target from the source activity to the new 1250 // one being started, including any failures. 1251 if (requestCode >= 0) { 1252 ActivityOptions.abort(options); 1253 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1254 } 1255 resultRecord = sourceRecord.resultTo; 1256 resultWho = sourceRecord.resultWho; 1257 requestCode = sourceRecord.requestCode; 1258 sourceRecord.resultTo = null; 1259 if (resultRecord != null) { 1260 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 1261 } 1262 if (sourceRecord.launchedFromUid == callingUid) { 1263 // The new activity is being launched from the same uid as the previous 1264 // activity in the flow, and asking to forward its result back to the 1265 // previous. In this case the activity is serving as a trampoline between 1266 // the two, so we also want to update its launchedFromPackage to be the 1267 // same as the previous activity. Note that this is safe, since we know 1268 // these two packages come from the same uid; the caller could just as 1269 // well have supplied that same package name itself. This specifially 1270 // deals with the case of an intent picker/chooser being launched in the app 1271 // flow to redirect to an activity picked by the user, where we want the final 1272 // activity to consider it to have been launched by the previous app activity. 1273 callingPackage = sourceRecord.launchedFromPackage; 1274 } 1275 } 1276 1277 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1278 // We couldn't find a class that can handle the given Intent. 1279 // That's the end of that! 1280 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1281 } 1282 1283 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1284 // We couldn't find the specific class specified in the Intent. 1285 // Also the end of the line. 1286 err = ActivityManager.START_CLASS_NOT_FOUND; 1287 } 1288 1289 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1290 && sourceRecord.task.voiceSession != null) { 1291 // If this activity is being launched as part of a voice session, we need 1292 // to ensure that it is safe to do so. If the upcoming activity will also 1293 // be part of the voice session, we can only launch it if it has explicitly 1294 // said it supports the VOICE category, or it is a part of the calling app. 1295 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1296 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1297 try { 1298 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1299 intent, resolvedType)) { 1300 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1301 } 1302 } catch (RemoteException e) { 1303 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1304 } 1305 } 1306 } 1307 1308 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1309 // If the caller is starting a new voice session, just make sure the target 1310 // is actually allowing it to run this way. 1311 try { 1312 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1313 intent, resolvedType)) { 1314 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1315 } 1316 } catch (RemoteException e) { 1317 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1318 } 1319 } 1320 1321 if (err != ActivityManager.START_SUCCESS) { 1322 if (resultRecord != null) { 1323 resultStack.sendActivityResultLocked(-1, 1324 resultRecord, resultWho, requestCode, 1325 Activity.RESULT_CANCELED, null); 1326 } 1327 setDismissKeyguard(false); 1328 ActivityOptions.abort(options); 1329 return err; 1330 } 1331 1332 final int startAnyPerm = mService.checkPermission( 1333 START_ANY_ACTIVITY, callingPid, callingUid); 1334 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1335 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1336 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1337 if (resultRecord != null) { 1338 resultStack.sendActivityResultLocked(-1, 1339 resultRecord, resultWho, requestCode, 1340 Activity.RESULT_CANCELED, null); 1341 } 1342 setDismissKeyguard(false); 1343 String msg; 1344 if (!aInfo.exported) { 1345 msg = "Permission Denial: starting " + intent.toString() 1346 + " from " + callerApp + " (pid=" + callingPid 1347 + ", uid=" + callingUid + ")" 1348 + " not exported from uid " + aInfo.applicationInfo.uid; 1349 } else { 1350 msg = "Permission Denial: starting " + intent.toString() 1351 + " from " + callerApp + " (pid=" + callingPid 1352 + ", uid=" + callingUid + ")" 1353 + " requires " + aInfo.permission; 1354 } 1355 Slog.w(TAG, msg); 1356 throw new SecurityException(msg); 1357 } 1358 1359 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1360 callingPid, resolvedType, aInfo.applicationInfo); 1361 1362 if (mService.mController != null) { 1363 try { 1364 // The Intent we give to the watcher has the extra data 1365 // stripped off, since it can contain private information. 1366 Intent watchIntent = intent.cloneFilter(); 1367 abort |= !mService.mController.activityStarting(watchIntent, 1368 aInfo.applicationInfo.packageName); 1369 } catch (RemoteException e) { 1370 mService.mController = null; 1371 } 1372 } 1373 1374 if (abort) { 1375 if (resultRecord != null) { 1376 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1377 Activity.RESULT_CANCELED, null); 1378 } 1379 // We pretend to the caller that it was really started, but 1380 // they will just get a cancel result. 1381 setDismissKeyguard(false); 1382 ActivityOptions.abort(options); 1383 return ActivityManager.START_SUCCESS; 1384 } 1385 1386 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1387 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1388 requestCode, componentSpecified, this, container, options); 1389 if (outActivity != null) { 1390 outActivity[0] = r; 1391 } 1392 1393 final ActivityStack stack = getFocusedStack(); 1394 if (voiceSession == null && (stack.mResumedActivity == null 1395 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1396 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1397 PendingActivityLaunch pal = 1398 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1399 mService.mPendingActivityLaunches.add(pal); 1400 setDismissKeyguard(false); 1401 ActivityOptions.abort(options); 1402 return ActivityManager.START_SWITCHES_CANCELED; 1403 } 1404 } 1405 1406 if (mService.mDidAppSwitch) { 1407 // This is the second allowed switch since we stopped switches, 1408 // so now just generally allow switches. Use case: user presses 1409 // home (switches disabled, switch to home, mDidAppSwitch now true); 1410 // user taps a home icon (coming from home so allowed, we hit here 1411 // and now allow anyone to switch again). 1412 mService.mAppSwitchesAllowedTime = 0; 1413 } else { 1414 mService.mDidAppSwitch = true; 1415 } 1416 1417 mService.doPendingActivityLaunchesLocked(false); 1418 1419 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1420 startFlags, true, options); 1421 1422 if (allPausedActivitiesComplete()) { 1423 // If someone asked to have the keyguard dismissed on the next 1424 // activity start, but we are not actually doing an activity 1425 // switch... just dismiss the keyguard now, because we 1426 // probably want to see whatever is behind it. 1427 dismissKeyguard(); 1428 } 1429 return err; 1430 } 1431 1432 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1433 final TaskRecord task = r.task; 1434 1435 // On leanback only devices we should keep all activities in the same stack. 1436 if (!mLeanbackOnlyDevice && 1437 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1438 if (task != null) { 1439 final ActivityStack taskStack = task.stack; 1440 if (taskStack.isOnHomeDisplay()) { 1441 if (mFocusedStack != taskStack) { 1442 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1443 "focused stack to r=" + r + " task=" + task); 1444 mFocusedStack = taskStack; 1445 } else { 1446 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1447 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1448 } 1449 } 1450 return taskStack; 1451 } 1452 1453 final ActivityContainer container = r.mInitialActivityContainer; 1454 if (container != null) { 1455 // The first time put it on the desired stack, after this put on task stack. 1456 r.mInitialActivityContainer = null; 1457 return container.mStack; 1458 } 1459 1460 if (mFocusedStack != mHomeStack && (!newTask || 1461 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1462 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1463 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1464 return mFocusedStack; 1465 } 1466 1467 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1468 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1469 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1470 if (!stack.isHomeStack()) { 1471 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1472 "adjustStackFocus: Setting focused stack=" + stack); 1473 mFocusedStack = stack; 1474 return mFocusedStack; 1475 } 1476 } 1477 1478 // Need to create an app stack for this user. 1479 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1480 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1481 " stackId=" + stackId); 1482 mFocusedStack = getStack(stackId); 1483 return mFocusedStack; 1484 } 1485 return mHomeStack; 1486 } 1487 1488 void setFocusedStack(ActivityRecord r) { 1489 if (r != null) { 1490 final TaskRecord task = r.task; 1491 boolean isHomeActivity = !r.isApplicationActivity(); 1492 if (!isHomeActivity && task != null) { 1493 isHomeActivity = !task.isApplicationTask(); 1494 } 1495 if (!isHomeActivity && task != null) { 1496 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1497 isHomeActivity = parent != null && parent.isHomeActivity(); 1498 } 1499 moveHomeStack(isHomeActivity); 1500 } 1501 } 1502 1503 final int startActivityUncheckedLocked(ActivityRecord r, 1504 ActivityRecord sourceRecord, 1505 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 1506 boolean doResume, Bundle options) { 1507 final Intent intent = r.intent; 1508 final int callingUid = r.launchedFromUid; 1509 1510 int launchFlags = intent.getFlags(); 1511 1512 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 1513 (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 1514 r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK)) { 1515 // We have a conflict between the Intent and the Activity manifest, manifest wins. 1516 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 1517 "\"singleInstance\" or \"singleTask\""); 1518 launchFlags &= 1519 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1520 } else { 1521 switch (r.info.documentLaunchMode) { 1522 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1523 break; 1524 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1525 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1526 break; 1527 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1528 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1529 break; 1530 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 1531 launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1532 break; 1533 } 1534 } 1535 1536 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1537 // For whatever reason this activity is being launched into a new 1538 // task... yet the caller has requested a result back. Well, that 1539 // is pretty messed up, so instead immediately send back a cancel 1540 // and let the new task continue launched as normal without a 1541 // dependency on its originator. 1542 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1543 r.resultTo.task.stack.sendActivityResultLocked(-1, 1544 r.resultTo, r.resultWho, r.requestCode, 1545 Activity.RESULT_CANCELED, null); 1546 r.resultTo = null; 1547 } 1548 1549 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 1550 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1551 } 1552 1553 // We'll invoke onUserLeaving before onPause only if the launching 1554 // activity did not explicitly state that this is an automated launch. 1555 mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1556 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1557 1558 // If the caller has asked not to resume at this point, we make note 1559 // of this in the record so that we can skip it when trying to find 1560 // the top running activity. 1561 if (!doResume) { 1562 r.delayedResume = true; 1563 } 1564 1565 ActivityRecord notTop = 1566 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1567 1568 // If the onlyIfNeeded flag is set, then we can do this if the activity 1569 // being launched is the same as the one making the call... or, as 1570 // a special case, if we do not know the caller then we count the 1571 // current top activity as the caller. 1572 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1573 ActivityRecord checkedCaller = sourceRecord; 1574 if (checkedCaller == null) { 1575 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1576 } 1577 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1578 // Caller is not the same as launcher, so always needed. 1579 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1580 } 1581 } 1582 1583 if (sourceRecord == null) { 1584 // This activity is not being started from another... in this 1585 // case we -always- start a new task. 1586 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1587 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1588 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1589 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1590 } 1591 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1592 // The original activity who is starting us is running as a single 1593 // instance... this new activity it is starting must go on its 1594 // own task. 1595 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1596 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1597 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1598 // The activity being started is a single instance... it always 1599 // gets launched into its own task. 1600 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1601 } 1602 1603 ActivityInfo newTaskInfo = null; 1604 Intent newTaskIntent = null; 1605 final ActivityStack sourceStack; 1606 if (sourceRecord != null) { 1607 if (sourceRecord.finishing) { 1608 // If the source is finishing, we can't further count it as our source. This 1609 // is because the task it is associated with may now be empty and on its way out, 1610 // so we don't want to blindly throw it in to that task. Instead we will take 1611 // the NEW_TASK flow and try to find a task for it. But save the task information 1612 // so it can be used when creating the new task. 1613 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1614 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1615 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1616 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1617 newTaskInfo = sourceRecord.info; 1618 newTaskIntent = sourceRecord.task.intent; 1619 } 1620 sourceRecord = null; 1621 sourceStack = null; 1622 } else { 1623 sourceStack = sourceRecord.task.stack; 1624 } 1625 } else { 1626 sourceStack = null; 1627 } 1628 1629 intent.setFlags(launchFlags); 1630 1631 boolean addingToTask = false; 1632 boolean movedHome = false; 1633 TaskRecord reuseTask = null; 1634 ActivityStack targetStack; 1635 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1636 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1637 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1638 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1639 // If bring to front is requested, and no result is requested, and 1640 // we can find a task that was started with this same 1641 // component, then instead of launching bring that one to the front. 1642 if (r.resultTo == null) { 1643 // See if there is a task to bring to the front. If this is 1644 // a SINGLE_INSTANCE activity, there can be one and only one 1645 // instance of it in the history, and it is always in its own 1646 // unique task, so we do a special search. 1647 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1648 ? findTaskLocked(r) 1649 : findActivityLocked(intent, r.info); 1650 if (intentActivity != null) { 1651 if (isLockTaskModeViolation(intentActivity.task)) { 1652 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1653 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1654 } 1655 if (r.task == null) { 1656 r.task = intentActivity.task; 1657 } 1658 targetStack = intentActivity.task.stack; 1659 targetStack.mLastPausedActivity = null; 1660 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1661 + " from " + intentActivity); 1662 targetStack.moveToFront(); 1663 if (intentActivity.task.intent == null) { 1664 // This task was started because of movement of 1665 // the activity based on affinity... now that we 1666 // are actually launching it, we can assign the 1667 // base intent. 1668 intentActivity.task.setIntent(intent, r.info); 1669 } 1670 // If the target task is not in the front, then we need 1671 // to bring it to the front... except... well, with 1672 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1673 // to have the same behavior as if a new instance was 1674 // being started, which means not bringing it to the front 1675 // if the caller is not itself in the front. 1676 final ActivityStack lastStack = getLastStack(); 1677 ActivityRecord curTop = lastStack == null? 1678 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1679 if (curTop != null && (curTop.task != intentActivity.task || 1680 curTop.task != lastStack.topTask())) { 1681 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1682 if (sourceRecord == null || (sourceStack.topActivity() != null && 1683 sourceStack.topActivity().task == sourceRecord.task)) { 1684 // We really do want to push this one into the 1685 // user's face, right now. 1686 movedHome = true; 1687 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1688 if ((launchFlags & 1689 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1690 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1691 // Caller wants to appear on home activity. 1692 intentActivity.task.mOnTopOfHome = true; 1693 } 1694 options = null; 1695 } 1696 } 1697 // If the caller has requested that the target task be 1698 // reset, then do so. 1699 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1700 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1701 } 1702 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1703 // We don't need to start a new activity, and 1704 // the client said not to do anything if that 1705 // is the case, so this is it! And for paranoia, make 1706 // sure we have correctly resumed the top activity. 1707 if (doResume) { 1708 resumeTopActivitiesLocked(targetStack, null, options); 1709 } else { 1710 ActivityOptions.abort(options); 1711 } 1712 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1713 } 1714 if ((launchFlags & 1715 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1716 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1717 // The caller has requested to completely replace any 1718 // existing task with its new activity. Well that should 1719 // not be too hard... 1720 reuseTask = intentActivity.task; 1721 reuseTask.performClearTaskLocked(); 1722 reuseTask.setIntent(r.intent, r.info); 1723 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1724 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1725 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1726 // In this situation we want to remove all activities 1727 // from the task up to the one being started. In most 1728 // cases this means we are resetting the task to its 1729 // initial state. 1730 ActivityRecord top = 1731 intentActivity.task.performClearTaskLocked(r, launchFlags); 1732 if (top != null) { 1733 if (top.frontOfTask) { 1734 // Activity aliases may mean we use different 1735 // intents for the top activity, so make sure 1736 // the task now has the identity of the new 1737 // intent. 1738 top.task.setIntent(r.intent, r.info); 1739 } 1740 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1741 r, top.task); 1742 top.deliverNewIntentLocked(callingUid, r.intent); 1743 } else { 1744 // A special case: we need to 1745 // start the activity because it is not currently 1746 // running, and the caller has asked to clear the 1747 // current task to have this activity at the top. 1748 addingToTask = true; 1749 // Now pretend like this activity is being started 1750 // by the top of its task, so it is put in the 1751 // right place. 1752 sourceRecord = intentActivity; 1753 } 1754 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1755 // In this case the top activity on the task is the 1756 // same as the one being launched, so we take that 1757 // as a request to bring the task to the foreground. 1758 // If the top activity in the task is the root 1759 // activity, deliver this new intent to it if it 1760 // desires. 1761 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1762 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1763 && intentActivity.realActivity.equals(r.realActivity)) { 1764 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1765 intentActivity.task); 1766 if (intentActivity.frontOfTask) { 1767 intentActivity.task.setIntent(r.intent, r.info); 1768 } 1769 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1770 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1771 // In this case we are launching the root activity 1772 // of the task, but with a different intent. We 1773 // should start a new instance on top. 1774 addingToTask = true; 1775 sourceRecord = intentActivity; 1776 } 1777 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1778 // In this case an activity is being launched in to an 1779 // existing task, without resetting that task. This 1780 // is typically the situation of launching an activity 1781 // from a notification or shortcut. We want to place 1782 // the new activity on top of the current task. 1783 addingToTask = true; 1784 sourceRecord = intentActivity; 1785 } else if (!intentActivity.task.rootWasReset) { 1786 // In this case we are launching in to an existing task 1787 // that has not yet been started from its front door. 1788 // The current task has been brought to the front. 1789 // Ideally, we'd probably like to place this new task 1790 // at the bottom of its stack, but that's a little hard 1791 // to do with the current organization of the code so 1792 // for now we'll just drop it. 1793 intentActivity.task.setIntent(r.intent, r.info); 1794 } 1795 if (!addingToTask && reuseTask == null) { 1796 // We didn't do anything... but it was needed (a.k.a., client 1797 // don't use that intent!) And for paranoia, make 1798 // sure we have correctly resumed the top activity. 1799 if (doResume) { 1800 targetStack.resumeTopActivityLocked(null, options); 1801 } else { 1802 ActivityOptions.abort(options); 1803 } 1804 return ActivityManager.START_TASK_TO_FRONT; 1805 } 1806 } 1807 } 1808 } 1809 1810 //String uri = r.intent.toURI(); 1811 //Intent intent2 = new Intent(uri); 1812 //Slog.i(TAG, "Given intent: " + r.intent); 1813 //Slog.i(TAG, "URI is: " + uri); 1814 //Slog.i(TAG, "To intent: " + intent2); 1815 1816 if (r.packageName != null) { 1817 // If the activity being launched is the same as the one currently 1818 // at the top, then we need to check if it should only be launched 1819 // once. 1820 ActivityStack topStack = getFocusedStack(); 1821 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1822 if (top != null && r.resultTo == null) { 1823 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1824 if (top.app != null && top.app.thread != null) { 1825 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1826 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1827 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1828 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1829 top.task); 1830 // For paranoia, make sure we have correctly 1831 // resumed the top activity. 1832 topStack.mLastPausedActivity = null; 1833 if (doResume) { 1834 resumeTopActivitiesLocked(); 1835 } 1836 ActivityOptions.abort(options); 1837 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1838 // We don't need to start a new activity, and 1839 // the client said not to do anything if that 1840 // is the case, so this is it! 1841 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1842 } 1843 top.deliverNewIntentLocked(callingUid, r.intent); 1844 return ActivityManager.START_DELIVERED_TO_TOP; 1845 } 1846 } 1847 } 1848 } 1849 1850 } else { 1851 if (r.resultTo != null) { 1852 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1853 r.requestCode, Activity.RESULT_CANCELED, null); 1854 } 1855 ActivityOptions.abort(options); 1856 return ActivityManager.START_CLASS_NOT_FOUND; 1857 } 1858 1859 boolean newTask = false; 1860 boolean keepCurTransition = false; 1861 1862 // Should this be considered a new task? 1863 if (r.resultTo == null && !addingToTask 1864 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1865 if (isLockTaskModeViolation(reuseTask)) { 1866 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1867 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1868 } 1869 newTask = true; 1870 targetStack = adjustStackFocus(r, newTask); 1871 targetStack.moveToFront(); 1872 if (reuseTask == null) { 1873 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1874 newTaskInfo != null ? newTaskInfo : r.info, 1875 newTaskIntent != null ? newTaskIntent : intent, 1876 voiceSession, voiceInteractor, true), null, true); 1877 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1878 r.task); 1879 } else { 1880 r.setTask(reuseTask, reuseTask, true); 1881 } 1882 if (!movedHome) { 1883 if ((launchFlags & 1884 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1885 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1886 // Caller wants to appear on home activity, so before starting 1887 // their own activity we will bring home to the front. 1888 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); 1889 } 1890 } 1891 } else if (sourceRecord != null) { 1892 TaskRecord sourceTask = sourceRecord.task; 1893 if (isLockTaskModeViolation(sourceTask)) { 1894 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1895 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1896 } 1897 targetStack = sourceTask.stack; 1898 targetStack.moveToFront(); 1899 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 1900 if (!addingToTask && 1901 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1902 // In this case, we are adding the activity to an existing 1903 // task, but the caller has asked to clear that task if the 1904 // activity is already running. 1905 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1906 keepCurTransition = true; 1907 if (top != null) { 1908 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1909 top.deliverNewIntentLocked(callingUid, r.intent); 1910 // For paranoia, make sure we have correctly 1911 // resumed the top activity. 1912 targetStack.mLastPausedActivity = null; 1913 if (doResume) { 1914 targetStack.resumeTopActivityLocked(null); 1915 } 1916 ActivityOptions.abort(options); 1917 return ActivityManager.START_DELIVERED_TO_TOP; 1918 } 1919 } else if (!addingToTask && 1920 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1921 // In this case, we are launching an activity in our own task 1922 // that may already be running somewhere in the history, and 1923 // we want to shuffle it to the front of the stack if so. 1924 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1925 if (top != null) { 1926 final TaskRecord task = top.task; 1927 task.moveActivityToFrontLocked(top); 1928 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1929 top.updateOptionsLocked(options); 1930 top.deliverNewIntentLocked(callingUid, r.intent); 1931 targetStack.mLastPausedActivity = null; 1932 if (doResume) { 1933 targetStack.resumeTopActivityLocked(null); 1934 } 1935 return ActivityManager.START_DELIVERED_TO_TOP; 1936 } 1937 } 1938 // An existing activity is starting this new activity, so we want 1939 // to keep the new one in the same task as the one that is starting 1940 // it. 1941 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1942 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1943 + " in existing task " + r.task + " from source " + sourceRecord); 1944 1945 } else { 1946 // This not being started from an existing activity, and not part 1947 // of a new task... just put it in the top task, though these days 1948 // this case should never happen. 1949 targetStack = adjustStackFocus(r, newTask); 1950 targetStack.moveToFront(); 1951 ActivityRecord prev = targetStack.topActivity(); 1952 r.setTask(prev != null ? prev.task 1953 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true), 1954 null, true); 1955 mWindowManager.moveTaskToTop(r.task.taskId); 1956 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1957 + " in new guessed " + r.task); 1958 } 1959 1960 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1961 intent, r.getUriPermissionsLocked(), r.userId); 1962 1963 if (newTask) { 1964 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1965 } 1966 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1967 targetStack.mLastPausedActivity = null; 1968 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1969 mService.setFocusedActivityLocked(r); 1970 return ActivityManager.START_SUCCESS; 1971 } 1972 1973 void acquireLaunchWakelock() { 1974 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1975 throw new IllegalStateException("Calling must be system uid"); 1976 } 1977 mLaunchingActivity.acquire(); 1978 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1979 // To be safe, don't allow the wake lock to be held for too long. 1980 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1981 } 1982 } 1983 1984 // Checked. 1985 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1986 Configuration config) { 1987 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1988 1989 ArrayList<ActivityRecord> stops = null; 1990 ArrayList<ActivityRecord> finishes = null; 1991 ArrayList<UserStartedState> startingUsers = null; 1992 int NS = 0; 1993 int NF = 0; 1994 boolean booting = false; 1995 boolean enableScreen = false; 1996 boolean activityRemoved = false; 1997 1998 ActivityRecord r = ActivityRecord.forToken(token); 1999 if (r != null) { 2000 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 2001 Debug.getCallers(4)); 2002 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2003 r.finishLaunchTickingLocked(); 2004 if (fromTimeout) { 2005 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2006 } 2007 2008 // This is a hack to semi-deal with a race condition 2009 // in the client where it can be constructed with a 2010 // newer configuration from when we asked it to launch. 2011 // We'll update with whatever configuration it now says 2012 // it used to launch. 2013 if (config != null) { 2014 r.configuration = config; 2015 } 2016 2017 // We are now idle. If someone is waiting for a thumbnail from 2018 // us, we can now deliver. 2019 r.idle = true; 2020 2021 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2022 if (!mService.mBooted && isFrontStack(r.task.stack)) { 2023 mService.mBooted = true; 2024 enableScreen = true; 2025 } 2026 } 2027 2028 if (allResumedActivitiesIdle()) { 2029 if (r != null) { 2030 mService.scheduleAppGcsLocked(); 2031 } 2032 2033 if (mLaunchingActivity.isHeld()) { 2034 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2035 if (VALIDATE_WAKE_LOCK_CALLER && 2036 Binder.getCallingUid() != Process.myUid()) { 2037 throw new IllegalStateException("Calling must be system uid"); 2038 } 2039 mLaunchingActivity.release(); 2040 } 2041 ensureActivitiesVisibleLocked(null, 0); 2042 } 2043 2044 // Atomically retrieve all of the other things to do. 2045 stops = processStoppingActivitiesLocked(true); 2046 NS = stops != null ? stops.size() : 0; 2047 if ((NF=mFinishingActivities.size()) > 0) { 2048 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 2049 mFinishingActivities.clear(); 2050 } 2051 2052 if (isFrontStack(mHomeStack)) { 2053 booting = mService.mBooting; 2054 mService.mBooting = false; 2055 } 2056 2057 if (mStartingUsers.size() > 0) { 2058 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 2059 mStartingUsers.clear(); 2060 } 2061 2062 // Stop any activities that are scheduled to do so but have been 2063 // waiting for the next one to start. 2064 for (int i = 0; i < NS; i++) { 2065 r = stops.get(i); 2066 final ActivityStack stack = r.task.stack; 2067 if (r.finishing) { 2068 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2069 } else { 2070 stack.stopActivityLocked(r); 2071 } 2072 } 2073 2074 // Finish any activities that are scheduled to do so but have been 2075 // waiting for the next one to start. 2076 for (int i = 0; i < NF; i++) { 2077 r = finishes.get(i); 2078 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 2079 } 2080 2081 if (booting) { 2082 mService.finishBooting(); 2083 } else { 2084 // Complete user switch 2085 if (startingUsers != null) { 2086 for (int i = 0; i < startingUsers.size(); i++) { 2087 mService.finishUserSwitch(startingUsers.get(i)); 2088 } 2089 } 2090 // Complete starting up of background users 2091 if (mStartingBackgroundUsers.size() > 0) { 2092 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2093 mStartingBackgroundUsers.clear(); 2094 for (int i = 0; i < startingUsers.size(); i++) { 2095 mService.finishUserBoot(startingUsers.get(i)); 2096 } 2097 } 2098 } 2099 2100 mService.trimApplications(); 2101 //dump(); 2102 //mWindowManager.dump(); 2103 2104 if (enableScreen) { 2105 mService.enableScreenAfterBoot(); 2106 } 2107 2108 if (activityRemoved) { 2109 resumeTopActivitiesLocked(); 2110 } 2111 2112 return r; 2113 } 2114 2115 boolean handleAppDiedLocked(ProcessRecord app) { 2116 boolean hasVisibleActivities = false; 2117 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2118 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2119 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2120 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2121 } 2122 } 2123 return hasVisibleActivities; 2124 } 2125 2126 void closeSystemDialogsLocked() { 2127 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2128 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2129 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2130 stacks.get(stackNdx).closeSystemDialogsLocked(); 2131 } 2132 } 2133 } 2134 2135 void removeUserLocked(int userId) { 2136 mUserStackInFront.delete(userId); 2137 } 2138 2139 /** 2140 * @return true if some activity was finished (or would have finished if doit were true). 2141 */ 2142 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2143 boolean didSomething = false; 2144 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2145 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2146 final int numStacks = stacks.size(); 2147 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2148 final ActivityStack stack = stacks.get(stackNdx); 2149 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2150 didSomething = true; 2151 } 2152 } 2153 } 2154 return didSomething; 2155 } 2156 2157 void updatePreviousProcessLocked(ActivityRecord r) { 2158 // Now that this process has stopped, we may want to consider 2159 // it to be the previous app to try to keep around in case 2160 // the user wants to return to it. 2161 2162 // First, found out what is currently the foreground app, so that 2163 // we don't blow away the previous app if this activity is being 2164 // hosted by the process that is actually still the foreground. 2165 ProcessRecord fgApp = null; 2166 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2167 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2168 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2169 final ActivityStack stack = stacks.get(stackNdx); 2170 if (isFrontStack(stack)) { 2171 if (stack.mResumedActivity != null) { 2172 fgApp = stack.mResumedActivity.app; 2173 } else if (stack.mPausingActivity != null) { 2174 fgApp = stack.mPausingActivity.app; 2175 } 2176 break; 2177 } 2178 } 2179 } 2180 2181 // Now set this one as the previous process, only if that really 2182 // makes sense to. 2183 if (r.app != null && fgApp != null && r.app != fgApp 2184 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2185 && r.app != mService.mHomeProcess) { 2186 mService.mPreviousProcess = r.app; 2187 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2188 } 2189 } 2190 2191 boolean resumeTopActivitiesLocked() { 2192 return resumeTopActivitiesLocked(null, null, null); 2193 } 2194 2195 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2196 Bundle targetOptions) { 2197 if (targetStack == null) { 2198 targetStack = getFocusedStack(); 2199 } 2200 // Do targetStack first. 2201 boolean result = false; 2202 if (isFrontStack(targetStack)) { 2203 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2204 } 2205 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2206 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2207 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2208 final ActivityStack stack = stacks.get(stackNdx); 2209 if (stack == targetStack) { 2210 // Already started above. 2211 continue; 2212 } 2213 if (isFrontStack(stack)) { 2214 stack.resumeTopActivityLocked(null); 2215 } 2216 } 2217 } 2218 return result; 2219 } 2220 2221 void finishTopRunningActivityLocked(ProcessRecord app) { 2222 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2223 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2224 final int numStacks = stacks.size(); 2225 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2226 final ActivityStack stack = stacks.get(stackNdx); 2227 stack.finishTopRunningActivityLocked(app); 2228 } 2229 } 2230 } 2231 2232 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2233 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2234 mUserLeaving = true; 2235 } 2236 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2237 // Caller wants the home activity moved with it. To accomplish this, 2238 // we'll just indicate that this task returns to the home task. 2239 task.mOnTopOfHome = true; 2240 } 2241 task.stack.moveTaskToFrontLocked(task, null, options); 2242 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2243 + task.stack); 2244 } 2245 2246 ActivityStack getStack(int stackId) { 2247 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2248 if (activityContainer != null) { 2249 return activityContainer.mStack; 2250 } 2251 return null; 2252 } 2253 2254 ArrayList<ActivityStack> getStacks() { 2255 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2256 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2257 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2258 } 2259 return allStacks; 2260 } 2261 2262 IBinder getHomeActivityToken() { 2263 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2264 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2265 final TaskRecord task = tasks.get(taskNdx); 2266 if (task.isHomeTask()) { 2267 final ArrayList<ActivityRecord> activities = task.mActivities; 2268 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2269 final ActivityRecord r = activities.get(activityNdx); 2270 if (r.isHomeActivity()) { 2271 return r.appToken; 2272 } 2273 } 2274 } 2275 } 2276 return null; 2277 } 2278 2279 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2280 IActivityContainerCallback callback) { 2281 ActivityContainer activityContainer = 2282 new VirtualActivityContainer(parentActivity, callback); 2283 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2284 if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer); 2285 parentActivity.mChildContainers.add(activityContainer); 2286 return activityContainer; 2287 } 2288 2289 void removeChildActivityContainers(ActivityRecord parentActivity) { 2290 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2291 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2292 ActivityContainer container = childStacks.remove(containerNdx); 2293 if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " + 2294 container); 2295 container.release(); 2296 } 2297 } 2298 2299 void deleteActivityContainer(IActivityContainer container) { 2300 ActivityContainer activityContainer = (ActivityContainer)container; 2301 if (activityContainer != null) { 2302 if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ", 2303 new RuntimeException("here").fillInStackTrace()); 2304 final int stackId = activityContainer.mStackId; 2305 mActivityContainers.remove(stackId); 2306 mWindowManager.removeStack(stackId); 2307 } 2308 } 2309 2310 private int createStackOnDisplay(int stackId, int displayId) { 2311 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2312 if (activityDisplay == null) { 2313 return -1; 2314 } 2315 2316 ActivityContainer activityContainer = new ActivityContainer(stackId); 2317 mActivityContainers.put(stackId, activityContainer); 2318 activityContainer.attachToDisplayLocked(activityDisplay); 2319 return stackId; 2320 } 2321 2322 int getNextStackId() { 2323 while (true) { 2324 if (++mLastStackId <= HOME_STACK_ID) { 2325 mLastStackId = HOME_STACK_ID + 1; 2326 } 2327 if (getStack(mLastStackId) == null) { 2328 break; 2329 } 2330 } 2331 return mLastStackId; 2332 } 2333 2334 void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { 2335 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2336 final ActivityStack stack = getStack(stackId); 2337 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2338 final TaskRecord task = tasks.get(taskNdx); 2339 stack.addTask(task, false, false); 2340 final int taskId = task.taskId; 2341 final ArrayList<ActivityRecord> activities = task.mActivities; 2342 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2343 final ActivityRecord r = activities.get(activityNdx); 2344 mWindowManager.addAppToken(0, r.appToken, taskId, stackId, 2345 r.info.screenOrientation, r.fullscreen, 2346 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, 2347 r.userId, r.info.configChanges, task.voiceSession != null); 2348 } 2349 mWindowManager.addTask(taskId, stackId, false); 2350 } 2351 resumeHomeActivity(null); 2352 } 2353 2354 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2355 final TaskRecord task = anyTaskForIdLocked(taskId); 2356 if (task == null) { 2357 return; 2358 } 2359 final ActivityStack stack = getStack(stackId); 2360 if (stack == null) { 2361 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2362 return; 2363 } 2364 task.stack.removeTask(task); 2365 stack.addTask(task, toTop, true); 2366 mWindowManager.addTask(taskId, stackId, toTop); 2367 resumeTopActivitiesLocked(); 2368 } 2369 2370 ActivityRecord findTaskLocked(ActivityRecord r) { 2371 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2372 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2373 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2374 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2375 final ActivityStack stack = stacks.get(stackNdx); 2376 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2377 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2378 continue; 2379 } 2380 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2381 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2382 stack); 2383 continue; 2384 } 2385 final ActivityRecord ar = stack.findTaskLocked(r); 2386 if (ar != null) { 2387 return ar; 2388 } 2389 } 2390 } 2391 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2392 return null; 2393 } 2394 2395 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2396 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2397 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2398 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2399 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2400 if (ar != null) { 2401 return ar; 2402 } 2403 } 2404 } 2405 return null; 2406 } 2407 2408 void goingToSleepLocked() { 2409 scheduleSleepTimeout(); 2410 if (!mGoingToSleep.isHeld()) { 2411 mGoingToSleep.acquire(); 2412 if (mLaunchingActivity.isHeld()) { 2413 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2414 throw new IllegalStateException("Calling must be system uid"); 2415 } 2416 mLaunchingActivity.release(); 2417 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2418 } 2419 } 2420 checkReadyForSleepLocked(); 2421 } 2422 2423 boolean shutdownLocked(int timeout) { 2424 goingToSleepLocked(); 2425 2426 boolean timedout = false; 2427 final long endTime = System.currentTimeMillis() + timeout; 2428 while (true) { 2429 boolean cantShutdown = false; 2430 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2431 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2432 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2433 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2434 } 2435 } 2436 if (cantShutdown) { 2437 long timeRemaining = endTime - System.currentTimeMillis(); 2438 if (timeRemaining > 0) { 2439 try { 2440 mService.wait(timeRemaining); 2441 } catch (InterruptedException e) { 2442 } 2443 } else { 2444 Slog.w(TAG, "Activity manager shutdown timed out"); 2445 timedout = true; 2446 break; 2447 } 2448 } else { 2449 break; 2450 } 2451 } 2452 2453 // Force checkReadyForSleep to complete. 2454 mSleepTimeout = true; 2455 checkReadyForSleepLocked(); 2456 2457 return timedout; 2458 } 2459 2460 void comeOutOfSleepIfNeededLocked() { 2461 removeSleepTimeouts(); 2462 if (mGoingToSleep.isHeld()) { 2463 mGoingToSleep.release(); 2464 } 2465 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2466 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2467 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2468 final ActivityStack stack = stacks.get(stackNdx); 2469 stack.awakeFromSleepingLocked(); 2470 if (isFrontStack(stack)) { 2471 resumeTopActivitiesLocked(); 2472 } 2473 } 2474 } 2475 mGoingToSleepActivities.clear(); 2476 } 2477 2478 void activitySleptLocked(ActivityRecord r) { 2479 mGoingToSleepActivities.remove(r); 2480 checkReadyForSleepLocked(); 2481 } 2482 2483 void checkReadyForSleepLocked() { 2484 if (!mService.isSleepingOrShuttingDown()) { 2485 // Do not care. 2486 return; 2487 } 2488 2489 if (!mSleepTimeout) { 2490 boolean dontSleep = false; 2491 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2492 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2493 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2494 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2495 } 2496 } 2497 2498 if (mStoppingActivities.size() > 0) { 2499 // Still need to tell some activities to stop; can't sleep yet. 2500 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2501 + mStoppingActivities.size() + " activities"); 2502 scheduleIdleLocked(); 2503 dontSleep = true; 2504 } 2505 2506 if (mGoingToSleepActivities.size() > 0) { 2507 // Still need to tell some activities to sleep; can't sleep yet. 2508 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2509 + mGoingToSleepActivities.size() + " activities"); 2510 dontSleep = true; 2511 } 2512 2513 if (dontSleep) { 2514 return; 2515 } 2516 } 2517 2518 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2519 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2520 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2521 stacks.get(stackNdx).goToSleep(); 2522 } 2523 } 2524 2525 removeSleepTimeouts(); 2526 2527 if (mGoingToSleep.isHeld()) { 2528 mGoingToSleep.release(); 2529 } 2530 if (mService.mShuttingDown) { 2531 mService.notifyAll(); 2532 } 2533 } 2534 2535 boolean reportResumedActivityLocked(ActivityRecord r) { 2536 final ActivityStack stack = r.task.stack; 2537 if (isFrontStack(stack)) { 2538 mService.updateUsageStats(r, true); 2539 } 2540 if (allResumedActivitiesComplete()) { 2541 ensureActivitiesVisibleLocked(null, 0); 2542 mWindowManager.executeAppTransition(); 2543 return true; 2544 } 2545 return false; 2546 } 2547 2548 void handleAppCrashLocked(ProcessRecord app) { 2549 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2550 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2551 final int numStacks = stacks.size(); 2552 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2553 final ActivityStack stack = stacks.get(stackNdx); 2554 stack.handleAppCrashLocked(app); 2555 } 2556 } 2557 } 2558 2559 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2560 // First the front stacks. In case any are not fullscreen and are in front of home. 2561 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2562 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2563 final int topStackNdx = stacks.size() - 1; 2564 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2565 final ActivityStack stack = stacks.get(stackNdx); 2566 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2567 } 2568 } 2569 } 2570 2571 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2572 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2573 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2574 final int numStacks = stacks.size(); 2575 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2576 final ActivityStack stack = stacks.get(stackNdx); 2577 stack.scheduleDestroyActivities(app, false, reason); 2578 } 2579 } 2580 } 2581 2582 boolean switchUserLocked(int userId, UserStartedState uss) { 2583 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2584 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2585 mCurrentUser = userId; 2586 2587 mStartingUsers.add(uss); 2588 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2589 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2590 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2591 final ActivityStack stack = stacks.get(stackNdx); 2592 stack.switchUserLocked(userId); 2593 TaskRecord task = stack.topTask(); 2594 if (task != null) { 2595 mWindowManager.moveTaskToTop(task.taskId); 2596 } 2597 } 2598 } 2599 2600 ActivityStack stack = getStack(restoreStackId); 2601 if (stack == null) { 2602 stack = mHomeStack; 2603 } 2604 final boolean homeInFront = stack.isHomeStack(); 2605 if (stack.isOnHomeDisplay()) { 2606 moveHomeStack(homeInFront); 2607 TaskRecord task = stack.topTask(); 2608 if (task != null) { 2609 mWindowManager.moveTaskToTop(task.taskId); 2610 } 2611 } else { 2612 // Stack was moved to another display while user was swapped out. 2613 resumeHomeActivity(null); 2614 } 2615 return homeInFront; 2616 } 2617 2618 /** 2619 * Add background users to send boot completed events to. 2620 * @param userId The user being started in the background 2621 * @param uss The state object for the user. 2622 */ 2623 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 2624 mStartingBackgroundUsers.add(uss); 2625 } 2626 2627 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2628 int N = mStoppingActivities.size(); 2629 if (N <= 0) return null; 2630 2631 ArrayList<ActivityRecord> stops = null; 2632 2633 final boolean nowVisible = allResumedActivitiesVisible(); 2634 for (int i=0; i<N; i++) { 2635 ActivityRecord s = mStoppingActivities.get(i); 2636 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2637 + nowVisible + " waitingVisible=" + s.waitingVisible 2638 + " finishing=" + s.finishing); 2639 if (s.waitingVisible && nowVisible) { 2640 mWaitingVisibleActivities.remove(s); 2641 s.waitingVisible = false; 2642 if (s.finishing) { 2643 // If this activity is finishing, it is sitting on top of 2644 // everyone else but we now know it is no longer needed... 2645 // so get rid of it. Otherwise, we need to go through the 2646 // normal flow and hide it once we determine that it is 2647 // hidden by the activities in front of it. 2648 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2649 mWindowManager.setAppVisibility(s.appToken, false); 2650 } 2651 } 2652 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2653 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2654 if (stops == null) { 2655 stops = new ArrayList<ActivityRecord>(); 2656 } 2657 stops.add(s); 2658 mStoppingActivities.remove(i); 2659 N--; 2660 i--; 2661 } 2662 } 2663 2664 return stops; 2665 } 2666 2667 void validateTopActivitiesLocked() { 2668 // FIXME 2669/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2670 final ActivityStack stack = stacks.get(stackNdx); 2671 final ActivityRecord r = stack.topRunningActivityLocked(null); 2672 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2673 if (isFrontStack(stack)) { 2674 if (r == null) { 2675 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2676 } else { 2677 final ActivityRecord pausing = stack.mPausingActivity; 2678 if (pausing != null && pausing == r) { 2679 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2680 " state=" + state); 2681 } 2682 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2683 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2684 " state=" + state); 2685 } 2686 } 2687 } else { 2688 final ActivityRecord resumed = stack.mResumedActivity; 2689 if (resumed != null && resumed == r) { 2690 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2691 " state=" + state); 2692 } 2693 if (r != null && (state == ActivityState.INITIALIZING 2694 || state == ActivityState.RESUMED)) { 2695 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2696 " state=" + state); 2697 } 2698 } 2699 } 2700*/ 2701 } 2702 2703 public void dump(PrintWriter pw, String prefix) { 2704 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2705 pw.println(mDismissKeyguardOnNextActivity); 2706 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2707 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2708 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2709 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2710 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2711 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2712 } 2713 2714 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2715 return getFocusedStack().getDumpActivitiesLocked(name); 2716 } 2717 2718 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2719 boolean needSep, String prefix) { 2720 if (activity != null) { 2721 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2722 if (needSep) { 2723 pw.println(); 2724 } 2725 pw.print(prefix); 2726 pw.println(activity); 2727 return true; 2728 } 2729 } 2730 return false; 2731 } 2732 2733 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2734 boolean dumpClient, String dumpPackage) { 2735 boolean printed = false; 2736 boolean needSep = false; 2737 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2738 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2739 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2740 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2741 final int numStacks = stacks.size(); 2742 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2743 final ActivityStack stack = stacks.get(stackNdx); 2744 StringBuilder stackHeader = new StringBuilder(128); 2745 stackHeader.append(" Stack #"); 2746 stackHeader.append(stack.mStackId); 2747 stackHeader.append(":"); 2748 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2749 needSep, stackHeader.toString()); 2750 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2751 !dumpAll, false, dumpPackage, true, 2752 " Running activities (most recent first):", null); 2753 2754 needSep = printed; 2755 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2756 " mPausingActivity: "); 2757 if (pr) { 2758 printed = true; 2759 needSep = false; 2760 } 2761 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2762 " mResumedActivity: "); 2763 if (pr) { 2764 printed = true; 2765 needSep = false; 2766 } 2767 if (dumpAll) { 2768 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2769 " mLastPausedActivity: "); 2770 if (pr) { 2771 printed = true; 2772 needSep = true; 2773 } 2774 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2775 needSep, " mLastNoHistoryActivity: "); 2776 } 2777 needSep = printed; 2778 } 2779 } 2780 2781 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2782 false, dumpPackage, true, " Activities waiting to finish:", null); 2783 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2784 false, dumpPackage, true, " Activities waiting to stop:", null); 2785 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2786 false, dumpPackage, true, " Activities waiting for another to become visible:", 2787 null); 2788 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2789 false, dumpPackage, true, " Activities waiting to sleep:", null); 2790 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2791 false, dumpPackage, true, " Activities waiting to sleep:", null); 2792 2793 return printed; 2794 } 2795 2796 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2797 String prefix, String label, boolean complete, boolean brief, boolean client, 2798 String dumpPackage, boolean needNL, String header1, String header2) { 2799 TaskRecord lastTask = null; 2800 String innerPrefix = null; 2801 String[] args = null; 2802 boolean printed = false; 2803 for (int i=list.size()-1; i>=0; i--) { 2804 final ActivityRecord r = list.get(i); 2805 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2806 continue; 2807 } 2808 if (innerPrefix == null) { 2809 innerPrefix = prefix + " "; 2810 args = new String[0]; 2811 } 2812 printed = true; 2813 final boolean full = !brief && (complete || !r.isInHistory()); 2814 if (needNL) { 2815 pw.println(""); 2816 needNL = false; 2817 } 2818 if (header1 != null) { 2819 pw.println(header1); 2820 header1 = null; 2821 } 2822 if (header2 != null) { 2823 pw.println(header2); 2824 header2 = null; 2825 } 2826 if (lastTask != r.task) { 2827 lastTask = r.task; 2828 pw.print(prefix); 2829 pw.print(full ? "* " : " "); 2830 pw.println(lastTask); 2831 if (full) { 2832 lastTask.dump(pw, prefix + " "); 2833 } else if (complete) { 2834 // Complete + brief == give a summary. Isn't that obvious?!? 2835 if (lastTask.intent != null) { 2836 pw.print(prefix); pw.print(" "); 2837 pw.println(lastTask.intent.toInsecureStringWithClip()); 2838 } 2839 } 2840 } 2841 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2842 pw.print(" #"); pw.print(i); pw.print(": "); 2843 pw.println(r); 2844 if (full) { 2845 r.dump(pw, innerPrefix); 2846 } else if (complete) { 2847 // Complete + brief == give a summary. Isn't that obvious?!? 2848 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2849 if (r.app != null) { 2850 pw.print(innerPrefix); pw.println(r.app); 2851 } 2852 } 2853 if (client && r.app != null && r.app.thread != null) { 2854 // flush anything that is already in the PrintWriter since the thread is going 2855 // to write to the file descriptor directly 2856 pw.flush(); 2857 try { 2858 TransferPipe tp = new TransferPipe(); 2859 try { 2860 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2861 r.appToken, innerPrefix, args); 2862 // Short timeout, since blocking here can 2863 // deadlock with the application. 2864 tp.go(fd, 2000); 2865 } finally { 2866 tp.kill(); 2867 } 2868 } catch (IOException e) { 2869 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2870 } catch (RemoteException e) { 2871 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2872 } 2873 needNL = true; 2874 } 2875 } 2876 return printed; 2877 } 2878 2879 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2880 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2881 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2882 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2883 } 2884 2885 final void scheduleIdleLocked() { 2886 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2887 } 2888 2889 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2890 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2891 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2892 } 2893 2894 final void scheduleResumeTopActivities() { 2895 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2896 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2897 } 2898 } 2899 2900 void removeSleepTimeouts() { 2901 mSleepTimeout = false; 2902 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2903 } 2904 2905 final void scheduleSleepTimeout() { 2906 removeSleepTimeouts(); 2907 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2908 } 2909 2910 @Override 2911 public void onDisplayAdded(int displayId) { 2912 Slog.v(TAG, "Display added displayId=" + displayId); 2913 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2914 } 2915 2916 @Override 2917 public void onDisplayRemoved(int displayId) { 2918 Slog.v(TAG, "Display removed displayId=" + displayId); 2919 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2920 } 2921 2922 @Override 2923 public void onDisplayChanged(int displayId) { 2924 Slog.v(TAG, "Display changed displayId=" + displayId); 2925 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2926 } 2927 2928 public void handleDisplayAddedLocked(int displayId) { 2929 boolean newDisplay; 2930 synchronized (mService) { 2931 newDisplay = mActivityDisplays.get(displayId) == null; 2932 if (newDisplay) { 2933 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2934 mActivityDisplays.put(displayId, activityDisplay); 2935 } 2936 } 2937 if (newDisplay) { 2938 mWindowManager.onDisplayAdded(displayId); 2939 } 2940 } 2941 2942 public void handleDisplayRemovedLocked(int displayId) { 2943 synchronized (mService) { 2944 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2945 if (activityDisplay != null) { 2946 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2947 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2948 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2949 } 2950 mActivityDisplays.remove(displayId); 2951 } 2952 } 2953 mWindowManager.onDisplayRemoved(displayId); 2954 } 2955 2956 public void handleDisplayChangedLocked(int displayId) { 2957 synchronized (mService) { 2958 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2959 if (activityDisplay != null) { 2960 // TODO: Update the bounds. 2961 } 2962 } 2963 mWindowManager.onDisplayChanged(displayId); 2964 } 2965 2966 StackInfo getStackInfo(ActivityStack stack) { 2967 StackInfo info = new StackInfo(); 2968 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2969 info.displayId = Display.DEFAULT_DISPLAY; 2970 info.stackId = stack.mStackId; 2971 2972 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2973 final int numTasks = tasks.size(); 2974 int[] taskIds = new int[numTasks]; 2975 String[] taskNames = new String[numTasks]; 2976 for (int i = 0; i < numTasks; ++i) { 2977 final TaskRecord task = tasks.get(i); 2978 taskIds[i] = task.taskId; 2979 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2980 : task.realActivity != null ? task.realActivity.flattenToString() 2981 : task.getTopActivity() != null ? task.getTopActivity().packageName 2982 : "unknown"; 2983 } 2984 info.taskIds = taskIds; 2985 info.taskNames = taskNames; 2986 return info; 2987 } 2988 2989 StackInfo getStackInfoLocked(int stackId) { 2990 ActivityStack stack = getStack(stackId); 2991 if (stack != null) { 2992 return getStackInfo(stack); 2993 } 2994 return null; 2995 } 2996 2997 ArrayList<StackInfo> getAllStackInfosLocked() { 2998 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2999 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3000 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3001 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3002 list.add(getStackInfo(stacks.get(ndx))); 3003 } 3004 } 3005 return list; 3006 } 3007 3008 void setLockTaskModeLocked(TaskRecord task) { 3009 if (task == null) { 3010 // Take out of lock task mode if necessary 3011 if (mLockTaskModeTask != null) { 3012 final Message lockTaskMsg = Message.obtain(); 3013 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3014 lockTaskMsg.what = LOCK_TASK_END_MSG; 3015 mLockTaskModeTask = null; 3016 mHandler.sendMessage(lockTaskMsg); 3017 } 3018 return; 3019 } 3020 if (isLockTaskModeViolation(task)) { 3021 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 3022 return; 3023 } 3024 mLockTaskModeTask = task; 3025 findTaskToMoveToFrontLocked(task, 0, null); 3026 resumeTopActivitiesLocked(); 3027 3028 final Message lockTaskMsg = Message.obtain(); 3029 lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName(); 3030 lockTaskMsg.arg1 = mLockTaskModeTask.userId; 3031 lockTaskMsg.what = LOCK_TASK_START_MSG; 3032 mHandler.sendMessage(lockTaskMsg); 3033 } 3034 3035 boolean isLockTaskModeViolation(TaskRecord task) { 3036 return mLockTaskModeTask != null && mLockTaskModeTask != task; 3037 } 3038 3039 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3040 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3041 mLockTaskModeTask = null; 3042 } 3043 } 3044 3045 boolean isInLockTaskMode() { 3046 return mLockTaskModeTask != null; 3047 } 3048 3049 private final class ActivityStackSupervisorHandler extends Handler { 3050 3051 public ActivityStackSupervisorHandler(Looper looper) { 3052 super(looper); 3053 } 3054 3055 void activityIdleInternal(ActivityRecord r) { 3056 synchronized (mService) { 3057 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3058 } 3059 } 3060 3061 @Override 3062 public void handleMessage(Message msg) { 3063 switch (msg.what) { 3064 case IDLE_TIMEOUT_MSG: { 3065 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3066 if (mService.mDidDexOpt) { 3067 mService.mDidDexOpt = false; 3068 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3069 nmsg.obj = msg.obj; 3070 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3071 return; 3072 } 3073 // We don't at this point know if the activity is fullscreen, 3074 // so we need to be conservative and assume it isn't. 3075 activityIdleInternal((ActivityRecord)msg.obj); 3076 } break; 3077 case IDLE_NOW_MSG: { 3078 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3079 activityIdleInternal((ActivityRecord)msg.obj); 3080 } break; 3081 case RESUME_TOP_ACTIVITY_MSG: { 3082 synchronized (mService) { 3083 resumeTopActivitiesLocked(); 3084 } 3085 } break; 3086 case SLEEP_TIMEOUT_MSG: { 3087 synchronized (mService) { 3088 if (mService.isSleepingOrShuttingDown()) { 3089 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3090 mSleepTimeout = true; 3091 checkReadyForSleepLocked(); 3092 } 3093 } 3094 } break; 3095 case LAUNCH_TIMEOUT_MSG: { 3096 if (mService.mDidDexOpt) { 3097 mService.mDidDexOpt = false; 3098 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3099 return; 3100 } 3101 synchronized (mService) { 3102 if (mLaunchingActivity.isHeld()) { 3103 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3104 if (VALIDATE_WAKE_LOCK_CALLER 3105 && Binder.getCallingUid() != Process.myUid()) { 3106 throw new IllegalStateException("Calling must be system uid"); 3107 } 3108 mLaunchingActivity.release(); 3109 } 3110 } 3111 } break; 3112 case HANDLE_DISPLAY_ADDED: { 3113 handleDisplayAddedLocked(msg.arg1); 3114 } break; 3115 case HANDLE_DISPLAY_CHANGED: { 3116 handleDisplayChangedLocked(msg.arg1); 3117 } break; 3118 case HANDLE_DISPLAY_REMOVED: { 3119 handleDisplayRemovedLocked(msg.arg1); 3120 } break; 3121 case CONTAINER_CALLBACK_VISIBILITY: { 3122 final ActivityContainer container = (ActivityContainer) msg.obj; 3123 final IActivityContainerCallback callback = container.mCallback; 3124 if (callback != null) { 3125 try { 3126 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3127 } catch (RemoteException e) { 3128 } 3129 } 3130 } break; 3131 case LOCK_TASK_START_MSG: { 3132 // When lock task starts, we disable the status bars. 3133 try { 3134 if (getStatusBarService() != null) { 3135 getStatusBarService().disable 3136 (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK, 3137 mToken, mService.mContext.getPackageName()); 3138 } 3139 if (getDevicePolicyManager() != null) { 3140 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3141 (String)msg.obj, 3142 msg.arg1); 3143 } 3144 } catch (RemoteException ex) { 3145 throw new RuntimeException(ex); 3146 } 3147 } break; 3148 case LOCK_TASK_END_MSG: { 3149 // When lock task ends, we enable the status bars. 3150 try { 3151 if (getStatusBarService() != null) { 3152 getStatusBarService().disable 3153 (StatusBarManager.DISABLE_NONE, 3154 mToken, mService.mContext.getPackageName()); 3155 } 3156 if (getDevicePolicyManager() != null) { 3157 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3158 msg.arg1); 3159 } 3160 } catch (RemoteException ex) { 3161 throw new RuntimeException(ex); 3162 } 3163 } break; 3164 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3165 final ActivityContainer container = (ActivityContainer) msg.obj; 3166 final IActivityContainerCallback callback = container.mCallback; 3167 if (callback != null) { 3168 try { 3169 callback.onAllActivitiesComplete(container.asBinder()); 3170 } catch (RemoteException e) { 3171 } 3172 } 3173 } break; 3174 case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: { 3175 synchronized (mService) { 3176 Slog.w(TAG, "Timeout waiting for all activities in task to finish. " + 3177 msg.obj); 3178 ((ActivityContainer) msg.obj).onTaskListEmptyLocked(); 3179 } 3180 } break; 3181 } 3182 } 3183 } 3184 3185 class ActivityContainer extends android.app.IActivityContainer.Stub { 3186 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3187 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3188 final int mStackId; 3189 IActivityContainerCallback mCallback = null; 3190 final ActivityStack mStack; 3191 ActivityRecord mParentActivity = null; 3192 String mIdString; 3193 3194 boolean mVisible = true; 3195 3196 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3197 ActivityDisplay mActivityDisplay; 3198 3199 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3200 final static int CONTAINER_STATE_NO_SURFACE = 1; 3201 final static int CONTAINER_STATE_FINISHING = 2; 3202 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3203 3204 ActivityContainer(int stackId) { 3205 synchronized (mService) { 3206 mStackId = stackId; 3207 mStack = new ActivityStack(this); 3208 mIdString = "ActivtyContainer{" + mStackId + "}"; 3209 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3210 } 3211 } 3212 3213 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3214 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3215 + " to display=" + activityDisplay); 3216 mActivityDisplay = activityDisplay; 3217 mStack.mDisplayId = activityDisplay.mDisplayId; 3218 mStack.mStacks = activityDisplay.mStacks; 3219 3220 activityDisplay.attachActivities(mStack); 3221 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3222 } 3223 3224 @Override 3225 public void attachToDisplay(int displayId) { 3226 synchronized (mService) { 3227 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3228 if (activityDisplay == null) { 3229 return; 3230 } 3231 attachToDisplayLocked(activityDisplay); 3232 } 3233 } 3234 3235 @Override 3236 public int getDisplayId() { 3237 synchronized (mService) { 3238 if (mActivityDisplay != null) { 3239 return mActivityDisplay.mDisplayId; 3240 } 3241 } 3242 return -1; 3243 } 3244 3245 @Override 3246 public boolean injectEvent(InputEvent event) { 3247 final long origId = Binder.clearCallingIdentity(); 3248 try { 3249 synchronized (mService) { 3250 if (mActivityDisplay != null) { 3251 return mInputManagerInternal.injectInputEvent(event, 3252 mActivityDisplay.mDisplayId, 3253 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3254 } 3255 } 3256 return false; 3257 } finally { 3258 Binder.restoreCallingIdentity(origId); 3259 } 3260 } 3261 3262 @Override 3263 public void release() { 3264 synchronized (mService) { 3265 if (mContainerState == CONTAINER_STATE_FINISHING) { 3266 return; 3267 } 3268 mContainerState = CONTAINER_STATE_FINISHING; 3269 3270 final Message msg = 3271 mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3272 mHandler.sendMessageDelayed(msg, 1000); 3273 3274 long origId = Binder.clearCallingIdentity(); 3275 try { 3276 mStack.finishAllActivitiesLocked(); 3277 } finally { 3278 Binder.restoreCallingIdentity(origId); 3279 } 3280 } 3281 } 3282 3283 private void detachLocked() { 3284 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3285 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3286 if (mActivityDisplay != null) { 3287 mActivityDisplay.detachActivitiesLocked(mStack); 3288 mActivityDisplay = null; 3289 mStack.mDisplayId = -1; 3290 mStack.mStacks = null; 3291 mWindowManager.detachStack(mStackId); 3292 } 3293 } 3294 3295 @Override 3296 public final int startActivity(Intent intent) { 3297 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3298 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3299 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3300 // TODO: Switch to user app stacks here. 3301 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3302 String mimeType = intent.getType(); 3303 if (mimeType == null && intent.getData() != null 3304 && "content".equals(intent.getData().getScheme())) { 3305 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3306 } 3307 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null, 3308 null, null, null, null, userId, this); 3309 } 3310 3311 @Override 3312 public final int startActivityIntentSender(IIntentSender intentSender) { 3313 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3314 3315 if (!(intentSender instanceof PendingIntentRecord)) { 3316 throw new IllegalArgumentException("Bad PendingIntent object"); 3317 } 3318 3319 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3320 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3321 } 3322 3323 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3324 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3325 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3326 if (resolvedType == null) { 3327 resolvedType = intent.getType(); 3328 if (resolvedType == null && intent.getData() != null 3329 && "content".equals(intent.getData().getScheme())) { 3330 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3331 } 3332 } 3333 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3334 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3335 throw new SecurityException( 3336 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3337 } 3338 } 3339 3340 /** Throw a SecurityException if allowEmbedded is not true */ 3341 @Override 3342 public final void checkEmbeddedAllowed(Intent intent) { 3343 checkEmbeddedAllowedInner(intent, null); 3344 } 3345 3346 /** Throw a SecurityException if allowEmbedded is not true */ 3347 @Override 3348 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3349 if (!(intentSender instanceof PendingIntentRecord)) { 3350 throw new IllegalArgumentException("Bad PendingIntent object"); 3351 } 3352 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3353 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3354 pendingIntent.key.requestResolvedType); 3355 } 3356 3357 @Override 3358 public IBinder asBinder() { 3359 return this; 3360 } 3361 3362 @Override 3363 public void setSurface(Surface surface, int width, int height, int density) { 3364 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3365 } 3366 3367 ActivityStackSupervisor getOuter() { 3368 return ActivityStackSupervisor.this; 3369 } 3370 3371 boolean isAttachedLocked() { 3372 return mActivityDisplay != null; 3373 } 3374 3375 void getBounds(Point outBounds) { 3376 synchronized (mService) { 3377 if (mActivityDisplay != null) { 3378 mActivityDisplay.getBounds(outBounds); 3379 } else { 3380 outBounds.set(0, 0); 3381 } 3382 } 3383 } 3384 3385 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3386 void setVisible(boolean visible) { 3387 if (mVisible != visible) { 3388 mVisible = visible; 3389 if (mCallback != null) { 3390 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3391 0 /* unused */, this).sendToTarget(); 3392 } 3393 } 3394 } 3395 3396 void setDrawn() { 3397 } 3398 3399 // You can always start a new task on a regular ActivityStack. 3400 boolean isEligibleForNewTasks() { 3401 return true; 3402 } 3403 3404 void onTaskListEmptyLocked() { 3405 mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this); 3406 if (!mStack.isHomeStack()) { 3407 detachLocked(); 3408 deleteActivityContainer(this); 3409 } 3410 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 3411 } 3412 3413 @Override 3414 public String toString() { 3415 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3416 } 3417 } 3418 3419 private class VirtualActivityContainer extends ActivityContainer { 3420 Surface mSurface; 3421 boolean mDrawn = false; 3422 3423 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3424 super(getNextStackId()); 3425 mParentActivity = parent; 3426 mCallback = callback; 3427 mContainerState = CONTAINER_STATE_NO_SURFACE; 3428 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3429 } 3430 3431 @Override 3432 public void setSurface(Surface surface, int width, int height, int density) { 3433 super.setSurface(surface, width, height, density); 3434 3435 synchronized (mService) { 3436 final long origId = Binder.clearCallingIdentity(); 3437 try { 3438 setSurfaceLocked(surface, width, height, density); 3439 } finally { 3440 Binder.restoreCallingIdentity(origId); 3441 } 3442 } 3443 } 3444 3445 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3446 if (mContainerState == CONTAINER_STATE_FINISHING) { 3447 return; 3448 } 3449 VirtualActivityDisplay virtualActivityDisplay = 3450 (VirtualActivityDisplay) mActivityDisplay; 3451 if (virtualActivityDisplay == null) { 3452 virtualActivityDisplay = 3453 new VirtualActivityDisplay(width, height, density); 3454 mActivityDisplay = virtualActivityDisplay; 3455 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3456 attachToDisplayLocked(virtualActivityDisplay); 3457 } 3458 3459 if (mSurface != null) { 3460 mSurface.release(); 3461 } 3462 3463 mSurface = surface; 3464 if (surface != null) { 3465 mStack.resumeTopActivityLocked(null); 3466 } else { 3467 mContainerState = CONTAINER_STATE_NO_SURFACE; 3468 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3469 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3470 mStack.startPausingLocked(false, true); 3471 } 3472 } 3473 3474 setSurfaceIfReadyLocked(); 3475 3476 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3477 + virtualActivityDisplay); 3478 } 3479 3480 @Override 3481 boolean isAttachedLocked() { 3482 return mSurface != null && super.isAttachedLocked(); 3483 } 3484 3485 @Override 3486 void setDrawn() { 3487 synchronized (mService) { 3488 mDrawn = true; 3489 setSurfaceIfReadyLocked(); 3490 } 3491 } 3492 3493 // Never start a new task on an ActivityView if it isn't explicitly specified. 3494 @Override 3495 boolean isEligibleForNewTasks() { 3496 return false; 3497 } 3498 3499 private void setSurfaceIfReadyLocked() { 3500 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 3501 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3502 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3503 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3504 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3505 } 3506 } 3507 } 3508 3509 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3510 * attached {@link ActivityStack}s */ 3511 class ActivityDisplay { 3512 /** Actual Display this object tracks. */ 3513 int mDisplayId; 3514 Display mDisplay; 3515 DisplayInfo mDisplayInfo = new DisplayInfo(); 3516 3517 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3518 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3519 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3520 3521 ActivityDisplay() { 3522 } 3523 3524 ActivityDisplay(int displayId) { 3525 init(mDisplayManager.getDisplay(displayId)); 3526 } 3527 3528 void init(Display display) { 3529 mDisplay = display; 3530 mDisplayId = display.getDisplayId(); 3531 mDisplay.getDisplayInfo(mDisplayInfo); 3532 } 3533 3534 void attachActivities(ActivityStack stack) { 3535 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3536 + mDisplayId); 3537 mStacks.add(stack); 3538 } 3539 3540 void detachActivitiesLocked(ActivityStack stack) { 3541 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3542 + " from displayId=" + mDisplayId); 3543 mStacks.remove(stack); 3544 } 3545 3546 void getBounds(Point bounds) { 3547 mDisplay.getDisplayInfo(mDisplayInfo); 3548 bounds.x = mDisplayInfo.appWidth; 3549 bounds.y = mDisplayInfo.appHeight; 3550 } 3551 3552 @Override 3553 public String toString() { 3554 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3555 } 3556 } 3557 3558 class VirtualActivityDisplay extends ActivityDisplay { 3559 VirtualDisplay mVirtualDisplay; 3560 3561 VirtualActivityDisplay(int width, int height, int density) { 3562 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3563 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3564 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3565 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3566 3567 init(mVirtualDisplay.getDisplay()); 3568 3569 mWindowManager.handleDisplayAdded(mDisplayId); 3570 } 3571 3572 void setSurface(Surface surface) { 3573 if (mVirtualDisplay != null) { 3574 mVirtualDisplay.setSurface(surface); 3575 } 3576 } 3577 3578 @Override 3579 void detachActivitiesLocked(ActivityStack stack) { 3580 super.detachActivitiesLocked(stack); 3581 if (mVirtualDisplay != null) { 3582 mVirtualDisplay.release(); 3583 mVirtualDisplay = null; 3584 } 3585 } 3586 3587 @Override 3588 public String toString() { 3589 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3590 } 3591 } 3592 3593 private boolean isLeanbackOnlyDevice() { 3594 boolean onLeanbackOnly = false; 3595 try { 3596 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 3597 PackageManager.FEATURE_LEANBACK_ONLY); 3598 } catch (RemoteException e) { 3599 // noop 3600 } 3601 3602 return onLeanbackOnly; 3603 } 3604} 3605