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