ActivityStackSupervisor.java revision 2d437d04614ba79ad54546b05f9aec93a479b603
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 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1026 System.identityHashCode(r), r.info, 1027 new Configuration(mService.mConfiguration), r.compat, r.task.voiceInteractor, 1028 app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, 1029 mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop 1030 ); 1031 1032 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 1033 // This may be a heavy-weight process! Note that the package 1034 // manager will ensure that only activity can run in the main 1035 // process of the .apk, which is the only thing that will be 1036 // considered heavy-weight. 1037 if (app.processName.equals(app.info.packageName)) { 1038 if (mService.mHeavyWeightProcess != null 1039 && mService.mHeavyWeightProcess != app) { 1040 Slog.w(TAG, "Starting new heavy weight process " + app 1041 + " when already running " 1042 + mService.mHeavyWeightProcess); 1043 } 1044 mService.mHeavyWeightProcess = app; 1045 Message msg = mService.mHandler.obtainMessage( 1046 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1047 msg.obj = r; 1048 mService.mHandler.sendMessage(msg); 1049 } 1050 } 1051 1052 } catch (RemoteException e) { 1053 if (r.launchFailed) { 1054 // This is the second time we failed -- finish activity 1055 // and give up. 1056 Slog.e(TAG, "Second failure launching " 1057 + r.intent.getComponent().flattenToShortString() 1058 + ", giving up", e); 1059 mService.appDiedLocked(app, app.pid, app.thread); 1060 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1061 "2nd-crash", false); 1062 return false; 1063 } 1064 1065 // This is the first time we failed -- restart process and 1066 // retry. 1067 app.activities.remove(r); 1068 throw e; 1069 } 1070 1071 r.launchFailed = false; 1072 if (stack.updateLRUListLocked(r)) { 1073 Slog.w(TAG, "Activity " + r 1074 + " being launched, but already in LRU list"); 1075 } 1076 1077 if (andResume) { 1078 // As part of the process of launching, ActivityThread also performs 1079 // a resume. 1080 stack.minimalResumeActivityLocked(r); 1081 } else { 1082 // This activity is not starting in the resumed state... which 1083 // should look like we asked it to pause+stop (but remain visible), 1084 // and it has done so and reported back the current icicle and 1085 // other state. 1086 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 1087 + " (starting in stopped state)"); 1088 r.state = ActivityState.STOPPED; 1089 r.stopped = true; 1090 } 1091 1092 // Launch the new version setup screen if needed. We do this -after- 1093 // launching the initial activity (that is, home), so that it can have 1094 // a chance to initialize itself while in the background, making the 1095 // switch back to it faster and look better. 1096 if (isFrontStack(stack)) { 1097 mService.startSetupActivityLocked(); 1098 } 1099 1100 return true; 1101 } 1102 1103 void startSpecificActivityLocked(ActivityRecord r, 1104 boolean andResume, boolean checkConfig) { 1105 // Is this activity's application already running? 1106 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1107 r.info.applicationInfo.uid, true); 1108 1109 r.task.stack.setLaunchTime(r); 1110 1111 if (app != null && app.thread != null) { 1112 try { 1113 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1114 || !"android".equals(r.info.packageName)) { 1115 // Don't add this if it is a platform component that is marked 1116 // to run in multiple processes, because this is actually 1117 // part of the framework so doesn't make sense to track as a 1118 // separate apk in the process. 1119 app.addPackage(r.info.packageName, mService.mProcessStats); 1120 } 1121 realStartActivityLocked(r, app, andResume, checkConfig); 1122 return; 1123 } catch (RemoteException e) { 1124 Slog.w(TAG, "Exception when starting activity " 1125 + r.intent.getComponent().flattenToShortString(), e); 1126 } 1127 1128 // If a dead object exception was thrown -- fall through to 1129 // restart the application. 1130 } 1131 1132 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1133 "activity", r.intent.getComponent(), false, false, true); 1134 } 1135 1136 final int startActivityLocked(IApplicationThread caller, 1137 Intent intent, String resolvedType, ActivityInfo aInfo, 1138 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1139 IBinder resultTo, String resultWho, int requestCode, 1140 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1141 boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { 1142 int err = ActivityManager.START_SUCCESS; 1143 1144 ProcessRecord callerApp = null; 1145 if (caller != null) { 1146 callerApp = mService.getRecordForAppLocked(caller); 1147 if (callerApp != null) { 1148 callingPid = callerApp.pid; 1149 callingUid = callerApp.info.uid; 1150 } else { 1151 Slog.w(TAG, "Unable to find app for caller " + caller 1152 + " (pid=" + callingPid + ") when starting: " 1153 + intent.toString()); 1154 err = ActivityManager.START_PERMISSION_DENIED; 1155 } 1156 } 1157 1158 if (err == ActivityManager.START_SUCCESS) { 1159 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1160 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1161 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) 1162 + " on display " + (container == null ? (mFocusedStack == null ? 1163 Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : 1164 (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : 1165 container.mActivityDisplay.mDisplayId))); 1166 } 1167 1168 ActivityRecord sourceRecord = null; 1169 ActivityRecord resultRecord = null; 1170 if (resultTo != null) { 1171 sourceRecord = isInAnyStackLocked(resultTo); 1172 if (DEBUG_RESULTS) Slog.v( 1173 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1174 if (sourceRecord != null) { 1175 if (requestCode >= 0 && !sourceRecord.finishing) { 1176 resultRecord = sourceRecord; 1177 } 1178 } 1179 } 1180 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1181 1182 final int launchFlags = intent.getFlags(); 1183 1184 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1185 && sourceRecord != null) { 1186 // Transfer the result target from the source activity to the new 1187 // one being started, including any failures. 1188 if (requestCode >= 0) { 1189 ActivityOptions.abort(options); 1190 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1191 } 1192 resultRecord = sourceRecord.resultTo; 1193 resultWho = sourceRecord.resultWho; 1194 requestCode = sourceRecord.requestCode; 1195 sourceRecord.resultTo = null; 1196 if (resultRecord != null) { 1197 resultRecord.removeResultsLocked( 1198 sourceRecord, resultWho, requestCode); 1199 } 1200 if (sourceRecord.launchedFromUid == callingUid) { 1201 // The new activity is being launched from the same uid as the previous 1202 // activity in the flow, and asking to forward its result back to the 1203 // previous. In this case the activity is serving as a trampoline between 1204 // the two, so we also want to update its launchedFromPackage to be the 1205 // same as the previous activity. Note that this is safe, since we know 1206 // these two packages come from the same uid; the caller could just as 1207 // well have supplied that same package name itself. This specifially 1208 // deals with the case of an intent picker/chooser being launched in the app 1209 // flow to redirect to an activity picked by the user, where we want the final 1210 // activity to consider it to have been launched by the previous app activity. 1211 callingPackage = sourceRecord.launchedFromPackage; 1212 } 1213 } 1214 1215 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1216 // We couldn't find a class that can handle the given Intent. 1217 // That's the end of that! 1218 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1219 } 1220 1221 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1222 // We couldn't find the specific class specified in the Intent. 1223 // Also the end of the line. 1224 err = ActivityManager.START_CLASS_NOT_FOUND; 1225 } 1226 1227 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1228 && sourceRecord.task.voiceSession != null) { 1229 // If this activity is being launched as part of a voice session, we need 1230 // to ensure that it is safe to do so. If the upcoming activity will also 1231 // be part of the voice session, we can only launch it if it has explicitly 1232 // said it supports the VOICE category, or it is a part of the calling app. 1233 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1234 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1235 try { 1236 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1237 intent, resolvedType)) { 1238 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1239 } 1240 } catch (RemoteException e) { 1241 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1242 } 1243 } 1244 } 1245 1246 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1247 // If the caller is starting a new voice session, just make sure the target 1248 // is actually allowing it to run this way. 1249 try { 1250 if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(), 1251 intent, resolvedType)) { 1252 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1253 } 1254 } catch (RemoteException e) { 1255 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1256 } 1257 } 1258 1259 if (err != ActivityManager.START_SUCCESS) { 1260 if (resultRecord != null) { 1261 resultStack.sendActivityResultLocked(-1, 1262 resultRecord, resultWho, requestCode, 1263 Activity.RESULT_CANCELED, null); 1264 } 1265 setDismissKeyguard(false); 1266 ActivityOptions.abort(options); 1267 return err; 1268 } 1269 1270 final int startAnyPerm = mService.checkPermission( 1271 START_ANY_ACTIVITY, callingPid, callingUid); 1272 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1273 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1274 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1275 if (resultRecord != null) { 1276 resultStack.sendActivityResultLocked(-1, 1277 resultRecord, resultWho, requestCode, 1278 Activity.RESULT_CANCELED, null); 1279 } 1280 setDismissKeyguard(false); 1281 String msg; 1282 if (!aInfo.exported) { 1283 msg = "Permission Denial: starting " + intent.toString() 1284 + " from " + callerApp + " (pid=" + callingPid 1285 + ", uid=" + callingUid + ")" 1286 + " not exported from uid " + aInfo.applicationInfo.uid; 1287 } else { 1288 msg = "Permission Denial: starting " + intent.toString() 1289 + " from " + callerApp + " (pid=" + callingPid 1290 + ", uid=" + callingUid + ")" 1291 + " requires " + aInfo.permission; 1292 } 1293 Slog.w(TAG, msg); 1294 throw new SecurityException(msg); 1295 } 1296 1297 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1298 callingPid, resolvedType, aInfo.applicationInfo); 1299 1300 if (mService.mController != null) { 1301 try { 1302 // The Intent we give to the watcher has the extra data 1303 // stripped off, since it can contain private information. 1304 Intent watchIntent = intent.cloneFilter(); 1305 abort |= !mService.mController.activityStarting(watchIntent, 1306 aInfo.applicationInfo.packageName); 1307 } catch (RemoteException e) { 1308 mService.mController = null; 1309 } 1310 } 1311 1312 if (abort) { 1313 if (resultRecord != null) { 1314 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1315 Activity.RESULT_CANCELED, null); 1316 } 1317 // We pretend to the caller that it was really started, but 1318 // they will just get a cancel result. 1319 setDismissKeyguard(false); 1320 ActivityOptions.abort(options); 1321 return ActivityManager.START_SUCCESS; 1322 } 1323 1324 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1325 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 1326 requestCode, componentSpecified, this, container, options); 1327 if (outActivity != null) { 1328 outActivity[0] = r; 1329 } 1330 1331 final ActivityStack stack = getFocusedStack(); 1332 if (voiceSession == null && (stack.mResumedActivity == null 1333 || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { 1334 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1335 PendingActivityLaunch pal = 1336 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1337 mService.mPendingActivityLaunches.add(pal); 1338 setDismissKeyguard(false); 1339 ActivityOptions.abort(options); 1340 return ActivityManager.START_SWITCHES_CANCELED; 1341 } 1342 } 1343 1344 if (mService.mDidAppSwitch) { 1345 // This is the second allowed switch since we stopped switches, 1346 // so now just generally allow switches. Use case: user presses 1347 // home (switches disabled, switch to home, mDidAppSwitch now true); 1348 // user taps a home icon (coming from home so allowed, we hit here 1349 // and now allow anyone to switch again). 1350 mService.mAppSwitchesAllowedTime = 0; 1351 } else { 1352 mService.mDidAppSwitch = true; 1353 } 1354 1355 mService.doPendingActivityLaunchesLocked(false); 1356 1357 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, 1358 startFlags, true, options); 1359 1360 if (allPausedActivitiesComplete()) { 1361 // If someone asked to have the keyguard dismissed on the next 1362 // activity start, but we are not actually doing an activity 1363 // switch... just dismiss the keyguard now, because we 1364 // probably want to see whatever is behind it. 1365 dismissKeyguard(); 1366 } 1367 return err; 1368 } 1369 1370 ActivityStack adjustStackFocus(ActivityRecord r) { 1371 final TaskRecord task = r.task; 1372 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1373 if (task != null) { 1374 final ActivityStack taskStack = task.stack; 1375 if (taskStack.isOnHomeDisplay()) { 1376 if (mFocusedStack != taskStack) { 1377 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + 1378 "focused stack to r=" + r + " task=" + task); 1379 mFocusedStack = taskStack; 1380 } else { 1381 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1382 "adjustStackFocus: Focused stack already=" + mFocusedStack); 1383 } 1384 } 1385 return taskStack; 1386 } 1387 1388 final ActivityContainer container = r.mInitialActivityContainer; 1389 if (container != null) { 1390 // The first time put it on the desired stack, after this put on task stack. 1391 r.mInitialActivityContainer = null; 1392 return container.mStack; 1393 } 1394 1395 if (mFocusedStack != mHomeStack) { 1396 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1397 "adjustStackFocus: Have a focused stack=" + mFocusedStack); 1398 return mFocusedStack; 1399 } 1400 1401 final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; 1402 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1403 final ActivityStack stack = homeDisplayStacks.get(stackNdx); 1404 if (!stack.isHomeStack()) { 1405 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, 1406 "adjustStackFocus: Setting focused stack=" + stack); 1407 mFocusedStack = stack; 1408 return mFocusedStack; 1409 } 1410 } 1411 1412 // Need to create an app stack for this user. 1413 int stackId = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY); 1414 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + 1415 " stackId=" + stackId); 1416 mFocusedStack = getStack(stackId); 1417 return mFocusedStack; 1418 } 1419 return mHomeStack; 1420 } 1421 1422 void setFocusedStack(ActivityRecord r) { 1423 if (r != null) { 1424 final TaskRecord task = r.task; 1425 boolean isHomeActivity = !r.isApplicationActivity(); 1426 if (!isHomeActivity && task != null) { 1427 isHomeActivity = !task.isApplicationTask(); 1428 } 1429 if (!isHomeActivity && task != null) { 1430 final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity; 1431 isHomeActivity = parent != null && parent.isHomeActivity(); 1432 } 1433 moveHomeStack(isHomeActivity); 1434 } 1435 } 1436 1437 final int startActivityUncheckedLocked(ActivityRecord r, 1438 ActivityRecord sourceRecord, 1439 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, 1440 boolean doResume, Bundle options) { 1441 final Intent intent = r.intent; 1442 final int callingUid = r.launchedFromUid; 1443 1444 int launchFlags = intent.getFlags(); 1445 1446 // We'll invoke onUserLeaving before onPause only if the launching 1447 // activity did not explicitly state that this is an automated launch. 1448 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1449 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1450 1451 // If the caller has asked not to resume at this point, we make note 1452 // of this in the record so that we can skip it when trying to find 1453 // the top running activity. 1454 if (!doResume) { 1455 r.delayedResume = true; 1456 } 1457 1458 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1459 1460 // If the onlyIfNeeded flag is set, then we can do this if the activity 1461 // being launched is the same as the one making the call... or, as 1462 // a special case, if we do not know the caller then we count the 1463 // current top activity as the caller. 1464 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1465 ActivityRecord checkedCaller = sourceRecord; 1466 if (checkedCaller == null) { 1467 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1468 } 1469 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1470 // Caller is not the same as launcher, so always needed. 1471 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1472 } 1473 } 1474 1475 switch (r.info.documentLaunchMode) { 1476 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1477 break; 1478 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1479 intent.addFlags( 1480 Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 1481 break; 1482 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1483 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 1484 break; 1485 } 1486 final boolean newDocument = intent.isDocument(); 1487 if (sourceRecord == null) { 1488 // This activity is not being started from another... in this 1489 // case we -always- start a new task. 1490 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1491 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1492 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1493 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1494 } 1495 } else if (newDocument) { 1496 if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) { 1497 Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\""); 1498 r.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 1499 } 1500 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1501 // The original activity who is starting us is running as a single 1502 // instance... this new activity it is starting must go on its 1503 // own task. 1504 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1505 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1506 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1507 // The activity being started is a single instance... it always 1508 // gets launched into its own task. 1509 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1510 } 1511 1512 ActivityInfo newTaskInfo = null; 1513 Intent newTaskIntent = null; 1514 final ActivityStack sourceStack; 1515 if (sourceRecord != null) { 1516 if (sourceRecord.finishing) { 1517 // If the source is finishing, we can't further count it as our source. This 1518 // is because the task it is associated with may now be empty and on its way out, 1519 // so we don't want to blindly throw it in to that task. Instead we will take 1520 // the NEW_TASK flow and try to find a task for it. But save the task information 1521 // so it can be used when creating the new task. 1522 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1523 Slog.w(TAG, "startActivity called from finishing " + sourceRecord 1524 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1525 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1526 newTaskInfo = sourceRecord.info; 1527 newTaskIntent = sourceRecord.task.intent; 1528 } 1529 sourceRecord = null; 1530 sourceStack = null; 1531 } else { 1532 sourceStack = sourceRecord.task.stack; 1533 } 1534 } else { 1535 sourceStack = null; 1536 } 1537 1538 if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1539 // For whatever reason this activity is being launched into a new 1540 // task... yet the caller has requested a result back. Well, that 1541 // is pretty messed up, so instead immediately send back a cancel 1542 // and let the new task continue launched as normal without a 1543 // dependency on its originator. 1544 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1545 r.resultTo.task.stack.sendActivityResultLocked(-1, 1546 r.resultTo, r.resultWho, r.requestCode, 1547 Activity.RESULT_CANCELED, null); 1548 r.resultTo = null; 1549 } 1550 1551 boolean addingToTask = false; 1552 boolean movedHome = false; 1553 TaskRecord reuseTask = null; 1554 ActivityStack targetStack; 1555 if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1556 (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1557 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1558 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1559 // If bring to front is requested, and no result is requested, and 1560 // we can find a task that was started with this same 1561 // component, then instead of launching bring that one to the front. 1562 if (r.resultTo == null) { 1563 // See if there is a task to bring to the front. If this is 1564 // a SINGLE_INSTANCE activity, there can be one and only one 1565 // instance of it in the history, and it is always in its own 1566 // unique task, so we do a special search. 1567 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1568 ? findTaskLocked(r) 1569 : findActivityLocked(intent, r.info); 1570 if (intentActivity != null) { 1571 if (isLockTaskModeViolation(intentActivity.task)) { 1572 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 1573 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1574 } 1575 if (r.task == null) { 1576 r.task = intentActivity.task; 1577 } 1578 targetStack = intentActivity.task.stack; 1579 targetStack.mLastPausedActivity = null; 1580 if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack 1581 + " from " + intentActivity); 1582 targetStack.moveToFront(); 1583 if (intentActivity.task.intent == null) { 1584 // This task was started because of movement of 1585 // the activity based on affinity... now that we 1586 // are actually launching it, we can assign the 1587 // base intent. 1588 intentActivity.task.setIntent(intent, r.info); 1589 } 1590 // If the target task is not in the front, then we need 1591 // to bring it to the front... except... well, with 1592 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1593 // to have the same behavior as if a new instance was 1594 // being started, which means not bringing it to the front 1595 // if the caller is not itself in the front. 1596 final ActivityStack lastStack = getLastStack(); 1597 ActivityRecord curTop = lastStack == null? 1598 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1599 if (curTop != null && (curTop.task != intentActivity.task || 1600 curTop.task != lastStack.topTask())) { 1601 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1602 if (sourceRecord == null || (sourceStack.topActivity() != null && 1603 sourceStack.topActivity().task == sourceRecord.task)) { 1604 // We really do want to push this one into the 1605 // user's face, right now. 1606 movedHome = true; 1607 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1608 if ((launchFlags & 1609 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1610 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1611 // Caller wants to appear on home activity. 1612 intentActivity.task.mOnTopOfHome = true; 1613 } 1614 options = null; 1615 } 1616 } 1617 // If the caller has requested that the target task be 1618 // reset, then do so. 1619 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1620 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1621 } 1622 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1623 // We don't need to start a new activity, and 1624 // the client said not to do anything if that 1625 // is the case, so this is it! And for paranoia, make 1626 // sure we have correctly resumed the top activity. 1627 if (doResume) { 1628 resumeTopActivitiesLocked(targetStack, null, options); 1629 } else { 1630 ActivityOptions.abort(options); 1631 } 1632 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1633 } 1634 if ((launchFlags & 1635 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1636 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1637 // The caller has requested to completely replace any 1638 // existing task with its new activity. Well that should 1639 // not be too hard... 1640 reuseTask = intentActivity.task; 1641 reuseTask.performClearTaskLocked(); 1642 reuseTask.setIntent(r.intent, r.info); 1643 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1644 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1645 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1646 // In this situation we want to remove all activities 1647 // from the task up to the one being started. In most 1648 // cases this means we are resetting the task to its 1649 // initial state. 1650 ActivityRecord top = 1651 intentActivity.task.performClearTaskLocked(r, launchFlags); 1652 if (top != null) { 1653 if (top.frontOfTask) { 1654 // Activity aliases may mean we use different 1655 // intents for the top activity, so make sure 1656 // the task now has the identity of the new 1657 // intent. 1658 top.task.setIntent(r.intent, r.info); 1659 } 1660 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1661 r, top.task); 1662 top.deliverNewIntentLocked(callingUid, r.intent); 1663 } else { 1664 // A special case: we need to 1665 // start the activity because it is not currently 1666 // running, and the caller has asked to clear the 1667 // current task to have this activity at the top. 1668 addingToTask = true; 1669 // Now pretend like this activity is being started 1670 // by the top of its task, so it is put in the 1671 // right place. 1672 sourceRecord = intentActivity; 1673 } 1674 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1675 // In this case the top activity on the task is the 1676 // same as the one being launched, so we take that 1677 // as a request to bring the task to the foreground. 1678 // If the top activity in the task is the root 1679 // activity, deliver this new intent to it if it 1680 // desires. 1681 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1682 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1683 && intentActivity.realActivity.equals(r.realActivity)) { 1684 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1685 intentActivity.task); 1686 if (intentActivity.frontOfTask) { 1687 intentActivity.task.setIntent(r.intent, r.info); 1688 } 1689 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1690 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1691 // In this case we are launching the root activity 1692 // of the task, but with a different intent. We 1693 // should start a new instance on top. 1694 addingToTask = true; 1695 sourceRecord = intentActivity; 1696 } 1697 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1698 // In this case an activity is being launched in to an 1699 // existing task, without resetting that task. This 1700 // is typically the situation of launching an activity 1701 // from a notification or shortcut. We want to place 1702 // the new activity on top of the current task. 1703 addingToTask = true; 1704 sourceRecord = intentActivity; 1705 } else if (!intentActivity.task.rootWasReset) { 1706 // In this case we are launching in to an existing task 1707 // that has not yet been started from its front door. 1708 // The current task has been brought to the front. 1709 // Ideally, we'd probably like to place this new task 1710 // at the bottom of its stack, but that's a little hard 1711 // to do with the current organization of the code so 1712 // for now we'll just drop it. 1713 intentActivity.task.setIntent(r.intent, r.info); 1714 } 1715 if (!addingToTask && reuseTask == null) { 1716 // We didn't do anything... but it was needed (a.k.a., client 1717 // don't use that intent!) And for paranoia, make 1718 // sure we have correctly resumed the top activity. 1719 if (doResume) { 1720 targetStack.resumeTopActivityLocked(null, options); 1721 } else { 1722 ActivityOptions.abort(options); 1723 } 1724 return ActivityManager.START_TASK_TO_FRONT; 1725 } 1726 } 1727 } 1728 } 1729 1730 //String uri = r.intent.toURI(); 1731 //Intent intent2 = new Intent(uri); 1732 //Slog.i(TAG, "Given intent: " + r.intent); 1733 //Slog.i(TAG, "URI is: " + uri); 1734 //Slog.i(TAG, "To intent: " + intent2); 1735 1736 if (r.packageName != null) { 1737 // If the activity being launched is the same as the one currently 1738 // at the top, then we need to check if it should only be launched 1739 // once. 1740 ActivityStack topStack = getFocusedStack(); 1741 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1742 if (top != null && r.resultTo == null) { 1743 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1744 if (top.app != null && top.app.thread != null) { 1745 if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1746 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1747 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1748 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1749 top.task); 1750 // For paranoia, make sure we have correctly 1751 // resumed the top activity. 1752 topStack.mLastPausedActivity = null; 1753 if (doResume) { 1754 resumeTopActivitiesLocked(); 1755 } 1756 ActivityOptions.abort(options); 1757 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1758 // We don't need to start a new activity, and 1759 // the client said not to do anything if that 1760 // is the case, so this is it! 1761 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1762 } 1763 top.deliverNewIntentLocked(callingUid, r.intent); 1764 return ActivityManager.START_DELIVERED_TO_TOP; 1765 } 1766 } 1767 } 1768 } 1769 1770 } else { 1771 if (r.resultTo != null) { 1772 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1773 r.requestCode, Activity.RESULT_CANCELED, null); 1774 } 1775 ActivityOptions.abort(options); 1776 return ActivityManager.START_CLASS_NOT_FOUND; 1777 } 1778 1779 boolean newTask = false; 1780 boolean keepCurTransition = false; 1781 1782 // Should this be considered a new task? 1783 if (r.resultTo == null && !addingToTask 1784 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1785 if (isLockTaskModeViolation(reuseTask)) { 1786 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1787 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1788 } 1789 targetStack = adjustStackFocus(r); 1790 targetStack.moveToFront(); 1791 if (reuseTask == null) { 1792 r.setTask(targetStack.createTaskRecord(getNextTaskId(), 1793 newTaskInfo != null ? newTaskInfo : r.info, 1794 newTaskIntent != null ? newTaskIntent : intent, 1795 voiceSession, voiceInteractor, true), null, true); 1796 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1797 r.task); 1798 } else { 1799 r.setTask(reuseTask, reuseTask, true); 1800 } 1801 newTask = true; 1802 if (!movedHome) { 1803 if ((launchFlags & 1804 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1805 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1806 // Caller wants to appear on home activity, so before starting 1807 // their own activity we will bring home to the front. 1808 r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); 1809 } 1810 } 1811 } else if (sourceRecord != null) { 1812 TaskRecord sourceTask = sourceRecord.task; 1813 if (isLockTaskModeViolation(sourceTask)) { 1814 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1815 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 1816 } 1817 targetStack = sourceTask.stack; 1818 targetStack.moveToFront(); 1819 mWindowManager.moveTaskToTop(targetStack.topTask().taskId); 1820 if (!addingToTask && 1821 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1822 // In this case, we are adding the activity to an existing 1823 // task, but the caller has asked to clear that task if the 1824 // activity is already running. 1825 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1826 keepCurTransition = true; 1827 if (top != null) { 1828 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1829 top.deliverNewIntentLocked(callingUid, r.intent); 1830 // For paranoia, make sure we have correctly 1831 // resumed the top activity. 1832 targetStack.mLastPausedActivity = null; 1833 if (doResume) { 1834 targetStack.resumeTopActivityLocked(null); 1835 } 1836 ActivityOptions.abort(options); 1837 return ActivityManager.START_DELIVERED_TO_TOP; 1838 } 1839 } else if (!addingToTask && 1840 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1841 // In this case, we are launching an activity in our own task 1842 // that may already be running somewhere in the history, and 1843 // we want to shuffle it to the front of the stack if so. 1844 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1845 if (top != null) { 1846 final TaskRecord task = top.task; 1847 task.moveActivityToFrontLocked(top); 1848 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1849 top.updateOptionsLocked(options); 1850 top.deliverNewIntentLocked(callingUid, r.intent); 1851 targetStack.mLastPausedActivity = null; 1852 if (doResume) { 1853 targetStack.resumeTopActivityLocked(null); 1854 } 1855 return ActivityManager.START_DELIVERED_TO_TOP; 1856 } 1857 } 1858 // An existing activity is starting this new activity, so we want 1859 // to keep the new one in the same task as the one that is starting 1860 // it. 1861 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1862 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1863 + " in existing task " + r.task + " from source " + sourceRecord); 1864 1865 } else { 1866 // This not being started from an existing activity, and not part 1867 // of a new task... just put it in the top task, though these days 1868 // this case should never happen. 1869 targetStack = adjustStackFocus(r); 1870 targetStack.moveToFront(); 1871 ActivityRecord prev = targetStack.topActivity(); 1872 r.setTask(prev != null ? prev.task 1873 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, null, null, true), 1874 null, true); 1875 mWindowManager.moveTaskToTop(r.task.taskId); 1876 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1877 + " in new guessed " + r.task); 1878 } 1879 1880 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1881 intent, r.getUriPermissionsLocked()); 1882 1883 if (newTask) { 1884 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1885 } 1886 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1887 targetStack.mLastPausedActivity = null; 1888 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1889 mService.setFocusedActivityLocked(r); 1890 return ActivityManager.START_SUCCESS; 1891 } 1892 1893 void acquireLaunchWakelock() { 1894 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1895 throw new IllegalStateException("Calling must be system uid"); 1896 } 1897 mLaunchingActivity.acquire(); 1898 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1899 // To be safe, don't allow the wake lock to be held for too long. 1900 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1901 } 1902 } 1903 1904 // Checked. 1905 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1906 Configuration config) { 1907 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1908 1909 ArrayList<ActivityRecord> stops = null; 1910 ArrayList<ActivityRecord> finishes = null; 1911 ArrayList<UserStartedState> startingUsers = null; 1912 int NS = 0; 1913 int NF = 0; 1914 boolean booting = false; 1915 boolean enableScreen = false; 1916 boolean activityRemoved = false; 1917 1918 ActivityRecord r = ActivityRecord.forToken(token); 1919 if (r != null) { 1920 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1921 Debug.getCallers(4)); 1922 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1923 r.finishLaunchTickingLocked(); 1924 if (fromTimeout) { 1925 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1926 } 1927 1928 // This is a hack to semi-deal with a race condition 1929 // in the client where it can be constructed with a 1930 // newer configuration from when we asked it to launch. 1931 // We'll update with whatever configuration it now says 1932 // it used to launch. 1933 if (config != null) { 1934 r.configuration = config; 1935 } 1936 1937 // We are now idle. If someone is waiting for a thumbnail from 1938 // us, we can now deliver. 1939 r.idle = true; 1940 1941 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1942 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1943 mService.mBooted = true; 1944 enableScreen = true; 1945 } 1946 } 1947 1948 if (allResumedActivitiesIdle()) { 1949 if (r != null) { 1950 mService.scheduleAppGcsLocked(); 1951 } 1952 1953 if (mLaunchingActivity.isHeld()) { 1954 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1955 if (VALIDATE_WAKE_LOCK_CALLER && 1956 Binder.getCallingUid() != Process.myUid()) { 1957 throw new IllegalStateException("Calling must be system uid"); 1958 } 1959 mLaunchingActivity.release(); 1960 } 1961 ensureActivitiesVisibleLocked(null, 0); 1962 } 1963 1964 // Atomically retrieve all of the other things to do. 1965 stops = processStoppingActivitiesLocked(true); 1966 NS = stops != null ? stops.size() : 0; 1967 if ((NF=mFinishingActivities.size()) > 0) { 1968 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1969 mFinishingActivities.clear(); 1970 } 1971 1972 if (isFrontStack(mHomeStack)) { 1973 booting = mService.mBooting; 1974 mService.mBooting = false; 1975 } 1976 1977 if (mStartingUsers.size() > 0) { 1978 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1979 mStartingUsers.clear(); 1980 } 1981 1982 // Stop any activities that are scheduled to do so but have been 1983 // waiting for the next one to start. 1984 for (int i = 0; i < NS; i++) { 1985 r = stops.get(i); 1986 final ActivityStack stack = r.task.stack; 1987 if (r.finishing) { 1988 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1989 } else { 1990 stack.stopActivityLocked(r); 1991 } 1992 } 1993 1994 // Finish any activities that are scheduled to do so but have been 1995 // waiting for the next one to start. 1996 for (int i = 0; i < NF; i++) { 1997 r = finishes.get(i); 1998 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1999 } 2000 2001 if (booting) { 2002 mService.finishBooting(); 2003 } else { 2004 // Complete user switch 2005 if (startingUsers != null) { 2006 for (int i = 0; i < startingUsers.size(); i++) { 2007 mService.finishUserSwitch(startingUsers.get(i)); 2008 } 2009 } 2010 // Complete starting up of background users 2011 if (mStartingBackgroundUsers.size() > 0) { 2012 startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers); 2013 mStartingBackgroundUsers.clear(); 2014 for (int i = 0; i < startingUsers.size(); i++) { 2015 mService.finishUserBoot(startingUsers.get(i)); 2016 } 2017 } 2018 } 2019 2020 mService.trimApplications(); 2021 //dump(); 2022 //mWindowManager.dump(); 2023 2024 if (enableScreen) { 2025 mService.enableScreenAfterBoot(); 2026 } 2027 2028 if (activityRemoved) { 2029 resumeTopActivitiesLocked(); 2030 } 2031 2032 return r; 2033 } 2034 2035 boolean handleAppDiedLocked(ProcessRecord app) { 2036 boolean hasVisibleActivities = false; 2037 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2038 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2039 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2040 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2041 } 2042 } 2043 return hasVisibleActivities; 2044 } 2045 2046 void closeSystemDialogsLocked() { 2047 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2048 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2049 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2050 stacks.get(stackNdx).closeSystemDialogsLocked(); 2051 } 2052 } 2053 } 2054 2055 void removeUserLocked(int userId) { 2056 mUserStackInFront.delete(userId); 2057 } 2058 2059 /** 2060 * @return true if some activity was finished (or would have finished if doit were true). 2061 */ 2062 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 2063 boolean didSomething = false; 2064 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2065 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2066 final int numStacks = stacks.size(); 2067 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2068 final ActivityStack stack = stacks.get(stackNdx); 2069 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 2070 didSomething = true; 2071 } 2072 } 2073 } 2074 return didSomething; 2075 } 2076 2077 void updatePreviousProcessLocked(ActivityRecord r) { 2078 // Now that this process has stopped, we may want to consider 2079 // it to be the previous app to try to keep around in case 2080 // the user wants to return to it. 2081 2082 // First, found out what is currently the foreground app, so that 2083 // we don't blow away the previous app if this activity is being 2084 // hosted by the process that is actually still the foreground. 2085 ProcessRecord fgApp = null; 2086 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2087 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2088 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2089 final ActivityStack stack = stacks.get(stackNdx); 2090 if (isFrontStack(stack)) { 2091 if (stack.mResumedActivity != null) { 2092 fgApp = stack.mResumedActivity.app; 2093 } else if (stack.mPausingActivity != null) { 2094 fgApp = stack.mPausingActivity.app; 2095 } 2096 break; 2097 } 2098 } 2099 } 2100 2101 // Now set this one as the previous process, only if that really 2102 // makes sense to. 2103 if (r.app != null && fgApp != null && r.app != fgApp 2104 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2105 && r.app != mService.mHomeProcess) { 2106 mService.mPreviousProcess = r.app; 2107 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2108 } 2109 } 2110 2111 boolean resumeTopActivitiesLocked() { 2112 return resumeTopActivitiesLocked(null, null, null); 2113 } 2114 2115 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 2116 Bundle targetOptions) { 2117 if (targetStack == null) { 2118 targetStack = getFocusedStack(); 2119 } 2120 // Do targetStack first. 2121 boolean result = false; 2122 if (isFrontStack(targetStack)) { 2123 result = targetStack.resumeTopActivityLocked(target, targetOptions); 2124 } 2125 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2126 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2127 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2128 final ActivityStack stack = stacks.get(stackNdx); 2129 if (stack == targetStack) { 2130 // Already started above. 2131 continue; 2132 } 2133 if (isFrontStack(stack)) { 2134 stack.resumeTopActivityLocked(null); 2135 } 2136 } 2137 } 2138 return result; 2139 } 2140 2141 void finishTopRunningActivityLocked(ProcessRecord app) { 2142 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2143 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2144 final int numStacks = stacks.size(); 2145 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2146 final ActivityStack stack = stacks.get(stackNdx); 2147 stack.finishTopRunningActivityLocked(app); 2148 } 2149 } 2150 } 2151 2152 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) { 2153 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2154 mUserLeaving = true; 2155 } 2156 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2157 // Caller wants the home activity moved with it. To accomplish this, 2158 // we'll just indicate that this task returns to the home task. 2159 task.mOnTopOfHome = true; 2160 } 2161 task.stack.moveTaskToFrontLocked(task, null, options); 2162 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" 2163 + task.stack); 2164 } 2165 2166 ActivityStack getStack(int stackId) { 2167 ActivityContainer activityContainer = mActivityContainers.get(stackId); 2168 if (activityContainer != null) { 2169 return activityContainer.mStack; 2170 } 2171 return null; 2172 } 2173 2174 ArrayList<ActivityStack> getStacks() { 2175 ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); 2176 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2177 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2178 } 2179 return allStacks; 2180 } 2181 2182 IBinder getHomeActivityToken() { 2183 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2184 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2185 final TaskRecord task = tasks.get(taskNdx); 2186 if (task.isHomeTask()) { 2187 final ArrayList<ActivityRecord> activities = task.mActivities; 2188 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2189 final ActivityRecord r = activities.get(activityNdx); 2190 if (r.isHomeActivity()) { 2191 return r.appToken; 2192 } 2193 } 2194 } 2195 } 2196 return null; 2197 } 2198 2199 ActivityContainer createActivityContainer(ActivityRecord parentActivity, 2200 IActivityContainerCallback callback) { 2201 ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback); 2202 mActivityContainers.put(activityContainer.mStackId, activityContainer); 2203 parentActivity.mChildContainers.add(activityContainer); 2204 return activityContainer; 2205 } 2206 2207 void removeChildActivityContainers(ActivityRecord parentActivity) { 2208 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 2209 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 2210 ActivityContainer container = childStacks.remove(containerNdx); 2211 container.release(); 2212 } 2213 } 2214 2215 void deleteActivityContainer(IActivityContainer container) { 2216 ActivityContainer activityContainer = (ActivityContainer)container; 2217 if (activityContainer != null) { 2218 activityContainer.mStack.finishAllActivitiesLocked(); 2219 final ActivityRecord parent = activityContainer.mParentActivity; 2220 if (parent != null) { 2221 parent.mChildContainers.remove(activityContainer); 2222 } 2223 final int stackId = activityContainer.mStackId; 2224 mActivityContainers.remove(stackId); 2225 mWindowManager.removeStack(stackId); 2226 } 2227 } 2228 2229 private int createStackOnDisplay(int stackId, int displayId) { 2230 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2231 if (activityDisplay == null) { 2232 return -1; 2233 } 2234 2235 ActivityContainer activityContainer = new ActivityContainer(stackId); 2236 mActivityContainers.put(stackId, activityContainer); 2237 activityContainer.attachToDisplayLocked(activityDisplay); 2238 return stackId; 2239 } 2240 2241 int getNextStackId() { 2242 while (true) { 2243 if (++mLastStackId <= HOME_STACK_ID) { 2244 mLastStackId = HOME_STACK_ID + 1; 2245 } 2246 if (getStack(mLastStackId) == null) { 2247 break; 2248 } 2249 } 2250 return mLastStackId; 2251 } 2252 2253 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 2254 final TaskRecord task = anyTaskForIdLocked(taskId); 2255 if (task == null) { 2256 return; 2257 } 2258 final ActivityStack stack = getStack(stackId); 2259 if (stack == null) { 2260 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 2261 return; 2262 } 2263 task.stack.removeTask(task); 2264 stack.addTask(task, toTop, true); 2265 mWindowManager.addTask(taskId, stackId, toTop); 2266 resumeTopActivitiesLocked(); 2267 } 2268 2269 ActivityRecord findTaskLocked(ActivityRecord r) { 2270 if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); 2271 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2272 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2273 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2274 final ActivityStack stack = stacks.get(stackNdx); 2275 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2276 if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); 2277 continue; 2278 } 2279 final ActivityRecord ar = stack.findTaskLocked(r); 2280 if (ar != null) { 2281 return ar; 2282 } 2283 } 2284 } 2285 if (DEBUG_TASKS) Slog.d(TAG, "No task found"); 2286 return null; 2287 } 2288 2289 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2290 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2291 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2292 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2293 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2294 if (ar != null) { 2295 return ar; 2296 } 2297 } 2298 } 2299 return null; 2300 } 2301 2302 void goingToSleepLocked() { 2303 scheduleSleepTimeout(); 2304 if (!mGoingToSleep.isHeld()) { 2305 mGoingToSleep.acquire(); 2306 if (mLaunchingActivity.isHeld()) { 2307 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2308 throw new IllegalStateException("Calling must be system uid"); 2309 } 2310 mLaunchingActivity.release(); 2311 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2312 } 2313 } 2314 checkReadyForSleepLocked(); 2315 } 2316 2317 boolean shutdownLocked(int timeout) { 2318 goingToSleepLocked(); 2319 2320 boolean timedout = false; 2321 final long endTime = System.currentTimeMillis() + timeout; 2322 while (true) { 2323 boolean cantShutdown = false; 2324 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2325 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2326 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2327 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2328 } 2329 } 2330 if (cantShutdown) { 2331 long timeRemaining = endTime - System.currentTimeMillis(); 2332 if (timeRemaining > 0) { 2333 try { 2334 mService.wait(timeRemaining); 2335 } catch (InterruptedException e) { 2336 } 2337 } else { 2338 Slog.w(TAG, "Activity manager shutdown timed out"); 2339 timedout = true; 2340 break; 2341 } 2342 } else { 2343 break; 2344 } 2345 } 2346 2347 // Force checkReadyForSleep to complete. 2348 mSleepTimeout = true; 2349 checkReadyForSleepLocked(); 2350 2351 return timedout; 2352 } 2353 2354 void comeOutOfSleepIfNeededLocked() { 2355 removeSleepTimeouts(); 2356 if (mGoingToSleep.isHeld()) { 2357 mGoingToSleep.release(); 2358 } 2359 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2360 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2361 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2362 final ActivityStack stack = stacks.get(stackNdx); 2363 stack.awakeFromSleepingLocked(); 2364 if (isFrontStack(stack)) { 2365 resumeTopActivitiesLocked(); 2366 } 2367 } 2368 } 2369 mGoingToSleepActivities.clear(); 2370 } 2371 2372 void activitySleptLocked(ActivityRecord r) { 2373 mGoingToSleepActivities.remove(r); 2374 checkReadyForSleepLocked(); 2375 } 2376 2377 void checkReadyForSleepLocked() { 2378 if (!mService.isSleepingOrShuttingDown()) { 2379 // Do not care. 2380 return; 2381 } 2382 2383 if (!mSleepTimeout) { 2384 boolean dontSleep = false; 2385 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2386 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2387 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2388 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2389 } 2390 } 2391 2392 if (mStoppingActivities.size() > 0) { 2393 // Still need to tell some activities to stop; can't sleep yet. 2394 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2395 + mStoppingActivities.size() + " activities"); 2396 scheduleIdleLocked(); 2397 dontSleep = true; 2398 } 2399 2400 if (mGoingToSleepActivities.size() > 0) { 2401 // Still need to tell some activities to sleep; can't sleep yet. 2402 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2403 + mGoingToSleepActivities.size() + " activities"); 2404 dontSleep = true; 2405 } 2406 2407 if (dontSleep) { 2408 return; 2409 } 2410 } 2411 2412 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2413 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2414 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2415 stacks.get(stackNdx).goToSleep(); 2416 } 2417 } 2418 2419 removeSleepTimeouts(); 2420 2421 if (mGoingToSleep.isHeld()) { 2422 mGoingToSleep.release(); 2423 } 2424 if (mService.mShuttingDown) { 2425 mService.notifyAll(); 2426 } 2427 } 2428 2429 boolean reportResumedActivityLocked(ActivityRecord r) { 2430 final ActivityStack stack = r.task.stack; 2431 if (isFrontStack(stack)) { 2432 mService.updateUsageStats(r, true); 2433 } 2434 if (allResumedActivitiesComplete()) { 2435 ensureActivitiesVisibleLocked(null, 0); 2436 mWindowManager.executeAppTransition(); 2437 return true; 2438 } 2439 return false; 2440 } 2441 2442 void handleAppCrashLocked(ProcessRecord app) { 2443 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2444 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2445 final int numStacks = stacks.size(); 2446 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2447 final ActivityStack stack = stacks.get(stackNdx); 2448 stack.handleAppCrashLocked(app); 2449 } 2450 } 2451 } 2452 2453 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2454 // First the front stacks. In case any are not fullscreen and are in front of home. 2455 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2456 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2457 final int topStackNdx = stacks.size() - 1; 2458 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2459 final ActivityStack stack = stacks.get(stackNdx); 2460 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2461 } 2462 } 2463 } 2464 2465 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2466 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2467 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2468 final int numStacks = stacks.size(); 2469 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2470 final ActivityStack stack = stacks.get(stackNdx); 2471 stack.scheduleDestroyActivities(app, false, reason); 2472 } 2473 } 2474 } 2475 2476 boolean switchUserLocked(int userId, UserStartedState uss) { 2477 mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); 2478 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 2479 mCurrentUser = userId; 2480 2481 mStartingUsers.add(uss); 2482 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2483 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2484 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2485 final ActivityStack stack = stacks.get(stackNdx); 2486 stack.switchUserLocked(userId); 2487 TaskRecord task = stack.topTask(); 2488 if (task != null) { 2489 mWindowManager.moveTaskToTop(task.taskId); 2490 } 2491 } 2492 } 2493 2494 ActivityStack stack = getStack(restoreStackId); 2495 if (stack == null) { 2496 stack = mHomeStack; 2497 } 2498 final boolean homeInFront = stack.isHomeStack(); 2499 if (stack.isOnHomeDisplay()) { 2500 moveHomeStack(homeInFront); 2501 TaskRecord task = stack.topTask(); 2502 if (task != null) { 2503 mWindowManager.moveTaskToTop(task.taskId); 2504 } 2505 } else { 2506 // Stack was moved to another display while user was swapped out. 2507 resumeHomeActivity(null); 2508 } 2509 return homeInFront; 2510 } 2511 2512 /** 2513 * Add background users to send boot completed events to. 2514 * @param userId The user being started in the background 2515 * @param uss The state object for the user. 2516 */ 2517 public void startBackgroundUserLocked(int userId, UserStartedState uss) { 2518 mStartingBackgroundUsers.add(uss); 2519 } 2520 2521 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2522 int N = mStoppingActivities.size(); 2523 if (N <= 0) return null; 2524 2525 ArrayList<ActivityRecord> stops = null; 2526 2527 final boolean nowVisible = allResumedActivitiesVisible(); 2528 for (int i=0; i<N; i++) { 2529 ActivityRecord s = mStoppingActivities.get(i); 2530 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2531 + nowVisible + " waitingVisible=" + s.waitingVisible 2532 + " finishing=" + s.finishing); 2533 if (s.waitingVisible && nowVisible) { 2534 mWaitingVisibleActivities.remove(s); 2535 s.waitingVisible = false; 2536 if (s.finishing) { 2537 // If this activity is finishing, it is sitting on top of 2538 // everyone else but we now know it is no longer needed... 2539 // so get rid of it. Otherwise, we need to go through the 2540 // normal flow and hide it once we determine that it is 2541 // hidden by the activities in front of it. 2542 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2543 mWindowManager.setAppVisibility(s.appToken, false); 2544 } 2545 } 2546 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2547 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2548 if (stops == null) { 2549 stops = new ArrayList<ActivityRecord>(); 2550 } 2551 stops.add(s); 2552 mStoppingActivities.remove(i); 2553 N--; 2554 i--; 2555 } 2556 } 2557 2558 return stops; 2559 } 2560 2561 void validateTopActivitiesLocked() { 2562 // FIXME 2563/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2564 final ActivityStack stack = stacks.get(stackNdx); 2565 final ActivityRecord r = stack.topRunningActivityLocked(null); 2566 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2567 if (isFrontStack(stack)) { 2568 if (r == null) { 2569 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2570 } else { 2571 final ActivityRecord pausing = stack.mPausingActivity; 2572 if (pausing != null && pausing == r) { 2573 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2574 " state=" + state); 2575 } 2576 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2577 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2578 " state=" + state); 2579 } 2580 } 2581 } else { 2582 final ActivityRecord resumed = stack.mResumedActivity; 2583 if (resumed != null && resumed == r) { 2584 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2585 " state=" + state); 2586 } 2587 if (r != null && (state == ActivityState.INITIALIZING 2588 || state == ActivityState.RESUMED)) { 2589 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2590 " state=" + state); 2591 } 2592 } 2593 } 2594*/ 2595 } 2596 2597 public void dump(PrintWriter pw, String prefix) { 2598 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); 2599 pw.println(mDismissKeyguardOnNextActivity); 2600 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 2601 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 2602 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 2603 pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); 2604 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 2605 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 2606 } 2607 2608 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2609 return getFocusedStack().getDumpActivitiesLocked(name); 2610 } 2611 2612 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2613 boolean needSep, String prefix) { 2614 if (activity != null) { 2615 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2616 if (needSep) { 2617 pw.println(); 2618 } 2619 pw.print(prefix); 2620 pw.println(activity); 2621 return true; 2622 } 2623 } 2624 return false; 2625 } 2626 2627 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2628 boolean dumpClient, String dumpPackage) { 2629 boolean printed = false; 2630 boolean needSep = false; 2631 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2632 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 2633 pw.print("Display #"); pw.println(activityDisplay.mDisplayId); 2634 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2635 final int numStacks = stacks.size(); 2636 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2637 final ActivityStack stack = stacks.get(stackNdx); 2638 StringBuilder stackHeader = new StringBuilder(128); 2639 stackHeader.append(" Stack #"); 2640 stackHeader.append(stack.mStackId); 2641 stackHeader.append(":"); 2642 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 2643 needSep, stackHeader.toString()); 2644 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 2645 !dumpAll, false, dumpPackage, true, 2646 " Running activities (most recent first):", null); 2647 2648 needSep = printed; 2649 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2650 " mPausingActivity: "); 2651 if (pr) { 2652 printed = true; 2653 needSep = false; 2654 } 2655 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2656 " mResumedActivity: "); 2657 if (pr) { 2658 printed = true; 2659 needSep = false; 2660 } 2661 if (dumpAll) { 2662 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2663 " mLastPausedActivity: "); 2664 if (pr) { 2665 printed = true; 2666 needSep = true; 2667 } 2668 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 2669 needSep, " mLastNoHistoryActivity: "); 2670 } 2671 needSep = printed; 2672 } 2673 } 2674 2675 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2676 false, dumpPackage, true, " Activities waiting to finish:", null); 2677 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2678 false, dumpPackage, true, " Activities waiting to stop:", null); 2679 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2680 false, dumpPackage, true, " Activities waiting for another to become visible:", 2681 null); 2682 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2683 false, dumpPackage, true, " Activities waiting to sleep:", null); 2684 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2685 false, dumpPackage, true, " Activities waiting to sleep:", null); 2686 2687 return printed; 2688 } 2689 2690 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2691 String prefix, String label, boolean complete, boolean brief, boolean client, 2692 String dumpPackage, boolean needNL, String header1, String header2) { 2693 TaskRecord lastTask = null; 2694 String innerPrefix = null; 2695 String[] args = null; 2696 boolean printed = false; 2697 for (int i=list.size()-1; i>=0; i--) { 2698 final ActivityRecord r = list.get(i); 2699 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2700 continue; 2701 } 2702 if (innerPrefix == null) { 2703 innerPrefix = prefix + " "; 2704 args = new String[0]; 2705 } 2706 printed = true; 2707 final boolean full = !brief && (complete || !r.isInHistory()); 2708 if (needNL) { 2709 pw.println(""); 2710 needNL = false; 2711 } 2712 if (header1 != null) { 2713 pw.println(header1); 2714 header1 = null; 2715 } 2716 if (header2 != null) { 2717 pw.println(header2); 2718 header2 = null; 2719 } 2720 if (lastTask != r.task) { 2721 lastTask = r.task; 2722 pw.print(prefix); 2723 pw.print(full ? "* " : " "); 2724 pw.println(lastTask); 2725 if (full) { 2726 lastTask.dump(pw, prefix + " "); 2727 } else if (complete) { 2728 // Complete + brief == give a summary. Isn't that obvious?!? 2729 if (lastTask.intent != null) { 2730 pw.print(prefix); pw.print(" "); 2731 pw.println(lastTask.intent.toInsecureStringWithClip()); 2732 } 2733 } 2734 } 2735 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2736 pw.print(" #"); pw.print(i); pw.print(": "); 2737 pw.println(r); 2738 if (full) { 2739 r.dump(pw, innerPrefix); 2740 } else if (complete) { 2741 // Complete + brief == give a summary. Isn't that obvious?!? 2742 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2743 if (r.app != null) { 2744 pw.print(innerPrefix); pw.println(r.app); 2745 } 2746 } 2747 if (client && r.app != null && r.app.thread != null) { 2748 // flush anything that is already in the PrintWriter since the thread is going 2749 // to write to the file descriptor directly 2750 pw.flush(); 2751 try { 2752 TransferPipe tp = new TransferPipe(); 2753 try { 2754 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2755 r.appToken, innerPrefix, args); 2756 // Short timeout, since blocking here can 2757 // deadlock with the application. 2758 tp.go(fd, 2000); 2759 } finally { 2760 tp.kill(); 2761 } 2762 } catch (IOException e) { 2763 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2764 } catch (RemoteException e) { 2765 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2766 } 2767 needNL = true; 2768 } 2769 } 2770 return printed; 2771 } 2772 2773 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2774 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2775 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2776 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2777 } 2778 2779 final void scheduleIdleLocked() { 2780 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2781 } 2782 2783 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2784 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2785 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2786 } 2787 2788 final void scheduleResumeTopActivities() { 2789 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2790 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2791 } 2792 } 2793 2794 void removeSleepTimeouts() { 2795 mSleepTimeout = false; 2796 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2797 } 2798 2799 final void scheduleSleepTimeout() { 2800 removeSleepTimeouts(); 2801 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2802 } 2803 2804 @Override 2805 public void onDisplayAdded(int displayId) { 2806 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 2807 } 2808 2809 @Override 2810 public void onDisplayRemoved(int displayId) { 2811 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 2812 } 2813 2814 @Override 2815 public void onDisplayChanged(int displayId) { 2816 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 2817 } 2818 2819 public void handleDisplayAddedLocked(int displayId) { 2820 boolean newDisplay; 2821 synchronized (mService) { 2822 newDisplay = mActivityDisplays.get(displayId) == null; 2823 if (newDisplay) { 2824 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 2825 mActivityDisplays.put(displayId, activityDisplay); 2826 } 2827 } 2828 if (newDisplay) { 2829 mWindowManager.onDisplayAdded(displayId); 2830 } 2831 } 2832 2833 public void handleDisplayRemovedLocked(int displayId) { 2834 synchronized (mService) { 2835 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2836 if (activityDisplay != null) { 2837 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 2838 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2839 stacks.get(stackNdx).mActivityContainer.detachLocked(); 2840 } 2841 mActivityDisplays.remove(displayId); 2842 } 2843 } 2844 mWindowManager.onDisplayRemoved(displayId); 2845 } 2846 2847 public void handleDisplayChangedLocked(int displayId) { 2848 synchronized (mService) { 2849 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2850 if (activityDisplay != null) { 2851 // TODO: Update the bounds. 2852 } 2853 } 2854 mWindowManager.onDisplayChanged(displayId); 2855 } 2856 2857 StackInfo getStackInfo(ActivityStack stack) { 2858 StackInfo info = new StackInfo(); 2859 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 2860 info.displayId = Display.DEFAULT_DISPLAY; 2861 info.stackId = stack.mStackId; 2862 2863 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2864 final int numTasks = tasks.size(); 2865 int[] taskIds = new int[numTasks]; 2866 String[] taskNames = new String[numTasks]; 2867 for (int i = 0; i < numTasks; ++i) { 2868 final TaskRecord task = tasks.get(i); 2869 taskIds[i] = task.taskId; 2870 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2871 : task.realActivity != null ? task.realActivity.flattenToString() 2872 : task.getTopActivity() != null ? task.getTopActivity().packageName 2873 : "unknown"; 2874 } 2875 info.taskIds = taskIds; 2876 info.taskNames = taskNames; 2877 return info; 2878 } 2879 2880 StackInfo getStackInfoLocked(int stackId) { 2881 ActivityStack stack = getStack(stackId); 2882 if (stack != null) { 2883 return getStackInfo(stack); 2884 } 2885 return null; 2886 } 2887 2888 ArrayList<StackInfo> getAllStackInfosLocked() { 2889 ArrayList<StackInfo> list = new ArrayList<StackInfo>(); 2890 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2891 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2892 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 2893 list.add(getStackInfo(stacks.get(ndx))); 2894 } 2895 } 2896 return list; 2897 } 2898 2899 void setLockTaskModeLocked(TaskRecord task) { 2900 if (task == null) { 2901 // Take out of lock task mode. 2902 mLockTaskModeTask = null; 2903 return; 2904 } 2905 if (isLockTaskModeViolation(task)) { 2906 Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task."); 2907 return; 2908 } 2909 mLockTaskModeTask = task; 2910 findTaskToMoveToFrontLocked(task, 0, null); 2911 resumeTopActivitiesLocked(); 2912 } 2913 2914 boolean isLockTaskModeViolation(TaskRecord task) { 2915 return mLockTaskModeTask != null && mLockTaskModeTask != task; 2916 } 2917 2918 void endLockTaskModeIfTaskEnding(TaskRecord task) { 2919 if (mLockTaskModeTask != null && mLockTaskModeTask == task) { 2920 mLockTaskModeTask = null; 2921 } 2922 } 2923 2924 boolean isInLockTaskMode() { 2925 return mLockTaskModeTask != null; 2926 } 2927 2928 private final class ActivityStackSupervisorHandler extends Handler { 2929 2930 public ActivityStackSupervisorHandler(Looper looper) { 2931 super(looper); 2932 } 2933 2934 void activityIdleInternal(ActivityRecord r) { 2935 synchronized (mService) { 2936 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2937 } 2938 } 2939 2940 @Override 2941 public void handleMessage(Message msg) { 2942 switch (msg.what) { 2943 case IDLE_TIMEOUT_MSG: { 2944 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2945 if (mService.mDidDexOpt) { 2946 mService.mDidDexOpt = false; 2947 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2948 nmsg.obj = msg.obj; 2949 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2950 return; 2951 } 2952 // We don't at this point know if the activity is fullscreen, 2953 // so we need to be conservative and assume it isn't. 2954 activityIdleInternal((ActivityRecord)msg.obj); 2955 } break; 2956 case IDLE_NOW_MSG: { 2957 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2958 activityIdleInternal((ActivityRecord)msg.obj); 2959 } break; 2960 case RESUME_TOP_ACTIVITY_MSG: { 2961 synchronized (mService) { 2962 resumeTopActivitiesLocked(); 2963 } 2964 } break; 2965 case SLEEP_TIMEOUT_MSG: { 2966 synchronized (mService) { 2967 if (mService.isSleepingOrShuttingDown()) { 2968 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2969 mSleepTimeout = true; 2970 checkReadyForSleepLocked(); 2971 } 2972 } 2973 } break; 2974 case LAUNCH_TIMEOUT_MSG: { 2975 if (mService.mDidDexOpt) { 2976 mService.mDidDexOpt = false; 2977 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 2978 return; 2979 } 2980 synchronized (mService) { 2981 if (mLaunchingActivity.isHeld()) { 2982 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2983 if (VALIDATE_WAKE_LOCK_CALLER 2984 && Binder.getCallingUid() != Process.myUid()) { 2985 throw new IllegalStateException("Calling must be system uid"); 2986 } 2987 mLaunchingActivity.release(); 2988 } 2989 } 2990 } break; 2991 case HANDLE_DISPLAY_ADDED: { 2992 handleDisplayAddedLocked(msg.arg1); 2993 } break; 2994 case HANDLE_DISPLAY_CHANGED: { 2995 handleDisplayChangedLocked(msg.arg1); 2996 } break; 2997 case HANDLE_DISPLAY_REMOVED: { 2998 handleDisplayRemovedLocked(msg.arg1); 2999 } break; 3000 case CONTAINER_CALLBACK_VISIBILITY: { 3001 final ActivityContainer container = (ActivityContainer) msg.obj; 3002 try { 3003 // We only send this message if mCallback is non-null. 3004 container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1); 3005 } catch (RemoteException e) { 3006 } 3007 } 3008 } 3009 } 3010 } 3011 3012 class ActivityContainer extends android.app.IActivityContainer.Stub { 3013 final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK | 3014 Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 3015 final int mStackId; 3016 IActivityContainerCallback mCallback = null; 3017 final ActivityStack mStack; 3018 ActivityRecord mParentActivity = null; 3019 String mIdString; 3020 3021 boolean mVisible = true; 3022 3023 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3024 ActivityDisplay mActivityDisplay; 3025 3026 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3027 final static int CONTAINER_STATE_NO_SURFACE = 1; 3028 final static int CONTAINER_STATE_FINISHING = 2; 3029 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3030 3031 ActivityContainer(int stackId) { 3032 synchronized (mService) { 3033 mStackId = stackId; 3034 mStack = new ActivityStack(this); 3035 mIdString = "ActivtyContainer{" + mStackId + "}"; 3036 if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); 3037 } 3038 } 3039 3040 void attachToDisplayLocked(ActivityDisplay activityDisplay) { 3041 if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this 3042 + " to display=" + activityDisplay); 3043 mActivityDisplay = activityDisplay; 3044 mStack.mDisplayId = activityDisplay.mDisplayId; 3045 mStack.mStacks = activityDisplay.mStacks; 3046 3047 activityDisplay.attachActivities(mStack); 3048 mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); 3049 } 3050 3051 @Override 3052 public void attachToDisplay(int displayId) { 3053 synchronized (mService) { 3054 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3055 if (activityDisplay == null) { 3056 return; 3057 } 3058 attachToDisplayLocked(activityDisplay); 3059 } 3060 } 3061 3062 @Override 3063 public int getDisplayId() { 3064 if (mActivityDisplay != null) { 3065 return mActivityDisplay.mDisplayId; 3066 } 3067 return -1; 3068 } 3069 3070 @Override 3071 public boolean injectEvent(InputEvent event) { 3072 final long origId = Binder.clearCallingIdentity(); 3073 try { 3074 if (mActivityDisplay != null) { 3075 return mInputManagerInternal.injectInputEvent(event, 3076 mActivityDisplay.mDisplayId, 3077 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3078 } 3079 return false; 3080 } finally { 3081 Binder.restoreCallingIdentity(origId); 3082 } 3083 } 3084 3085 @Override 3086 public void release() { 3087 mContainerState = CONTAINER_STATE_FINISHING; 3088 mStack.finishAllActivitiesLocked(); 3089 detachLocked(); 3090 mWindowManager.removeStack(mStackId); 3091 } 3092 3093 private void detachLocked() { 3094 if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" 3095 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 3096 if (mActivityDisplay != null) { 3097 mActivityDisplay.detachActivitiesLocked(mStack); 3098 mActivityDisplay = null; 3099 mStack.mDisplayId = -1; 3100 mStack.mStacks = null; 3101 mWindowManager.detachStack(mStackId); 3102 } 3103 } 3104 3105 @Override 3106 public final int startActivity(Intent intent) { 3107 mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); 3108 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3109 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3110 // TODO: Switch to user app stacks here. 3111 intent.addFlags(FORCE_NEW_TASK_FLAGS); 3112 String mimeType = intent.getType(); 3113 if (mimeType == null && intent.getData() != null 3114 && "content".equals(intent.getData().getScheme())) { 3115 mimeType = mService.getProviderMimeType(intent.getData(), userId); 3116 } 3117 return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, 0, 0, null, 3118 null, null, null, null, userId, this); 3119 } 3120 3121 @Override 3122 public final int startActivityIntentSender(IIntentSender intentSender) { 3123 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 3124 3125 if (!(intentSender instanceof PendingIntentRecord)) { 3126 throw new IllegalArgumentException("Bad PendingIntent object"); 3127 } 3128 3129 return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, 3130 null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 3131 } 3132 3133 private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { 3134 int userId = mService.handleIncomingUser(Binder.getCallingPid(), 3135 Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); 3136 if (resolvedType == null) { 3137 resolvedType = intent.getType(); 3138 if (resolvedType == null && intent.getData() != null 3139 && "content".equals(intent.getData().getScheme())) { 3140 resolvedType = mService.getProviderMimeType(intent.getData(), userId); 3141 } 3142 } 3143 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); 3144 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 3145 throw new SecurityException( 3146 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 3147 } 3148 } 3149 3150 /** Throw a SecurityException if allowEmbedded is not true */ 3151 @Override 3152 public final void checkEmbeddedAllowed(Intent intent) { 3153 checkEmbeddedAllowedInner(intent, null); 3154 } 3155 3156 /** Throw a SecurityException if allowEmbedded is not true */ 3157 @Override 3158 public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { 3159 if (!(intentSender instanceof PendingIntentRecord)) { 3160 throw new IllegalArgumentException("Bad PendingIntent object"); 3161 } 3162 PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 3163 checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, 3164 pendingIntent.key.requestResolvedType); 3165 } 3166 3167 @Override 3168 public IBinder asBinder() { 3169 return this; 3170 } 3171 3172 @Override 3173 public void setSurface(Surface surface, int width, int height, int density) { 3174 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 3175 } 3176 3177 ActivityStackSupervisor getOuter() { 3178 return ActivityStackSupervisor.this; 3179 } 3180 3181 boolean isAttached() { 3182 return mActivityDisplay != null; 3183 } 3184 3185 void getBounds(Point outBounds) { 3186 if (mActivityDisplay != null) { 3187 mActivityDisplay.getBounds(outBounds); 3188 } else { 3189 outBounds.set(0, 0); 3190 } 3191 } 3192 3193 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 3194 void setVisible(boolean visible) { 3195 if (mVisible != visible) { 3196 mVisible = visible; 3197 if (mCallback != null) { 3198 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 3199 0 /* unused */, this).sendToTarget(); 3200 } 3201 } 3202 } 3203 3204 void setDrawn() { 3205 } 3206 3207 @Override 3208 public String toString() { 3209 return mIdString + (mActivityDisplay == null ? "N" : "A"); 3210 } 3211 } 3212 3213 private class VirtualActivityContainer extends ActivityContainer { 3214 Surface mSurface; 3215 boolean mDrawn = false; 3216 3217 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 3218 super(getNextStackId()); 3219 mParentActivity = parent; 3220 mCallback = callback; 3221 mContainerState = CONTAINER_STATE_NO_SURFACE; 3222 mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 3223 } 3224 3225 @Override 3226 public void setSurface(Surface surface, int width, int height, int density) { 3227 super.setSurface(surface, width, height, density); 3228 3229 synchronized (mService) { 3230 final long origId = Binder.clearCallingIdentity(); 3231 try { 3232 setSurfaceLocked(surface, width, height, density); 3233 } finally { 3234 Binder.restoreCallingIdentity(origId); 3235 } 3236 } 3237 } 3238 3239 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 3240 if (mContainerState == CONTAINER_STATE_FINISHING) { 3241 return; 3242 } 3243 VirtualActivityDisplay virtualActivityDisplay = 3244 (VirtualActivityDisplay) mActivityDisplay; 3245 if (virtualActivityDisplay == null) { 3246 virtualActivityDisplay = 3247 new VirtualActivityDisplay(width, height, density); 3248 mActivityDisplay = virtualActivityDisplay; 3249 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 3250 attachToDisplayLocked(virtualActivityDisplay); 3251 } 3252 3253 if (mSurface != null) { 3254 mSurface.release(); 3255 } 3256 3257 mSurface = surface; 3258 if (surface != null) { 3259 mStack.resumeTopActivityLocked(null); 3260 } else { 3261 mContainerState = CONTAINER_STATE_NO_SURFACE; 3262 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 3263 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 3264 mStack.startPausingLocked(false, true); 3265 } 3266 } 3267 3268 setSurfaceIfReady(); 3269 3270 if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display=" 3271 + virtualActivityDisplay); 3272 } 3273 3274 @Override 3275 boolean isAttached() { 3276 return mSurface != null && super.isAttached(); 3277 } 3278 3279 @Override 3280 void setDrawn() { 3281 synchronized (mService) { 3282 mDrawn = true; 3283 setSurfaceIfReady(); 3284 } 3285 } 3286 3287 private void setSurfaceIfReady() { 3288 if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn + 3289 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 3290 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 3291 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 3292 mContainerState = CONTAINER_STATE_HAS_SURFACE; 3293 } 3294 } 3295 } 3296 3297 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 3298 * attached {@link ActivityStack}s */ 3299 class ActivityDisplay { 3300 /** Actual Display this object tracks. */ 3301 int mDisplayId; 3302 Display mDisplay; 3303 DisplayInfo mDisplayInfo = new DisplayInfo(); 3304 3305 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 3306 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 3307 final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 3308 3309 ActivityDisplay() { 3310 } 3311 3312 ActivityDisplay(int displayId) { 3313 init(mDisplayManager.getDisplay(displayId)); 3314 } 3315 3316 void init(Display display) { 3317 mDisplay = display; 3318 mDisplayId = display.getDisplayId(); 3319 mDisplay.getDisplayInfo(mDisplayInfo); 3320 } 3321 3322 void attachActivities(ActivityStack stack) { 3323 if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" 3324 + mDisplayId); 3325 mStacks.add(stack); 3326 } 3327 3328 void detachActivitiesLocked(ActivityStack stack) { 3329 if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack 3330 + " from displayId=" + mDisplayId); 3331 mStacks.remove(stack); 3332 } 3333 3334 void getBounds(Point bounds) { 3335 mDisplay.getDisplayInfo(mDisplayInfo); 3336 bounds.x = mDisplayInfo.appWidth; 3337 bounds.y = mDisplayInfo.appHeight; 3338 } 3339 3340 @Override 3341 public String toString() { 3342 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 3343 } 3344 } 3345 3346 class VirtualActivityDisplay extends ActivityDisplay { 3347 VirtualDisplay mVirtualDisplay; 3348 3349 VirtualActivityDisplay(int width, int height, int density) { 3350 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3351 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, VIRTUAL_DISPLAY_BASE_NAME, 3352 width, height, density, null, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 3353 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); 3354 3355 init(mVirtualDisplay.getDisplay()); 3356 3357 mWindowManager.handleDisplayAdded(mDisplayId); 3358 } 3359 3360 void setSurface(Surface surface) { 3361 if (mVirtualDisplay != null) { 3362 mVirtualDisplay.setSurface(surface); 3363 } 3364 } 3365 3366 @Override 3367 void detachActivitiesLocked(ActivityStack stack) { 3368 super.detachActivitiesLocked(stack); 3369 if (mVirtualDisplay != null) { 3370 mVirtualDisplay.release(); 3371 mVirtualDisplay = null; 3372 } 3373 } 3374 3375 @Override 3376 public String toString() { 3377 return "VirtualActivityDisplay={" + mDisplayId + "}"; 3378 } 3379 } 3380} 3381