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