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