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