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