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