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