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