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