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