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