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