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