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