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