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