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