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