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