ActivityStackSupervisor.java revision 8a985d24ce9a38f40ed88fecbdcd0e75e3a68f44
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, null)) { 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, Bundle resumeArgs) 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 1026 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); 1027 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1028 System.identityHashCode(r), r.info, 1029 new Configuration(mService.mConfiguration), r.compat, 1030 app.repProcState, r.icicle, results, newIntents, !andResume, 1031 mService.isNextTransitionForward(), profileFile, profileFd, 1032 profileAutoStop, resumeArgs); 1033 1034 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 1035 // This may be a heavy-weight process! Note that the package 1036 // manager will ensure that only activity can run in the main 1037 // process of the .apk, which is the only thing that will be 1038 // considered heavy-weight. 1039 if (app.processName.equals(app.info.packageName)) { 1040 if (mService.mHeavyWeightProcess != null 1041 && mService.mHeavyWeightProcess != app) { 1042 Slog.w(TAG, "Starting new heavy weight process " + app 1043 + " when already running " 1044 + mService.mHeavyWeightProcess); 1045 } 1046 mService.mHeavyWeightProcess = app; 1047 Message msg = mService.mHandler.obtainMessage( 1048 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1049 msg.obj = r; 1050 mService.mHandler.sendMessage(msg); 1051 } 1052 } 1053 1054 } catch (RemoteException e) { 1055 if (r.launchFailed) { 1056 // This is the second time we failed -- finish activity 1057 // and give up. 1058 Slog.e(TAG, "Second failure launching " 1059 + r.intent.getComponent().flattenToShortString() 1060 + ", giving up", e); 1061 mService.appDiedLocked(app, app.pid, app.thread); 1062 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1063 "2nd-crash", false); 1064 return false; 1065 } 1066 1067 // This is the first time we failed -- restart process and 1068 // retry. 1069 app.activities.remove(r); 1070 throw e; 1071 } 1072 1073 r.launchFailed = false; 1074 if (stack.updateLRUListLocked(r)) { 1075 Slog.w(TAG, "Activity " + r 1076 + " being launched, but already in LRU list"); 1077 } 1078 1079 if (andResume) { 1080 // As part of the process of launching, ActivityThread also performs 1081 // a resume. 1082 stack.minimalResumeActivityLocked(r); 1083 } else { 1084 // This activity is not starting in the resumed state... which 1085 // should look like we asked it to pause+stop (but remain visible), 1086 // and it has done so and reported back the current icicle and 1087 // other state. 1088 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1089 + " (starting in stopped state)"); 1090 r.state = ActivityState.STOPPED; 1091 r.stopped = true; 1092 } 1093 1094 // Launch the new version setup screen if needed. We do this -after- 1095 // launching the initial activity (that is, home), so that it can have 1096 // a chance to initialize itself while in the background, making the 1097 // switch back to it faster and look better. 1098 if (isFrontStack(stack)) { 1099 mService.startSetupActivityLocked(); 1100 } 1101 1102 return true; 1103 } 1104 1105 void startSpecificActivityLocked(ActivityRecord r, 1106 boolean andResume, boolean checkConfig, Bundle resumeArgs) { 1107 // Is this activity's application already running? 1108 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1109 r.info.applicationInfo.uid, true); 1110 1111 r.task.stack.setLaunchTime(r); 1112 1113 if (app != null && app.thread != null) { 1114 try { 1115 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1116 || !"android".equals(r.info.packageName)) { 1117 // Don't add this if it is a platform component that is marked 1118 // to run in multiple processes, because this is actually 1119 // part of the framework so doesn't make sense to track as a 1120 // separate apk in the process. 1121 app.addPackage(r.info.packageName, mService.mProcessStats); 1122 } 1123 realStartActivityLocked(r, app, andResume, checkConfig, resumeArgs); 1124 return; 1125 } catch (RemoteException e) { 1126 Slog.w(TAG, "Exception when starting activity " 1127 + r.intent.getComponent().flattenToShortString(), e); 1128 } 1129 1130 // If a dead object exception was thrown -- fall through to 1131 // restart the application. 1132 } 1133 1134 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1135 "activity", r.intent.getComponent(), false, false, true); 1136 } 1137 1138 final int startActivityLocked(IApplicationThread caller, 1139 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 1140 String resultWho, int requestCode, 1141 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1142 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { 1143 int err = ActivityManager.START_SUCCESS; 1144 1145 ProcessRecord callerApp = null; 1146 if (caller != null) { 1147 callerApp = mService.getRecordForAppLocked(caller); 1148 if (callerApp != null) { 1149 callingPid = callerApp.pid; 1150 callingUid = callerApp.info.uid; 1151 } else { 1152 Slog.w(TAG, "Unable to find app for caller " + caller 1153 + " (pid=" + callingPid + ") when starting: " 1154 + intent.toString()); 1155 err = ActivityManager.START_PERMISSION_DENIED; 1156 } 1157 } 1158 1159 if (err == ActivityManager.START_SUCCESS) { 1160 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1161 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1162 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) 1163 + " on display " + (container == null ? (mFocusedStack == null ? 1164 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1165 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1166 container.mActivityDisplay.mDisplayId))); 1167 } 1168 1169 ActivityRecord sourceRecord = null; 1170 ActivityRecord resultRecord = null; 1171 if (resultTo != null) { 1172 sourceRecord = isInAnyStackLocked(resultTo); 1173 if (DEBUG_RESULTS) Slog.v( 1174 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1175 if (sourceRecord != null) { 1176 if (requestCode >= 0 && !sourceRecord.finishing) { 1177 resultRecord = sourceRecord; 1178 } 1179 } 1180 } 1181 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1182 1183 int launchFlags = intent.getFlags(); 1184 1185 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1186 && sourceRecord != null) { 1187 // Transfer the result target from the source activity to the new 1188 // one being started, including any failures. 1189 if (requestCode >= 0) { 1190 ActivityOptions.abort(options); 1191 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1192 } 1193 resultRecord = sourceRecord.resultTo; 1194 resultWho = sourceRecord.resultWho; 1195 requestCode = sourceRecord.requestCode; 1196 sourceRecord.resultTo = null; 1197 if (resultRecord != null) { 1198 resultRecord.removeResultsLocked( 1199 sourceRecord, resultWho, requestCode); 1200 } 1201 } 1202 1203 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1204 // We couldn't find a class that can handle the given Intent. 1205 // That's the end of that! 1206 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1207 } 1208 1209 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1210 // We couldn't find the specific class specified in the Intent. 1211 // Also the end of the line. 1212 err = ActivityManager.START_CLASS_NOT_FOUND; 1213 } 1214 1215 if (err != ActivityManager.START_SUCCESS) { 1216 if (resultRecord != null) { 1217 resultStack.sendActivityResultLocked(-1, 1218 resultRecord, resultWho, requestCode, 1219 Activity.RESULT_CANCELED, null); 1220 } 1221 setDismissKeyguard(false); 1222 ActivityOptions.abort(options); 1223 return err; 1224 } 1225 1226 final int startAnyPerm = mService.checkPermission( 1227 START_ANY_ACTIVITY, callingPid, callingUid); 1228 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1229 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1230 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1231 if (resultRecord != null) { 1232 resultStack.sendActivityResultLocked(-1, 1233 resultRecord, resultWho, requestCode, 1234 Activity.RESULT_CANCELED, null); 1235 } 1236 setDismissKeyguard(false); 1237 String msg; 1238 if (!aInfo.exported) { 1239 msg = "Permission Denial: starting " + intent.toString() 1240 + " from " + callerApp + " (pid=" + callingPid 1241 + ", uid=" + callingUid + ")" 1242 + " not exported from uid " + aInfo.applicationInfo.uid; 1243 } else { 1244 msg = "Permission Denial: starting " + intent.toString() 1245 + " from " + callerApp + " (pid=" + callingPid 1246 + ", uid=" + callingUid + ")" 1247 + " requires " + aInfo.permission; 1248 } 1249 Slog.w(TAG, msg); 1250 throw new SecurityException(msg); 1251 } 1252 1253 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1254 callingPid, resolvedType, aInfo.applicationInfo); 1255 1256 if (mService.mController != null) { 1257 try { 1258 // The Intent we give to the watcher has the extra data 1259 // stripped off, since it can contain private information. 1260 Intent watchIntent = intent.cloneFilter(); 1261 abort |= !mService.mController.activityStarting(watchIntent, 1262 aInfo.applicationInfo.packageName); 1263 } catch (RemoteException e) { 1264 mService.mController = null; 1265 } 1266 } 1267 1268 if (abort) { 1269 if (resultRecord != null) { 1270 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1271 Activity.RESULT_CANCELED, null); 1272 } 1273 // We pretend to the caller that it was really started, but 1274 // they will just get a cancel result. 1275 setDismissKeyguard(false); 1276 ActivityOptions.abort(options); 1277 return ActivityManager.START_SUCCESS; 1278 } 1279 1280 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1281 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1282 requestCode, componentSpecified, this, container); 1283 if (outActivity != null) { 1284 outActivity[0] = r; 1285 } 1286 1287 final ActivityStack stack = getFocusedStack(); 1288 if (stack.mResumedActivity == null 1289 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1290 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1291 PendingActivityLaunch pal = 1292 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1293 mService.mPendingActivityLaunches.add(pal); 1294 setDismissKeyguard(false); 1295 ActivityOptions.abort(options); 1296 return ActivityManager.START_SWITCHES_CANCELED; 1297 } 1298 } 1299 1300 if (mService.mDidAppSwitch) { 1301 // This is the second allowed switch since we stopped switches, 1302 // so now just generally allow switches. Use case: user presses 1303 // home (switches disabled, switch to home, mDidAppSwitch now true); 1304 // user taps a home icon (coming from home so allowed, we hit here 1305 // and now allow anyone to switch again). 1306 mService.mAppSwitchesAllowedTime = 0; 1307 } else { 1308 mService.mDidAppSwitch = true; 1309 } 1310 1311 mService.doPendingActivityLaunchesLocked(false); 1312 1313 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1314 1315 if (allPausedActivitiesComplete()) { 1316 // If someone asked to have the keyguard dismissed on the next 1317 // activity start, but we are not actually doing an activity 1318 // switch... just dismiss the keyguard now, because we 1319 // probably want to see whatever is behind it. 1320 dismissKeyguard(); 1321 } 1322 return err; 1323 } 1324 1325 ActivityStack adjustStackFocus(ActivityRecord r) { 1326 final TaskRecord task = r.task; 1327 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1328 if (task != null) { 1329 final ActivityStack taskStack = task.stack; 1330 if (taskStack.isOnHomeDisplay()) { 1331 if (mFocusedStack != taskStack) { 1332 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1333 "focused stack to r=" + r + " task=" + task); 1334 mFocusedStack = taskStack; 1335 } else { 1336 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1337 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1338 } 1339 } 1340 return taskStack; 1341 } 1342 1343 final ActivityContainer container = r.mInitialActivityContainer; 1344 if (container != null) { 1345 // The first time put it on the desired stack, after this put on task stack. 1346 r.mInitialActivityContainer = null; 1347 return container.mStack; 1348 } 1349 1350 if (mFocusedStack != mHomeStack) { 1351 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1352 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1353 return mFocusedStack; 1354 } 1355 1356 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1357 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1358 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1359 if (!stack.isHomeStack()) { 1360 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1361 "adjustStackFocus: Setting focused stack=" + stack); 1362 mFocusedStack = stack; 1363 return mFocusedStack; 1364 } 1365 } 1366 1367 // Need to create an app stack for this user. 1368 int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY); 1369 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1370 " stackId=" + stackId); 1371 mFocusedStack = getStack(stackId); 1372 return mFocusedStack; 1373 } 1374 return mHomeStack; 1375 } 1376 1377 void setFocusedStack(ActivityRecord r) { 1378 if (r != null) { 1379 final TaskRecord task = r.task; 1380 boolean isHomeActivity = !r.isApplicationActivity(); 1381 if (!isHomeActivity && task != null) { 1382 isHomeActivity = !task.isApplicationTask(); 1383 } 1384 if (!isHomeActivity && task != null) { 1385 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1386 isHomeActivity = parent != null && parent.isHomeActivity(); 1387 } 1388 moveHomeStack(isHomeActivity); 1389 } 1390 } 1391 1392 final int startActivityUncheckedLocked(ActivityRecord r, 1393 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1394 Bundle options) { 1395 final Intent intent = r.intent; 1396 final int callingUid = r.launchedFromUid; 1397 1398 int launchFlags = intent.getFlags(); 1399 1400 // We'll invoke onUserLeaving before onPause only if the launching 1401 // activity did not explicitly state that this is an automated launch. 1402 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1403 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1404 1405 // If the caller has asked not to resume at this point, we make note 1406 // of this in the record so that we can skip it when trying to find 1407 // the top running activity. 1408 if (!doResume) { 1409 r.delayedResume = true; 1410 } 1411 1412 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1413 1414 // If the onlyIfNeeded flag is set, then we can do this if the activity 1415 // being launched is the same as the one making the call... or, as 1416 // a special case, if we do not know the caller then we count the 1417 // current top activity as the caller. 1418 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1419 ActivityRecord checkedCaller = sourceRecord; 1420 if (checkedCaller == null) { 1421 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1422 } 1423 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1424 // Caller is not the same as launcher, so always needed. 1425 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1426 } 1427 } 1428 1429 if (sourceRecord == null) { 1430 // This activity is not being started from another... in this 1431 // case we -always- start a new task. 1432 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1433 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1434 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1435 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1436 } 1437 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1438 // The original activity who is starting us is running as a single 1439 // instance... this new activity it is starting must go on its 1440 // own task. 1441 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1442 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1443 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1444 // The activity being started is a single instance... it always 1445 // gets launched into its own task. 1446 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1447 } 1448 1449 ActivityInfo newTaskInfo = null; 1450 Intent newTaskIntent = null; 1451 final ActivityStack sourceStack; 1452 if (sourceRecord != null) { 1453 if (sourceRecord.finishing) { 1454 // If the source is finishing, we can't further count it as our source. This 1455 // is because the task it is associated with may now be empty and on its way out, 1456 // so we don't want to blindly throw it in to that task. Instead we will take 1457 // the NEW_TASK flow and try to find a task for it. But save the task information 1458 // so it can be used when creating the new task. 1459 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1460 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1461 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1462 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1463 newTaskInfo = sourceRecord.info; 1464 newTaskIntent = sourceRecord.task.intent; 1465 } 1466 sourceRecord = null; 1467 sourceStack = null; 1468 } else { 1469 sourceStack = sourceRecord.task.stack; 1470 } 1471 } else { 1472 sourceStack = null; 1473 } 1474 1475 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1476 // For whatever reason this activity is being launched into a new 1477 // task... yet the caller has requested a result back. Well, that 1478 // is pretty messed up, so instead immediately send back a cancel 1479 // and let the new task continue launched as normal without a 1480 // dependency on its originator. 1481 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1482 r.resultTo.task.stack.sendActivityResultLocked(-1, 1483 r.resultTo, r.resultWho, r.requestCode, 1484 Activity.RESULT_CANCELED, null); 1485 r.resultTo = null; 1486 } 1487 1488 boolean addingToTask = false; 1489 boolean movedHome = false; 1490 TaskRecord reuseTask = null; 1491 ActivityStack targetStack; 1492 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1493 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1494 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1495 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1496 // If bring to front is requested, and no result is requested, and 1497 // we can find a task that was started with this same 1498 // component, then instead of launching bring that one to the front. 1499 if (r.resultTo == null) { 1500 // See if there is a task to bring to the front. If this is 1501 // a SINGLE_INSTANCE activity, there can be one and only one 1502 // instance of it in the history, and it is always in its own 1503 // unique task, so we do a special search. 1504 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1505 ? findTaskLocked(r) 1506 : findActivityLocked(intent, r.info); 1507 if (intentActivity != null) { 1508 if (r.task == null) { 1509 r.task = intentActivity.task; 1510 } 1511 targetStack = intentActivity.task.stack; 1512 targetStack.mLastPausedActivity = null; 1513 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1514 + " from " + intentActivity); 1515 targetStack.moveToFront(); 1516 if (intentActivity.task.intent == null) { 1517 // This task was started because of movement of 1518 // the activity based on affinity... now that we 1519 // are actually launching it, we can assign the 1520 // base intent. 1521 intentActivity.task.setIntent(intent, r.info); 1522 } 1523 // If the target task is not in the front, then we need 1524 // to bring it to the front... except... well, with 1525 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1526 // to have the same behavior as if a new instance was 1527 // being started, which means not bringing it to the front 1528 // if the caller is not itself in the front. 1529 final ActivityStack lastStack = getLastStack(); 1530 ActivityRecord curTop = lastStack == null? 1531 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1532 if (curTop != null && (curTop.task != intentActivity.task || 1533 curTop.task != lastStack.topTask())) { 1534 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1535 if (sourceRecord == null || (sourceStack.topActivity() != null && 1536 sourceStack.topActivity().task == sourceRecord.task)) { 1537 // We really do want to push this one into the 1538 // user's face, right now. 1539 movedHome = true; 1540 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1541 if ((launchFlags & 1542 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1543 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1544 // Caller wants to appear on home activity. 1545 intentActivity.task.mOnTopOfHome = true; 1546 } 1547 options = null; 1548 } 1549 } 1550 // If the caller has requested that the target task be 1551 // reset, then do so. 1552 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1553 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1554 } 1555 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1556 // We don't need to start a new activity, and 1557 // the client said not to do anything if that 1558 // is the case, so this is it! And for paranoia, make 1559 // sure we have correctly resumed the top activity. 1560 if (doResume) { 1561 resumeTopActivitiesLocked(targetStack, null, options); 1562 } else { 1563 ActivityOptions.abort(options); 1564 } 1565 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1566 } 1567 if ((launchFlags & 1568 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1569 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1570 // The caller has requested to completely replace any 1571 // existing task with its new activity. Well that should 1572 // not be too hard... 1573 reuseTask = intentActivity.task; 1574 reuseTask.performClearTaskLocked(); 1575 reuseTask.setIntent(r.intent, r.info); 1576 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1577 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1578 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1579 // In this situation we want to remove all activities 1580 // from the task up to the one being started. In most 1581 // cases this means we are resetting the task to its 1582 // initial state. 1583 ActivityRecord top = 1584 intentActivity.task.performClearTaskLocked(r, launchFlags); 1585 if (top != null) { 1586 if (top.frontOfTask) { 1587 // Activity aliases may mean we use different 1588 // intents for the top activity, so make sure 1589 // the task now has the identity of the new 1590 // intent. 1591 top.task.setIntent(r.intent, r.info); 1592 } 1593 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1594 r, top.task); 1595 top.deliverNewIntentLocked(callingUid, r.intent); 1596 } else { 1597 // A special case: we need to 1598 // start the activity because it is not currently 1599 // running, and the caller has asked to clear the 1600 // current task to have this activity at the top. 1601 addingToTask = true; 1602 // Now pretend like this activity is being started 1603 // by the top of its task, so it is put in the 1604 // right place. 1605 sourceRecord = intentActivity; 1606 } 1607 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1608 // In this case the top activity on the task is the 1609 // same as the one being launched, so we take that 1610 // as a request to bring the task to the foreground. 1611 // If the top activity in the task is the root 1612 // activity, deliver this new intent to it if it 1613 // desires. 1614 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1615 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1616 && intentActivity.realActivity.equals(r.realActivity)) { 1617 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1618 intentActivity.task); 1619 if (intentActivity.frontOfTask) { 1620 intentActivity.task.setIntent(r.intent, r.info); 1621 } 1622 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1623 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1624 // In this case we are launching the root activity 1625 // of the task, but with a different intent. We 1626 // should start a new instance on top. 1627 addingToTask = true; 1628 sourceRecord = intentActivity; 1629 } 1630 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1631 // In this case an activity is being launched in to an 1632 // existing task, without resetting that task. This 1633 // is typically the situation of launching an activity 1634 // from a notification or shortcut. We want to place 1635 // the new activity on top of the current task. 1636 addingToTask = true; 1637 sourceRecord = intentActivity; 1638 } else if (!intentActivity.task.rootWasReset) { 1639 // In this case we are launching in to an existing task 1640 // that has not yet been started from its front door. 1641 // The current task has been brought to the front. 1642 // Ideally, we'd probably like to place this new task 1643 // at the bottom of its stack, but that's a little hard 1644 // to do with the current organization of the code so 1645 // for now we'll just drop it. 1646 intentActivity.task.setIntent(r.intent, r.info); 1647 } 1648 if (!addingToTask && reuseTask == null) { 1649 // We didn't do anything... but it was needed (a.k.a., client 1650 // don't use that intent!) And for paranoia, make 1651 // sure we have correctly resumed the top activity. 1652 if (doResume) { 1653 targetStack.resumeTopActivityLocked(null, options); 1654 } else { 1655 ActivityOptions.abort(options); 1656 } 1657 return ActivityManager.START_TASK_TO_FRONT; 1658 } 1659 } 1660 } 1661 } 1662 1663 //String uri = r.intent.toURI(); 1664 //Intent intent2 = new Intent(uri); 1665 //Slog.i(TAG, "Given intent: " + r.intent); 1666 //Slog.i(TAG, "URI is: " + uri); 1667 //Slog.i(TAG, "To intent: " + intent2); 1668 1669 if (r.packageName != null) { 1670 // If the activity being launched is the same as the one currently 1671 // at the top, then we need to check if it should only be launched 1672 // once. 1673 ActivityStack topStack = getFocusedStack(); 1674 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1675 if (top != null && r.resultTo == null) { 1676 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1677 if (top.app != null && top.app.thread != null) { 1678 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1679 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1680 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1681 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1682 top.task); 1683 // For paranoia, make sure we have correctly 1684 // resumed the top activity. 1685 topStack.mLastPausedActivity = null; 1686 if (doResume) { 1687 resumeTopActivitiesLocked(); 1688 } 1689 ActivityOptions.abort(options); 1690 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1691 // We don't need to start a new activity, and 1692 // the client said not to do anything if that 1693 // is the case, so this is it! 1694 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1695 } 1696 top.deliverNewIntentLocked(callingUid, r.intent); 1697 return ActivityManager.START_DELIVERED_TO_TOP; 1698 } 1699 } 1700 } 1701 } 1702 1703 } else { 1704 if (r.resultTo != null) { 1705 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1706 r.requestCode, Activity.RESULT_CANCELED, null); 1707 } 1708 ActivityOptions.abort(options); 1709 return ActivityManager.START_CLASS_NOT_FOUND; 1710 } 1711 1712 boolean newTask = false; 1713 boolean keepCurTransition = false; 1714 1715 // Should this be considered a new task? 1716 if (r.resultTo == null && !addingToTask 1717 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1718 targetStack = adjustStackFocus(r); 1719 targetStack.moveToFront(); 1720 if (reuseTask == null) { 1721 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1722 newTaskInfo != null ? newTaskInfo : r.info, 1723 newTaskIntent != null ? newTaskIntent : intent, 1724 true), null, true); 1725 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1726 r.task); 1727 } else { 1728 r.setTask(reuseTask, reuseTask, true); 1729 } 1730 newTask = true; 1731 if (!movedHome) { 1732 if ((launchFlags & 1733 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1734 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1735 // Caller wants to appear on home activity, so before starting 1736 // their own activity we will bring home to the front. 1737 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); 1738 } 1739 } 1740 } else if (sourceRecord != null) { 1741 TaskRecord sourceTask = sourceRecord.task; 1742 targetStack = sourceTask.stack; 1743 targetStack.moveToFront(); 1744 if (!addingToTask && 1745 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1746 // In this case, we are adding the activity to an existing 1747 // task, but the caller has asked to clear that task if the 1748 // activity is already running. 1749 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1750 keepCurTransition = true; 1751 if (top != null) { 1752 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1753 top.deliverNewIntentLocked(callingUid, r.intent); 1754 // For paranoia, make sure we have correctly 1755 // resumed the top activity. 1756 targetStack.mLastPausedActivity = null; 1757 if (doResume) { 1758 targetStack.resumeTopActivityLocked(null); 1759 } 1760 ActivityOptions.abort(options); 1761 return ActivityManager.START_DELIVERED_TO_TOP; 1762 } 1763 } else if (!addingToTask && 1764 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1765 // In this case, we are launching an activity in our own task 1766 // that may already be running somewhere in the history, and 1767 // we want to shuffle it to the front of the stack if so. 1768 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1769 if (top != null) { 1770 final TaskRecord task = top.task; 1771 task.moveActivityToFrontLocked(top); 1772 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1773 top.updateOptionsLocked(options); 1774 top.deliverNewIntentLocked(callingUid, r.intent); 1775 targetStack.mLastPausedActivity = null; 1776 if (doResume) { 1777 targetStack.resumeTopActivityLocked(null); 1778 } 1779 return ActivityManager.START_DELIVERED_TO_TOP; 1780 } 1781 } 1782 // An existing activity is starting this new activity, so we want 1783 // to keep the new one in the same task as the one that is starting 1784 // it. 1785 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1786 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1787 + " in existing task " + r.task + " from source " + sourceRecord); 1788 1789 } else { 1790 // This not being started from an existing activity, and not part 1791 // of a new task... just put it in the top task, though these days 1792 // this case should never happen. 1793 targetStack = adjustStackFocus(r); 1794 targetStack.moveToFront(); 1795 ActivityRecord prev = targetStack.topActivity(); 1796 r.setTask(prev != null ? prev.task 1797 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1798 null, true); 1799 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1800 + " in new guessed " + r.task); 1801 } 1802 1803 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1804 intent, r.getUriPermissionsLocked()); 1805 1806 if (newTask) { 1807 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1808 } 1809 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1810 targetStack.mLastPausedActivity = null; 1811 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1812 mService.setFocusedActivityLocked(r); 1813 return ActivityManager.START_SUCCESS; 1814 } 1815 1816 void acquireLaunchWakelock() { 1817 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1818 throw new IllegalStateException("Calling must be system uid"); 1819 } 1820 mLaunchingActivity.acquire(); 1821 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1822 // To be safe, don't allow the wake lock to be held for too long. 1823 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1824 } 1825 } 1826 1827 // Checked. 1828 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1829 Configuration config) { 1830 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1831 1832 ArrayList<ActivityRecord> stops = null; 1833 ArrayList<ActivityRecord> finishes = null; 1834 ArrayList<UserStartedState> startingUsers = null; 1835 int NS = 0; 1836 int NF = 0; 1837 IApplicationThread sendThumbnail = null; 1838 boolean booting = false; 1839 boolean enableScreen = false; 1840 boolean activityRemoved = false; 1841 1842 ActivityRecord r = ActivityRecord.forToken(token); 1843 if (r != null) { 1844 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1845 Debug.getCallers(4)); 1846 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1847 r.finishLaunchTickingLocked(); 1848 if (fromTimeout) { 1849 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1850 } 1851 1852 // This is a hack to semi-deal with a race condition 1853 // in the client where it can be constructed with a 1854 // newer configuration from when we asked it to launch. 1855 // We'll update with whatever configuration it now says 1856 // it used to launch. 1857 if (config != null) { 1858 r.configuration = config; 1859 } 1860 1861 // We are now idle. If someone is waiting for a thumbnail from 1862 // us, we can now deliver. 1863 r.idle = true; 1864 1865 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 1866 sendThumbnail = r.app.thread; 1867 r.thumbnailNeeded = false; 1868 } 1869 1870 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1871 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1872 mService.mBooted = true; 1873 enableScreen = true; 1874 } 1875 } 1876 1877 if (allResumedActivitiesIdle()) { 1878 if (r != null) { 1879 mService.scheduleAppGcsLocked(); 1880 } 1881 1882 if (mLaunchingActivity.isHeld()) { 1883 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1884 if (VALIDATE_WAKE_LOCK_CALLER && 1885 Binder.getCallingUid() != Process.myUid()) { 1886 throw new IllegalStateException("Calling must be system uid"); 1887 } 1888 mLaunchingActivity.release(); 1889 } 1890 ensureActivitiesVisibleLocked(null, 0); 1891 } 1892 1893 // Atomically retrieve all of the other things to do. 1894 stops = processStoppingActivitiesLocked(true); 1895 NS = stops != null ? stops.size() : 0; 1896 if ((NF=mFinishingActivities.size()) > 0) { 1897 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1898 mFinishingActivities.clear(); 1899 } 1900 1901 final ArrayList<ActivityRecord> thumbnails; 1902 final int NT = mCancelledThumbnails.size(); 1903 if (NT > 0) { 1904 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 1905 mCancelledThumbnails.clear(); 1906 } else { 1907 thumbnails = null; 1908 } 1909 1910 if (isFrontStack(mHomeStack)) { 1911 booting = mService.mBooting; 1912 mService.mBooting = false; 1913 } 1914 1915 if (mStartingUsers.size() > 0) { 1916 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1917 mStartingUsers.clear(); 1918 } 1919 1920 // Perform the following actions from unsynchronized state. 1921 final IApplicationThread thumbnailThread = sendThumbnail; 1922 mHandler.post(new Runnable() { 1923 @Override 1924 public void run() { 1925 if (thumbnailThread != null) { 1926 try { 1927 thumbnailThread.requestThumbnail(token); 1928 } catch (Exception e) { 1929 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1930 mService.sendPendingThumbnail(null, token, null, null, true); 1931 } 1932 } 1933 1934 // Report back to any thumbnail receivers. 1935 for (int i = 0; i < NT; i++) { 1936 ActivityRecord r = thumbnails.get(i); 1937 mService.sendPendingThumbnail(r, null, null, null, true); 1938 } 1939 } 1940 }); 1941 1942 // Stop any activities that are scheduled to do so but have been 1943 // waiting for the next one to start. 1944 for (int i = 0; i < NS; i++) { 1945 r = stops.get(i); 1946 final ActivityStack stack = r.task.stack; 1947 if (r.finishing) { 1948 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1949 } else { 1950 stack.stopActivityLocked(r); 1951 } 1952 } 1953 1954 // Finish any activities that are scheduled to do so but have been 1955 // waiting for the next one to start. 1956 for (int i = 0; i < NF; i++) { 1957 r = finishes.get(i); 1958 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1959 } 1960 1961 if (booting) { 1962 mService.finishBooting(); 1963 } else if (startingUsers != null) { 1964 for (int i = 0; i < startingUsers.size(); i++) { 1965 mService.finishUserSwitch(startingUsers.get(i)); 1966 } 1967 } 1968 1969 mService.trimApplications(); 1970 //dump(); 1971 //mWindowManager.dump(); 1972 1973 if (enableScreen) { 1974 mService.enableScreenAfterBoot(); 1975 } 1976 1977 if (activityRemoved) { 1978 resumeTopActivitiesLocked(); 1979 } 1980 1981 return r; 1982 } 1983 1984 boolean handleAppDiedLocked(ProcessRecord app) { 1985 boolean hasVisibleActivities = false; 1986 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1987 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1988 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1989 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 1990 } 1991 } 1992 return hasVisibleActivities; 1993 } 1994 1995 void closeSystemDialogsLocked() { 1996 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1997 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1998 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1999 stacks.get(stackNdx).closeSystemDialogsLocked(); 2000 } 2001 } 2002 } 2003 2004 void removeUserLocked(int userId) { 2005 mUserStackInFront.delete(userId); 2006 } 2007 2008 /** 2009 * @return true if some activity was finished (or would have finished if doit were true). 2010 */ 2011 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2012 boolean didSomething = false; 2013 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2014 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2015 final int numStacks = stacks.size(); 2016 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2017 final ActivityStack stack = stacks.get(stackNdx); 2018 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2019 didSomething = true; 2020 } 2021 } 2022 } 2023 return didSomething; 2024 } 2025 2026 void updatePreviousProcessLocked(ActivityRecord r) { 2027 // Now that this process has stopped, we may want to consider 2028 // it to be the previous app to try to keep around in case 2029 // the user wants to return to it. 2030 2031 // First, found out what is currently the foreground app, so that 2032 // we don't blow away the previous app if this activity is being 2033 // hosted by the process that is actually still the foreground. 2034 ProcessRecord fgApp = null; 2035 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2036 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2037 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2038 final ActivityStack stack = stacks.get(stackNdx); 2039 if (isFrontStack(stack)) { 2040 if (stack.mResumedActivity != null) { 2041 fgApp = stack.mResumedActivity.app; 2042 } else if (stack.mPausingActivity != null) { 2043 fgApp = stack.mPausingActivity.app; 2044 } 2045 break; 2046 } 2047 } 2048 } 2049 2050 // Now set this one as the previous process, only if that really 2051 // makes sense to. 2052 if (r.app != null && fgApp != null && r.app != fgApp 2053 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2054 && r.app != mService.mHomeProcess) { 2055 mService.mPreviousProcess = r.app; 2056 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2057 } 2058 } 2059 2060 boolean resumeTopActivitiesLocked() { 2061 return resumeTopActivitiesLocked(null, null, null); 2062 } 2063 2064 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2065 Bundle targetOptions) { 2066 if (targetStack == null) { 2067 targetStack = getFocusedStack(); 2068 } 2069 // Do targetStack first. 2070 boolean result = false; 2071 if (isFrontStack(targetStack)) { 2072 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2073 } 2074 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2075 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2076 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2077 final ActivityStack stack = stacks.get(stackNdx); 2078 if (stack == targetStack) { 2079 // Already started above. 2080 continue; 2081 } 2082 if (isFrontStack(stack)) { 2083 stack.resumeTopActivityLocked(null); 2084 } 2085 } 2086 } 2087 return result; 2088 } 2089 2090 void finishTopRunningActivityLocked(ProcessRecord app) { 2091 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2092 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2093 final int numStacks = stacks.size(); 2094 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2095 final ActivityStack stack = stacks.get(stackNdx); 2096 stack.finishTopRunningActivityLocked(app); 2097 } 2098 } 2099 } 2100 2101 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 2102 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2103 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2104 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2105 if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 2106 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2107 + stacks.get(stackNdx)); 2108 return; 2109 } 2110 } 2111 } 2112 } 2113 2114 ActivityStack getStack(int stackId) { 2115 WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId); 2116 if (weakReference != null) { 2117 ActivityContainer activityContainer = weakReference.get(); 2118 if (activityContainer != null) { 2119 return activityContainer.mStack; 2120 } else { 2121 mActivityContainers.remove(stackId); 2122 } 2123 } 2124 return null; 2125 } 2126 2127 ArrayList<ActivityStack> getStacks() { 2128 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2129 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2130 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2131 } 2132 return allStacks; 2133 } 2134 2135 IBinder getHomeActivityToken() { 2136 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2137 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2138 final TaskRecord task = tasks.get(taskNdx); 2139 if (task.isHomeTask()) { 2140 final ArrayList<ActivityRecord> activities = task.mActivities; 2141 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2142 final ActivityRecord r = activities.get(activityNdx); 2143 if (r.isHomeActivity()) { 2144 return r.appToken; 2145 } 2146 } 2147 } 2148 } 2149 return null; 2150 } 2151 2152 ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId, 2153 IActivityContainerCallback callback) { 2154 ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId, 2155 callback); 2156 mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer)); 2157 if (parentActivity != null) { 2158 parentActivity.mChildContainers.add(activityContainer.mStack); 2159 } 2160 return activityContainer; 2161 } 2162 2163 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2164 IActivityContainerCallback callback) { 2165 return createActivityContainer(parentActivity, getNextStackId(), callback); 2166 } 2167 2168 void removeChildActivityContainers(ActivityRecord parentActivity) { 2169 for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) { 2170 final ActivityContainer container = mActivityContainers.valueAt(ndx).get(); 2171 if (container == null) { 2172 mActivityContainers.removeAt(ndx); 2173 continue; 2174 } 2175 if (container.mParentActivity != parentActivity) { 2176 continue; 2177 } 2178 2179 ActivityStack stack = container.mStack; 2180 ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null); 2181 if (top != null) { 2182 // TODO: Make sure the next activity doesn't start up when top is destroyed. 2183 stack.destroyActivityLocked(top, true, true, "stack removal"); 2184 } 2185 mActivityContainers.removeAt(ndx); 2186 container.detachLocked(); 2187 } 2188 } 2189 2190 private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) { 2191 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2192 if (activityDisplay == null) { 2193 return -1; 2194 } 2195 2196 ActivityContainer activityContainer = 2197 createActivityContainer(parentActivity, stackId, null); 2198 activityContainer.attachToDisplayLocked(activityDisplay); 2199 return stackId; 2200 } 2201 2202 int getNextStackId() { 2203 while (true) { 2204 if (++mLastStackId <= HOME_STACK_ID) { 2205 mLastStackId = HOME_STACK_ID + 1; 2206 } 2207 if (getStack(mLastStackId) == null) { 2208 break; 2209 } 2210 } 2211 return mLastStackId; 2212 } 2213 2214 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2215 final TaskRecord task = anyTaskForIdLocked(taskId); 2216 if (task == null) { 2217 return; 2218 } 2219 final ActivityStack stack = getStack(stackId); 2220 if (stack == null) { 2221 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2222 return; 2223 } 2224 task.stack.removeTask(task); 2225 stack.addTask(task, toTop); 2226 mWindowManager.addTask(taskId, stackId, toTop); 2227 resumeTopActivitiesLocked(); 2228 } 2229 2230 ActivityRecord findTaskLocked(ActivityRecord r) { 2231 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2232 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2233 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2234 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2235 final ActivityStack stack = stacks.get(stackNdx); 2236 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2237 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); 2238 continue; 2239 } 2240 final ActivityRecord ar = stack.findTaskLocked(r); 2241 if (ar != null) { 2242 return ar; 2243 } 2244 } 2245 } 2246 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2247 return null; 2248 } 2249 2250 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2251 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2252 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2253 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2254 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2255 if (ar != null) { 2256 return ar; 2257 } 2258 } 2259 } 2260 return null; 2261 } 2262 2263 void goingToSleepLocked() { 2264 scheduleSleepTimeout(); 2265 if (!mGoingToSleep.isHeld()) { 2266 mGoingToSleep.acquire(); 2267 if (mLaunchingActivity.isHeld()) { 2268 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2269 throw new IllegalStateException("Calling must be system uid"); 2270 } 2271 mLaunchingActivity.release(); 2272 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2273 } 2274 } 2275 checkReadyForSleepLocked(); 2276 } 2277 2278 boolean shutdownLocked(int timeout) { 2279 boolean timedout = false; 2280 goingToSleepLocked(); 2281 2282 final long endTime = System.currentTimeMillis() + timeout; 2283 while (true) { 2284 boolean cantShutdown = false; 2285 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2286 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2287 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2288 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2289 } 2290 } 2291 if (cantShutdown) { 2292 long timeRemaining = endTime - System.currentTimeMillis(); 2293 if (timeRemaining > 0) { 2294 try { 2295 mService.wait(timeRemaining); 2296 } catch (InterruptedException e) { 2297 } 2298 } else { 2299 Slog.w(TAG, "Activity manager shutdown timed out"); 2300 timedout = true; 2301 break; 2302 } 2303 } else { 2304 break; 2305 } 2306 } 2307 2308 // Force checkReadyForSleep to complete. 2309 mSleepTimeout = true; 2310 checkReadyForSleepLocked(); 2311 2312 return timedout; 2313 } 2314 2315 void comeOutOfSleepIfNeededLocked() { 2316 removeSleepTimeouts(); 2317 if (mGoingToSleep.isHeld()) { 2318 mGoingToSleep.release(); 2319 } 2320 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2321 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2322 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2323 final ActivityStack stack = stacks.get(stackNdx); 2324 stack.awakeFromSleepingLocked(); 2325 if (isFrontStack(stack)) { 2326 resumeTopActivitiesLocked(); 2327 } 2328 } 2329 } 2330 mGoingToSleepActivities.clear(); 2331 } 2332 2333 void activitySleptLocked(ActivityRecord r) { 2334 mGoingToSleepActivities.remove(r); 2335 checkReadyForSleepLocked(); 2336 } 2337 2338 void checkReadyForSleepLocked() { 2339 if (!mService.isSleepingOrShuttingDown()) { 2340 // Do not care. 2341 return; 2342 } 2343 2344 if (!mSleepTimeout) { 2345 boolean dontSleep = false; 2346 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2347 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2348 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2349 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2350 } 2351 } 2352 2353 if (mStoppingActivities.size() > 0) { 2354 // Still need to tell some activities to stop; can't sleep yet. 2355 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2356 + mStoppingActivities.size() + " activities"); 2357 scheduleIdleLocked(); 2358 dontSleep = true; 2359 } 2360 2361 if (mGoingToSleepActivities.size() > 0) { 2362 // Still need to tell some activities to sleep; can't sleep yet. 2363 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2364 + mGoingToSleepActivities.size() + " activities"); 2365 dontSleep = true; 2366 } 2367 2368 if (dontSleep) { 2369 return; 2370 } 2371 } 2372 2373 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2374 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2375 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2376 stacks.get(stackNdx).goToSleep(); 2377 } 2378 } 2379 2380 removeSleepTimeouts(); 2381 2382 if (mGoingToSleep.isHeld()) { 2383 mGoingToSleep.release(); 2384 } 2385 if (mService.mShuttingDown) { 2386 mService.notifyAll(); 2387 } 2388 } 2389 2390 boolean reportResumedActivityLocked(ActivityRecord r) { 2391 final ActivityStack stack = r.task.stack; 2392 if (isFrontStack(stack)) { 2393 mService.updateUsageStats(r, true); 2394 } 2395 if (allResumedActivitiesComplete()) { 2396 ensureActivitiesVisibleLocked(null, 0); 2397 mWindowManager.executeAppTransition(); 2398 return true; 2399 } 2400 return false; 2401 } 2402 2403 void handleAppCrashLocked(ProcessRecord app) { 2404 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2405 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2406 final int numStacks = stacks.size(); 2407 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2408 final ActivityStack stack = stacks.get(stackNdx); 2409 stack.handleAppCrashLocked(app); 2410 } 2411 } 2412 } 2413 2414 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2415 // First the front stacks. In case any are not fullscreen and are in front of home. 2416 boolean showHomeBehindStack = false; 2417 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2418 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2419 final int topStackNdx = stacks.size() - 1; 2420 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2421 final ActivityStack stack = stacks.get(stackNdx); 2422 if (stackNdx == topStackNdx) { 2423 // Top stack. 2424 showHomeBehindStack = 2425 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2426 } else { 2427 // Back stack. 2428 stack.ensureActivitiesVisibleLocked(starting, configChanges, 2429 showHomeBehindStack); 2430 } 2431 } 2432 } 2433 } 2434 2435 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2436 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2437 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2438 final int numStacks = stacks.size(); 2439 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2440 final ActivityStack stack = stacks.get(stackNdx); 2441 stack.scheduleDestroyActivities(app, false, reason); 2442 } 2443 } 2444 } 2445 2446 boolean switchUserLocked(int userId, UserStartedState uss) { 2447 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2448 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2449 mCurrentUser = userId; 2450 2451 mStartingUsers.add(uss); 2452 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2453 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2454 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2455 final ActivityStack stack = stacks.get(stackNdx); 2456 stack.switchUserLocked(userId); 2457 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2458 } 2459 } 2460 2461 ActivityStack stack = getStack(restoreStackId); 2462 if (stack == null) { 2463 stack = mHomeStack; 2464 } 2465 final boolean homeInFront = stack.isHomeStack(); 2466 if (stack.isOnHomeDisplay()) { 2467 moveHomeStack(homeInFront); 2468 mWindowManager.moveTaskToTop(stack.topTask().taskId); 2469 } else { 2470 // Stack was moved to another display while user was swapped out. 2471 resumeHomeActivity(null); 2472 } 2473 return homeInFront; 2474 } 2475 2476 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2477 int N = mStoppingActivities.size(); 2478 if (N <= 0) return null; 2479 2480 ArrayList<ActivityRecord> stops = null; 2481 2482 final boolean nowVisible = allResumedActivitiesVisible(); 2483 for (int i=0; i<N; i++) { 2484 ActivityRecord s = mStoppingActivities.get(i); 2485 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2486 + nowVisible + " waitingVisible=" + s.waitingVisible 2487 + " finishing=" + s.finishing); 2488 if (s.waitingVisible && nowVisible) { 2489 mWaitingVisibleActivities.remove(s); 2490 s.waitingVisible = false; 2491 if (s.finishing) { 2492 // If this activity is finishing, it is sitting on top of 2493 // everyone else but we now know it is no longer needed... 2494 // so get rid of it. Otherwise, we need to go through the 2495 // normal flow and hide it once we determine that it is 2496 // hidden by the activities in front of it. 2497 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2498 mWindowManager.setAppVisibility(s.appToken, false); 2499 } 2500 } 2501 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2502 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2503 if (stops == null) { 2504 stops = new ArrayList<ActivityRecord>(); 2505 } 2506 stops.add(s); 2507 mStoppingActivities.remove(i); 2508 N--; 2509 i--; 2510 } 2511 } 2512 2513 return stops; 2514 } 2515 2516 void validateTopActivitiesLocked() { 2517 // FIXME 2518/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2519 final ActivityStack stack = stacks.get(stackNdx); 2520 final ActivityRecord r = stack.topRunningActivityLocked(null); 2521 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2522 if (isFrontStack(stack)) { 2523 if (r == null) { 2524 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2525 } else { 2526 final ActivityRecord pausing = stack.mPausingActivity; 2527 if (pausing != null && pausing == r) { 2528 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2529 " state=" + state); 2530 } 2531 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2532 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2533 " state=" + state); 2534 } 2535 } 2536 } else { 2537 final ActivityRecord resumed = stack.mResumedActivity; 2538 if (resumed != null && resumed == r) { 2539 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2540 " state=" + state); 2541 } 2542 if (r != null && (state == ActivityState.INITIALIZING 2543 || state == ActivityState.RESUMED)) { 2544 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2545 " state=" + state); 2546 } 2547 } 2548 } 2549*/ 2550 } 2551 2552 public void dump(PrintWriter pw, String prefix) { 2553 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2554 pw.println(mDismissKeyguardOnNextActivity); 2555 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2556 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2557 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2558 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2559 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2560 } 2561 2562 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2563 return getFocusedStack().getDumpActivitiesLocked(name); 2564 } 2565 2566 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2567 boolean needSep, String prefix) { 2568 if (activity != null) { 2569 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2570 if (needSep) { 2571 pw.println(); 2572 } 2573 pw.print(prefix); 2574 pw.println(activity); 2575 return true; 2576 } 2577 } 2578 return false; 2579 } 2580 2581 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2582 boolean dumpClient, String dumpPackage) { 2583 boolean printed = false; 2584 boolean needSep = false; 2585 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2586 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2587 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2588 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2589 final int numStacks = stacks.size(); 2590 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2591 final ActivityStack stack = stacks.get(stackNdx); 2592 StringBuilder stackHeader = new StringBuilder(128); 2593 stackHeader.append(" Stack #"); 2594 stackHeader.append(stack.mStackId); 2595 stackHeader.append(":"); 2596 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2597 needSep, stackHeader.toString()); 2598 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2599 !dumpAll, false, dumpPackage, true, 2600 " Running activities (most recent first):", null); 2601 2602 needSep = printed; 2603 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2604 " mPausingActivity: "); 2605 if (pr) { 2606 printed = true; 2607 needSep = false; 2608 } 2609 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2610 " mResumedActivity: "); 2611 if (pr) { 2612 printed = true; 2613 needSep = false; 2614 } 2615 if (dumpAll) { 2616 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2617 " mLastPausedActivity: "); 2618 if (pr) { 2619 printed = true; 2620 needSep = true; 2621 } 2622 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2623 needSep, " mLastNoHistoryActivity: "); 2624 } 2625 needSep = printed; 2626 } 2627 } 2628 2629 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2630 false, dumpPackage, true, " Activities waiting to finish:", null); 2631 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2632 false, dumpPackage, true, " Activities waiting to stop:", null); 2633 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2634 false, dumpPackage, true, " Activities waiting for another to become visible:", 2635 null); 2636 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2637 false, dumpPackage, true, " Activities waiting to sleep:", null); 2638 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2639 false, dumpPackage, true, " Activities waiting to sleep:", null); 2640 2641 return printed; 2642 } 2643 2644 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2645 String prefix, String label, boolean complete, boolean brief, boolean client, 2646 String dumpPackage, boolean needNL, String header1, String header2) { 2647 TaskRecord lastTask = null; 2648 String innerPrefix = null; 2649 String[] args = null; 2650 boolean printed = false; 2651 for (int i=list.size()-1; i>=0; i--) { 2652 final ActivityRecord r = list.get(i); 2653 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2654 continue; 2655 } 2656 if (innerPrefix == null) { 2657 innerPrefix = prefix + " "; 2658 args = new String[0]; 2659 } 2660 printed = true; 2661 final boolean full = !brief && (complete || !r.isInHistory()); 2662 if (needNL) { 2663 pw.println(""); 2664 needNL = false; 2665 } 2666 if (header1 != null) { 2667 pw.println(header1); 2668 header1 = null; 2669 } 2670 if (header2 != null) { 2671 pw.println(header2); 2672 header2 = null; 2673 } 2674 if (lastTask != r.task) { 2675 lastTask = r.task; 2676 pw.print(prefix); 2677 pw.print(full ? "* " : " "); 2678 pw.println(lastTask); 2679 if (full) { 2680 lastTask.dump(pw, prefix + " "); 2681 } else if (complete) { 2682 // Complete + brief == give a summary. Isn't that obvious?!? 2683 if (lastTask.intent != null) { 2684 pw.print(prefix); pw.print(" "); 2685 pw.println(lastTask.intent.toInsecureStringWithClip()); 2686 } 2687 } 2688 } 2689 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2690 pw.print(" #"); pw.print(i); pw.print(": "); 2691 pw.println(r); 2692 if (full) { 2693 r.dump(pw, innerPrefix); 2694 } else if (complete) { 2695 // Complete + brief == give a summary. Isn't that obvious?!? 2696 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2697 if (r.app != null) { 2698 pw.print(innerPrefix); pw.println(r.app); 2699 } 2700 } 2701 if (client && r.app != null && r.app.thread != null) { 2702 // flush anything that is already in the PrintWriter since the thread is going 2703 // to write to the file descriptor directly 2704 pw.flush(); 2705 try { 2706 TransferPipe tp = new TransferPipe(); 2707 try { 2708 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2709 r.appToken, innerPrefix, args); 2710 // Short timeout, since blocking here can 2711 // deadlock with the application. 2712 tp.go(fd, 2000); 2713 } finally { 2714 tp.kill(); 2715 } 2716 } catch (IOException e) { 2717 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2718 } catch (RemoteException e) { 2719 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2720 } 2721 needNL = true; 2722 } 2723 } 2724 return printed; 2725 } 2726 2727 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2728 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2729 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2730 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2731 } 2732 2733 final void scheduleIdleLocked() { 2734 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2735 } 2736 2737 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2738 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2739 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2740 } 2741 2742 final void scheduleResumeTopActivities() { 2743 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2744 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2745 } 2746 } 2747 2748 void removeSleepTimeouts() { 2749 mSleepTimeout = false; 2750 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2751 } 2752 2753 final void scheduleSleepTimeout() { 2754 removeSleepTimeouts(); 2755 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2756 } 2757 2758 @Override 2759 public void onDisplayAdded(int displayId) { 2760 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2761 } 2762 2763 @Override 2764 public void onDisplayRemoved(int displayId) { 2765 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2766 } 2767 2768 @Override 2769 public void onDisplayChanged(int displayId) { 2770 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2771 } 2772 2773 public void handleDisplayAddedLocked(int displayId) { 2774 boolean newDisplay; 2775 synchronized (mService) { 2776 newDisplay = mActivityDisplays.get(displayId) == null; 2777 if (newDisplay) { 2778 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2779 mActivityDisplays.put(displayId, activityDisplay); 2780 } 2781 } 2782 if (newDisplay) { 2783 mWindowManager.onDisplayAdded(displayId); 2784 } 2785 } 2786 2787 public void handleDisplayRemovedLocked(int displayId) { 2788 synchronized (mService) { 2789 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2790 if (activityDisplay != null) { 2791 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2792 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2793 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2794 } 2795 mActivityDisplays.remove(displayId); 2796 } 2797 } 2798 mWindowManager.onDisplayRemoved(displayId); 2799 } 2800 2801 public void handleDisplayChangedLocked(int displayId) { 2802 synchronized (mService) { 2803 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2804 if (activityDisplay != null) { 2805 // TODO: Update the bounds. 2806 } 2807 } 2808 mWindowManager.onDisplayChanged(displayId); 2809 } 2810 2811 StackInfo getStackInfo(ActivityStack stack) { 2812 StackInfo info = new StackInfo(); 2813 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2814 info.displayId = Display.DEFAULT_DISPLAY; 2815 info.stackId = stack.mStackId; 2816 2817 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2818 final int numTasks = tasks.size(); 2819 int[] taskIds = new int[numTasks]; 2820 String[] taskNames = new String[numTasks]; 2821 for (int i = 0; i < numTasks; ++i) { 2822 final TaskRecord task = tasks.get(i); 2823 taskIds[i] = task.taskId; 2824 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2825 : task.realActivity != null ? task.realActivity.flattenToString() 2826 : task.getTopActivity() != null ? task.getTopActivity().packageName 2827 : "unknown"; 2828 } 2829 info.taskIds = taskIds; 2830 info.taskNames = taskNames; 2831 return info; 2832 } 2833 2834 StackInfo getStackInfoLocked(int stackId) { 2835 ActivityStack stack = getStack(stackId); 2836 if (stack != null) { 2837 return getStackInfo(stack); 2838 } 2839 return null; 2840 } 2841 2842 ArrayList<StackInfo> getAllStackInfosLocked() { 2843 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2844 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2845 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2846 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2847 list.add(getStackInfo(stacks.get(ndx))); 2848 } 2849 } 2850 return list; 2851 } 2852 2853 private final class ActivityStackSupervisorHandler extends Handler { 2854 2855 public ActivityStackSupervisorHandler(Looper looper) { 2856 super(looper); 2857 } 2858 2859 void activityIdleInternal(ActivityRecord r) { 2860 synchronized (mService) { 2861 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2862 } 2863 } 2864 2865 @Override 2866 public void handleMessage(Message msg) { 2867 switch (msg.what) { 2868 case IDLE_TIMEOUT_MSG: { 2869 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2870 if (mService.mDidDexOpt) { 2871 mService.mDidDexOpt = false; 2872 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2873 nmsg.obj = msg.obj; 2874 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2875 return; 2876 } 2877 // We don't at this point know if the activity is fullscreen, 2878 // so we need to be conservative and assume it isn't. 2879 activityIdleInternal((ActivityRecord)msg.obj); 2880 } break; 2881 case IDLE_NOW_MSG: { 2882 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2883 activityIdleInternal((ActivityRecord)msg.obj); 2884 } break; 2885 case RESUME_TOP_ACTIVITY_MSG: { 2886 synchronized (mService) { 2887 resumeTopActivitiesLocked(); 2888 } 2889 } break; 2890 case SLEEP_TIMEOUT_MSG: { 2891 synchronized (mService) { 2892 if (mService.isSleepingOrShuttingDown()) { 2893 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2894 mSleepTimeout = true; 2895 checkReadyForSleepLocked(); 2896 } 2897 } 2898 } break; 2899 case LAUNCH_TIMEOUT_MSG: { 2900 if (mService.mDidDexOpt) { 2901 mService.mDidDexOpt = false; 2902 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2903 return; 2904 } 2905 synchronized (mService) { 2906 if (mLaunchingActivity.isHeld()) { 2907 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2908 if (VALIDATE_WAKE_LOCK_CALLER 2909 && Binder.getCallingUid() != Process.myUid()) { 2910 throw new IllegalStateException("Calling must be system uid"); 2911 } 2912 mLaunchingActivity.release(); 2913 } 2914 } 2915 } break; 2916 case HANDLE_DISPLAY_ADDED: { 2917 handleDisplayAddedLocked(msg.arg1); 2918 } break; 2919 case HANDLE_DISPLAY_CHANGED: { 2920 handleDisplayChangedLocked(msg.arg1); 2921 } break; 2922 case HANDLE_DISPLAY_REMOVED: { 2923 handleDisplayRemovedLocked(msg.arg1); 2924 } break; 2925 } 2926 } 2927 } 2928 2929 class ActivityContainer extends IActivityContainer.Stub { 2930 final int mStackId; 2931 final IActivityContainerCallback mCallback; 2932 final ActivityStack mStack; 2933 final ActivityRecord mParentActivity; 2934 final String mIdString; 2935 2936 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 2937 ActivityDisplay mActivityDisplay; 2938 2939 ActivityContainer(ActivityRecord parentActivity, int stackId, 2940 IActivityContainerCallback callback) { 2941 synchronized (mService) { 2942 mStackId = stackId; 2943 mStack = new ActivityStack(this); 2944 mParentActivity = parentActivity; 2945 mCallback = callback; 2946 mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 2947 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 2948 } 2949 } 2950 2951 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 2952 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 2953 + " to display=" + activityDisplay); 2954 mActivityDisplay = activityDisplay; 2955 mStack.mDisplayId = activityDisplay.mDisplayId; 2956 mStack.mStacks = activityDisplay.mStacks; 2957 2958 activityDisplay.attachActivities(mStack); 2959 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 2960 } 2961 2962 @Override 2963 public void attachToDisplay(int displayId) { 2964 synchronized (mService) { 2965 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2966 if (activityDisplay == null) { 2967 return; 2968 } 2969 attachToDisplayLocked(activityDisplay); 2970 } 2971 } 2972 2973 @Override 2974 public int getDisplayId() { 2975 if (mActivityDisplay != null) { 2976 return mActivityDisplay.mDisplayId; 2977 } 2978 return -1; 2979 } 2980 2981 @Override 2982 public boolean injectEvent(InputEvent event) { 2983 final long origId = Binder.clearCallingIdentity(); 2984 try { 2985 if (mActivityDisplay != null) { 2986 return mInputManagerInternal.injectInputEvent(event, 2987 mActivityDisplay.mDisplayId, 2988 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 2989 } 2990 return false; 2991 } finally { 2992 Binder.restoreCallingIdentity(origId); 2993 } 2994 } 2995 2996 private void detachLocked() { 2997 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 2998 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 2999 if (mActivityDisplay != null) { 3000 mActivityDisplay.detachActivitiesLocked(mStack); 3001 mActivityDisplay = null; 3002 mStack.mDisplayId = -1; 3003 mStack.mStacks = null; 3004 mWindowManager.detachStack(mStackId); 3005 } 3006 } 3007 3008 @Override 3009 public void detachFromDisplay() { 3010 synchronized (mService) { 3011 detachLocked(); 3012 } 3013 } 3014 3015 @Override 3016 public final int startActivity(Intent intent) { 3017 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3018 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3019 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3020 // TODO: Switch to user app stacks here. 3021 String mimeType = intent.getType(); 3022 if (mimeType == null && intent.getData() != null 3023 && "content".equals(intent.getData().getScheme())) { 3024 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3025 } 3026 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null, 3027 null, null, null, null, userId, this); 3028 } 3029 3030 @Override 3031 public final int startActivityIntentSender(IIntentSender intentSender) { 3032 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3033 3034 if (!(intentSender instanceof PendingIntentRecord)) { 3035 throw new IllegalArgumentException("Bad PendingIntent object"); 3036 } 3037 3038 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3039 null, 0, 0, 0, null, this); 3040 } 3041 3042 @Override 3043 public IBinder asBinder() { 3044 return this; 3045 } 3046 3047 @Override 3048 public void attachToSurface(Surface surface, int width, int height, int density) { 3049 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3050 3051 final long origId = Binder.clearCallingIdentity(); 3052 try { 3053 synchronized (mService) { 3054 ActivityDisplay activityDisplay = 3055 new ActivityDisplay(surface, width, height, density); 3056 mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay); 3057 attachToDisplayLocked(activityDisplay); 3058 mStack.resumeTopActivityLocked(null); 3059 } 3060 if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display=" 3061 + mActivityDisplay); 3062 } finally { 3063 Binder.restoreCallingIdentity(origId); 3064 } 3065 } 3066 3067 ActivityStackSupervisor getOuter() { 3068 return ActivityStackSupervisor.this; 3069 } 3070 3071 boolean isAttached() { 3072 return mActivityDisplay != null; 3073 } 3074 3075 void getBounds(Point outBounds) { 3076 if (mActivityDisplay != null) { 3077 mActivityDisplay.getBounds(outBounds); 3078 } else { 3079 outBounds.set(0, 0); 3080 } 3081 } 3082 3083 @Override 3084 public String toString() { 3085 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3086 } 3087 } 3088 3089 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3090 * attached {@link ActivityStack}s */ 3091 final class ActivityDisplay { 3092 /** Actual Display this object tracks. */ 3093 int mDisplayId; 3094 Display mDisplay; 3095 DisplayInfo mDisplayInfo = new DisplayInfo(); 3096 Surface mSurface; 3097 3098 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3099 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3100 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3101 3102 /** If this display is for an ActivityView then the VirtualDisplay created for it is stored 3103 * here. */ 3104 VirtualDisplay mVirtualDisplay; 3105 3106 ActivityDisplay(int displayId) { 3107 init(mDisplayManager.getDisplay(displayId)); 3108 } 3109 3110 ActivityDisplay(Surface surface, int width, int height, int density) { 3111 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3112 long ident = Binder.clearCallingIdentity(); 3113 try { 3114 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, 3115 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface, 3116 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3117 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3118 } finally { 3119 Binder.restoreCallingIdentity(ident); 3120 } 3121 3122 init(mVirtualDisplay.getDisplay()); 3123 mSurface = surface; 3124 3125 mWindowManager.handleDisplayAdded(mDisplayId); 3126 } 3127 3128 private void init(Display display) { 3129 mDisplay = display; 3130 mDisplayId = display.getDisplayId(); 3131 mDisplay.getDisplayInfo(mDisplayInfo); 3132 } 3133 3134 void attachActivities(ActivityStack stack) { 3135 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3136 + mDisplayId); 3137 mStacks.add(stack); 3138 } 3139 3140 void detachActivitiesLocked(ActivityStack stack) { 3141 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3142 + " from displayId=" + mDisplayId); 3143 mStacks.remove(stack); 3144 if (mStacks.isEmpty() && mVirtualDisplay != null) { 3145 mVirtualDisplay.release(); 3146 mVirtualDisplay = null; 3147 } 3148 mSurface.release(); 3149 } 3150 3151 void getBounds(Point bounds) { 3152 mDisplay.getDisplayInfo(mDisplayInfo); 3153 bounds.x = mDisplayInfo.appWidth; 3154 bounds.y = mDisplayInfo.appHeight; 3155 } 3156 3157 @Override 3158 public String toString() { 3159 return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V") 3160 + " numStacks=" + mStacks.size() + "}"; 3161 } 3162 } 3163} 3164