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