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