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