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