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