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