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