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