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