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