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