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