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