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