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