ActivityStackSupervisor.java revision c6cf95c0f5f7250c65e40c441fe58d8cbfd114c9
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(sourceRecord, resultWho, requestCode); 1242 } 1243 if (sourceRecord.launchedFromUid == callingUid) { 1244 // The new activity is being launched from the same uid as the previous 1245 // activity in the flow, and asking to forward its result back to the 1246 // previous. In this case the activity is serving as a trampoline between 1247 // the two, so we also want to update its launchedFromPackage to be the 1248 // same as the previous activity. Note that this is safe, since we know 1249 // these two packages come from the same uid; the caller could just as 1250 // well have supplied that same package name itself. This specifially 1251 // deals with the case of an intent picker/chooser being launched in the app 1252 // flow to redirect to an activity picked by the user, where we want the final 1253 // activity to consider it to have been launched by the previous app activity. 1254 callingPackage = sourceRecord.launchedFromPackage; 1255 } 1256 } 1257 1258 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1259 // We couldn't find a class that can handle the given Intent. 1260 // That's the end of that! 1261 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1262 } 1263 1264 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1265 // We couldn't find the specific class specified in the Intent. 1266 // Also the end of the line. 1267 err = ActivityManager.START_CLASS_NOT_FOUND; 1268 } 1269 1270 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1271 && sourceRecord.task.voiceSession != null) { 1272 // If this activity is being launched as part of a voice session, we need 1273 // to ensure that it is safe to do so. If the upcoming activity will also 1274 // be part of the voice session, we can only launch it if it has explicitly 1275 // said it supports the VOICE category, or it is a part of the calling app. 1276 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1277 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1278 try { 1279 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1280 intent, resolvedType)) { 1281 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1282 } 1283 } catch (RemoteException e) { 1284 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1285 } 1286 } 1287 } 1288 1289 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1290 // If the caller is starting a new voice session, just make sure the target 1291 // is actually allowing it to run this way. 1292 try { 1293 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1294 intent, resolvedType)) { 1295 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1296 } 1297 } catch (RemoteException e) { 1298 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1299 } 1300 } 1301 1302 if (err != ActivityManager.START_SUCCESS) { 1303 if (resultRecord != null) { 1304 resultStack.sendActivityResultLocked(-1, 1305 resultRecord, resultWho, requestCode, 1306 Activity.RESULT_CANCELED, null); 1307 } 1308 setDismissKeyguard(false); 1309 ActivityOptions.abort(options); 1310 return err; 1311 } 1312 1313 final int startAnyPerm = mService.checkPermission( 1314 START_ANY_ACTIVITY, callingPid, callingUid); 1315 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1316 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1317 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1318 if (resultRecord != null) { 1319 resultStack.sendActivityResultLocked(-1, 1320 resultRecord, resultWho, requestCode, 1321 Activity.RESULT_CANCELED, null); 1322 } 1323 setDismissKeyguard(false); 1324 String msg; 1325 if (!aInfo.exported) { 1326 msg = "Permission Denial: starting " + intent.toString() 1327 + " from " + callerApp + " (pid=" + callingPid 1328 + ", uid=" + callingUid + ")" 1329 + " not exported from uid " + aInfo.applicationInfo.uid; 1330 } else { 1331 msg = "Permission Denial: starting " + intent.toString() 1332 + " from " + callerApp + " (pid=" + callingPid 1333 + ", uid=" + callingUid + ")" 1334 + " requires " + aInfo.permission; 1335 } 1336 Slog.w(TAG, msg); 1337 throw new SecurityException(msg); 1338 } 1339 1340 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1341 callingPid, resolvedType, aInfo.applicationInfo); 1342 1343 if (mService.mController != null) { 1344 try { 1345 // The Intent we give to the watcher has the extra data 1346 // stripped off, since it can contain private information. 1347 Intent watchIntent = intent.cloneFilter(); 1348 abort |= !mService.mController.activityStarting(watchIntent, 1349 aInfo.applicationInfo.packageName); 1350 } catch (RemoteException e) { 1351 mService.mController = null; 1352 } 1353 } 1354 1355 if (abort) { 1356 if (resultRecord != null) { 1357 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1358 Activity.RESULT_CANCELED, null); 1359 } 1360 // We pretend to the caller that it was really started, but 1361 // they will just get a cancel result. 1362 setDismissKeyguard(false); 1363 ActivityOptions.abort(options); 1364 return ActivityManager.START_SUCCESS; 1365 } 1366 1367 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1368 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1369 requestCode, componentSpecified, this, container, options); 1370 if (outActivity != null) { 1371 outActivity[0] = r; 1372 } 1373 1374 final ActivityStack stack = getFocusedStack(); 1375 if (voiceSession == null && (stack.mResumedActivity == null 1376 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1377 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1378 PendingActivityLaunch pal = 1379 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1380 mService.mPendingActivityLaunches.add(pal); 1381 setDismissKeyguard(false); 1382 ActivityOptions.abort(options); 1383 return ActivityManager.START_SWITCHES_CANCELED; 1384 } 1385 } 1386 1387 if (mService.mDidAppSwitch) { 1388 // This is the second allowed switch since we stopped switches, 1389 // so now just generally allow switches. Use case: user presses 1390 // home (switches disabled, switch to home, mDidAppSwitch now true); 1391 // user taps a home icon (coming from home so allowed, we hit here 1392 // and now allow anyone to switch again). 1393 mService.mAppSwitchesAllowedTime = 0; 1394 } else { 1395 mService.mDidAppSwitch = true; 1396 } 1397 1398 mService.doPendingActivityLaunchesLocked(false); 1399 1400 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1401 startFlags, true, options); 1402 1403 if (allPausedActivitiesComplete()) { 1404 // If someone asked to have the keyguard dismissed on the next 1405 // activity start, but we are not actually doing an activity 1406 // switch... just dismiss the keyguard now, because we 1407 // probably want to see whatever is behind it. 1408 dismissKeyguard(); 1409 } 1410 return err; 1411 } 1412 1413 ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) { 1414 final TaskRecord task = r.task; 1415 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1416 if (task != null) { 1417 final ActivityStack taskStack = task.stack; 1418 if (taskStack.isOnHomeDisplay()) { 1419 if (mFocusedStack != taskStack) { 1420 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1421 "focused stack to r=" + r + " task=" + task); 1422 mFocusedStack = taskStack; 1423 } else { 1424 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1425 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1426 } 1427 } 1428 return taskStack; 1429 } 1430 1431 final ActivityContainer container = r.mInitialActivityContainer; 1432 if (container != null) { 1433 // The first time put it on the desired stack, after this put on task stack. 1434 r.mInitialActivityContainer = null; 1435 return container.mStack; 1436 } 1437 1438 if (mFocusedStack != mHomeStack && (!newTask || 1439 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 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 = 1503 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1504 1505 // If the onlyIfNeeded flag is set, then we can do this if the activity 1506 // being launched is the same as the one making the call... or, as 1507 // a special case, if we do not know the caller then we count the 1508 // current top activity as the caller. 1509 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1510 ActivityRecord checkedCaller = sourceRecord; 1511 if (checkedCaller == null) { 1512 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1513 } 1514 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1515 // Caller is not the same as launcher, so always needed. 1516 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1517 } 1518 } 1519 1520 switch (r.info.documentLaunchMode) { 1521 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1522 break; 1523 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1524 intent.addFlags( 1525 Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1526 launchFlags = intent.getFlags(); 1527 break; 1528 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1529 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 1530 launchFlags = intent.getFlags(); 1531 break; 1532 } 1533 final boolean newDocument = intent.isDocument(); 1534 if (sourceRecord == null) { 1535 // This activity is not being started from another... in this 1536 // case we -always- start a new task. 1537 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1538 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1539 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1540 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1541 } 1542 } else if (newDocument) { 1543 if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) { 1544 Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\""); 1545 r.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 1546 } 1547 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1548 // The original activity who is starting us is running as a single 1549 // instance... this new activity it is starting must go on its 1550 // own task. 1551 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1552 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1553 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1554 // The activity being started is a single instance... it always 1555 // gets launched into its own task. 1556 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1557 } 1558 1559 ActivityInfo newTaskInfo = null; 1560 Intent newTaskIntent = null; 1561 final ActivityStack sourceStack; 1562 if (sourceRecord != null) { 1563 if (sourceRecord.finishing) { 1564 // If the source is finishing, we can't further count it as our source. This 1565 // is because the task it is associated with may now be empty and on its way out, 1566 // so we don't want to blindly throw it in to that task. Instead we will take 1567 // the NEW_TASK flow and try to find a task for it. But save the task information 1568 // so it can be used when creating the new task. 1569 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1570 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1571 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1572 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1573 newTaskInfo = sourceRecord.info; 1574 newTaskIntent = sourceRecord.task.intent; 1575 } 1576 sourceRecord = null; 1577 sourceStack = null; 1578 } else { 1579 sourceStack = sourceRecord.task.stack; 1580 } 1581 } else { 1582 sourceStack = null; 1583 } 1584 1585 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1586 // For whatever reason this activity is being launched into a new 1587 // task... yet the caller has requested a result back. Well, that 1588 // is pretty messed up, so instead immediately send back a cancel 1589 // and let the new task continue launched as normal without a 1590 // dependency on its originator. 1591 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1592 r.resultTo.task.stack.sendActivityResultLocked(-1, 1593 r.resultTo, r.resultWho, r.requestCode, 1594 Activity.RESULT_CANCELED, null); 1595 r.resultTo = null; 1596 } 1597 1598 boolean addingToTask = false; 1599 boolean movedHome = false; 1600 TaskRecord reuseTask = null; 1601 ActivityStack targetStack; 1602 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1603 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1604 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1605 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1606 // If bring to front is requested, and no result is requested, and 1607 // we can find a task that was started with this same 1608 // component, then instead of launching bring that one to the front. 1609 if (r.resultTo == null) { 1610 // See if there is a task to bring to the front. If this is 1611 // a SINGLE_INSTANCE activity, there can be one and only one 1612 // instance of it in the history, and it is always in its own 1613 // unique task, so we do a special search. 1614 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1615 ? findTaskLocked(r) 1616 : findActivityLocked(intent, r.info); 1617 if (intentActivity != null) { 1618 if (isLockTaskModeViolation(intentActivity.task)) { 1619 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1620 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1621 } 1622 if (r.task == null) { 1623 r.task = intentActivity.task; 1624 } 1625 targetStack = intentActivity.task.stack; 1626 targetStack.mLastPausedActivity = null; 1627 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1628 + " from " + intentActivity); 1629 targetStack.moveToFront(); 1630 if (intentActivity.task.intent == null) { 1631 // This task was started because of movement of 1632 // the activity based on affinity... now that we 1633 // are actually launching it, we can assign the 1634 // base intent. 1635 intentActivity.task.setIntent(intent, r.info); 1636 } 1637 // If the target task is not in the front, then we need 1638 // to bring it to the front... except... well, with 1639 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1640 // to have the same behavior as if a new instance was 1641 // being started, which means not bringing it to the front 1642 // if the caller is not itself in the front. 1643 final ActivityStack lastStack = getLastStack(); 1644 ActivityRecord curTop = lastStack == null? 1645 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1646 if (curTop != null && (curTop.task != intentActivity.task || 1647 curTop.task != lastStack.topTask())) { 1648 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1649 if (sourceRecord == null || (sourceStack.topActivity() != null && 1650 sourceStack.topActivity().task == sourceRecord.task)) { 1651 // We really do want to push this one into the 1652 // user's face, right now. 1653 movedHome = true; 1654 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1655 if ((launchFlags & 1656 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1657 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1658 // Caller wants to appear on home activity. 1659 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1660 } 1661 options = null; 1662 } 1663 } 1664 // If the caller has requested that the target task be 1665 // reset, then do so. 1666 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1667 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1668 } 1669 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1670 // We don't need to start a new activity, and 1671 // the client said not to do anything if that 1672 // is the case, so this is it! And for paranoia, make 1673 // sure we have correctly resumed the top activity. 1674 if (doResume) { 1675 resumeTopActivitiesLocked(targetStack, null, options); 1676 } else { 1677 ActivityOptions.abort(options); 1678 } 1679 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1680 } 1681 if ((launchFlags & 1682 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1683 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1684 // The caller has requested to completely replace any 1685 // existing task with its new activity. Well that should 1686 // not be too hard... 1687 reuseTask = intentActivity.task; 1688 reuseTask.performClearTaskLocked(); 1689 reuseTask.setIntent(r.intent, r.info); 1690 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1691 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1692 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1693 // In this situation we want to remove all activities 1694 // from the task up to the one being started. In most 1695 // cases this means we are resetting the task to its 1696 // initial state. 1697 ActivityRecord top = 1698 intentActivity.task.performClearTaskLocked(r, launchFlags); 1699 if (top != null) { 1700 if (top.frontOfTask) { 1701 // Activity aliases may mean we use different 1702 // intents for the top activity, so make sure 1703 // the task now has the identity of the new 1704 // intent. 1705 top.task.setIntent(r.intent, r.info); 1706 } 1707 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1708 r, top.task); 1709 top.deliverNewIntentLocked(callingUid, r.intent); 1710 } else { 1711 // A special case: we need to 1712 // start the activity because it is not currently 1713 // running, and the caller has asked to clear the 1714 // current task to have this activity at the top. 1715 addingToTask = true; 1716 // Now pretend like this activity is being started 1717 // by the top of its task, so it is put in the 1718 // right place. 1719 sourceRecord = intentActivity; 1720 } 1721 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1722 // In this case the top activity on the task is the 1723 // same as the one being launched, so we take that 1724 // as a request to bring the task to the foreground. 1725 // If the top activity in the task is the root 1726 // activity, deliver this new intent to it if it 1727 // desires. 1728 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1729 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1730 && intentActivity.realActivity.equals(r.realActivity)) { 1731 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1732 intentActivity.task); 1733 if (intentActivity.frontOfTask) { 1734 intentActivity.task.setIntent(r.intent, r.info); 1735 } 1736 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1737 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1738 // In this case we are launching the root activity 1739 // of the task, but with a different intent. We 1740 // should start a new instance on top. 1741 addingToTask = true; 1742 sourceRecord = intentActivity; 1743 } 1744 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1745 // In this case an activity is being launched in to an 1746 // existing task, without resetting that task. This 1747 // is typically the situation of launching an activity 1748 // from a notification or shortcut. We want to place 1749 // the new activity on top of the current task. 1750 addingToTask = true; 1751 sourceRecord = intentActivity; 1752 } else if (!intentActivity.task.rootWasReset) { 1753 // In this case we are launching in to an existing task 1754 // that has not yet been started from its front door. 1755 // The current task has been brought to the front. 1756 // Ideally, we'd probably like to place this new task 1757 // at the bottom of its stack, but that's a little hard 1758 // to do with the current organization of the code so 1759 // for now we'll just drop it. 1760 intentActivity.task.setIntent(r.intent, r.info); 1761 } 1762 if (!addingToTask && reuseTask == null) { 1763 // We didn't do anything... but it was needed (a.k.a., client 1764 // don't use that intent!) And for paranoia, make 1765 // sure we have correctly resumed the top activity. 1766 if (doResume) { 1767 targetStack.resumeTopActivityLocked(null, options); 1768 } else { 1769 ActivityOptions.abort(options); 1770 } 1771 return ActivityManager.START_TASK_TO_FRONT; 1772 } 1773 } 1774 } 1775 } 1776 1777 //String uri = r.intent.toURI(); 1778 //Intent intent2 = new Intent(uri); 1779 //Slog.i(TAG, "Given intent: " + r.intent); 1780 //Slog.i(TAG, "URI is: " + uri); 1781 //Slog.i(TAG, "To intent: " + intent2); 1782 1783 if (r.packageName != null) { 1784 // If the activity being launched is the same as the one currently 1785 // at the top, then we need to check if it should only be launched 1786 // once. 1787 ActivityStack topStack = getFocusedStack(); 1788 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1789 if (top != null && r.resultTo == null) { 1790 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1791 if (top.app != null && top.app.thread != null) { 1792 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1793 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1794 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1795 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1796 top.task); 1797 // For paranoia, make sure we have correctly 1798 // resumed the top activity. 1799 topStack.mLastPausedActivity = null; 1800 if (doResume) { 1801 resumeTopActivitiesLocked(); 1802 } 1803 ActivityOptions.abort(options); 1804 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1805 // We don't need to start a new activity, and 1806 // the client said not to do anything if that 1807 // is the case, so this is it! 1808 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1809 } 1810 top.deliverNewIntentLocked(callingUid, r.intent); 1811 return ActivityManager.START_DELIVERED_TO_TOP; 1812 } 1813 } 1814 } 1815 } 1816 1817 } else { 1818 if (r.resultTo != null) { 1819 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1820 r.requestCode, Activity.RESULT_CANCELED, null); 1821 } 1822 ActivityOptions.abort(options); 1823 return ActivityManager.START_CLASS_NOT_FOUND; 1824 } 1825 1826 boolean newTask = false; 1827 boolean keepCurTransition = false; 1828 1829 // Should this be considered a new task? 1830 if (r.resultTo == null && !addingToTask 1831 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1832 if (isLockTaskModeViolation(reuseTask)) { 1833 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1834 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1835 } 1836 newTask = true; 1837 targetStack = adjustStackFocus(r, newTask); 1838 targetStack.moveToFront(); 1839 if (reuseTask == null) { 1840 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1841 newTaskInfo != null ? newTaskInfo : r.info, 1842 newTaskIntent != null ? newTaskIntent : intent, 1843 voiceSession, voiceInteractor, true), null, true); 1844 if (sourceRecord == null) { 1845 // Launched from a service or notification or task that is finishing. 1846 r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ? 1847 mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE); 1848 } 1849 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1850 r.task); 1851 } else { 1852 r.setTask(reuseTask, reuseTask, true); 1853 } 1854 if (!movedHome) { 1855 if ((launchFlags & 1856 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1857 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1858 // Caller wants to appear on home activity, so before starting 1859 // their own activity we will bring home to the front. 1860 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1861 } 1862 } 1863 } else if (sourceRecord != null) { 1864 TaskRecord sourceTask = sourceRecord.task; 1865 if (isLockTaskModeViolation(sourceTask)) { 1866 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1867 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1868 } 1869 targetStack = sourceTask.stack; 1870 targetStack.moveToFront(); 1871 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 1872 if (!addingToTask && 1873 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1874 // In this case, we are adding the activity to an existing 1875 // task, but the caller has asked to clear that task if the 1876 // activity is already running. 1877 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1878 keepCurTransition = true; 1879 if (top != null) { 1880 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1881 top.deliverNewIntentLocked(callingUid, r.intent); 1882 // For paranoia, make sure we have correctly 1883 // resumed the top activity. 1884 targetStack.mLastPausedActivity = null; 1885 if (doResume) { 1886 targetStack.resumeTopActivityLocked(null); 1887 } 1888 ActivityOptions.abort(options); 1889 return ActivityManager.START_DELIVERED_TO_TOP; 1890 } 1891 } else if (!addingToTask && 1892 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1893 // In this case, we are launching an activity in our own task 1894 // that may already be running somewhere in the history, and 1895 // we want to shuffle it to the front of the stack if so. 1896 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1897 if (top != null) { 1898 final TaskRecord task = top.task; 1899 task.moveActivityToFrontLocked(top); 1900 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1901 top.updateOptionsLocked(options); 1902 top.deliverNewIntentLocked(callingUid, r.intent); 1903 targetStack.mLastPausedActivity = null; 1904 if (doResume) { 1905 targetStack.resumeTopActivityLocked(null); 1906 } 1907 return ActivityManager.START_DELIVERED_TO_TOP; 1908 } 1909 } 1910 // An existing activity is starting this new activity, so we want 1911 // to keep the new one in the same task as the one that is starting 1912 // it. 1913 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1914 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1915 + " in existing task " + r.task + " from source " + sourceRecord); 1916 1917 } else { 1918 // This not being started from an existing activity, and not part 1919 // of a new task... just put it in the top task, though these days 1920 // this case should never happen. 1921 targetStack = adjustStackFocus(r, newTask); 1922 targetStack.moveToFront(); 1923 ActivityRecord prev = targetStack.topActivity(); 1924 r.setTask(prev != null ? prev.task 1925 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true), 1926 null, true); 1927 mWindowManager.moveTaskToTop(r.task.taskId); 1928 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1929 + " in new guessed " + r.task); 1930 } 1931 1932 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1933 intent, r.getUriPermissionsLocked(), r.userId); 1934 1935 if (newTask) { 1936 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1937 } 1938 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1939 targetStack.mLastPausedActivity = null; 1940 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1941 mService.setFocusedActivityLocked(r); 1942 return ActivityManager.START_SUCCESS; 1943 } 1944 1945 void acquireLaunchWakelock() { 1946 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1947 throw new IllegalStateException("Calling must be system uid"); 1948 } 1949 mLaunchingActivity.acquire(); 1950 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1951 // To be safe, don't allow the wake lock to be held for too long. 1952 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1953 } 1954 } 1955 1956 // Checked. 1957 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1958 Configuration config) { 1959 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1960 1961 ArrayList<ActivityRecord> stops = null; 1962 ArrayList<ActivityRecord> finishes = null; 1963 ArrayList<UserStartedState> startingUsers = null; 1964 int NS = 0; 1965 int NF = 0; 1966 boolean booting = false; 1967 boolean enableScreen = false; 1968 boolean activityRemoved = false; 1969 1970 ActivityRecord r = ActivityRecord.forToken(token); 1971 if (r != null) { 1972 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1973 Debug.getCallers(4)); 1974 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1975 r.finishLaunchTickingLocked(); 1976 if (fromTimeout) { 1977 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1978 } 1979 1980 // This is a hack to semi-deal with a race condition 1981 // in the client where it can be constructed with a 1982 // newer configuration from when we asked it to launch. 1983 // We'll update with whatever configuration it now says 1984 // it used to launch. 1985 if (config != null) { 1986 r.configuration = config; 1987 } 1988 1989 // We are now idle. If someone is waiting for a thumbnail from 1990 // us, we can now deliver. 1991 r.idle = true; 1992 1993 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1994 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1995 mService.mBooted = true; 1996 enableScreen = true; 1997 } 1998 } 1999 2000 if (allResumedActivitiesIdle()) { 2001 if (r != null) { 2002 mService.scheduleAppGcsLocked(); 2003 } 2004 2005 if (mLaunchingActivity.isHeld()) { 2006 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2007 if (VALIDATE_WAKE_LOCK_CALLER && 2008 Binder.getCallingUid() != Process.myUid()) { 2009 throw new IllegalStateException("Calling must be system uid"); 2010 } 2011 mLaunchingActivity.release(); 2012 } 2013 ensureActivitiesVisibleLocked(null, 0); 2014 } 2015 2016 // Atomically retrieve all of the other things to do. 2017 stops = processStoppingActivitiesLocked(true); 2018 NS = stops != null ? stops.size() : 0; 2019 if ((NF=mFinishingActivities.size()) > 0) { 2020 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 2021 mFinishingActivities.clear(); 2022 } 2023 2024 if (isFrontStack(mHomeStack)) { 2025 booting = mService.mBooting; 2026 mService.mBooting = false; 2027 } 2028 2029 if (mStartingUsers.size() > 0) { 2030 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 2031 mStartingUsers.clear(); 2032 } 2033 2034 // Stop any activities that are scheduled to do so but have been 2035 // waiting for the next one to start. 2036 for (int i = 0; i < NS; i++) { 2037 r = stops.get(i); 2038 final ActivityStack stack = r.task.stack; 2039 if (r.finishing) { 2040 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2041 } else { 2042 stack.stopActivityLocked(r); 2043 } 2044 } 2045 2046 // Finish any activities that are scheduled to do so but have been 2047 // waiting for the next one to start. 2048 for (int i = 0; i < NF; i++) { 2049 r = finishes.get(i); 2050 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 2051 } 2052 2053 if (booting) { 2054 mService.finishBooting(); 2055 } else { 2056 // Complete user switch 2057 if (startingUsers != null) { 2058 for (int i = 0; i < startingUsers.size(); i++) { 2059 mService.finishUserSwitch(startingUsers.get(i)); 2060 } 2061 } 2062 // Complete starting up of background users 2063 if (mStartingBackgroundUsers.size() > 0) { 2064 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2065 mStartingBackgroundUsers.clear(); 2066 for (int i = 0; i < startingUsers.size(); i++) { 2067 mService.finishUserBoot(startingUsers.get(i)); 2068 } 2069 } 2070 } 2071 2072 mService.trimApplications(); 2073 //dump(); 2074 //mWindowManager.dump(); 2075 2076 if (enableScreen) { 2077 mService.enableScreenAfterBoot(); 2078 } 2079 2080 if (activityRemoved) { 2081 resumeTopActivitiesLocked(); 2082 } 2083 2084 return r; 2085 } 2086 2087 boolean handleAppDiedLocked(ProcessRecord app) { 2088 boolean hasVisibleActivities = false; 2089 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2090 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2091 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2092 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2093 } 2094 } 2095 return hasVisibleActivities; 2096 } 2097 2098 void closeSystemDialogsLocked() { 2099 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2100 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2101 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2102 stacks.get(stackNdx).closeSystemDialogsLocked(); 2103 } 2104 } 2105 } 2106 2107 void removeUserLocked(int userId) { 2108 mUserStackInFront.delete(userId); 2109 } 2110 2111 /** 2112 * @return true if some activity was finished (or would have finished if doit were true). 2113 */ 2114 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2115 boolean didSomething = false; 2116 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2117 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2118 final int numStacks = stacks.size(); 2119 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2120 final ActivityStack stack = stacks.get(stackNdx); 2121 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2122 didSomething = true; 2123 } 2124 } 2125 } 2126 return didSomething; 2127 } 2128 2129 void updatePreviousProcessLocked(ActivityRecord r) { 2130 // Now that this process has stopped, we may want to consider 2131 // it to be the previous app to try to keep around in case 2132 // the user wants to return to it. 2133 2134 // First, found out what is currently the foreground app, so that 2135 // we don't blow away the previous app if this activity is being 2136 // hosted by the process that is actually still the foreground. 2137 ProcessRecord fgApp = null; 2138 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2139 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2140 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2141 final ActivityStack stack = stacks.get(stackNdx); 2142 if (isFrontStack(stack)) { 2143 if (stack.mResumedActivity != null) { 2144 fgApp = stack.mResumedActivity.app; 2145 } else if (stack.mPausingActivity != null) { 2146 fgApp = stack.mPausingActivity.app; 2147 } 2148 break; 2149 } 2150 } 2151 } 2152 2153 // Now set this one as the previous process, only if that really 2154 // makes sense to. 2155 if (r.app != null && fgApp != null && r.app != fgApp 2156 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2157 && r.app != mService.mHomeProcess) { 2158 mService.mPreviousProcess = r.app; 2159 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2160 } 2161 } 2162 2163 boolean resumeTopActivitiesLocked() { 2164 return resumeTopActivitiesLocked(null, null, null); 2165 } 2166 2167 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2168 Bundle targetOptions) { 2169 if (targetStack == null) { 2170 targetStack = getFocusedStack(); 2171 } 2172 // Do targetStack first. 2173 boolean result = false; 2174 if (isFrontStack(targetStack)) { 2175 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2176 } 2177 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2178 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2179 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2180 final ActivityStack stack = stacks.get(stackNdx); 2181 if (stack == targetStack) { 2182 // Already started above. 2183 continue; 2184 } 2185 if (isFrontStack(stack)) { 2186 stack.resumeTopActivityLocked(null); 2187 } 2188 } 2189 } 2190 return result; 2191 } 2192 2193 void finishTopRunningActivityLocked(ProcessRecord app) { 2194 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2195 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2196 final int numStacks = stacks.size(); 2197 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2198 final ActivityStack stack = stacks.get(stackNdx); 2199 stack.finishTopRunningActivityLocked(app); 2200 } 2201 } 2202 } 2203 2204 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2205 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2206 mUserLeaving = true; 2207 } 2208 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2209 // Caller wants the home activity moved with it. To accomplish this, 2210 // we'll just indicate that this task returns to the home task. 2211 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2212 } 2213 task.stack.moveTaskToFrontLocked(task, null, options); 2214 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2215 + task.stack); 2216 } 2217 2218 ActivityStack getStack(int stackId) { 2219 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2220 if (activityContainer != null) { 2221 return activityContainer.mStack; 2222 } 2223 return null; 2224 } 2225 2226 ArrayList<ActivityStack> getStacks() { 2227 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2228 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2229 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2230 } 2231 return allStacks; 2232 } 2233 2234 IBinder getHomeActivityToken() { 2235 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2236 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2237 final TaskRecord task = tasks.get(taskNdx); 2238 if (task.isHomeTask()) { 2239 final ArrayList<ActivityRecord> activities = task.mActivities; 2240 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2241 final ActivityRecord r = activities.get(activityNdx); 2242 if (r.isHomeActivity()) { 2243 return r.appToken; 2244 } 2245 } 2246 } 2247 } 2248 return null; 2249 } 2250 2251 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2252 IActivityContainerCallback callback) { 2253 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback); 2254 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2255 parentActivity.mChildContainers.add(activityContainer); 2256 return activityContainer; 2257 } 2258 2259 void removeChildActivityContainers(ActivityRecord parentActivity) { 2260 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2261 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2262 ActivityContainer container = childStacks.remove(containerNdx); 2263 container.release(); 2264 } 2265 } 2266 2267 void deleteActivityContainer(IActivityContainer container) { 2268 ActivityContainer activityContainer = (ActivityContainer)container; 2269 if (activityContainer != null) { 2270 activityContainer.mStack.finishAllActivitiesLocked(); 2271 final ActivityRecord parent = activityContainer.mParentActivity; 2272 if (parent != null) { 2273 parent.mChildContainers.remove(activityContainer); 2274 } 2275 final int stackId = activityContainer.mStackId; 2276 mActivityContainers.remove(stackId); 2277 mWindowManager.removeStack(stackId); 2278 } 2279 } 2280 2281 private int createStackOnDisplay(int stackId, int displayId) { 2282 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2283 if (activityDisplay == null) { 2284 return -1; 2285 } 2286 2287 ActivityContainer activityContainer = new ActivityContainer(stackId); 2288 mActivityContainers.put(stackId, activityContainer); 2289 activityContainer.attachToDisplayLocked(activityDisplay); 2290 return stackId; 2291 } 2292 2293 int getNextStackId() { 2294 while (true) { 2295 if (++mLastStackId <= HOME_STACK_ID) { 2296 mLastStackId = HOME_STACK_ID + 1; 2297 } 2298 if (getStack(mLastStackId) == null) { 2299 break; 2300 } 2301 } 2302 return mLastStackId; 2303 } 2304 2305 void createStackForRestoredTaskHistory(ArrayList<TaskRecord> tasks) { 2306 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2307 final ActivityStack stack = getStack(stackId); 2308 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2309 final TaskRecord task = tasks.get(taskNdx); 2310 stack.addTask(task, false, false); 2311 final int taskId = task.taskId; 2312 final ArrayList<ActivityRecord> activities = task.mActivities; 2313 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2314 final ActivityRecord r = activities.get(activityNdx); 2315 mWindowManager.addAppToken(0, r.appToken, taskId, stackId, 2316 r.info.screenOrientation, r.fullscreen, 2317 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, 2318 r.userId, r.info.configChanges); 2319 } 2320 mWindowManager.addTask(taskId, stackId, false); 2321 } 2322 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2323 } 2324 2325 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2326 final TaskRecord task = anyTaskForIdLocked(taskId); 2327 if (task == null) { 2328 return; 2329 } 2330 final ActivityStack stack = getStack(stackId); 2331 if (stack == null) { 2332 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2333 return; 2334 } 2335 task.stack.removeTask(task); 2336 stack.addTask(task, toTop, true); 2337 mWindowManager.addTask(taskId, stackId, toTop); 2338 resumeTopActivitiesLocked(); 2339 } 2340 2341 ActivityRecord findTaskLocked(ActivityRecord r) { 2342 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2343 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2344 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2345 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2346 final ActivityStack stack = stacks.get(stackNdx); 2347 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2348 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (home activity) " + stack); 2349 continue; 2350 } 2351 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2352 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: (new task not allowed) " + 2353 stack); 2354 continue; 2355 } 2356 final ActivityRecord ar = stack.findTaskLocked(r); 2357 if (ar != null) { 2358 return ar; 2359 } 2360 } 2361 } 2362 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2363 return null; 2364 } 2365 2366 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2367 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2368 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2369 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2370 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2371 if (ar != null) { 2372 return ar; 2373 } 2374 } 2375 } 2376 return null; 2377 } 2378 2379 void goingToSleepLocked() { 2380 scheduleSleepTimeout(); 2381 if (!mGoingToSleep.isHeld()) { 2382 mGoingToSleep.acquire(); 2383 if (mLaunchingActivity.isHeld()) { 2384 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2385 throw new IllegalStateException("Calling must be system uid"); 2386 } 2387 mLaunchingActivity.release(); 2388 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2389 } 2390 } 2391 checkReadyForSleepLocked(); 2392 } 2393 2394 boolean shutdownLocked(int timeout) { 2395 goingToSleepLocked(); 2396 2397 boolean timedout = false; 2398 final long endTime = System.currentTimeMillis() + timeout; 2399 while (true) { 2400 boolean cantShutdown = false; 2401 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2402 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2403 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2404 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2405 } 2406 } 2407 if (cantShutdown) { 2408 long timeRemaining = endTime - System.currentTimeMillis(); 2409 if (timeRemaining > 0) { 2410 try { 2411 mService.wait(timeRemaining); 2412 } catch (InterruptedException e) { 2413 } 2414 } else { 2415 Slog.w(TAG, "Activity manager shutdown timed out"); 2416 timedout = true; 2417 break; 2418 } 2419 } else { 2420 break; 2421 } 2422 } 2423 2424 // Force checkReadyForSleep to complete. 2425 mSleepTimeout = true; 2426 checkReadyForSleepLocked(); 2427 2428 return timedout; 2429 } 2430 2431 void comeOutOfSleepIfNeededLocked() { 2432 removeSleepTimeouts(); 2433 if (mGoingToSleep.isHeld()) { 2434 mGoingToSleep.release(); 2435 } 2436 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2437 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2438 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2439 final ActivityStack stack = stacks.get(stackNdx); 2440 stack.awakeFromSleepingLocked(); 2441 if (isFrontStack(stack)) { 2442 resumeTopActivitiesLocked(); 2443 } 2444 } 2445 } 2446 mGoingToSleepActivities.clear(); 2447 } 2448 2449 void activitySleptLocked(ActivityRecord r) { 2450 mGoingToSleepActivities.remove(r); 2451 checkReadyForSleepLocked(); 2452 } 2453 2454 void checkReadyForSleepLocked() { 2455 if (!mService.isSleepingOrShuttingDown()) { 2456 // Do not care. 2457 return; 2458 } 2459 2460 if (!mSleepTimeout) { 2461 boolean dontSleep = false; 2462 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2463 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2464 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2465 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2466 } 2467 } 2468 2469 if (mStoppingActivities.size() > 0) { 2470 // Still need to tell some activities to stop; can't sleep yet. 2471 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2472 + mStoppingActivities.size() + " activities"); 2473 scheduleIdleLocked(); 2474 dontSleep = true; 2475 } 2476 2477 if (mGoingToSleepActivities.size() > 0) { 2478 // Still need to tell some activities to sleep; can't sleep yet. 2479 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2480 + mGoingToSleepActivities.size() + " activities"); 2481 dontSleep = true; 2482 } 2483 2484 if (dontSleep) { 2485 return; 2486 } 2487 } 2488 2489 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2490 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2491 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2492 stacks.get(stackNdx).goToSleep(); 2493 } 2494 } 2495 2496 removeSleepTimeouts(); 2497 2498 if (mGoingToSleep.isHeld()) { 2499 mGoingToSleep.release(); 2500 } 2501 if (mService.mShuttingDown) { 2502 mService.notifyAll(); 2503 } 2504 } 2505 2506 boolean reportResumedActivityLocked(ActivityRecord r) { 2507 final ActivityStack stack = r.task.stack; 2508 if (isFrontStack(stack)) { 2509 mService.updateUsageStats(r, true); 2510 } 2511 if (allResumedActivitiesComplete()) { 2512 ensureActivitiesVisibleLocked(null, 0); 2513 mWindowManager.executeAppTransition(); 2514 return true; 2515 } 2516 return false; 2517 } 2518 2519 void handleAppCrashLocked(ProcessRecord app) { 2520 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2521 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2522 final int numStacks = stacks.size(); 2523 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2524 final ActivityStack stack = stacks.get(stackNdx); 2525 stack.handleAppCrashLocked(app); 2526 } 2527 } 2528 } 2529 2530 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2531 // First the front stacks. In case any are not fullscreen and are in front of home. 2532 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2533 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2534 final int topStackNdx = stacks.size() - 1; 2535 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2536 final ActivityStack stack = stacks.get(stackNdx); 2537 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2538 } 2539 } 2540 } 2541 2542 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2543 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2544 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2545 final int numStacks = stacks.size(); 2546 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2547 final ActivityStack stack = stacks.get(stackNdx); 2548 stack.scheduleDestroyActivities(app, false, reason); 2549 } 2550 } 2551 } 2552 2553 boolean switchUserLocked(int userId, UserStartedState uss) { 2554 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2555 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2556 mCurrentUser = userId; 2557 2558 mStartingUsers.add(uss); 2559 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2560 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2561 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2562 final ActivityStack stack = stacks.get(stackNdx); 2563 stack.switchUserLocked(userId); 2564 TaskRecord task = stack.topTask(); 2565 if (task != null) { 2566 mWindowManager.moveTaskToTop(task.taskId); 2567 } 2568 } 2569 } 2570 2571 ActivityStack stack = getStack(restoreStackId); 2572 if (stack == null) { 2573 stack = mHomeStack; 2574 } 2575 final boolean homeInFront = stack.isHomeStack(); 2576 if (stack.isOnHomeDisplay()) { 2577 moveHomeStack(homeInFront); 2578 TaskRecord task = stack.topTask(); 2579 if (task != null) { 2580 mWindowManager.moveTaskToTop(task.taskId); 2581 } 2582 } else { 2583 // Stack was moved to another display while user was swapped out. 2584 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); 2585 } 2586 return homeInFront; 2587 } 2588 2589 /** 2590 * Add background users to send boot completed events to. 2591 * @param userId The user being started in the background 2592 * @param uss The state object for the user. 2593 */ 2594 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 2595 mStartingBackgroundUsers.add(uss); 2596 } 2597 2598 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2599 int N = mStoppingActivities.size(); 2600 if (N <= 0) return null; 2601 2602 ArrayList<ActivityRecord> stops = null; 2603 2604 final boolean nowVisible = allResumedActivitiesVisible(); 2605 for (int i=0; i<N; i++) { 2606 ActivityRecord s = mStoppingActivities.get(i); 2607 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2608 + nowVisible + " waitingVisible=" + s.waitingVisible 2609 + " finishing=" + s.finishing); 2610 if (s.waitingVisible && nowVisible) { 2611 mWaitingVisibleActivities.remove(s); 2612 s.waitingVisible = false; 2613 if (s.finishing) { 2614 // If this activity is finishing, it is sitting on top of 2615 // everyone else but we now know it is no longer needed... 2616 // so get rid of it. Otherwise, we need to go through the 2617 // normal flow and hide it once we determine that it is 2618 // hidden by the activities in front of it. 2619 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2620 mWindowManager.setAppVisibility(s.appToken, false); 2621 } 2622 } 2623 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2624 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2625 if (stops == null) { 2626 stops = new ArrayList<ActivityRecord>(); 2627 } 2628 stops.add(s); 2629 mStoppingActivities.remove(i); 2630 N--; 2631 i--; 2632 } 2633 } 2634 2635 return stops; 2636 } 2637 2638 void validateTopActivitiesLocked() { 2639 // FIXME 2640/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2641 final ActivityStack stack = stacks.get(stackNdx); 2642 final ActivityRecord r = stack.topRunningActivityLocked(null); 2643 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2644 if (isFrontStack(stack)) { 2645 if (r == null) { 2646 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2647 } else { 2648 final ActivityRecord pausing = stack.mPausingActivity; 2649 if (pausing != null && pausing == r) { 2650 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2651 " state=" + state); 2652 } 2653 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2654 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2655 " state=" + state); 2656 } 2657 } 2658 } else { 2659 final ActivityRecord resumed = stack.mResumedActivity; 2660 if (resumed != null && resumed == r) { 2661 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2662 " state=" + state); 2663 } 2664 if (r != null && (state == ActivityState.INITIALIZING 2665 || state == ActivityState.RESUMED)) { 2666 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2667 " state=" + state); 2668 } 2669 } 2670 } 2671*/ 2672 } 2673 2674 public void dump(PrintWriter pw, String prefix) { 2675 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2676 pw.println(mDismissKeyguardOnNextActivity); 2677 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2678 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2679 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2680 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2681 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2682 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2683 } 2684 2685 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2686 return getFocusedStack().getDumpActivitiesLocked(name); 2687 } 2688 2689 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2690 boolean needSep, String prefix) { 2691 if (activity != null) { 2692 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2693 if (needSep) { 2694 pw.println(); 2695 } 2696 pw.print(prefix); 2697 pw.println(activity); 2698 return true; 2699 } 2700 } 2701 return false; 2702 } 2703 2704 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2705 boolean dumpClient, String dumpPackage) { 2706 boolean printed = false; 2707 boolean needSep = false; 2708 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2709 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2710 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2711 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2712 final int numStacks = stacks.size(); 2713 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2714 final ActivityStack stack = stacks.get(stackNdx); 2715 StringBuilder stackHeader = new StringBuilder(128); 2716 stackHeader.append(" Stack #"); 2717 stackHeader.append(stack.mStackId); 2718 stackHeader.append(":"); 2719 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2720 needSep, stackHeader.toString()); 2721 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2722 !dumpAll, false, dumpPackage, true, 2723 " Running activities (most recent first):", null); 2724 2725 needSep = printed; 2726 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2727 " mPausingActivity: "); 2728 if (pr) { 2729 printed = true; 2730 needSep = false; 2731 } 2732 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2733 " mResumedActivity: "); 2734 if (pr) { 2735 printed = true; 2736 needSep = false; 2737 } 2738 if (dumpAll) { 2739 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2740 " mLastPausedActivity: "); 2741 if (pr) { 2742 printed = true; 2743 needSep = true; 2744 } 2745 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2746 needSep, " mLastNoHistoryActivity: "); 2747 } 2748 needSep = printed; 2749 } 2750 } 2751 2752 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2753 false, dumpPackage, true, " Activities waiting to finish:", null); 2754 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2755 false, dumpPackage, true, " Activities waiting to stop:", null); 2756 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2757 false, dumpPackage, true, " Activities waiting for another to become visible:", 2758 null); 2759 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2760 false, dumpPackage, true, " Activities waiting to sleep:", null); 2761 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2762 false, dumpPackage, true, " Activities waiting to sleep:", null); 2763 2764 return printed; 2765 } 2766 2767 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2768 String prefix, String label, boolean complete, boolean brief, boolean client, 2769 String dumpPackage, boolean needNL, String header1, String header2) { 2770 TaskRecord lastTask = null; 2771 String innerPrefix = null; 2772 String[] args = null; 2773 boolean printed = false; 2774 for (int i=list.size()-1; i>=0; i--) { 2775 final ActivityRecord r = list.get(i); 2776 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2777 continue; 2778 } 2779 if (innerPrefix == null) { 2780 innerPrefix = prefix + " "; 2781 args = new String[0]; 2782 } 2783 printed = true; 2784 final boolean full = !brief && (complete || !r.isInHistory()); 2785 if (needNL) { 2786 pw.println(""); 2787 needNL = false; 2788 } 2789 if (header1 != null) { 2790 pw.println(header1); 2791 header1 = null; 2792 } 2793 if (header2 != null) { 2794 pw.println(header2); 2795 header2 = null; 2796 } 2797 if (lastTask != r.task) { 2798 lastTask = r.task; 2799 pw.print(prefix); 2800 pw.print(full ? "* " : " "); 2801 pw.println(lastTask); 2802 if (full) { 2803 lastTask.dump(pw, prefix + " "); 2804 } else if (complete) { 2805 // Complete + brief == give a summary. Isn't that obvious?!? 2806 if (lastTask.intent != null) { 2807 pw.print(prefix); pw.print(" "); 2808 pw.println(lastTask.intent.toInsecureStringWithClip()); 2809 } 2810 } 2811 } 2812 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2813 pw.print(" #"); pw.print(i); pw.print(": "); 2814 pw.println(r); 2815 if (full) { 2816 r.dump(pw, innerPrefix); 2817 } else if (complete) { 2818 // Complete + brief == give a summary. Isn't that obvious?!? 2819 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2820 if (r.app != null) { 2821 pw.print(innerPrefix); pw.println(r.app); 2822 } 2823 } 2824 if (client && r.app != null && r.app.thread != null) { 2825 // flush anything that is already in the PrintWriter since the thread is going 2826 // to write to the file descriptor directly 2827 pw.flush(); 2828 try { 2829 TransferPipe tp = new TransferPipe(); 2830 try { 2831 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2832 r.appToken, innerPrefix, args); 2833 // Short timeout, since blocking here can 2834 // deadlock with the application. 2835 tp.go(fd, 2000); 2836 } finally { 2837 tp.kill(); 2838 } 2839 } catch (IOException e) { 2840 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2841 } catch (RemoteException e) { 2842 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2843 } 2844 needNL = true; 2845 } 2846 } 2847 return printed; 2848 } 2849 2850 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2851 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2852 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2853 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2854 } 2855 2856 final void scheduleIdleLocked() { 2857 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2858 } 2859 2860 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2861 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2862 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2863 } 2864 2865 final void scheduleResumeTopActivities() { 2866 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2867 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2868 } 2869 } 2870 2871 void removeSleepTimeouts() { 2872 mSleepTimeout = false; 2873 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2874 } 2875 2876 final void scheduleSleepTimeout() { 2877 removeSleepTimeouts(); 2878 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2879 } 2880 2881 @Override 2882 public void onDisplayAdded(int displayId) { 2883 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2884 } 2885 2886 @Override 2887 public void onDisplayRemoved(int displayId) { 2888 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2889 } 2890 2891 @Override 2892 public void onDisplayChanged(int displayId) { 2893 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2894 } 2895 2896 public void handleDisplayAddedLocked(int displayId) { 2897 boolean newDisplay; 2898 synchronized (mService) { 2899 newDisplay = mActivityDisplays.get(displayId) == null; 2900 if (newDisplay) { 2901 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2902 mActivityDisplays.put(displayId, activityDisplay); 2903 } 2904 } 2905 if (newDisplay) { 2906 mWindowManager.onDisplayAdded(displayId); 2907 } 2908 } 2909 2910 public void handleDisplayRemovedLocked(int displayId) { 2911 synchronized (mService) { 2912 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2913 if (activityDisplay != null) { 2914 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2915 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2916 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2917 } 2918 mActivityDisplays.remove(displayId); 2919 } 2920 } 2921 mWindowManager.onDisplayRemoved(displayId); 2922 } 2923 2924 public void handleDisplayChangedLocked(int displayId) { 2925 synchronized (mService) { 2926 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2927 if (activityDisplay != null) { 2928 // TODO: Update the bounds. 2929 } 2930 } 2931 mWindowManager.onDisplayChanged(displayId); 2932 } 2933 2934 StackInfo getStackInfo(ActivityStack stack) { 2935 StackInfo info = new StackInfo(); 2936 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2937 info.displayId = Display.DEFAULT_DISPLAY; 2938 info.stackId = stack.mStackId; 2939 2940 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2941 final int numTasks = tasks.size(); 2942 int[] taskIds = new int[numTasks]; 2943 String[] taskNames = new String[numTasks]; 2944 for (int i = 0; i < numTasks; ++i) { 2945 final TaskRecord task = tasks.get(i); 2946 taskIds[i] = task.taskId; 2947 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2948 : task.realActivity != null ? task.realActivity.flattenToString() 2949 : task.getTopActivity() != null ? task.getTopActivity().packageName 2950 : "unknown"; 2951 } 2952 info.taskIds = taskIds; 2953 info.taskNames = taskNames; 2954 return info; 2955 } 2956 2957 StackInfo getStackInfoLocked(int stackId) { 2958 ActivityStack stack = getStack(stackId); 2959 if (stack != null) { 2960 return getStackInfo(stack); 2961 } 2962 return null; 2963 } 2964 2965 ArrayList<StackInfo> getAllStackInfosLocked() { 2966 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2967 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2968 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2969 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2970 list.add(getStackInfo(stacks.get(ndx))); 2971 } 2972 } 2973 return list; 2974 } 2975 2976 void setLockTaskModeLocked(TaskRecord task) { 2977 final Message lockTaskMsg = Message.obtain(); 2978 if (task == null) { 2979 // Take out of lock task mode. 2980 mLockTaskModeTask = null; 2981 lockTaskMsg.what = LOCK_TASK_END_MSG; 2982 mHandler.sendMessage(lockTaskMsg); 2983 return; 2984 } 2985 if (isLockTaskModeViolation(task)) { 2986 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 2987 return; 2988 } 2989 mLockTaskModeTask = task; 2990 findTaskToMoveToFrontLocked(task, 0, null); 2991 resumeTopActivitiesLocked(); 2992 lockTaskMsg.what = LOCK_TASK_START_MSG; 2993 mHandler.sendMessage(lockTaskMsg); 2994 } 2995 2996 boolean isLockTaskModeViolation(TaskRecord task) { 2997 return mLockTaskModeTask != null && mLockTaskModeTask != task; 2998 } 2999 3000 void endLockTaskModeIfTaskEnding(TaskRecord task) { 3001 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 3002 mLockTaskModeTask = null; 3003 } 3004 } 3005 3006 boolean isInLockTaskMode() { 3007 return mLockTaskModeTask != null; 3008 } 3009 3010 private final class ActivityStackSupervisorHandler extends Handler { 3011 3012 public ActivityStackSupervisorHandler(Looper looper) { 3013 super(looper); 3014 } 3015 3016 void activityIdleInternal(ActivityRecord r) { 3017 synchronized (mService) { 3018 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3019 } 3020 } 3021 3022 @Override 3023 public void handleMessage(Message msg) { 3024 switch (msg.what) { 3025 case IDLE_TIMEOUT_MSG: { 3026 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3027 if (mService.mDidDexOpt) { 3028 mService.mDidDexOpt = false; 3029 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3030 nmsg.obj = msg.obj; 3031 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3032 return; 3033 } 3034 // We don't at this point know if the activity is fullscreen, 3035 // so we need to be conservative and assume it isn't. 3036 activityIdleInternal((ActivityRecord)msg.obj); 3037 } break; 3038 case IDLE_NOW_MSG: { 3039 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3040 activityIdleInternal((ActivityRecord)msg.obj); 3041 } break; 3042 case RESUME_TOP_ACTIVITY_MSG: { 3043 synchronized (mService) { 3044 resumeTopActivitiesLocked(); 3045 } 3046 } break; 3047 case SLEEP_TIMEOUT_MSG: { 3048 synchronized (mService) { 3049 if (mService.isSleepingOrShuttingDown()) { 3050 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3051 mSleepTimeout = true; 3052 checkReadyForSleepLocked(); 3053 } 3054 } 3055 } break; 3056 case LAUNCH_TIMEOUT_MSG: { 3057 if (mService.mDidDexOpt) { 3058 mService.mDidDexOpt = false; 3059 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3060 return; 3061 } 3062 synchronized (mService) { 3063 if (mLaunchingActivity.isHeld()) { 3064 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3065 if (VALIDATE_WAKE_LOCK_CALLER 3066 && Binder.getCallingUid() != Process.myUid()) { 3067 throw new IllegalStateException("Calling must be system uid"); 3068 } 3069 mLaunchingActivity.release(); 3070 } 3071 } 3072 } break; 3073 case HANDLE_DISPLAY_ADDED: { 3074 handleDisplayAddedLocked(msg.arg1); 3075 } break; 3076 case HANDLE_DISPLAY_CHANGED: { 3077 handleDisplayChangedLocked(msg.arg1); 3078 } break; 3079 case HANDLE_DISPLAY_REMOVED: { 3080 handleDisplayRemovedLocked(msg.arg1); 3081 } break; 3082 case CONTAINER_CALLBACK_VISIBILITY: { 3083 final ActivityContainer container = (ActivityContainer) msg.obj; 3084 try { 3085 // We only send this message if mCallback is non-null. 3086 container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1); 3087 } catch (RemoteException e) { 3088 } 3089 } 3090 case LOCK_TASK_START_MSG: { 3091 // When lock task starts, we disable the status bars. 3092 try { 3093 if (getStatusBarService() != null) { 3094 getStatusBarService().disable 3095 (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK, 3096 mToken, mService.mContext.getPackageName()); 3097 } 3098 } catch (RemoteException ex) { 3099 throw new RuntimeException(ex); 3100 } 3101 break; 3102 } 3103 case LOCK_TASK_END_MSG: { 3104 // When lock task ends, we enable the status bars. 3105 try { 3106 if (getStatusBarService() != null) { 3107 getStatusBarService().disable 3108 (StatusBarManager.DISABLE_NONE, 3109 mToken, mService.mContext.getPackageName()); 3110 } 3111 } catch (RemoteException ex) { 3112 throw new RuntimeException(ex); 3113 } 3114 break; 3115 } 3116 } 3117 } 3118 } 3119 3120 class ActivityContainer extends android.app.IActivityContainer.Stub { 3121 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3122 Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 3123 final int mStackId; 3124 IActivityContainerCallback mCallback = null; 3125 final ActivityStack mStack; 3126 ActivityRecord mParentActivity = null; 3127 String mIdString; 3128 3129 boolean mVisible = true; 3130 3131 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3132 ActivityDisplay mActivityDisplay; 3133 3134 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3135 final static int CONTAINER_STATE_NO_SURFACE = 1; 3136 final static int CONTAINER_STATE_FINISHING = 2; 3137 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3138 3139 ActivityContainer(int stackId) { 3140 synchronized (mService) { 3141 mStackId = stackId; 3142 mStack = new ActivityStack(this); 3143 mIdString = "ActivtyContainer{" + mStackId + "}"; 3144 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3145 } 3146 } 3147 3148 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3149 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3150 + " to display=" + activityDisplay); 3151 mActivityDisplay = activityDisplay; 3152 mStack.mDisplayId = activityDisplay.mDisplayId; 3153 mStack.mStacks = activityDisplay.mStacks; 3154 3155 activityDisplay.attachActivities(mStack); 3156 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3157 } 3158 3159 @Override 3160 public void attachToDisplay(int displayId) { 3161 synchronized (mService) { 3162 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3163 if (activityDisplay == null) { 3164 return; 3165 } 3166 attachToDisplayLocked(activityDisplay); 3167 } 3168 } 3169 3170 @Override 3171 public int getDisplayId() { 3172 if (mActivityDisplay != null) { 3173 return mActivityDisplay.mDisplayId; 3174 } 3175 return -1; 3176 } 3177 3178 @Override 3179 public boolean injectEvent(InputEvent event) { 3180 final long origId = Binder.clearCallingIdentity(); 3181 try { 3182 if (mActivityDisplay != null) { 3183 return mInputManagerInternal.injectInputEvent(event, 3184 mActivityDisplay.mDisplayId, 3185 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3186 } 3187 return false; 3188 } finally { 3189 Binder.restoreCallingIdentity(origId); 3190 } 3191 } 3192 3193 @Override 3194 public void release() { 3195 mContainerState = CONTAINER_STATE_FINISHING; 3196 mStack.finishAllActivitiesLocked(); 3197 detachLocked(); 3198 mWindowManager.removeStack(mStackId); 3199 } 3200 3201 private void detachLocked() { 3202 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3203 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3204 if (mActivityDisplay != null) { 3205 mActivityDisplay.detachActivitiesLocked(mStack); 3206 mActivityDisplay = null; 3207 mStack.mDisplayId = -1; 3208 mStack.mStacks = null; 3209 mWindowManager.detachStack(mStackId); 3210 } 3211 } 3212 3213 @Override 3214 public final int startActivity(Intent intent) { 3215 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3216 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3217 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3218 // TODO: Switch to user app stacks here. 3219 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3220 String mimeType = intent.getType(); 3221 if (mimeType == null && intent.getData() != null 3222 && "content".equals(intent.getData().getScheme())) { 3223 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3224 } 3225 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null, 3226 null, null, null, null, userId, this); 3227 } 3228 3229 @Override 3230 public final int startActivityIntentSender(IIntentSender intentSender) { 3231 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3232 3233 if (!(intentSender instanceof PendingIntentRecord)) { 3234 throw new IllegalArgumentException("Bad PendingIntent object"); 3235 } 3236 3237 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3238 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3239 } 3240 3241 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3242 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3243 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3244 if (resolvedType == null) { 3245 resolvedType = intent.getType(); 3246 if (resolvedType == null && intent.getData() != null 3247 && "content".equals(intent.getData().getScheme())) { 3248 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3249 } 3250 } 3251 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3252 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3253 throw new SecurityException( 3254 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3255 } 3256 } 3257 3258 /** Throw a SecurityException if allowEmbedded is not true */ 3259 @Override 3260 public final void checkEmbeddedAllowed(Intent intent) { 3261 checkEmbeddedAllowedInner(intent, null); 3262 } 3263 3264 /** Throw a SecurityException if allowEmbedded is not true */ 3265 @Override 3266 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3267 if (!(intentSender instanceof PendingIntentRecord)) { 3268 throw new IllegalArgumentException("Bad PendingIntent object"); 3269 } 3270 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3271 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3272 pendingIntent.key.requestResolvedType); 3273 } 3274 3275 @Override 3276 public IBinder asBinder() { 3277 return this; 3278 } 3279 3280 @Override 3281 public void setSurface(Surface surface, int width, int height, int density) { 3282 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3283 } 3284 3285 ActivityStackSupervisor getOuter() { 3286 return ActivityStackSupervisor.this; 3287 } 3288 3289 boolean isAttached() { 3290 return mActivityDisplay != null; 3291 } 3292 3293 void getBounds(Point outBounds) { 3294 if (mActivityDisplay != null) { 3295 mActivityDisplay.getBounds(outBounds); 3296 } else { 3297 outBounds.set(0, 0); 3298 } 3299 } 3300 3301 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3302 void setVisible(boolean visible) { 3303 if (mVisible != visible) { 3304 mVisible = visible; 3305 if (mCallback != null) { 3306 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3307 0 /* unused */, this).sendToTarget(); 3308 } 3309 } 3310 } 3311 3312 void setDrawn() { 3313 } 3314 3315 // You can always start a new task on a regular ActivityStack. 3316 boolean isEligibleForNewTasks() { 3317 return true; 3318 } 3319 3320 @Override 3321 public String toString() { 3322 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3323 } 3324 } 3325 3326 private class VirtualActivityContainer extends ActivityContainer { 3327 Surface mSurface; 3328 boolean mDrawn = false; 3329 3330 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3331 super(getNextStackId()); 3332 mParentActivity = parent; 3333 mCallback = callback; 3334 mContainerState = CONTAINER_STATE_NO_SURFACE; 3335 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3336 } 3337 3338 @Override 3339 public void setSurface(Surface surface, int width, int height, int density) { 3340 super.setSurface(surface, width, height, density); 3341 3342 synchronized (mService) { 3343 final long origId = Binder.clearCallingIdentity(); 3344 try { 3345 setSurfaceLocked(surface, width, height, density); 3346 } finally { 3347 Binder.restoreCallingIdentity(origId); 3348 } 3349 } 3350 } 3351 3352 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3353 if (mContainerState == CONTAINER_STATE_FINISHING) { 3354 return; 3355 } 3356 VirtualActivityDisplay virtualActivityDisplay = 3357 (VirtualActivityDisplay) mActivityDisplay; 3358 if (virtualActivityDisplay == null) { 3359 virtualActivityDisplay = 3360 new VirtualActivityDisplay(width, height, density); 3361 mActivityDisplay = virtualActivityDisplay; 3362 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3363 attachToDisplayLocked(virtualActivityDisplay); 3364 } 3365 3366 if (mSurface != null) { 3367 mSurface.release(); 3368 } 3369 3370 mSurface = surface; 3371 if (surface != null) { 3372 mStack.resumeTopActivityLocked(null); 3373 } else { 3374 mContainerState = CONTAINER_STATE_NO_SURFACE; 3375 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3376 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3377 mStack.startPausingLocked(false, true); 3378 } 3379 } 3380 3381 setSurfaceIfReady(); 3382 3383 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3384 + virtualActivityDisplay); 3385 } 3386 3387 @Override 3388 boolean isAttached() { 3389 return mSurface != null && super.isAttached(); 3390 } 3391 3392 @Override 3393 void setDrawn() { 3394 synchronized (mService) { 3395 mDrawn = true; 3396 setSurfaceIfReady(); 3397 } 3398 } 3399 3400 // Never start a new task on an ActivityView if it isn't explicitly specified. 3401 @Override 3402 boolean isEligibleForNewTasks() { 3403 return false; 3404 } 3405 3406 private void setSurfaceIfReady() { 3407 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn + 3408 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3409 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3410 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3411 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3412 } 3413 } 3414 } 3415 3416 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3417 * attached {@link ActivityStack}s */ 3418 class ActivityDisplay { 3419 /** Actual Display this object tracks. */ 3420 int mDisplayId; 3421 Display mDisplay; 3422 DisplayInfo mDisplayInfo = new DisplayInfo(); 3423 3424 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3425 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3426 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3427 3428 ActivityDisplay() { 3429 } 3430 3431 ActivityDisplay(int displayId) { 3432 init(mDisplayManager.getDisplay(displayId)); 3433 } 3434 3435 void init(Display display) { 3436 mDisplay = display; 3437 mDisplayId = display.getDisplayId(); 3438 mDisplay.getDisplayInfo(mDisplayInfo); 3439 } 3440 3441 void attachActivities(ActivityStack stack) { 3442 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3443 + mDisplayId); 3444 mStacks.add(stack); 3445 } 3446 3447 void detachActivitiesLocked(ActivityStack stack) { 3448 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3449 + " from displayId=" + mDisplayId); 3450 mStacks.remove(stack); 3451 } 3452 3453 void getBounds(Point bounds) { 3454 mDisplay.getDisplayInfo(mDisplayInfo); 3455 bounds.x = mDisplayInfo.appWidth; 3456 bounds.y = mDisplayInfo.appHeight; 3457 } 3458 3459 @Override 3460 public String toString() { 3461 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3462 } 3463 } 3464 3465 class VirtualActivityDisplay extends ActivityDisplay { 3466 VirtualDisplay mVirtualDisplay; 3467 3468 VirtualActivityDisplay(int width, int height, int density) { 3469 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3470 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3471 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3472 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3473 3474 init(mVirtualDisplay.getDisplay()); 3475 3476 mWindowManager.handleDisplayAdded(mDisplayId); 3477 } 3478 3479 void setSurface(Surface surface) { 3480 if (mVirtualDisplay != null) { 3481 mVirtualDisplay.setSurface(surface); 3482 } 3483 } 3484 3485 @Override 3486 void detachActivitiesLocked(ActivityStack stack) { 3487 super.detachActivitiesLocked(stack); 3488 if (mVirtualDisplay != null) { 3489 mVirtualDisplay.release(); 3490 mVirtualDisplay = null; 3491 } 3492 } 3493 3494 @Override 3495 public String toString() { 3496 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3497 } 3498 } 3499} 3500