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