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