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