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