ActivityStackSupervisor.java revision a7cfbe0e548ac76f20915b65851b8bc9095aa541
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 if (!AppGlobals.getPackageManager().activitySupportsIntent( 1510 intent.getComponent(), intent, resolvedType)) { 1511 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1512 } 1513 } catch (RemoteException e) { 1514 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1515 } 1516 } 1517 } 1518 1519 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1520 // If the caller is starting a new voice session, just make sure the target 1521 // is actually allowing it to run this way. 1522 try { 1523 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1524 intent, resolvedType)) { 1525 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1526 } 1527 } catch (RemoteException e) { 1528 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1529 } 1530 } 1531 1532 final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1533 1534 if (err != ActivityManager.START_SUCCESS) { 1535 if (resultRecord != null) { 1536 resultStack.sendActivityResultLocked(-1, 1537 resultRecord, resultWho, requestCode, 1538 Activity.RESULT_CANCELED, null); 1539 } 1540 ActivityOptions.abort(options); 1541 return err; 1542 } 1543 1544 boolean abort = false; 1545 1546 final int startAnyPerm = mService.checkPermission( 1547 START_ANY_ACTIVITY, callingPid, callingUid); 1548 1549 if (startAnyPerm != PERMISSION_GRANTED) { 1550 final int componentRestriction = getComponentRestrictionForCallingPackage( 1551 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); 1552 final int actionRestriction = getActionRestrictionForCallingPackage( 1553 intent.getAction(), callingPackage, callingPid, callingUid); 1554 1555 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1556 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1557 if (resultRecord != null) { 1558 resultStack.sendActivityResultLocked(-1, 1559 resultRecord, resultWho, requestCode, 1560 Activity.RESULT_CANCELED, null); 1561 } 1562 String msg; 1563 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1564 msg = "Permission Denial: starting " + intent.toString() 1565 + " from " + callerApp + " (pid=" + callingPid 1566 + ", uid=" + callingUid + ")" + " with revoked permission " 1567 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1568 } else if (!aInfo.exported) { 1569 msg = "Permission Denial: starting " + intent.toString() 1570 + " from " + callerApp + " (pid=" + callingPid 1571 + ", uid=" + callingUid + ")" 1572 + " not exported from uid " + aInfo.applicationInfo.uid; 1573 } else { 1574 msg = "Permission Denial: starting " + intent.toString() 1575 + " from " + callerApp + " (pid=" + callingPid 1576 + ", uid=" + callingUid + ")" 1577 + " requires " + aInfo.permission; 1578 } 1579 Slog.w(TAG, msg); 1580 throw new SecurityException(msg); 1581 } 1582 1583 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1584 String message = "Appop Denial: starting " + intent.toString() 1585 + " from " + callerApp + " (pid=" + callingPid 1586 + ", uid=" + callingUid + ")" 1587 + " requires " + AppOpsManager.permissionToOp( 1588 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1589 Slog.w(TAG, message); 1590 abort = true; 1591 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1592 String message = "Appop Denial: starting " + intent.toString() 1593 + " from " + callerApp + " (pid=" + callingPid 1594 + ", uid=" + callingUid + ")" 1595 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1596 Slog.w(TAG, message); 1597 abort = true; 1598 } 1599 } 1600 1601 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1602 callingPid, resolvedType, aInfo.applicationInfo); 1603 1604 if (mService.mController != null) { 1605 try { 1606 // The Intent we give to the watcher has the extra data 1607 // stripped off, since it can contain private information. 1608 Intent watchIntent = intent.cloneFilter(); 1609 abort |= !mService.mController.activityStarting(watchIntent, 1610 aInfo.applicationInfo.packageName); 1611 } catch (RemoteException e) { 1612 mService.mController = null; 1613 } 1614 } 1615 1616 if (abort) { 1617 if (resultRecord != null) { 1618 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1619 Activity.RESULT_CANCELED, null); 1620 } 1621 // We pretend to the caller that it was really started, but 1622 // they will just get a cancel result. 1623 ActivityOptions.abort(options); 1624 return ActivityManager.START_SUCCESS; 1625 } 1626 1627 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1628 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1629 requestCode, componentSpecified, this, container, options); 1630 if (outActivity != null) { 1631 outActivity[0] = r; 1632 } 1633 1634 if (r.appTimeTracker == null && sourceRecord != null) { 1635 // If the caller didn't specify an explicit time tracker, we want to continue 1636 // tracking under any it has. 1637 r.appTimeTracker = sourceRecord.appTimeTracker; 1638 } 1639 1640 final ActivityStack stack = mFocusedStack; 1641 if (voiceSession == null && (stack.mResumedActivity == null 1642 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1643 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, 1644 realCallingPid, realCallingUid, "Activity start")) { 1645 PendingActivityLaunch pal = 1646 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1647 mPendingActivityLaunches.add(pal); 1648 ActivityOptions.abort(options); 1649 return ActivityManager.START_SWITCHES_CANCELED; 1650 } 1651 } 1652 1653 if (mService.mDidAppSwitch) { 1654 // This is the second allowed switch since we stopped switches, 1655 // so now just generally allow switches. Use case: user presses 1656 // home (switches disabled, switch to home, mDidAppSwitch now true); 1657 // user taps a home icon (coming from home so allowed, we hit here 1658 // and now allow anyone to switch again). 1659 mService.mAppSwitchesAllowedTime = 0; 1660 } else { 1661 mService.mDidAppSwitch = true; 1662 } 1663 1664 doPendingActivityLaunchesLocked(false); 1665 1666 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1667 startFlags, true, options, inTask); 1668 1669 if (err < 0) { 1670 // If someone asked to have the keyguard dismissed on the next 1671 // activity start, but we are not actually doing an activity 1672 // switch... just dismiss the keyguard now, because we 1673 // probably want to see whatever is behind it. 1674 notifyActivityDrawnForKeyguard(); 1675 } 1676 return err; 1677 } 1678 1679 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1680 String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { 1681 if (activityInfo.permission == null) { 1682 return ACTIVITY_RESTRICTION_NONE; 1683 } 1684 1685 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1686 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1687 == PackageManager.PERMISSION_DENIED) { 1688 return ACTIVITY_RESTRICTION_PERMISSION; 1689 } 1690 1691 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1692 if (opCode == AppOpsManager.OP_NONE) { 1693 return ACTIVITY_RESTRICTION_NONE; 1694 } 1695 1696 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1697 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1698 if (!ignoreTargetSecurity) { 1699 return ACTIVITY_RESTRICTION_APPOP; 1700 } 1701 } 1702 1703 return ACTIVITY_RESTRICTION_NONE; 1704 } 1705 1706 private int getActionRestrictionForCallingPackage(String action, 1707 String callingPackage, int callingPid, int callingUid) { 1708 if (action == null) { 1709 return ACTIVITY_RESTRICTION_NONE; 1710 } 1711 1712 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1713 if (permission == null) { 1714 return ACTIVITY_RESTRICTION_NONE; 1715 } 1716 1717 final PackageInfo packageInfo; 1718 try { 1719 packageInfo = mService.mContext.getPackageManager() 1720 .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); 1721 } catch (PackageManager.NameNotFoundException e) { 1722 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1723 return ACTIVITY_RESTRICTION_NONE; 1724 } 1725 1726 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1727 return ACTIVITY_RESTRICTION_NONE; 1728 } 1729 1730 if (mService.checkPermission(permission, callingPid, callingUid) == 1731 PackageManager.PERMISSION_DENIED) { 1732 return ACTIVITY_RESTRICTION_PERMISSION; 1733 } 1734 1735 final int opCode = AppOpsManager.permissionToOpCode(permission); 1736 if (opCode == AppOpsManager.OP_NONE) { 1737 return ACTIVITY_RESTRICTION_NONE; 1738 } 1739 1740 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1741 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1742 return ACTIVITY_RESTRICTION_APPOP; 1743 } 1744 1745 return ACTIVITY_RESTRICTION_NONE; 1746 } 1747 1748 ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) { 1749 final TaskRecord task = r.task; 1750 1751 // On leanback only devices we should keep all activities in the same stack. 1752 if (!mLeanbackOnlyDevice && 1753 (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1754 1755 ActivityStack stack; 1756 1757 if (task != null && task.stack != null) { 1758 stack = task.stack; 1759 if (stack.isOnHomeDisplay()) { 1760 if (mFocusedStack != stack) { 1761 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1762 "computeStackFocus: Setting " + "focused stack to r=" + r 1763 + " task=" + task); 1764 } else { 1765 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1766 "computeStackFocus: Focused stack already=" + mFocusedStack); 1767 } 1768 } 1769 return stack; 1770 } 1771 1772 final ActivityContainer container = r.mInitialActivityContainer; 1773 if (container != null) { 1774 // The first time put it on the desired stack, after this put on task stack. 1775 r.mInitialActivityContainer = null; 1776 return container.mStack; 1777 } 1778 1779 if (mFocusedStack != mHomeStack && (!newTask || 1780 mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1781 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1782 "computeStackFocus: Have a focused stack=" + mFocusedStack); 1783 return mFocusedStack; 1784 } 1785 1786 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1787 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1788 stack = homeDisplayStacks.get(stackNdx); 1789 if (!stack.isHomeStack()) { 1790 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1791 "computeStackFocus: Setting focused stack=" + stack); 1792 return stack; 1793 } 1794 } 1795 1796 // Need to create an app stack for this user. 1797 stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1798 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r=" 1799 + r + " stackId=" + stack.mStackId); 1800 return stack; 1801 } 1802 return mHomeStack; 1803 } 1804 1805 boolean setFocusedStack(ActivityRecord r, String reason) { 1806 if (r == null) { 1807 // Not sure what you are trying to do, but it is not going to work... 1808 return false; 1809 } 1810 final TaskRecord task = r.task; 1811 if (task == null || task.stack == null) { 1812 Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task); 1813 return false; 1814 } 1815 task.stack.moveToFront(reason); 1816 return true; 1817 } 1818 1819 final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord, 1820 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 1821 boolean doResume, Bundle options, TaskRecord inTask) { 1822 final Intent intent = r.intent; 1823 final int callingUid = r.launchedFromUid; 1824 1825 // In some flows in to this function, we retrieve the task record and hold on to it 1826 // without a lock before calling back in to here... so the task at this point may 1827 // not actually be in recents. Check for that, and if it isn't in recents just 1828 // consider it invalid. 1829 if (inTask != null && !inTask.inRecents) { 1830 Slog.w(TAG, "Starting activity in task not in recents: " + inTask); 1831 inTask = null; 1832 } 1833 1834 final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP; 1835 final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; 1836 final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; 1837 1838 int launchFlags = intent.getFlags(); 1839 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 1840 (launchSingleInstance || launchSingleTask)) { 1841 // We have a conflict between the Intent and the Activity manifest, manifest wins. 1842 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 1843 "\"singleInstance\" or \"singleTask\""); 1844 launchFlags &= 1845 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1846 } else { 1847 switch (r.info.documentLaunchMode) { 1848 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1849 break; 1850 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1851 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1852 break; 1853 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1854 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1855 break; 1856 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 1857 launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1858 break; 1859 } 1860 } 1861 1862 final boolean launchTaskBehind = r.mLaunchTaskBehind 1863 && !launchSingleTask && !launchSingleInstance 1864 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 1865 1866 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 1867 && r.resultTo.task.stack != null) { 1868 // For whatever reason this activity is being launched into a new 1869 // task... yet the caller has requested a result back. Well, that 1870 // is pretty messed up, so instead immediately send back a cancel 1871 // and let the new task continue launched as normal without a 1872 // dependency on its originator. 1873 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1874 r.resultTo.task.stack.sendActivityResultLocked(-1, 1875 r.resultTo, r.resultWho, r.requestCode, 1876 Activity.RESULT_CANCELED, null); 1877 r.resultTo = null; 1878 } 1879 1880 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 1881 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1882 } 1883 1884 // If we are actually going to launch in to a new task, there are some cases where 1885 // we further want to do multiple task. 1886 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1887 if (launchTaskBehind 1888 || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) { 1889 launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1890 } 1891 } 1892 1893 // We'll invoke onUserLeaving before onPause only if the launching 1894 // activity did not explicitly state that this is an automated launch. 1895 mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1896 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 1897 "startActivity() => mUserLeaving=" + mUserLeaving); 1898 1899 // If the caller has asked not to resume at this point, we make note 1900 // of this in the record so that we can skip it when trying to find 1901 // the top running activity. 1902 if (!doResume) { 1903 r.delayedResume = true; 1904 } 1905 1906 ActivityRecord notTop = 1907 (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1908 1909 // If the onlyIfNeeded flag is set, then we can do this if the activity 1910 // being launched is the same as the one making the call... or, as 1911 // a special case, if we do not know the caller then we count the 1912 // current top activity as the caller. 1913 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1914 ActivityRecord checkedCaller = sourceRecord; 1915 if (checkedCaller == null) { 1916 checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop); 1917 } 1918 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1919 // Caller is not the same as launcher, so always needed. 1920 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1921 } 1922 } 1923 1924 boolean addingToTask = false; 1925 TaskRecord reuseTask = null; 1926 1927 // If the caller is not coming from another activity, but has given us an 1928 // explicit task into which they would like us to launch the new activity, 1929 // then let's see about doing that. 1930 if (sourceRecord == null && inTask != null && inTask.stack != null) { 1931 final Intent baseIntent = inTask.getBaseIntent(); 1932 final ActivityRecord root = inTask.getRootActivity(); 1933 if (baseIntent == null) { 1934 ActivityOptions.abort(options); 1935 throw new IllegalArgumentException("Launching into task without base intent: " 1936 + inTask); 1937 } 1938 1939 // If this task is empty, then we are adding the first activity -- it 1940 // determines the root, and must be launching as a NEW_TASK. 1941 if (launchSingleInstance || launchSingleTask) { 1942 if (!baseIntent.getComponent().equals(r.intent.getComponent())) { 1943 ActivityOptions.abort(options); 1944 throw new IllegalArgumentException("Trying to launch singleInstance/Task " 1945 + r + " into different task " + inTask); 1946 } 1947 if (root != null) { 1948 ActivityOptions.abort(options); 1949 throw new IllegalArgumentException("Caller with inTask " + inTask 1950 + " has root " + root + " but target is singleInstance/Task"); 1951 } 1952 } 1953 1954 // If task is empty, then adopt the interesting intent launch flags in to the 1955 // activity being started. 1956 if (root == null) { 1957 final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK 1958 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT 1959 | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; 1960 launchFlags = (launchFlags&~flagsOfInterest) 1961 | (baseIntent.getFlags()&flagsOfInterest); 1962 intent.setFlags(launchFlags); 1963 inTask.setIntent(r); 1964 addingToTask = true; 1965 1966 // If the task is not empty and the caller is asking to start it as the root 1967 // of a new task, then we don't actually want to start this on the task. We 1968 // will bring the task to the front, and possibly give it a new intent. 1969 } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1970 addingToTask = false; 1971 1972 } else { 1973 addingToTask = true; 1974 } 1975 1976 reuseTask = inTask; 1977 } else { 1978 inTask = null; 1979 } 1980 1981 if (inTask == null) { 1982 if (sourceRecord == null) { 1983 // This activity is not being started from another... in this 1984 // case we -always- start a new task. 1985 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) { 1986 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1987 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1988 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1989 } 1990 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1991 // The original activity who is starting us is running as a single 1992 // instance... this new activity it is starting must go on its 1993 // own task. 1994 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1995 } else if (launchSingleInstance || launchSingleTask) { 1996 // The activity being started is a single instance... it always 1997 // gets launched into its own task. 1998 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1999 } 2000 } 2001 2002 ActivityInfo newTaskInfo = null; 2003 Intent newTaskIntent = null; 2004 ActivityStack sourceStack; 2005 if (sourceRecord != null) { 2006 if (sourceRecord.finishing) { 2007 // If the source is finishing, we can't further count it as our source. This 2008 // is because the task it is associated with may now be empty and on its way out, 2009 // so we don't want to blindly throw it in to that task. Instead we will take 2010 // the NEW_TASK flow and try to find a task for it. But save the task information 2011 // so it can be used when creating the new task. 2012 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 2013 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 2014 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 2015 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 2016 newTaskInfo = sourceRecord.info; 2017 newTaskIntent = sourceRecord.task.intent; 2018 } 2019 sourceRecord = null; 2020 sourceStack = null; 2021 } else { 2022 sourceStack = sourceRecord.task.stack; 2023 } 2024 } else { 2025 sourceStack = null; 2026 } 2027 2028 boolean movedHome = false; 2029 ActivityStack targetStack; 2030 2031 intent.setFlags(launchFlags); 2032 final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0; 2033 2034 // We may want to try to place the new activity in to an existing task. We always 2035 // do this if the target activity is singleTask or singleInstance; we will also do 2036 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 2037 // us to still place it in a new task: multi task, always doc mode, or being asked to 2038 // launch this as a new task behind the current one. 2039 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 2040 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 2041 || launchSingleInstance || launchSingleTask) { 2042 // If bring to front is requested, and no result is requested and we have not 2043 // been given an explicit task to launch in to, and 2044 // we can find a task that was started with this same 2045 // component, then instead of launching bring that one to the front. 2046 if (inTask == null && r.resultTo == null) { 2047 // See if there is a task to bring to the front. If this is 2048 // a SINGLE_INSTANCE activity, there can be one and only one 2049 // instance of it in the history, and it is always in its own 2050 // unique task, so we do a special search. 2051 ActivityRecord intentActivity = !launchSingleInstance ? 2052 findTaskLocked(r) : findActivityLocked(intent, r.info); 2053 if (intentActivity != null) { 2054 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused 2055 // but still needs to be a lock task mode violation since the task gets 2056 // cleared out and the device would otherwise leave the locked task. 2057 if (isLockTaskModeViolation(intentActivity.task, 2058 (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 2059 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) { 2060 showLockTaskToast(); 2061 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); 2062 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2063 } 2064 if (r.task == null) { 2065 r.task = intentActivity.task; 2066 } 2067 if (intentActivity.task.intent == null) { 2068 // This task was started because of movement of 2069 // the activity based on affinity... now that we 2070 // are actually launching it, we can assign the 2071 // base intent. 2072 intentActivity.task.setIntent(r); 2073 } 2074 targetStack = intentActivity.task.stack; 2075 targetStack.mLastPausedActivity = null; 2076 // If the target task is not in the front, then we need 2077 // to bring it to the front... except... well, with 2078 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 2079 // to have the same behavior as if a new instance was 2080 // being started, which means not bringing it to the front 2081 // if the caller is not itself in the front. 2082 final ActivityStack focusStack = getFocusedStack(); 2083 ActivityRecord curTop = (focusStack == null) 2084 ? null : focusStack.topRunningNonDelayedActivityLocked(notTop); 2085 boolean movedToFront = false; 2086 if (curTop != null && (curTop.task != intentActivity.task || 2087 curTop.task != focusStack.topTask())) { 2088 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 2089 if (sourceRecord == null || (sourceStack.topActivity() != null && 2090 sourceStack.topActivity().task == sourceRecord.task)) { 2091 // We really do want to push this one into the user's face, right now. 2092 if (launchTaskBehind && sourceRecord != null) { 2093 intentActivity.setTaskToAffiliateWith(sourceRecord.task); 2094 } 2095 movedHome = true; 2096 targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation, 2097 options, r.appTimeTracker, "bringingFoundTaskToFront"); 2098 movedToFront = true; 2099 if ((launchFlags & 2100 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 2101 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 2102 // Caller wants to appear on home activity. 2103 intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2104 } 2105 options = null; 2106 } 2107 } 2108 if (!movedToFront) { 2109 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack 2110 + " from " + intentActivity); 2111 targetStack.moveToFront("intentActivityFound"); 2112 } 2113 2114 // If the caller has requested that the target task be 2115 // reset, then do so. 2116 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2117 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 2118 } 2119 if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2120 // We don't need to start a new activity, and 2121 // the client said not to do anything if that 2122 // is the case, so this is it! And for paranoia, make 2123 // sure we have correctly resumed the top activity. 2124 if (doResume) { 2125 resumeTopActivitiesLocked(targetStack, null, options); 2126 2127 // Make sure to notify Keyguard as well if we are not running an app 2128 // transition later. 2129 if (!movedToFront) { 2130 notifyActivityDrawnForKeyguard(); 2131 } 2132 } else { 2133 ActivityOptions.abort(options); 2134 } 2135 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2136 } 2137 if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 2138 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) { 2139 // The caller has requested to completely replace any 2140 // existing task with its new activity. Well that should 2141 // not be too hard... 2142 reuseTask = intentActivity.task; 2143 reuseTask.performClearTaskLocked(); 2144 reuseTask.setIntent(r); 2145 } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 2146 || launchSingleInstance || launchSingleTask) { 2147 // In this situation we want to remove all activities 2148 // from the task up to the one being started. In most 2149 // cases this means we are resetting the task to its 2150 // initial state. 2151 ActivityRecord top = 2152 intentActivity.task.performClearTaskLocked(r, launchFlags); 2153 if (top != null) { 2154 if (top.frontOfTask) { 2155 // Activity aliases may mean we use different 2156 // intents for the top activity, so make sure 2157 // the task now has the identity of the new 2158 // intent. 2159 top.task.setIntent(r); 2160 } 2161 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 2162 r, top.task); 2163 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2164 } else { 2165 // A special case: we need to start the activity because it is not 2166 // currently running, and the caller has asked to clear the current 2167 // task to have this activity at the top. 2168 addingToTask = true; 2169 // Now pretend like this activity is being started by the top of its 2170 // task, so it is put in the right place. 2171 sourceRecord = intentActivity; 2172 TaskRecord task = sourceRecord.task; 2173 if (task != null && task.stack == null) { 2174 // Target stack got cleared when we all activities were removed 2175 // above. Go ahead and reset it. 2176 targetStack = computeStackFocus(sourceRecord, false /* newTask */); 2177 targetStack.addTask( 2178 task, !launchTaskBehind /* toTop */, false /* moving */); 2179 } 2180 2181 } 2182 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 2183 // In this case the top activity on the task is the 2184 // same as the one being launched, so we take that 2185 // as a request to bring the task to the foreground. 2186 // If the top activity in the task is the root 2187 // activity, deliver this new intent to it if it 2188 // desires. 2189 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop) 2190 && intentActivity.realActivity.equals(r.realActivity)) { 2191 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 2192 intentActivity.task); 2193 if (intentActivity.frontOfTask) { 2194 intentActivity.task.setIntent(r); 2195 } 2196 intentActivity.deliverNewIntentLocked(callingUid, r.intent, 2197 r.launchedFromPackage); 2198 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 2199 // In this case we are launching the root activity 2200 // of the task, but with a different intent. We 2201 // should start a new instance on top. 2202 addingToTask = true; 2203 sourceRecord = intentActivity; 2204 } 2205 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 2206 // In this case an activity is being launched in to an 2207 // existing task, without resetting that task. This 2208 // is typically the situation of launching an activity 2209 // from a notification or shortcut. We want to place 2210 // the new activity on top of the current task. 2211 addingToTask = true; 2212 sourceRecord = intentActivity; 2213 } else if (!intentActivity.task.rootWasReset) { 2214 // In this case we are launching in to an existing task 2215 // that has not yet been started from its front door. 2216 // The current task has been brought to the front. 2217 // Ideally, we'd probably like to place this new task 2218 // at the bottom of its stack, but that's a little hard 2219 // to do with the current organization of the code so 2220 // for now we'll just drop it. 2221 intentActivity.task.setIntent(r); 2222 } 2223 if (!addingToTask && reuseTask == null) { 2224 // We didn't do anything... but it was needed (a.k.a., client 2225 // don't use that intent!) And for paranoia, make 2226 // sure we have correctly resumed the top activity. 2227 if (doResume) { 2228 targetStack.resumeTopActivityLocked(null, options); 2229 if (!movedToFront) { 2230 // Make sure to notify Keyguard as well if we are not running an app 2231 // transition later. 2232 notifyActivityDrawnForKeyguard(); 2233 } 2234 } else { 2235 ActivityOptions.abort(options); 2236 } 2237 return ActivityManager.START_TASK_TO_FRONT; 2238 } 2239 } 2240 } 2241 } 2242 2243 //String uri = r.intent.toURI(); 2244 //Intent intent2 = new Intent(uri); 2245 //Slog.i(TAG, "Given intent: " + r.intent); 2246 //Slog.i(TAG, "URI is: " + uri); 2247 //Slog.i(TAG, "To intent: " + intent2); 2248 2249 if (r.packageName != null) { 2250 // If the activity being launched is the same as the one currently 2251 // at the top, then we need to check if it should only be launched 2252 // once. 2253 ActivityStack topStack = mFocusedStack; 2254 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 2255 if (top != null && r.resultTo == null) { 2256 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 2257 if (top.app != null && top.app.thread != null) { 2258 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 2259 || launchSingleTop || launchSingleTask) { 2260 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 2261 top.task); 2262 // For paranoia, make sure we have correctly 2263 // resumed the top activity. 2264 topStack.mLastPausedActivity = null; 2265 if (doResume) { 2266 resumeTopActivitiesLocked(); 2267 } 2268 ActivityOptions.abort(options); 2269 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2270 // We don't need to start a new activity, and 2271 // the client said not to do anything if that 2272 // is the case, so this is it! 2273 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2274 } 2275 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2276 return ActivityManager.START_DELIVERED_TO_TOP; 2277 } 2278 } 2279 } 2280 } 2281 2282 } else { 2283 if (r.resultTo != null && r.resultTo.task.stack != null) { 2284 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 2285 r.requestCode, Activity.RESULT_CANCELED, null); 2286 } 2287 ActivityOptions.abort(options); 2288 return ActivityManager.START_CLASS_NOT_FOUND; 2289 } 2290 2291 boolean newTask = false; 2292 boolean keepCurTransition = false; 2293 2294 TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ? 2295 sourceRecord.task : null; 2296 2297 // Should this be considered a new task? 2298 if (r.resultTo == null && inTask == null && !addingToTask 2299 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 2300 newTask = true; 2301 targetStack = computeStackFocus(r, newTask); 2302 targetStack.moveToFront("startingNewTask"); 2303 2304 if (reuseTask == null) { 2305 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 2306 newTaskInfo != null ? newTaskInfo : r.info, 2307 newTaskIntent != null ? newTaskIntent : intent, 2308 voiceSession, voiceInteractor, !launchTaskBehind /* toTop */), 2309 taskToAffiliate); 2310 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 2311 "Starting new activity " + r + " in new task " + r.task); 2312 } else { 2313 r.setTask(reuseTask, taskToAffiliate); 2314 } 2315 if (isLockTaskModeViolation(r.task)) { 2316 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2317 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2318 } 2319 if (!movedHome) { 2320 if ((launchFlags & 2321 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 2322 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 2323 // Caller wants to appear on home activity, so before starting 2324 // their own activity we will bring home to the front. 2325 r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2326 } 2327 } 2328 } else if (sourceRecord != null) { 2329 final TaskRecord sourceTask = sourceRecord.task; 2330 if (isLockTaskModeViolation(sourceTask)) { 2331 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2332 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2333 } 2334 targetStack = sourceTask.stack; 2335 targetStack.moveToFront("sourceStackToFront"); 2336 final TaskRecord topTask = targetStack.topTask(); 2337 if (topTask != sourceTask) { 2338 targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options, 2339 r.appTimeTracker, "sourceTaskToFront"); 2340 } 2341 if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 2342 // In this case, we are adding the activity to an existing 2343 // task, but the caller has asked to clear that task if the 2344 // activity is already running. 2345 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 2346 keepCurTransition = true; 2347 if (top != null) { 2348 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 2349 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2350 // For paranoia, make sure we have correctly 2351 // resumed the top activity. 2352 targetStack.mLastPausedActivity = null; 2353 if (doResume) { 2354 targetStack.resumeTopActivityLocked(null); 2355 } 2356 ActivityOptions.abort(options); 2357 return ActivityManager.START_DELIVERED_TO_TOP; 2358 } 2359 } else if (!addingToTask && 2360 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 2361 // In this case, we are launching an activity in our own task 2362 // that may already be running somewhere in the history, and 2363 // we want to shuffle it to the front of the stack if so. 2364 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 2365 if (top != null) { 2366 final TaskRecord task = top.task; 2367 task.moveActivityToFrontLocked(top); 2368 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 2369 top.updateOptionsLocked(options); 2370 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2371 targetStack.mLastPausedActivity = null; 2372 if (doResume) { 2373 targetStack.resumeTopActivityLocked(null); 2374 } 2375 return ActivityManager.START_DELIVERED_TO_TOP; 2376 } 2377 } 2378 // An existing activity is starting this new activity, so we want 2379 // to keep the new one in the same task as the one that is starting 2380 // it. 2381 r.setTask(sourceTask, null); 2382 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r 2383 + " in existing task " + r.task + " from source " + sourceRecord); 2384 2385 } else if (inTask != null) { 2386 // The caller is asking that the new activity be started in an explicit 2387 // task it has provided to us. 2388 if (isLockTaskModeViolation(inTask)) { 2389 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 2390 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 2391 } 2392 targetStack = inTask.stack; 2393 targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker, 2394 "inTaskToFront"); 2395 2396 // Check whether we should actually launch the new activity in to the task, 2397 // or just reuse the current activity on top. 2398 ActivityRecord top = inTask.getTopActivity(); 2399 if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 2400 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 2401 || launchSingleTop || launchSingleTask) { 2402 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 2403 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 2404 // We don't need to start a new activity, and 2405 // the client said not to do anything if that 2406 // is the case, so this is it! 2407 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 2408 } 2409 top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); 2410 return ActivityManager.START_DELIVERED_TO_TOP; 2411 } 2412 } 2413 2414 if (!addingToTask) { 2415 // We don't actually want to have this activity added to the task, so just 2416 // stop here but still tell the caller that we consumed the intent. 2417 ActivityOptions.abort(options); 2418 return ActivityManager.START_TASK_TO_FRONT; 2419 } 2420 2421 r.setTask(inTask, null); 2422 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r 2423 + " in explicit task " + r.task); 2424 2425 } else { 2426 // This not being started from an existing activity, and not part 2427 // of a new task... just put it in the top task, though these days 2428 // this case should never happen. 2429 targetStack = computeStackFocus(r, newTask); 2430 targetStack.moveToFront("addingToTopTask"); 2431 ActivityRecord prev = targetStack.topActivity(); 2432 r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), 2433 r.info, intent, null, null, true), null); 2434 mWindowManager.moveTaskToTop(r.task.taskId); 2435 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r 2436 + " in new guessed " + r.task); 2437 } 2438 2439 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 2440 intent, r.getUriPermissionsLocked(), r.userId); 2441 2442 if (sourceRecord != null && sourceRecord.isRecentsActivity()) { 2443 r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE); 2444 } 2445 if (newTask) { 2446 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 2447 } 2448 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 2449 targetStack.mLastPausedActivity = null; 2450 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 2451 if (!launchTaskBehind) { 2452 // Don't set focus on an activity that's going to the back. 2453 mService.setFocusedActivityLocked(r, "startedActivity"); 2454 } 2455 return ActivityManager.START_SUCCESS; 2456 } 2457 2458 final void doPendingActivityLaunchesLocked(boolean doResume) { 2459 while (!mPendingActivityLaunches.isEmpty()) { 2460 PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); 2461 startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 2462 doResume && mPendingActivityLaunches.isEmpty(), null, null); 2463 } 2464 } 2465 2466 void removePendingActivityLaunchesLocked(ActivityStack stack) { 2467 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) { 2468 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx); 2469 if (pal.stack == stack) { 2470 mPendingActivityLaunches.remove(palNdx); 2471 } 2472 } 2473 } 2474 2475 void setLaunchSource(int uid) { 2476 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 2477 } 2478 2479 void acquireLaunchWakelock() { 2480 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2481 throw new IllegalStateException("Calling must be system uid"); 2482 } 2483 mLaunchingActivity.acquire(); 2484 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2485 // To be safe, don't allow the wake lock to be held for too long. 2486 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2487 } 2488 } 2489 2490 /** 2491 * Called when the frontmost task is idle. 2492 * @return the state of mService.mBooting before this was called. 2493 */ 2494 private boolean checkFinishBootingLocked() { 2495 final boolean booting = mService.mBooting; 2496 boolean enableScreen = false; 2497 mService.mBooting = false; 2498 if (!mService.mBooted) { 2499 mService.mBooted = true; 2500 enableScreen = true; 2501 } 2502 if (booting || enableScreen) { 2503 mService.postFinishBooting(booting, enableScreen); 2504 } 2505 return booting; 2506 } 2507 2508 // Checked. 2509 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 2510 Configuration config) { 2511 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); 2512 2513 ArrayList<ActivityRecord> stops = null; 2514 ArrayList<ActivityRecord> finishes = null; 2515 ArrayList<UserState> startingUsers = null; 2516 int NS = 0; 2517 int NF = 0; 2518 boolean booting = false; 2519 boolean activityRemoved = false; 2520 2521 ActivityRecord r = ActivityRecord.forTokenLocked(token); 2522 if (r != null) { 2523 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" 2524 + Debug.getCallers(4)); 2525 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2526 r.finishLaunchTickingLocked(); 2527 if (fromTimeout) { 2528 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2529 } 2530 2531 // This is a hack to semi-deal with a race condition 2532 // in the client where it can be constructed with a 2533 // newer configuration from when we asked it to launch. 2534 // We'll update with whatever configuration it now says 2535 // it used to launch. 2536 if (config != null) { 2537 r.configuration = config; 2538 } 2539 2540 // We are now idle. If someone is waiting for a thumbnail from 2541 // us, we can now deliver. 2542 r.idle = true; 2543 2544 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2545 if (isFrontStack(r.task.stack) || fromTimeout) { 2546 booting = checkFinishBootingLocked(); 2547 } 2548 } 2549 2550 if (allResumedActivitiesIdle()) { 2551 if (r != null) { 2552 mService.scheduleAppGcsLocked(); 2553 } 2554 2555 if (mLaunchingActivity.isHeld()) { 2556 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2557 if (VALIDATE_WAKE_LOCK_CALLER && 2558 Binder.getCallingUid() != Process.myUid()) { 2559 throw new IllegalStateException("Calling must be system uid"); 2560 } 2561 mLaunchingActivity.release(); 2562 } 2563 ensureActivitiesVisibleLocked(null, 0); 2564 } 2565 2566 // Atomically retrieve all of the other things to do. 2567 stops = processStoppingActivitiesLocked(true); 2568 NS = stops != null ? stops.size() : 0; 2569 if ((NF = mFinishingActivities.size()) > 0) { 2570 finishes = new ArrayList<>(mFinishingActivities); 2571 mFinishingActivities.clear(); 2572 } 2573 2574 if (mStartingUsers.size() > 0) { 2575 startingUsers = new ArrayList<>(mStartingUsers); 2576 mStartingUsers.clear(); 2577 } 2578 2579 // Stop any activities that are scheduled to do so but have been 2580 // waiting for the next one to start. 2581 for (int i = 0; i < NS; i++) { 2582 r = stops.get(i); 2583 final ActivityStack stack = r.task.stack; 2584 if (stack != null) { 2585 if (r.finishing) { 2586 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 2587 } else { 2588 stack.stopActivityLocked(r); 2589 } 2590 } 2591 } 2592 2593 // Finish any activities that are scheduled to do so but have been 2594 // waiting for the next one to start. 2595 for (int i = 0; i < NF; i++) { 2596 r = finishes.get(i); 2597 final ActivityStack stack = r.task.stack; 2598 if (stack != null) { 2599 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); 2600 } 2601 } 2602 2603 if (!booting) { 2604 // Complete user switch 2605 if (startingUsers != null) { 2606 for (int i = 0; i < startingUsers.size(); i++) { 2607 mService.finishUserSwitch(startingUsers.get(i)); 2608 } 2609 } 2610 // Complete starting up of background users 2611 if (mStartingBackgroundUsers.size() > 0) { 2612 startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers); 2613 mStartingBackgroundUsers.clear(); 2614 for (int i = 0; i < startingUsers.size(); i++) { 2615 mService.finishUserBoot(startingUsers.get(i)); 2616 } 2617 } 2618 } 2619 2620 mService.trimApplications(); 2621 //dump(); 2622 //mWindowManager.dump(); 2623 2624 if (activityRemoved) { 2625 resumeTopActivitiesLocked(); 2626 } 2627 2628 return r; 2629 } 2630 2631 boolean handleAppDiedLocked(ProcessRecord app) { 2632 boolean hasVisibleActivities = false; 2633 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2634 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2635 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2636 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2637 } 2638 } 2639 return hasVisibleActivities; 2640 } 2641 2642 void closeSystemDialogsLocked() { 2643 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2644 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2645 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2646 stacks.get(stackNdx).closeSystemDialogsLocked(); 2647 } 2648 } 2649 } 2650 2651 void removeUserLocked(int userId) { 2652 mUserStackInFront.delete(userId); 2653 } 2654 2655 /** 2656 * @return true if some activity was finished (or would have finished if doit were true). 2657 */ 2658 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 2659 boolean doit, boolean evenPersistent, int userId) { 2660 boolean didSomething = false; 2661 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2662 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2663 final int numStacks = stacks.size(); 2664 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2665 final ActivityStack stack = stacks.get(stackNdx); 2666 if (stack.finishDisabledPackageActivitiesLocked( 2667 packageName, filterByClasses, doit, evenPersistent, userId)) { 2668 didSomething = true; 2669 } 2670 } 2671 } 2672 return didSomething; 2673 } 2674 2675 void updatePreviousProcessLocked(ActivityRecord r) { 2676 // Now that this process has stopped, we may want to consider 2677 // it to be the previous app to try to keep around in case 2678 // the user wants to return to it. 2679 2680 // First, found out what is currently the foreground app, so that 2681 // we don't blow away the previous app if this activity is being 2682 // hosted by the process that is actually still the foreground. 2683 ProcessRecord fgApp = null; 2684 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2685 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2686 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2687 final ActivityStack stack = stacks.get(stackNdx); 2688 if (isFrontStack(stack)) { 2689 if (stack.mResumedActivity != null) { 2690 fgApp = stack.mResumedActivity.app; 2691 } else if (stack.mPausingActivity != null) { 2692 fgApp = stack.mPausingActivity.app; 2693 } 2694 break; 2695 } 2696 } 2697 } 2698 2699 // Now set this one as the previous process, only if that really 2700 // makes sense to. 2701 if (r.app != null && fgApp != null && r.app != fgApp 2702 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2703 && r.app != mService.mHomeProcess) { 2704 mService.mPreviousProcess = r.app; 2705 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2706 } 2707 } 2708 2709 boolean resumeTopActivitiesLocked() { 2710 return resumeTopActivitiesLocked(null, null, null); 2711 } 2712 2713 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2714 Bundle targetOptions) { 2715 if (targetStack == null) { 2716 targetStack = mFocusedStack; 2717 } 2718 // Do targetStack first. 2719 boolean result = false; 2720 if (isFrontStack(targetStack)) { 2721 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2722 } 2723 2724 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2725 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2726 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2727 final ActivityStack stack = stacks.get(stackNdx); 2728 if (stack == targetStack) { 2729 // Already started above. 2730 continue; 2731 } 2732 if (isFrontStack(stack)) { 2733 stack.resumeTopActivityLocked(null); 2734 } 2735 } 2736 } 2737 return result; 2738 } 2739 2740 void finishTopRunningActivityLocked(ProcessRecord app, String reason) { 2741 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2742 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2743 final int numStacks = stacks.size(); 2744 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2745 final ActivityStack stack = stacks.get(stackNdx); 2746 stack.finishTopRunningActivityLocked(app, reason); 2747 } 2748 } 2749 } 2750 2751 void finishVoiceTask(IVoiceInteractionSession session) { 2752 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2753 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2754 final int numStacks = stacks.size(); 2755 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2756 final ActivityStack stack = stacks.get(stackNdx); 2757 stack.finishVoiceTask(session); 2758 } 2759 } 2760 } 2761 2762 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options, String reason) { 2763 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2764 mUserLeaving = true; 2765 } 2766 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2767 // Caller wants the home activity moved with it. To accomplish this, 2768 // we'll just indicate that this task returns to the home task. 2769 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2770 } 2771 if (task.stack == null) { 2772 Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task=" 2773 + task + " to front. Stack is null"); 2774 return; 2775 } 2776 task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 2777 task.getTopActivity() == null ? null : task.getTopActivity().appTimeTracker, 2778 reason); 2779 if (DEBUG_STACK) Slog.d(TAG_STACK, 2780 "findTaskToMoveToFront: moved to front of stack=" + task.stack); 2781 } 2782 2783 ActivityStack getStack(int stackId) { 2784 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2785 if (activityContainer != null) { 2786 return activityContainer.mStack; 2787 } 2788 return null; 2789 } 2790 2791 ArrayList<ActivityStack> getStacks() { 2792 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2793 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2794 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2795 } 2796 return allStacks; 2797 } 2798 2799 IBinder getHomeActivityToken() { 2800 ActivityRecord homeActivity = getHomeActivity(); 2801 if (homeActivity != null) { 2802 return homeActivity.appToken; 2803 } 2804 return null; 2805 } 2806 2807 ActivityRecord getHomeActivity() { 2808 return getHomeActivityForUser(mCurrentUser); 2809 } 2810 2811 ActivityRecord getHomeActivityForUser(int userId) { 2812 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2813 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2814 final TaskRecord task = tasks.get(taskNdx); 2815 if (task.isHomeTask()) { 2816 final ArrayList<ActivityRecord> activities = task.mActivities; 2817 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2818 final ActivityRecord r = activities.get(activityNdx); 2819 if (r.isHomeActivity() 2820 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 2821 return r; 2822 } 2823 } 2824 } 2825 } 2826 return null; 2827 } 2828 2829 ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity, 2830 IActivityContainerCallback callback) { 2831 ActivityContainer activityContainer = 2832 new VirtualActivityContainer(parentActivity, callback); 2833 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2834 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 2835 "createActivityContainer: " + activityContainer); 2836 parentActivity.mChildContainers.add(activityContainer); 2837 return activityContainer; 2838 } 2839 2840 void removeChildActivityContainers(ActivityRecord parentActivity) { 2841 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2842 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2843 ActivityContainer container = childStacks.remove(containerNdx); 2844 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing " 2845 + container); 2846 container.release(); 2847 } 2848 } 2849 2850 void deleteActivityContainer(IActivityContainer container) { 2851 ActivityContainer activityContainer = (ActivityContainer)container; 2852 if (activityContainer != null) { 2853 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 2854 "deleteActivityContainer: callers=" + Debug.getCallers(4)); 2855 final int stackId = activityContainer.mStackId; 2856 mActivityContainers.remove(stackId); 2857 mWindowManager.removeStack(stackId); 2858 } 2859 } 2860 2861 void resizeStackLocked(int stackId, Rect bounds) { 2862 final ActivityStack stack = getStack(stackId); 2863 if (stack == null) { 2864 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); 2865 return; 2866 } 2867 2868 final ActivityRecord r = stack.topRunningActivityLocked(null); 2869 if (r != null && !r.task.mResizeable) { 2870 Slog.w(TAG, "resizeStack: top task " + r.task + " not resizeable."); 2871 return; 2872 } 2873 2874 final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds); 2875 if (stack.updateOverrideConfiguration(overrideConfig)) { 2876 if (r != null) { 2877 final boolean updated = stack.ensureActivityConfigurationLocked(r, 0); 2878 // And we need to make sure at this point that all other activities 2879 // are made visible with the correct configuration. 2880 ensureActivitiesVisibleLocked(r, 0); 2881 if (!updated) { 2882 resumeTopActivitiesLocked(stack, null, null); 2883 } 2884 } 2885 } 2886 } 2887 2888 /** Makes sure the input task is in a stack with the specified bounds by either resizing the 2889 * current task stack if it only has one entry, moving the task to a stack that matches the 2890 * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/ 2891 void resizeTaskLocked(TaskRecord task, Rect bounds) { 2892 task.mResizeable = true; 2893 final ActivityStack currentStack = task.stack; 2894 if (currentStack.isHomeStack()) { 2895 // Can't move task off the home stack. Sorry! 2896 return; 2897 } 2898 2899 final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds); 2900 if (matchingStackId != -1) { 2901 // There is already a stack with the right bounds! 2902 if (currentStack != null && currentStack.mStackId == matchingStackId) { 2903 // Nothing to do here. Already in the right stack... 2904 return; 2905 } 2906 // Move task to stack with matching bounds. 2907 moveTaskToStackLocked(task.taskId, matchingStackId, true); 2908 return; 2909 } 2910 2911 if (currentStack != null && currentStack.numTasks() == 1) { 2912 // Just resize the current stack since this is the task in it. 2913 resizeStackLocked(currentStack.mStackId, bounds); 2914 return; 2915 } 2916 2917 // Create new stack and move the task to it. 2918 final int displayId = (currentStack != null && currentStack.mDisplayId != -1) 2919 ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY; 2920 ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId); 2921 2922 if (newStack == null) { 2923 Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task); 2924 return; 2925 } 2926 moveTaskToStackLocked(task.taskId, newStack.mStackId, true); 2927 resizeStackLocked(newStack.mStackId, bounds); 2928 } 2929 2930 ActivityStack createStackOnDisplay(int stackId, int displayId) { 2931 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2932 if (activityDisplay == null) { 2933 return null; 2934 } 2935 2936 ActivityContainer activityContainer = new ActivityContainer(stackId); 2937 mActivityContainers.put(stackId, activityContainer); 2938 activityContainer.attachToDisplayLocked(activityDisplay); 2939 return activityContainer.mStack; 2940 } 2941 2942 int getNextStackId() { 2943 while (true) { 2944 if (++mLastStackId <= HOME_STACK_ID) { 2945 mLastStackId = HOME_STACK_ID + 1; 2946 } 2947 if (getStack(mLastStackId) == null) { 2948 break; 2949 } 2950 } 2951 return mLastStackId; 2952 } 2953 2954 private boolean restoreRecentTaskLocked(TaskRecord task) { 2955 ActivityStack stack = null; 2956 // Determine stack to restore task to. 2957 if (mLeanbackOnlyDevice) { 2958 // There is only one stack for lean back devices. 2959 stack = mHomeStack; 2960 } else { 2961 // Look for the top stack on the home display that isn't the home stack. 2962 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 2963 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2964 final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx); 2965 if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) { 2966 stack = tmpStack; 2967 break; 2968 } 2969 } 2970 } 2971 2972 if (stack == null) { 2973 // We couldn't find a stack to restore the task to. Possible if are restoring recents 2974 // before an application stack is created...Go ahead and create one on the default 2975 // display. 2976 stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 2977 // Restore home stack to top. 2978 moveHomeStack(true, "restoreRecentTask"); 2979 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2980 "Created stack=" + stack + " for recents restoration."); 2981 } 2982 2983 if (stack == null) { 2984 // What does this mean??? Not sure how we would get here... 2985 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2986 "Unable to find/create stack to restore recent task=" + task); 2987 return false; 2988 } 2989 2990 stack.addTask(task, false, false); 2991 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2992 "Added restored task=" + task + " to stack=" + stack); 2993 final ArrayList<ActivityRecord> activities = task.mActivities; 2994 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2995 final ActivityRecord r = activities.get(activityNdx); 2996 mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId, 2997 r.info.screenOrientation, r.fullscreen, 2998 (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, 2999 r.userId, r.info.configChanges, task.voiceSession != null, 3000 r.mLaunchTaskBehind); 3001 } 3002 return true; 3003 } 3004 3005 void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) { 3006 final TaskRecord task = anyTaskForIdLocked(taskId); 3007 if (task == null) { 3008 Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); 3009 return; 3010 } 3011 final ActivityStack stack = getStack(stackId); 3012 if (stack == null) { 3013 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 3014 return; 3015 } 3016 mWindowManager.moveTaskToStack(taskId, stackId, toTop); 3017 if (task.stack != null) { 3018 task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */); 3019 } 3020 stack.addTask(task, toTop, true); 3021 // The task might have already been running and its visibility needs to be synchronized with 3022 // the visibility of the stack / windows. 3023 stack.ensureActivitiesVisibleLocked(null, 0); 3024 resumeTopActivitiesLocked(); 3025 } 3026 3027 ActivityRecord findTaskLocked(ActivityRecord r) { 3028 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 3029 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3030 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3031 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3032 final ActivityStack stack = stacks.get(stackNdx); 3033 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 3034 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack); 3035 continue; 3036 } 3037 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 3038 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 3039 "Skipping stack: (new task not allowed) " + stack); 3040 continue; 3041 } 3042 final ActivityRecord ar = stack.findTaskLocked(r); 3043 if (ar != null) { 3044 return ar; 3045 } 3046 } 3047 } 3048 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "No task found"); 3049 return null; 3050 } 3051 3052 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 3053 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3054 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3055 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3056 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 3057 if (ar != null) { 3058 return ar; 3059 } 3060 } 3061 } 3062 return null; 3063 } 3064 3065 void goingToSleepLocked() { 3066 scheduleSleepTimeout(); 3067 if (!mGoingToSleep.isHeld()) { 3068 mGoingToSleep.acquire(); 3069 if (mLaunchingActivity.isHeld()) { 3070 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 3071 throw new IllegalStateException("Calling must be system uid"); 3072 } 3073 mLaunchingActivity.release(); 3074 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 3075 } 3076 } 3077 checkReadyForSleepLocked(); 3078 } 3079 3080 boolean shutdownLocked(int timeout) { 3081 goingToSleepLocked(); 3082 3083 boolean timedout = false; 3084 final long endTime = System.currentTimeMillis() + timeout; 3085 while (true) { 3086 boolean cantShutdown = false; 3087 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3088 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3089 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3090 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 3091 } 3092 } 3093 if (cantShutdown) { 3094 long timeRemaining = endTime - System.currentTimeMillis(); 3095 if (timeRemaining > 0) { 3096 try { 3097 mService.wait(timeRemaining); 3098 } catch (InterruptedException e) { 3099 } 3100 } else { 3101 Slog.w(TAG, "Activity manager shutdown timed out"); 3102 timedout = true; 3103 break; 3104 } 3105 } else { 3106 break; 3107 } 3108 } 3109 3110 // Force checkReadyForSleep to complete. 3111 mSleepTimeout = true; 3112 checkReadyForSleepLocked(); 3113 3114 return timedout; 3115 } 3116 3117 void comeOutOfSleepIfNeededLocked() { 3118 removeSleepTimeouts(); 3119 if (mGoingToSleep.isHeld()) { 3120 mGoingToSleep.release(); 3121 } 3122 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3123 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3124 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3125 final ActivityStack stack = stacks.get(stackNdx); 3126 stack.awakeFromSleepingLocked(); 3127 if (isFrontStack(stack)) { 3128 resumeTopActivitiesLocked(); 3129 } 3130 } 3131 } 3132 mGoingToSleepActivities.clear(); 3133 } 3134 3135 void activitySleptLocked(ActivityRecord r) { 3136 mGoingToSleepActivities.remove(r); 3137 checkReadyForSleepLocked(); 3138 } 3139 3140 void checkReadyForSleepLocked() { 3141 if (!mService.isSleepingOrShuttingDown()) { 3142 // Do not care. 3143 return; 3144 } 3145 3146 if (!mSleepTimeout) { 3147 boolean dontSleep = false; 3148 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3149 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3150 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3151 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 3152 } 3153 } 3154 3155 if (mStoppingActivities.size() > 0) { 3156 // Still need to tell some activities to stop; can't sleep yet. 3157 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " 3158 + mStoppingActivities.size() + " activities"); 3159 scheduleIdleLocked(); 3160 dontSleep = true; 3161 } 3162 3163 if (mGoingToSleepActivities.size() > 0) { 3164 // Still need to tell some activities to sleep; can't sleep yet. 3165 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep " 3166 + mGoingToSleepActivities.size() + " activities"); 3167 dontSleep = true; 3168 } 3169 3170 if (dontSleep) { 3171 return; 3172 } 3173 } 3174 3175 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3176 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3177 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3178 stacks.get(stackNdx).goToSleep(); 3179 } 3180 } 3181 3182 removeSleepTimeouts(); 3183 3184 if (mGoingToSleep.isHeld()) { 3185 mGoingToSleep.release(); 3186 } 3187 if (mService.mShuttingDown) { 3188 mService.notifyAll(); 3189 } 3190 } 3191 3192 boolean reportResumedActivityLocked(ActivityRecord r) { 3193 final ActivityStack stack = r.task.stack; 3194 if (isFrontStack(stack)) { 3195 mService.updateUsageStats(r, true); 3196 } 3197 if (allResumedActivitiesComplete()) { 3198 ensureActivitiesVisibleLocked(null, 0); 3199 mWindowManager.executeAppTransition(); 3200 return true; 3201 } 3202 return false; 3203 } 3204 3205 void handleAppCrashLocked(ProcessRecord app) { 3206 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3207 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3208 final int numStacks = stacks.size(); 3209 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 3210 final ActivityStack stack = stacks.get(stackNdx); 3211 stack.handleAppCrashLocked(app); 3212 } 3213 } 3214 } 3215 3216 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 3217 final ActivityStack stack = r.task.stack; 3218 if (stack == null) { 3219 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 3220 "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null"); 3221 return false; 3222 } 3223 final boolean isVisible = stack.hasVisibleBehindActivity(); 3224 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 3225 "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible); 3226 3227 final ActivityRecord top = topRunningActivityLocked(); 3228 if (top == null || top == r || (visible == isVisible)) { 3229 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return"); 3230 stack.setVisibleBehindActivity(visible ? r : null); 3231 return true; 3232 } 3233 3234 // A non-top activity is reporting a visibility change. 3235 if (visible && top.fullscreen) { 3236 // Let the caller know that it can't be seen. 3237 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 3238 "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen 3239 + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" 3240 + top.app.thread); 3241 return false; 3242 } else if (!visible && stack.getVisibleBehindActivity() != r) { 3243 // Only the activity set as currently visible behind should actively reset its 3244 // visible behind state. 3245 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 3246 "requestVisibleBehind: returning visible=" + visible 3247 + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity() 3248 + " r=" + r); 3249 return false; 3250 } 3251 3252 stack.setVisibleBehindActivity(visible ? r : null); 3253 if (!visible) { 3254 // Make the activity immediately above r opaque. 3255 final ActivityRecord next = stack.findNextTranslucentActivity(r); 3256 if (next != null) { 3257 mService.convertFromTranslucent(next.appToken); 3258 } 3259 } 3260 if (top.app != null && top.app.thread != null) { 3261 // Notify the top app of the change. 3262 try { 3263 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 3264 } catch (RemoteException e) { 3265 } 3266 } 3267 return true; 3268 } 3269 3270 // Called when WindowManager has finished animating the launchingBehind activity to the back. 3271 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 3272 r.mLaunchTaskBehind = false; 3273 final TaskRecord task = r.task; 3274 task.setLastThumbnail(task.stack.screenshotActivities(r)); 3275 mRecentTasks.addLocked(task); 3276 mService.notifyTaskStackChangedLocked(); 3277 mWindowManager.setAppVisibility(r.appToken, false); 3278 } 3279 3280 void scheduleLaunchTaskBehindComplete(IBinder token) { 3281 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 3282 } 3283 3284 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 3285 // First the front stacks. In case any are not fullscreen and are in front of home. 3286 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3287 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3288 final int topStackNdx = stacks.size() - 1; 3289 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 3290 final ActivityStack stack = stacks.get(stackNdx); 3291 stack.ensureActivitiesVisibleLocked(starting, configChanges); 3292 } 3293 } 3294 } 3295 3296 void clearOtherAppTimeTrackers(AppTimeTracker except) { 3297 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3298 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3299 final int topStackNdx = stacks.size() - 1; 3300 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 3301 final ActivityStack stack = stacks.get(stackNdx); 3302 stack.clearOtherAppTimeTrackers(except); 3303 } 3304 } 3305 } 3306 3307 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 3308 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3309 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3310 final int numStacks = stacks.size(); 3311 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 3312 final ActivityStack stack = stacks.get(stackNdx); 3313 stack.scheduleDestroyActivities(app, reason); 3314 } 3315 } 3316 } 3317 3318 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 3319 // Examine all activities currently running in the process. 3320 TaskRecord firstTask = null; 3321 // Tasks is non-null only if two or more tasks are found. 3322 ArraySet<TaskRecord> tasks = null; 3323 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 3324 for (int i = 0; i < app.activities.size(); i++) { 3325 ActivityRecord r = app.activities.get(i); 3326 // First, if we find an activity that is in the process of being destroyed, 3327 // then we just aren't going to do anything for now; we want things to settle 3328 // down before we try to prune more activities. 3329 if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) { 3330 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 3331 return; 3332 } 3333 // Don't consider any activies that are currently not in a state where they 3334 // can be destroyed. 3335 if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING 3336 || r.state == PAUSED || r.state == STOPPING) { 3337 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 3338 continue; 3339 } 3340 if (r.task != null) { 3341 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task 3342 + " from " + r); 3343 if (firstTask == null) { 3344 firstTask = r.task; 3345 } else if (firstTask != r.task) { 3346 if (tasks == null) { 3347 tasks = new ArraySet<>(); 3348 tasks.add(firstTask); 3349 } 3350 tasks.add(r.task); 3351 } 3352 } 3353 } 3354 if (tasks == null) { 3355 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 3356 return; 3357 } 3358 // If we have activities in multiple tasks that are in a position to be destroyed, 3359 // let's iterate through the tasks and release the oldest one. 3360 final int numDisplays = mActivityDisplays.size(); 3361 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 3362 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3363 // Step through all stacks starting from behind, to hit the oldest things first. 3364 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 3365 final ActivityStack stack = stacks.get(stackNdx); 3366 // Try to release activities in this stack; if we manage to, we are done. 3367 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 3368 return; 3369 } 3370 } 3371 } 3372 } 3373 3374 boolean switchUserLocked(int userId, UserState uss) { 3375 mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId()); 3376 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 3377 mCurrentUser = userId; 3378 3379 mStartingUsers.add(uss); 3380 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3381 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3382 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3383 final ActivityStack stack = stacks.get(stackNdx); 3384 stack.switchUserLocked(userId); 3385 TaskRecord task = stack.topTask(); 3386 if (task != null) { 3387 mWindowManager.moveTaskToTop(task.taskId); 3388 } 3389 } 3390 } 3391 3392 ActivityStack stack = getStack(restoreStackId); 3393 if (stack == null) { 3394 stack = mHomeStack; 3395 } 3396 final boolean homeInFront = stack.isHomeStack(); 3397 if (stack.isOnHomeDisplay()) { 3398 moveHomeStack(homeInFront, "switchUserOnHomeDisplay"); 3399 TaskRecord task = stack.topTask(); 3400 if (task != null) { 3401 mWindowManager.moveTaskToTop(task.taskId); 3402 } 3403 } else { 3404 // Stack was moved to another display while user was swapped out. 3405 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay"); 3406 } 3407 return homeInFront; 3408 } 3409 3410 /** 3411 * Add background users to send boot completed events to. 3412 * @param userId The user being started in the background 3413 * @param uss The state object for the user. 3414 */ 3415 public void startBackgroundUserLocked(int userId, UserState uss) { 3416 mStartingBackgroundUsers.add(uss); 3417 } 3418 3419 /** Checks whether the userid is a profile of the current user. */ 3420 boolean isCurrentProfileLocked(int userId) { 3421 if (userId == mCurrentUser) return true; 3422 for (int i = 0; i < mService.mCurrentProfileIds.length; i++) { 3423 if (mService.mCurrentProfileIds[i] == userId) return true; 3424 } 3425 return false; 3426 } 3427 3428 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 3429 ArrayList<ActivityRecord> stops = null; 3430 3431 final boolean nowVisible = allResumedActivitiesVisible(); 3432 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3433 ActivityRecord s = mStoppingActivities.get(activityNdx); 3434 final boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3435 if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3436 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3437 if (waitingVisible && nowVisible) { 3438 mWaitingVisibleActivities.remove(s); 3439 if (s.finishing) { 3440 // If this activity is finishing, it is sitting on top of 3441 // everyone else but we now know it is no longer needed... 3442 // so get rid of it. Otherwise, we need to go through the 3443 // normal flow and hide it once we determine that it is 3444 // hidden by the activities in front of it. 3445 if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s); 3446 mWindowManager.setAppVisibility(s.appToken, false); 3447 } 3448 } 3449 if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3450 if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s); 3451 if (stops == null) { 3452 stops = new ArrayList<>(); 3453 } 3454 stops.add(s); 3455 mStoppingActivities.remove(activityNdx); 3456 } 3457 } 3458 3459 return stops; 3460 } 3461 3462 void validateTopActivitiesLocked() { 3463 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3464 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3465 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3466 final ActivityStack stack = stacks.get(stackNdx); 3467 final ActivityRecord r = stack.topRunningActivityLocked(null); 3468 final ActivityState state = r == null ? DESTROYED : r.state; 3469 if (isFrontStack(stack)) { 3470 if (r == null) Slog.e(TAG, 3471 "validateTop...: null top activity, stack=" + stack); 3472 else { 3473 final ActivityRecord pausing = stack.mPausingActivity; 3474 if (pausing != null && pausing == r) Slog.e(TAG, 3475 "validateTop...: top stack has pausing activity r=" + r 3476 + " state=" + state); 3477 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3478 "validateTop...: activity in front not resumed r=" + r 3479 + " state=" + state); 3480 } 3481 } else { 3482 final ActivityRecord resumed = stack.mResumedActivity; 3483 if (resumed != null && resumed == r) Slog.e(TAG, 3484 "validateTop...: back stack has resumed activity r=" + r 3485 + " state=" + state); 3486 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3487 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3488 } 3489 } 3490 } 3491 } 3492 3493 private String lockTaskModeToString() { 3494 switch (mLockTaskModeState) { 3495 case LOCK_TASK_MODE_LOCKED: 3496 return "LOCKED"; 3497 case LOCK_TASK_MODE_PINNED: 3498 return "PINNED"; 3499 case LOCK_TASK_MODE_NONE: 3500 return "NONE"; 3501 default: return "unknown=" + mLockTaskModeState; 3502 } 3503 } 3504 3505 public void dump(PrintWriter pw, String prefix) { 3506 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3507 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3508 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3509 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 3510 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3511 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3512 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3513 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3514 if (packages.size() > 0) { 3515 pw.println(" mLockTaskPackages (userId:packages)="); 3516 for (int i = 0; i < packages.size(); ++i) { 3517 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3518 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3519 } 3520 } 3521 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3522 } 3523 3524 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3525 return mFocusedStack.getDumpActivitiesLocked(name); 3526 } 3527 3528 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3529 boolean needSep, String prefix) { 3530 if (activity != null) { 3531 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3532 if (needSep) { 3533 pw.println(); 3534 } 3535 pw.print(prefix); 3536 pw.println(activity); 3537 return true; 3538 } 3539 } 3540 return false; 3541 } 3542 3543 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3544 boolean dumpClient, String dumpPackage) { 3545 boolean printed = false; 3546 boolean needSep = false; 3547 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3548 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3549 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3550 pw.println(" (activities from top to bottom):"); 3551 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3552 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3553 final ActivityStack stack = stacks.get(stackNdx); 3554 StringBuilder stackHeader = new StringBuilder(128); 3555 stackHeader.append(" Stack #"); 3556 stackHeader.append(stack.mStackId); 3557 stackHeader.append(":"); 3558 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3559 needSep, stackHeader.toString()); 3560 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3561 !dumpAll, false, dumpPackage, true, 3562 " Running activities (most recent first):", null); 3563 3564 needSep = printed; 3565 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3566 " mPausingActivity: "); 3567 if (pr) { 3568 printed = true; 3569 needSep = false; 3570 } 3571 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3572 " mResumedActivity: "); 3573 if (pr) { 3574 printed = true; 3575 needSep = false; 3576 } 3577 if (dumpAll) { 3578 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3579 " mLastPausedActivity: "); 3580 if (pr) { 3581 printed = true; 3582 needSep = true; 3583 } 3584 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3585 needSep, " mLastNoHistoryActivity: "); 3586 } 3587 needSep = printed; 3588 } 3589 } 3590 3591 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3592 false, dumpPackage, true, " Activities waiting to finish:", null); 3593 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3594 false, dumpPackage, true, " Activities waiting to stop:", null); 3595 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3596 false, dumpPackage, true, " Activities waiting for another to become visible:", 3597 null); 3598 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3599 false, dumpPackage, true, " Activities waiting to sleep:", null); 3600 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3601 false, dumpPackage, true, " Activities waiting to sleep:", null); 3602 3603 return printed; 3604 } 3605 3606 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3607 String prefix, String label, boolean complete, boolean brief, boolean client, 3608 String dumpPackage, boolean needNL, String header1, String header2) { 3609 TaskRecord lastTask = null; 3610 String innerPrefix = null; 3611 String[] args = null; 3612 boolean printed = false; 3613 for (int i=list.size()-1; i>=0; i--) { 3614 final ActivityRecord r = list.get(i); 3615 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3616 continue; 3617 } 3618 if (innerPrefix == null) { 3619 innerPrefix = prefix + " "; 3620 args = new String[0]; 3621 } 3622 printed = true; 3623 final boolean full = !brief && (complete || !r.isInHistory()); 3624 if (needNL) { 3625 pw.println(""); 3626 needNL = false; 3627 } 3628 if (header1 != null) { 3629 pw.println(header1); 3630 header1 = null; 3631 } 3632 if (header2 != null) { 3633 pw.println(header2); 3634 header2 = null; 3635 } 3636 if (lastTask != r.task) { 3637 lastTask = r.task; 3638 pw.print(prefix); 3639 pw.print(full ? "* " : " "); 3640 pw.println(lastTask); 3641 if (full) { 3642 lastTask.dump(pw, prefix + " "); 3643 } else if (complete) { 3644 // Complete + brief == give a summary. Isn't that obvious?!? 3645 if (lastTask.intent != null) { 3646 pw.print(prefix); pw.print(" "); 3647 pw.println(lastTask.intent.toInsecureStringWithClip()); 3648 } 3649 } 3650 } 3651 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3652 pw.print(" #"); pw.print(i); pw.print(": "); 3653 pw.println(r); 3654 if (full) { 3655 r.dump(pw, innerPrefix); 3656 } else if (complete) { 3657 // Complete + brief == give a summary. Isn't that obvious?!? 3658 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3659 if (r.app != null) { 3660 pw.print(innerPrefix); pw.println(r.app); 3661 } 3662 } 3663 if (client && r.app != null && r.app.thread != null) { 3664 // flush anything that is already in the PrintWriter since the thread is going 3665 // to write to the file descriptor directly 3666 pw.flush(); 3667 try { 3668 TransferPipe tp = new TransferPipe(); 3669 try { 3670 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3671 r.appToken, innerPrefix, args); 3672 // Short timeout, since blocking here can 3673 // deadlock with the application. 3674 tp.go(fd, 2000); 3675 } finally { 3676 tp.kill(); 3677 } 3678 } catch (IOException e) { 3679 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3680 } catch (RemoteException e) { 3681 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3682 } 3683 needNL = true; 3684 } 3685 } 3686 return printed; 3687 } 3688 3689 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3690 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3691 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3692 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3693 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3694 } 3695 3696 final void scheduleIdleLocked() { 3697 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3698 } 3699 3700 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3701 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3702 + Debug.getCallers(4)); 3703 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3704 } 3705 3706 final void scheduleResumeTopActivities() { 3707 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3708 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3709 } 3710 } 3711 3712 void removeSleepTimeouts() { 3713 mSleepTimeout = false; 3714 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3715 } 3716 3717 final void scheduleSleepTimeout() { 3718 removeSleepTimeouts(); 3719 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3720 } 3721 3722 @Override 3723 public void onDisplayAdded(int displayId) { 3724 Slog.v(TAG, "Display added displayId=" + displayId); 3725 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3726 } 3727 3728 @Override 3729 public void onDisplayRemoved(int displayId) { 3730 Slog.v(TAG, "Display removed displayId=" + displayId); 3731 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3732 } 3733 3734 @Override 3735 public void onDisplayChanged(int displayId) { 3736 Slog.v(TAG, "Display changed displayId=" + displayId); 3737 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3738 } 3739 3740 private void handleDisplayAdded(int displayId) { 3741 boolean newDisplay; 3742 synchronized (mService) { 3743 newDisplay = mActivityDisplays.get(displayId) == null; 3744 if (newDisplay) { 3745 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3746 if (activityDisplay.mDisplay == null) { 3747 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3748 return; 3749 } 3750 mActivityDisplays.put(displayId, activityDisplay); 3751 } 3752 } 3753 if (newDisplay) { 3754 mWindowManager.onDisplayAdded(displayId); 3755 } 3756 } 3757 3758 private void handleDisplayRemoved(int displayId) { 3759 synchronized (mService) { 3760 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3761 if (activityDisplay != null) { 3762 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3763 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3764 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3765 } 3766 mActivityDisplays.remove(displayId); 3767 } 3768 } 3769 mWindowManager.onDisplayRemoved(displayId); 3770 } 3771 3772 private void handleDisplayChanged(int displayId) { 3773 synchronized (mService) { 3774 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3775 if (activityDisplay != null) { 3776 // TODO: Update the bounds. 3777 } 3778 } 3779 mWindowManager.onDisplayChanged(displayId); 3780 } 3781 3782 private StackInfo getStackInfoLocked(ActivityStack stack) { 3783 StackInfo info = new StackInfo(); 3784 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3785 info.displayId = Display.DEFAULT_DISPLAY; 3786 info.stackId = stack.mStackId; 3787 3788 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3789 final int numTasks = tasks.size(); 3790 int[] taskIds = new int[numTasks]; 3791 String[] taskNames = new String[numTasks]; 3792 for (int i = 0; i < numTasks; ++i) { 3793 final TaskRecord task = tasks.get(i); 3794 taskIds[i] = task.taskId; 3795 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3796 : task.realActivity != null ? task.realActivity.flattenToString() 3797 : task.getTopActivity() != null ? task.getTopActivity().packageName 3798 : "unknown"; 3799 } 3800 info.taskIds = taskIds; 3801 info.taskNames = taskNames; 3802 return info; 3803 } 3804 3805 StackInfo getStackInfoLocked(int stackId) { 3806 ActivityStack stack = getStack(stackId); 3807 if (stack != null) { 3808 return getStackInfoLocked(stack); 3809 } 3810 return null; 3811 } 3812 3813 ArrayList<StackInfo> getAllStackInfosLocked() { 3814 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 3815 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3816 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3817 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3818 list.add(getStackInfoLocked(stacks.get(ndx))); 3819 } 3820 } 3821 return list; 3822 } 3823 3824 TaskRecord getLockedTaskLocked() { 3825 final int top = mLockTaskModeTasks.size() - 1; 3826 if (top >= 0) { 3827 return mLockTaskModeTasks.get(top); 3828 } 3829 return null; 3830 } 3831 3832 boolean isLockedTask(TaskRecord task) { 3833 return mLockTaskModeTasks.contains(task); 3834 } 3835 3836 boolean isLastLockedTask(TaskRecord task) { 3837 return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task); 3838 } 3839 3840 void removeLockedTaskLocked(final TaskRecord task) { 3841 if (!mLockTaskModeTasks.remove(task)) { 3842 return; 3843 } 3844 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task); 3845 if (mLockTaskModeTasks.isEmpty()) { 3846 // Last one. 3847 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + 3848 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); 3849 final Message lockTaskMsg = Message.obtain(); 3850 lockTaskMsg.arg1 = task.userId; 3851 lockTaskMsg.what = LOCK_TASK_END_MSG; 3852 mHandler.sendMessage(lockTaskMsg); 3853 } 3854 } 3855 3856 void showLockTaskToast() { 3857 mLockTaskNotify.showToast(mLockTaskModeState); 3858 } 3859 3860 void showLockTaskEscapeMessageLocked(TaskRecord task) { 3861 if (mLockTaskModeTasks.contains(task)) { 3862 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 3863 } 3864 } 3865 3866 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 3867 boolean andResume) { 3868 if (task == null) { 3869 // Take out of lock task mode if necessary 3870 final TaskRecord lockedTask = getLockedTaskLocked(); 3871 if (lockedTask != null) { 3872 removeLockedTaskLocked(lockedTask); 3873 if (!mLockTaskModeTasks.isEmpty()) { 3874 // There are locked tasks remaining, can only finish this task, not unlock it. 3875 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3876 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 3877 lockedTask.performClearTaskLocked(); 3878 resumeTopActivitiesLocked(); 3879 return; 3880 } 3881 } 3882 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3883 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 3884 return; 3885 } 3886 3887 // Should have already been checked, but do it again. 3888 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 3889 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3890 "setLockTaskModeLocked: Can't lock due to auth"); 3891 return; 3892 } 3893 if (isLockTaskModeViolation(task)) { 3894 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 3895 return; 3896 } 3897 3898 if (mLockTaskModeTasks.isEmpty()) { 3899 // First locktask. 3900 final Message lockTaskMsg = Message.obtain(); 3901 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 3902 lockTaskMsg.arg1 = task.userId; 3903 lockTaskMsg.what = LOCK_TASK_START_MSG; 3904 lockTaskMsg.arg2 = lockTaskModeState; 3905 mHandler.sendMessage(lockTaskMsg); 3906 } 3907 // Add it or move it to the top. 3908 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 3909 " Callers=" + Debug.getCallers(4)); 3910 mLockTaskModeTasks.remove(task); 3911 mLockTaskModeTasks.add(task); 3912 3913 if (task.mLockTaskUid == -1) { 3914 task.mLockTaskUid = task.mCallingUid; 3915 } 3916 3917 if (andResume) { 3918 findTaskToMoveToFrontLocked(task, 0, null, reason); 3919 resumeTopActivitiesLocked(); 3920 } 3921 } 3922 3923 boolean isLockTaskModeViolation(TaskRecord task) { 3924 return isLockTaskModeViolation(task, false); 3925 } 3926 3927 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 3928 if (getLockedTaskLocked() == task && !isNewClearTask) { 3929 return false; 3930 } 3931 final int lockTaskAuth = task.mLockTaskAuth; 3932 switch (lockTaskAuth) { 3933 case LOCK_TASK_AUTH_DONT_LOCK: 3934 return !mLockTaskModeTasks.isEmpty(); 3935 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 3936 case LOCK_TASK_AUTH_LAUNCHABLE: 3937 case LOCK_TASK_AUTH_WHITELISTED: 3938 return false; 3939 case LOCK_TASK_AUTH_PINNABLE: 3940 // Pinnable tasks can't be launched on top of locktask tasks. 3941 return !mLockTaskModeTasks.isEmpty(); 3942 default: 3943 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 3944 return true; 3945 } 3946 } 3947 3948 void onLockTaskPackagesUpdatedLocked() { 3949 boolean didSomething = false; 3950 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 3951 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 3952 final boolean wasWhitelisted = 3953 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3954 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3955 lockedTask.setLockTaskAuth(); 3956 final boolean isWhitelisted = 3957 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3958 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3959 if (wasWhitelisted && !isWhitelisted) { 3960 // Lost whitelisting authorization. End it now. 3961 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 3962 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 3963 removeLockedTaskLocked(lockedTask); 3964 lockedTask.performClearTaskLocked(); 3965 didSomething = true; 3966 } 3967 } 3968 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3969 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3970 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3971 final ActivityStack stack = stacks.get(stackNdx); 3972 stack.onLockTaskPackagesUpdatedLocked(); 3973 } 3974 } 3975 final ActivityRecord r = topRunningActivityLocked(); 3976 final TaskRecord task = r != null ? r.task : null; 3977 if (mLockTaskModeTasks.isEmpty() && task != null 3978 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 3979 // This task must have just been authorized. 3980 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 3981 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 3982 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 3983 false); 3984 didSomething = true; 3985 } 3986 if (didSomething) { 3987 resumeTopActivitiesLocked(); 3988 } 3989 } 3990 3991 int getLockTaskModeState() { 3992 return mLockTaskModeState; 3993 } 3994 3995 private final class ActivityStackSupervisorHandler extends Handler { 3996 3997 public ActivityStackSupervisorHandler(Looper looper) { 3998 super(looper); 3999 } 4000 4001 void activityIdleInternal(ActivityRecord r) { 4002 synchronized (mService) { 4003 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 4004 } 4005 } 4006 4007 @Override 4008 public void handleMessage(Message msg) { 4009 switch (msg.what) { 4010 case IDLE_TIMEOUT_MSG: { 4011 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 4012 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 4013 if (mService.mDidDexOpt) { 4014 mService.mDidDexOpt = false; 4015 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 4016 nmsg.obj = msg.obj; 4017 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 4018 return; 4019 } 4020 // We don't at this point know if the activity is fullscreen, 4021 // so we need to be conservative and assume it isn't. 4022 activityIdleInternal((ActivityRecord)msg.obj); 4023 } break; 4024 case IDLE_NOW_MSG: { 4025 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 4026 activityIdleInternal((ActivityRecord)msg.obj); 4027 } break; 4028 case RESUME_TOP_ACTIVITY_MSG: { 4029 synchronized (mService) { 4030 resumeTopActivitiesLocked(); 4031 } 4032 } break; 4033 case SLEEP_TIMEOUT_MSG: { 4034 synchronized (mService) { 4035 if (mService.isSleepingOrShuttingDown()) { 4036 Slog.w(TAG, "Sleep timeout! Sleeping now."); 4037 mSleepTimeout = true; 4038 checkReadyForSleepLocked(); 4039 } 4040 } 4041 } break; 4042 case LAUNCH_TIMEOUT_MSG: { 4043 if (mService.mDidDexOpt) { 4044 mService.mDidDexOpt = false; 4045 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 4046 return; 4047 } 4048 synchronized (mService) { 4049 if (mLaunchingActivity.isHeld()) { 4050 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 4051 if (VALIDATE_WAKE_LOCK_CALLER 4052 && Binder.getCallingUid() != Process.myUid()) { 4053 throw new IllegalStateException("Calling must be system uid"); 4054 } 4055 mLaunchingActivity.release(); 4056 } 4057 } 4058 } break; 4059 case HANDLE_DISPLAY_ADDED: { 4060 handleDisplayAdded(msg.arg1); 4061 } break; 4062 case HANDLE_DISPLAY_CHANGED: { 4063 handleDisplayChanged(msg.arg1); 4064 } break; 4065 case HANDLE_DISPLAY_REMOVED: { 4066 handleDisplayRemoved(msg.arg1); 4067 } break; 4068 case CONTAINER_CALLBACK_VISIBILITY: { 4069 final ActivityContainer container = (ActivityContainer) msg.obj; 4070 final IActivityContainerCallback callback = container.mCallback; 4071 if (callback != null) { 4072 try { 4073 callback.setVisible(container.asBinder(), msg.arg1 == 1); 4074 } catch (RemoteException e) { 4075 } 4076 } 4077 } break; 4078 case LOCK_TASK_START_MSG: { 4079 // When lock task starts, we disable the status bars. 4080 try { 4081 if (mLockTaskNotify == null) { 4082 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4083 } 4084 mLockTaskNotify.show(true); 4085 mLockTaskModeState = msg.arg2; 4086 if (getStatusBarService() != null) { 4087 int flags = 0; 4088 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 4089 flags = StatusBarManager.DISABLE_MASK 4090 & (~StatusBarManager.DISABLE_BACK); 4091 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 4092 flags = StatusBarManager.DISABLE_MASK 4093 & (~StatusBarManager.DISABLE_BACK) 4094 & (~StatusBarManager.DISABLE_HOME) 4095 & (~StatusBarManager.DISABLE_RECENT); 4096 } 4097 getStatusBarService().disable(flags, mToken, 4098 mService.mContext.getPackageName()); 4099 } 4100 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 4101 if (getDevicePolicyManager() != null) { 4102 getDevicePolicyManager().notifyLockTaskModeChanged(true, 4103 (String)msg.obj, msg.arg1); 4104 } 4105 } catch (RemoteException ex) { 4106 throw new RuntimeException(ex); 4107 } 4108 } break; 4109 case LOCK_TASK_END_MSG: { 4110 // When lock task ends, we enable the status bars. 4111 try { 4112 if (getStatusBarService() != null) { 4113 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 4114 mService.mContext.getPackageName()); 4115 } 4116 mWindowManager.reenableKeyguard(mToken); 4117 if (getDevicePolicyManager() != null) { 4118 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 4119 msg.arg1); 4120 } 4121 if (mLockTaskNotify == null) { 4122 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4123 } 4124 mLockTaskNotify.show(false); 4125 try { 4126 boolean shouldLockKeyguard = Settings.Secure.getInt( 4127 mService.mContext.getContentResolver(), 4128 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 4129 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 4130 mWindowManager.lockNow(null); 4131 mWindowManager.dismissKeyguard(); 4132 new LockPatternUtils(mService.mContext) 4133 .requireCredentialEntry(UserHandle.USER_ALL); 4134 } 4135 } catch (SettingNotFoundException e) { 4136 // No setting, don't lock. 4137 } 4138 } catch (RemoteException ex) { 4139 throw new RuntimeException(ex); 4140 } finally { 4141 mLockTaskModeState = LOCK_TASK_MODE_NONE; 4142 } 4143 } break; 4144 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 4145 if (mLockTaskNotify == null) { 4146 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4147 } 4148 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 4149 } break; 4150 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 4151 final ActivityContainer container = (ActivityContainer) msg.obj; 4152 final IActivityContainerCallback callback = container.mCallback; 4153 if (callback != null) { 4154 try { 4155 callback.onAllActivitiesComplete(container.asBinder()); 4156 } catch (RemoteException e) { 4157 } 4158 } 4159 } break; 4160 case LAUNCH_TASK_BEHIND_COMPLETE: { 4161 synchronized (mService) { 4162 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 4163 if (r != null) { 4164 handleLaunchTaskBehindCompleteLocked(r); 4165 } 4166 } 4167 } break; 4168 } 4169 } 4170 } 4171 4172 class ActivityContainer extends android.app.IActivityContainer.Stub { 4173 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 4174 Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 4175 final int mStackId; 4176 IActivityContainerCallback mCallback = null; 4177 final ActivityStack mStack; 4178 ActivityRecord mParentActivity = null; 4179 String mIdString; 4180 4181 boolean mVisible = true; 4182 4183 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 4184 ActivityDisplay mActivityDisplay; 4185 4186 final static int CONTAINER_STATE_HAS_SURFACE = 0; 4187 final static int CONTAINER_STATE_NO_SURFACE = 1; 4188 final static int CONTAINER_STATE_FINISHING = 2; 4189 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 4190 4191 ActivityContainer(int stackId) { 4192 synchronized (mService) { 4193 mStackId = stackId; 4194 mStack = new ActivityStack(this, mRecentTasks); 4195 mIdString = "ActivtyContainer{" + mStackId + "}"; 4196 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); 4197 } 4198 } 4199 4200 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 4201 if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this 4202 + " to display=" + activityDisplay); 4203 mActivityDisplay = activityDisplay; 4204 mStack.mDisplayId = activityDisplay.mDisplayId; 4205 mStack.mStacks = activityDisplay.mStacks; 4206 4207 activityDisplay.attachActivities(mStack); 4208 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 4209 } 4210 4211 @Override 4212 public void attachToDisplay(int displayId) { 4213 synchronized (mService) { 4214 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4215 if (activityDisplay == null) { 4216 return; 4217 } 4218 attachToDisplayLocked(activityDisplay); 4219 } 4220 } 4221 4222 @Override 4223 public int getDisplayId() { 4224 synchronized (mService) { 4225 if (mActivityDisplay != null) { 4226 return mActivityDisplay.mDisplayId; 4227 } 4228 } 4229 return -1; 4230 } 4231 4232 @Override 4233 public int getStackId() { 4234 synchronized (mService) { 4235 return mStackId; 4236 } 4237 } 4238 4239 @Override 4240 public boolean injectEvent(InputEvent event) { 4241 final long origId = Binder.clearCallingIdentity(); 4242 try { 4243 synchronized (mService) { 4244 if (mActivityDisplay != null) { 4245 return mInputManagerInternal.injectInputEvent(event, 4246 mActivityDisplay.mDisplayId, 4247 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 4248 } 4249 } 4250 return false; 4251 } finally { 4252 Binder.restoreCallingIdentity(origId); 4253 } 4254 } 4255 4256 @Override 4257 public void release() { 4258 synchronized (mService) { 4259 if (mContainerState == CONTAINER_STATE_FINISHING) { 4260 return; 4261 } 4262 mContainerState = CONTAINER_STATE_FINISHING; 4263 4264 long origId = Binder.clearCallingIdentity(); 4265 try { 4266 mStack.finishAllActivitiesLocked(false); 4267 removePendingActivityLaunchesLocked(mStack); 4268 } finally { 4269 Binder.restoreCallingIdentity(origId); 4270 } 4271 } 4272 } 4273 4274 protected void detachLocked() { 4275 if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display=" 4276 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 4277 if (mActivityDisplay != null) { 4278 mActivityDisplay.detachActivitiesLocked(mStack); 4279 mActivityDisplay = null; 4280 mStack.mDisplayId = -1; 4281 mStack.mStacks = null; 4282 mWindowManager.detachStack(mStackId); 4283 } 4284 } 4285 4286 @Override 4287 public final int startActivity(Intent intent) { 4288 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 4289 final int userId = mService.handleIncomingUser(Binder.getCallingPid(), 4290 Binder.getCallingUid(), mCurrentUser, false, 4291 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4292 4293 // TODO: Switch to user app stacks here. 4294 String mimeType = intent.getType(); 4295 final Uri data = intent.getData(); 4296 if (mimeType == null && data != null && "content".equals(data.getScheme())) { 4297 mimeType = mService.getProviderMimeType(data, userId); 4298 } 4299 checkEmbeddedAllowedInner(userId, intent, mimeType); 4300 4301 intent.addFlags(FORCE_NEW_TASK_FLAGS); 4302 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 4303 0, 0, null, null, null, null, false, userId, this, null); 4304 } 4305 4306 @Override 4307 public final int startActivityIntentSender(IIntentSender intentSender) 4308 throws TransactionTooLargeException { 4309 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 4310 4311 if (!(intentSender instanceof PendingIntentRecord)) { 4312 throw new IllegalArgumentException("Bad PendingIntent object"); 4313 } 4314 4315 final int userId = mService.handleIncomingUser(Binder.getCallingPid(), 4316 Binder.getCallingUid(), mCurrentUser, false, 4317 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4318 4319 final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 4320 checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, 4321 pendingIntent.key.requestResolvedType); 4322 4323 return pendingIntent.sendInner(0, null, null, null, null, null, null, 0, 4324 FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 4325 } 4326 4327 private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { 4328 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 4329 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 4330 throw new SecurityException( 4331 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 4332 } 4333 } 4334 4335 @Override 4336 public IBinder asBinder() { 4337 return this; 4338 } 4339 4340 @Override 4341 public void setSurface(Surface surface, int width, int height, int density) { 4342 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 4343 } 4344 4345 ActivityStackSupervisor getOuter() { 4346 return ActivityStackSupervisor.this; 4347 } 4348 4349 boolean isAttachedLocked() { 4350 return mActivityDisplay != null; 4351 } 4352 4353 void getBounds(Point outBounds) { 4354 synchronized (mService) { 4355 if (mActivityDisplay != null) { 4356 mActivityDisplay.getBounds(outBounds); 4357 } else { 4358 outBounds.set(0, 0); 4359 } 4360 } 4361 } 4362 4363 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 4364 void setVisible(boolean visible) { 4365 if (mVisible != visible) { 4366 mVisible = visible; 4367 if (mCallback != null) { 4368 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 4369 0 /* unused */, this).sendToTarget(); 4370 } 4371 } 4372 } 4373 4374 void setDrawn() { 4375 } 4376 4377 // You can always start a new task on a regular ActivityStack. 4378 boolean isEligibleForNewTasks() { 4379 return true; 4380 } 4381 4382 void onTaskListEmptyLocked() { 4383 detachLocked(); 4384 deleteActivityContainer(this); 4385 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 4386 } 4387 4388 @Override 4389 public String toString() { 4390 return mIdString + (mActivityDisplay == null ? "N" : "A"); 4391 } 4392 } 4393 4394 private class VirtualActivityContainer extends ActivityContainer { 4395 Surface mSurface; 4396 boolean mDrawn = false; 4397 4398 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 4399 super(getNextStackId()); 4400 mParentActivity = parent; 4401 mCallback = callback; 4402 mContainerState = CONTAINER_STATE_NO_SURFACE; 4403 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 4404 } 4405 4406 @Override 4407 public void setSurface(Surface surface, int width, int height, int density) { 4408 super.setSurface(surface, width, height, density); 4409 4410 synchronized (mService) { 4411 final long origId = Binder.clearCallingIdentity(); 4412 try { 4413 setSurfaceLocked(surface, width, height, density); 4414 } finally { 4415 Binder.restoreCallingIdentity(origId); 4416 } 4417 } 4418 } 4419 4420 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 4421 if (mContainerState == CONTAINER_STATE_FINISHING) { 4422 return; 4423 } 4424 VirtualActivityDisplay virtualActivityDisplay = 4425 (VirtualActivityDisplay) mActivityDisplay; 4426 if (virtualActivityDisplay == null) { 4427 virtualActivityDisplay = 4428 new VirtualActivityDisplay(width, height, density); 4429 mActivityDisplay = virtualActivityDisplay; 4430 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 4431 attachToDisplayLocked(virtualActivityDisplay); 4432 } 4433 4434 if (mSurface != null) { 4435 mSurface.release(); 4436 } 4437 4438 mSurface = surface; 4439 if (surface != null) { 4440 mStack.resumeTopActivityLocked(null); 4441 } else { 4442 mContainerState = CONTAINER_STATE_NO_SURFACE; 4443 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 4444 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 4445 mStack.startPausingLocked(false, true, false, false); 4446 } 4447 } 4448 4449 setSurfaceIfReadyLocked(); 4450 4451 if (DEBUG_STACK) Slog.d(TAG_STACK, 4452 "setSurface: " + this + " to display=" + virtualActivityDisplay); 4453 } 4454 4455 @Override 4456 boolean isAttachedLocked() { 4457 return mSurface != null && super.isAttachedLocked(); 4458 } 4459 4460 @Override 4461 void setDrawn() { 4462 synchronized (mService) { 4463 mDrawn = true; 4464 setSurfaceIfReadyLocked(); 4465 } 4466 } 4467 4468 // Never start a new task on an ActivityView if it isn't explicitly specified. 4469 @Override 4470 boolean isEligibleForNewTasks() { 4471 return false; 4472 } 4473 4474 private void setSurfaceIfReadyLocked() { 4475 if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 4476 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 4477 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 4478 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 4479 mContainerState = CONTAINER_STATE_HAS_SURFACE; 4480 } 4481 } 4482 } 4483 4484 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4485 * attached {@link ActivityStack}s */ 4486 class ActivityDisplay { 4487 /** Actual Display this object tracks. */ 4488 int mDisplayId; 4489 Display mDisplay; 4490 DisplayInfo mDisplayInfo = new DisplayInfo(); 4491 4492 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4493 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4494 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 4495 4496 ActivityRecord mVisibleBehindActivity; 4497 4498 ActivityDisplay() { 4499 } 4500 4501 // After instantiation, check that mDisplay is not null before using this. The alternative 4502 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4503 ActivityDisplay(int displayId) { 4504 final Display display = mDisplayManager.getDisplay(displayId); 4505 if (display == null) { 4506 return; 4507 } 4508 init(display); 4509 } 4510 4511 void init(Display display) { 4512 mDisplay = display; 4513 mDisplayId = display.getDisplayId(); 4514 mDisplay.getDisplayInfo(mDisplayInfo); 4515 } 4516 4517 void attachActivities(ActivityStack stack) { 4518 if (DEBUG_STACK) Slog.v(TAG_STACK, 4519 "attachActivities: attaching " + stack + " to displayId=" + mDisplayId); 4520 mStacks.add(stack); 4521 } 4522 4523 void detachActivitiesLocked(ActivityStack stack) { 4524 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack 4525 + " from displayId=" + mDisplayId); 4526 mStacks.remove(stack); 4527 } 4528 4529 void getBounds(Point bounds) { 4530 mDisplay.getDisplayInfo(mDisplayInfo); 4531 bounds.x = mDisplayInfo.appWidth; 4532 bounds.y = mDisplayInfo.appHeight; 4533 } 4534 4535 void setVisibleBehindActivity(ActivityRecord r) { 4536 mVisibleBehindActivity = r; 4537 } 4538 4539 boolean hasVisibleBehindActivity() { 4540 return mVisibleBehindActivity != null; 4541 } 4542 4543 @Override 4544 public String toString() { 4545 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4546 } 4547 } 4548 4549 class VirtualActivityDisplay extends ActivityDisplay { 4550 VirtualDisplay mVirtualDisplay; 4551 4552 VirtualActivityDisplay(int width, int height, int density) { 4553 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4554 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4555 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4556 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4557 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4558 4559 init(mVirtualDisplay.getDisplay()); 4560 4561 mWindowManager.handleDisplayAdded(mDisplayId); 4562 } 4563 4564 void setSurface(Surface surface) { 4565 if (mVirtualDisplay != null) { 4566 mVirtualDisplay.setSurface(surface); 4567 } 4568 } 4569 4570 @Override 4571 void detachActivitiesLocked(ActivityStack stack) { 4572 super.detachActivitiesLocked(stack); 4573 if (mVirtualDisplay != null) { 4574 mVirtualDisplay.release(); 4575 mVirtualDisplay = null; 4576 } 4577 } 4578 4579 @Override 4580 public String toString() { 4581 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4582 } 4583 } 4584 4585 private boolean isLeanbackOnlyDevice() { 4586 boolean onLeanbackOnly = false; 4587 try { 4588 onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature( 4589 PackageManager.FEATURE_LEANBACK_ONLY); 4590 } catch (RemoteException e) { 4591 // noop 4592 } 4593 4594 return onLeanbackOnly; 4595 } 4596} 4597