ActivityStackSupervisor.java revision f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130c
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_PAUSE; 26import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS; 27import static com.android.server.am.ActivityManagerService.DEBUG_STACK; 28import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH; 29import static com.android.server.am.ActivityManagerService.DEBUG_TASKS; 30import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING; 31import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 32import static com.android.server.am.ActivityManagerService.TAG; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityOptions; 37import android.app.AppGlobals; 38import android.app.IActivityManager; 39import android.app.IApplicationThread; 40import android.app.IThumbnailReceiver; 41import android.app.PendingIntent; 42import android.app.ActivityManager.RunningTaskInfo; 43import android.app.IActivityManager.WaitResult; 44import android.app.ResultInfo; 45import android.content.ComponentName; 46import android.content.Context; 47import android.content.IIntentSender; 48import android.content.Intent; 49import android.content.IntentSender; 50import android.content.pm.ActivityInfo; 51import android.content.pm.ApplicationInfo; 52import android.content.pm.PackageManager; 53import android.content.pm.ResolveInfo; 54import android.content.res.Configuration; 55import android.os.Binder; 56import android.os.Bundle; 57import android.os.Debug; 58import android.os.Handler; 59import android.os.IBinder; 60import android.os.Looper; 61import android.os.Message; 62import android.os.ParcelFileDescriptor; 63import android.os.PowerManager; 64import android.os.RemoteException; 65import android.os.SystemClock; 66import android.os.UserHandle; 67import android.util.EventLog; 68import android.util.Slog; 69import android.util.SparseArray; 70 71import com.android.internal.app.HeavyWeightSwitcherActivity; 72import com.android.internal.os.TransferPipe; 73import com.android.server.am.ActivityManagerService.PendingActivityLaunch; 74import com.android.server.am.ActivityStack.ActivityState; 75import com.android.server.wm.StackBox; 76import com.android.server.wm.WindowManagerService; 77 78import java.io.FileDescriptor; 79import java.io.IOException; 80import java.io.PrintWriter; 81import java.util.ArrayList; 82import java.util.List; 83 84public final class ActivityStackSupervisor { 85 static final boolean DEBUG = ActivityManagerService.DEBUG || false; 86 static final boolean DEBUG_ADD_REMOVE = DEBUG || false; 87 static final boolean DEBUG_APP = DEBUG || false; 88 static final boolean DEBUG_SAVED_STATE = DEBUG || false; 89 static final boolean DEBUG_STATES = DEBUG || false; 90 static final boolean DEBUG_IDLE = DEBUG || false; 91 92 public static final int HOME_STACK_ID = 0; 93 94 /** How long we wait until giving up on the last activity telling us it is idle. */ 95 static final int IDLE_TIMEOUT = 10*1000; 96 97 /** How long we can hold the sleep wake lock before giving up. */ 98 static final int SLEEP_TIMEOUT = 5*1000; 99 100 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 101 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 102 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 103 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 104 105 final ActivityManagerService mService; 106 final Context mContext; 107 final Looper mLooper; 108 109 final ActivityStackSupervisorHandler mHandler; 110 111 /** Short cut */ 112 WindowManagerService mWindowManager; 113 114 /** Dismiss the keyguard after the next activity is displayed? */ 115 private boolean mDismissKeyguardOnNextActivity = false; 116 117 /** Identifier counter for all ActivityStacks */ 118 private int mLastStackId = HOME_STACK_ID; 119 120 /** Task identifier that activities are currently being started in. Incremented each time a 121 * new task is created. */ 122 private int mCurTaskId = 0; 123 124 /** The current user */ 125 private int mCurrentUser; 126 127 /** The stack containing the launcher app */ 128 private ActivityStack mHomeStack; 129 130 /** The non-home stack currently receiving input or launching the next activity. If home is 131 * in front then mHomeStack overrides mFocusedStack. 132 * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */ 133 private ActivityStack mFocusedStack; 134 135 /** All the non-launcher stacks */ 136 private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); 137 138 private static final int STACK_STATE_HOME_IN_FRONT = 0; 139 private static final int STACK_STATE_HOME_TO_BACK = 1; 140 private static final int STACK_STATE_HOME_IN_BACK = 2; 141 private static final int STACK_STATE_HOME_TO_FRONT = 3; 142 private int mStackState = STACK_STATE_HOME_IN_FRONT; 143 144 /** List of activities that are waiting for a new activity to become visible before completing 145 * whatever operation they are supposed to do. */ 146 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>(); 147 148 /** List of processes waiting to find out about the next visible activity. */ 149 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = 150 new ArrayList<IActivityManager.WaitResult>(); 151 152 /** List of processes waiting to find out about the next launched activity. */ 153 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = 154 new ArrayList<IActivityManager.WaitResult>(); 155 156 /** List of activities that are ready to be stopped, but waiting for the next activity to 157 * settle down before doing so. */ 158 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>(); 159 160 /** List of activities that are ready to be finished, but waiting for the previous activity to 161 * settle down before doing so. It contains ActivityRecord objects. */ 162 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>(); 163 164 /** List of activities that are in the process of going to sleep. */ 165 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>(); 166 167 /** List of ActivityRecord objects that have been finished and must still report back to a 168 * pending thumbnail receiver. */ 169 final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>(); 170 171 /** Used on user changes */ 172 final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>(); 173 174 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 175 * is being brought in front of us. */ 176 boolean mUserLeaving = false; 177 178 /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */ 179 final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); 180 181 /** Set when we have taken too long waiting to go to sleep. */ 182 boolean mSleepTimeout = false; 183 184 /** 185 * Set when the system is going to sleep, until we have 186 * successfully paused the current activity and released our wake lock. 187 * At that point the system is allowed to actually sleep. 188 */ 189 final PowerManager.WakeLock mGoingToSleep; 190 191 public ActivityStackSupervisor(ActivityManagerService service, Context context, 192 Looper looper) { 193 mService = service; 194 mContext = context; 195 mLooper = looper; 196 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 197 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 198 mHandler = new ActivityStackSupervisorHandler(looper); 199 } 200 201 void setWindowManager(WindowManagerService wm) { 202 mWindowManager = wm; 203 mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID); 204 mStacks.add(mHomeStack); 205 } 206 207 void dismissKeyguard() { 208 if (mDismissKeyguardOnNextActivity) { 209 mDismissKeyguardOnNextActivity = false; 210 mWindowManager.dismissKeyguard(); 211 } 212 } 213 214 ActivityStack getFocusedStack() { 215 if (mFocusedStack == null) { 216 return mHomeStack; 217 } 218 switch (mStackState) { 219 case STACK_STATE_HOME_IN_FRONT: 220 case STACK_STATE_HOME_TO_FRONT: 221 return mHomeStack; 222 case STACK_STATE_HOME_IN_BACK: 223 case STACK_STATE_HOME_TO_BACK: 224 default: 225 return mFocusedStack; 226 } 227 } 228 229 ActivityStack getLastStack() { 230 switch (mStackState) { 231 case STACK_STATE_HOME_IN_FRONT: 232 case STACK_STATE_HOME_TO_BACK: 233 return mHomeStack; 234 case STACK_STATE_HOME_TO_FRONT: 235 case STACK_STATE_HOME_IN_BACK: 236 default: 237 return mFocusedStack; 238 } 239 } 240 241 boolean isFrontStack(ActivityStack stack) { 242 return (stack.mCurrentUser == mCurrentUser) && 243 !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); 244 } 245 246 void moveHomeStack(boolean toFront) { 247 final boolean homeInFront = isFrontStack(mHomeStack); 248 if (homeInFront ^ toFront) { 249 if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" + 250 stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ? 251 STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT)); 252 mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT; 253 } 254 } 255 256 boolean resumeHomeActivity(ActivityRecord prev) { 257 moveHomeStack(true); 258 if (prev != null) { 259 prev.mLaunchHomeTaskNext = false; 260 } 261 if (mHomeStack.topRunningActivityLocked(null) != null) { 262 return resumeTopActivitiesLocked(mHomeStack, prev, null); 263 } 264 return mService.startHomeActivityLocked(mCurrentUser); 265 } 266 267 final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r, 268 ActivityStack stack) { 269 if (stack == mHomeStack) { 270 return; 271 } 272 if ((sourceRecord == null && getLastStack() == mHomeStack) || 273 (sourceRecord != null && sourceRecord.isHomeActivity())) { 274 if (r == null) { 275 r = stack.topRunningActivityLocked(null); 276 } 277 if (r != null && !r.isHomeActivity() && r.isRootActivity()) { 278 r.mLaunchHomeTaskNext = true; 279 } 280 } 281 } 282 283 void setDismissKeyguard(boolean dismiss) { 284 mDismissKeyguardOnNextActivity = dismiss; 285 } 286 287 TaskRecord anyTaskForIdLocked(int id) { 288 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 289 ActivityStack stack = mStacks.get(stackNdx); 290 TaskRecord task = stack.taskForIdLocked(id); 291 if (task != null) { 292 return task; 293 } 294 } 295 return null; 296 } 297 298 ActivityRecord isInAnyStackLocked(IBinder token) { 299 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 300 final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token); 301 if (r != null) { 302 return r; 303 } 304 } 305 return null; 306 } 307 308 int getNextTaskId() { 309 do { 310 mCurTaskId++; 311 if (mCurTaskId <= 0) { 312 mCurTaskId = 1; 313 } 314 } while (anyTaskForIdLocked(mCurTaskId) != null); 315 return mCurTaskId; 316 } 317 318 void removeTask(TaskRecord task) { 319 mWindowManager.removeTask(task.taskId); 320 final ActivityStack stack = task.stack; 321 final ActivityRecord r = stack.mResumedActivity; 322 if (r != null && r.task == task) { 323 stack.mResumedActivity = null; 324 } 325 if (stack.removeTask(task) && !stack.isHomeStack()) { 326 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); 327 mStacks.remove(stack); 328 final int stackId = stack.mStackId; 329 final int nextStackId = mWindowManager.removeStack(stackId); 330 // TODO: Perhaps we need to let the ActivityManager determine the next focus... 331 if (getFocusedStack().mStackId == stackId) { 332 // If this is the last app stack, set mFocusedStack to null. 333 mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); 334 } 335 } 336 } 337 338 ActivityRecord resumedAppLocked() { 339 ActivityStack stack = getFocusedStack(); 340 if (stack == null) { 341 return null; 342 } 343 ActivityRecord resumedActivity = stack.mResumedActivity; 344 if (resumedActivity == null || resumedActivity.app == null) { 345 resumedActivity = stack.mPausingActivity; 346 if (resumedActivity == null || resumedActivity.app == null) { 347 resumedActivity = stack.topRunningActivityLocked(null); 348 } 349 } 350 return resumedActivity; 351 } 352 353 boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { 354 boolean didSomething = false; 355 final String processName = app.processName; 356 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 357 final ActivityStack stack = mStacks.get(stackNdx); 358 if (!isFrontStack(stack)) { 359 continue; 360 } 361 ActivityRecord hr = stack.topRunningActivityLocked(null); 362 if (hr != null) { 363 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 364 && processName.equals(hr.processName)) { 365 try { 366 if (headless) { 367 Slog.e(TAG, "Starting activities not supported on headless device: " 368 + hr); 369 } else if (realStartActivityLocked(hr, app, true, true)) { 370 didSomething = true; 371 } 372 } catch (Exception e) { 373 Slog.w(TAG, "Exception in new application when starting activity " 374 + hr.intent.getComponent().flattenToShortString(), e); 375 throw e; 376 } 377 } 378 } 379 } 380 if (!didSomething) { 381 ensureActivitiesVisibleLocked(null, 0); 382 } 383 return didSomething; 384 } 385 386 boolean allResumedActivitiesIdle() { 387 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 388 final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity; 389 if (resumedActivity == null || !resumedActivity.idle) { 390 return false; 391 } 392 } 393 return true; 394 } 395 396 boolean allResumedActivitiesComplete() { 397 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 398 final ActivityStack stack = mStacks.get(stackNdx); 399 if (isFrontStack(stack)) { 400 final ActivityRecord r = stack.mResumedActivity; 401 if (r != null && r.state != ActivityState.RESUMED) { 402 return false; 403 } 404 } 405 } 406 // TODO: Not sure if this should check if all Paused are complete too. 407 switch (mStackState) { 408 case STACK_STATE_HOME_TO_BACK: 409 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 410 stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" + 411 stackStateToString(STACK_STATE_HOME_IN_BACK)); 412 mStackState = STACK_STATE_HOME_IN_BACK; 413 break; 414 case STACK_STATE_HOME_TO_FRONT: 415 if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + 416 stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" + 417 stackStateToString(STACK_STATE_HOME_IN_FRONT)); 418 mStackState = STACK_STATE_HOME_IN_FRONT; 419 break; 420 } 421 return true; 422 } 423 424 boolean allResumedActivitiesVisible() { 425 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 426 final ActivityStack stack = mStacks.get(stackNdx); 427 final ActivityRecord r = stack.mResumedActivity; 428 if (r != null && (!r.nowVisible || r.waitingVisible)) { 429 return false; 430 } 431 } 432 return true; 433 } 434 435 boolean pauseBackStacks(boolean userLeaving) { 436 boolean someActivityPaused = false; 437 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 438 final ActivityStack stack = mStacks.get(stackNdx); 439 if (!isFrontStack(stack) && stack.mResumedActivity != null) { 440 stack.startPausingLocked(userLeaving, false); 441 someActivityPaused = true; 442 } 443 } 444 return someActivityPaused; 445 } 446 447 boolean allPausedActivitiesComplete() { 448 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 449 final ActivityStack stack = mStacks.get(stackNdx); 450 final ActivityRecord r = stack.mPausingActivity; 451 if (r != null && r.state != ActivityState.PAUSED 452 && r.state != ActivityState.STOPPED 453 && r.state != ActivityState.STOPPING) { 454 return false; 455 } 456 } 457 return true; 458 } 459 460 void reportActivityVisibleLocked(ActivityRecord r) { 461 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 462 WaitResult w = mWaitingActivityVisible.get(i); 463 w.timeout = false; 464 if (r != null) { 465 w.who = new ComponentName(r.info.packageName, r.info.name); 466 } 467 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 468 w.thisTime = w.totalTime; 469 } 470 mService.notifyAll(); 471 dismissKeyguard(); 472 } 473 474 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 475 long thisTime, long totalTime) { 476 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 477 WaitResult w = mWaitingActivityLaunched.remove(i); 478 w.timeout = timeout; 479 if (r != null) { 480 w.who = new ComponentName(r.info.packageName, r.info.name); 481 } 482 w.thisTime = thisTime; 483 w.totalTime = totalTime; 484 } 485 mService.notifyAll(); 486 } 487 488 ActivityRecord topRunningActivityLocked() { 489 final ActivityStack focusedStack = getFocusedStack(); 490 ActivityRecord r = focusedStack.topRunningActivityLocked(null); 491 if (r != null) { 492 return r; 493 } 494 495 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 496 final ActivityStack stack = mStacks.get(stackNdx); 497 if (stack.mCurrentUser == mCurrentUser && stack != focusedStack && 498 isFrontStack(stack)) { 499 r = stack.topRunningActivityLocked(null); 500 if (r != null) { 501 return r; 502 } 503 } 504 } 505 return null; 506 } 507 508 ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, 509 PendingThumbnailsRecord pending, List<RunningTaskInfo> list) { 510 ActivityRecord r = null; 511 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 512 final ActivityStack stack = mStacks.get(stackNdx); 513 final ActivityRecord ar = 514 stack.getTasksLocked(maxNum - list.size(), receiver, pending, list); 515 if (isFrontStack(stack)) { 516 r = ar; 517 } 518 } 519 return r; 520 } 521 522 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 523 String profileFile, ParcelFileDescriptor profileFd, int userId) { 524 // Collect information about the target of the Intent. 525 ActivityInfo aInfo; 526 try { 527 ResolveInfo rInfo = 528 AppGlobals.getPackageManager().resolveIntent( 529 intent, resolvedType, 530 PackageManager.MATCH_DEFAULT_ONLY 531 | ActivityManagerService.STOCK_PM_FLAGS, userId); 532 aInfo = rInfo != null ? rInfo.activityInfo : null; 533 } catch (RemoteException e) { 534 aInfo = null; 535 } 536 537 if (aInfo != null) { 538 // Store the found target back into the intent, because now that 539 // we have it we never want to do this again. For example, if the 540 // user navigates back to this point in the history, we should 541 // always restart the exact same activity. 542 intent.setComponent(new ComponentName( 543 aInfo.applicationInfo.packageName, aInfo.name)); 544 545 // Don't debug things in the system process 546 if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) { 547 if (!aInfo.processName.equals("system")) { 548 mService.setDebugApp(aInfo.processName, true, false); 549 } 550 } 551 552 if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) { 553 if (!aInfo.processName.equals("system")) { 554 mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName); 555 } 556 } 557 558 if (profileFile != null) { 559 if (!aInfo.processName.equals("system")) { 560 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, 561 profileFile, profileFd, 562 (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0); 563 } 564 } 565 } 566 return aInfo; 567 } 568 569 void startHomeActivity(Intent intent, ActivityInfo aInfo) { 570 moveHomeStack(true); 571 startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, 572 null, false, null); 573 } 574 575 final int startActivityMayWait(IApplicationThread caller, int callingUid, 576 String callingPackage, Intent intent, String resolvedType, IBinder resultTo, 577 String resultWho, int requestCode, int startFlags, String profileFile, 578 ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, 579 Bundle options, int userId) { 580 // Refuse possible leaked file descriptors 581 if (intent != null && intent.hasFileDescriptors()) { 582 throw new IllegalArgumentException("File descriptors passed in Intent"); 583 } 584 boolean componentSpecified = intent.getComponent() != null; 585 586 // Don't modify the client's object! 587 intent = new Intent(intent); 588 589 // Collect information about the target of the Intent. 590 ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 591 profileFile, profileFd, userId); 592 593 synchronized (mService) { 594 int callingPid; 595 if (callingUid >= 0) { 596 callingPid = -1; 597 } else if (caller == null) { 598 callingPid = Binder.getCallingPid(); 599 callingUid = Binder.getCallingUid(); 600 } else { 601 callingPid = callingUid = -1; 602 } 603 604 final ActivityStack stack = getFocusedStack(); 605 stack.mConfigWillChange = config != null 606 && mService.mConfiguration.diff(config) != 0; 607 if (DEBUG_CONFIGURATION) Slog.v(TAG, 608 "Starting activity when config will change = " + stack.mConfigWillChange); 609 610 final long origId = Binder.clearCallingIdentity(); 611 612 if (aInfo != null && 613 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 614 // This may be a heavy-weight process! Check to see if we already 615 // have another, different heavy-weight process running. 616 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 617 if (mService.mHeavyWeightProcess != null && 618 (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid || 619 !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) { 620 int realCallingUid = callingUid; 621 if (caller != null) { 622 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 623 if (callerApp != null) { 624 realCallingUid = callerApp.info.uid; 625 } else { 626 Slog.w(TAG, "Unable to find app for caller " + caller 627 + " (pid=" + callingPid + ") when starting: " 628 + intent.toString()); 629 ActivityOptions.abort(options); 630 return ActivityManager.START_PERMISSION_DENIED; 631 } 632 } 633 634 IIntentSender target = mService.getIntentSenderLocked( 635 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 636 realCallingUid, userId, null, null, 0, new Intent[] { intent }, 637 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 638 | PendingIntent.FLAG_ONE_SHOT, null); 639 640 Intent newIntent = new Intent(); 641 if (requestCode >= 0) { 642 // Caller is requesting a result. 643 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 644 } 645 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 646 new IntentSender(target)); 647 if (mService.mHeavyWeightProcess.activities.size() > 0) { 648 ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0); 649 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 650 hist.packageName); 651 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 652 hist.task.taskId); 653 } 654 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 655 aInfo.packageName); 656 newIntent.setFlags(intent.getFlags()); 657 newIntent.setClassName("android", 658 HeavyWeightSwitcherActivity.class.getName()); 659 intent = newIntent; 660 resolvedType = null; 661 caller = null; 662 callingUid = Binder.getCallingUid(); 663 callingPid = Binder.getCallingPid(); 664 componentSpecified = true; 665 try { 666 ResolveInfo rInfo = 667 AppGlobals.getPackageManager().resolveIntent( 668 intent, null, 669 PackageManager.MATCH_DEFAULT_ONLY 670 | ActivityManagerService.STOCK_PM_FLAGS, userId); 671 aInfo = rInfo != null ? rInfo.activityInfo : null; 672 aInfo = mService.getActivityInfoForUser(aInfo, userId); 673 } catch (RemoteException e) { 674 aInfo = null; 675 } 676 } 677 } 678 } 679 680 int res = startActivityLocked(caller, intent, resolvedType, 681 aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, 682 callingPackage, startFlags, options, componentSpecified, null); 683 684 if (stack.mConfigWillChange) { 685 // If the caller also wants to switch to a new configuration, 686 // do so now. This allows a clean switch, as we are waiting 687 // for the current activity to pause (so we will not destroy 688 // it), and have not yet started the next activity. 689 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 690 "updateConfiguration()"); 691 stack.mConfigWillChange = false; 692 if (DEBUG_CONFIGURATION) Slog.v(TAG, 693 "Updating to new configuration after starting activity."); 694 mService.updateConfigurationLocked(config, null, false, false); 695 } 696 697 Binder.restoreCallingIdentity(origId); 698 699 if (outResult != null) { 700 outResult.result = res; 701 if (res == ActivityManager.START_SUCCESS) { 702 mWaitingActivityLaunched.add(outResult); 703 do { 704 try { 705 mService.wait(); 706 } catch (InterruptedException e) { 707 } 708 } while (!outResult.timeout && outResult.who == null); 709 } else if (res == ActivityManager.START_TASK_TO_FRONT) { 710 ActivityRecord r = stack.topRunningActivityLocked(null); 711 if (r.nowVisible) { 712 outResult.timeout = false; 713 outResult.who = new ComponentName(r.info.packageName, r.info.name); 714 outResult.totalTime = 0; 715 outResult.thisTime = 0; 716 } else { 717 outResult.thisTime = SystemClock.uptimeMillis(); 718 mWaitingActivityVisible.add(outResult); 719 do { 720 try { 721 mService.wait(); 722 } catch (InterruptedException e) { 723 } 724 } while (!outResult.timeout && outResult.who == null); 725 } 726 } 727 } 728 729 return res; 730 } 731 } 732 733 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 734 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 735 Bundle options, int userId) { 736 if (intents == null) { 737 throw new NullPointerException("intents is null"); 738 } 739 if (resolvedTypes == null) { 740 throw new NullPointerException("resolvedTypes is null"); 741 } 742 if (intents.length != resolvedTypes.length) { 743 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 744 } 745 746 747 int callingPid; 748 if (callingUid >= 0) { 749 callingPid = -1; 750 } else if (caller == null) { 751 callingPid = Binder.getCallingPid(); 752 callingUid = Binder.getCallingUid(); 753 } else { 754 callingPid = callingUid = -1; 755 } 756 final long origId = Binder.clearCallingIdentity(); 757 try { 758 synchronized (mService) { 759 ActivityRecord[] outActivity = new ActivityRecord[1]; 760 for (int i=0; i<intents.length; i++) { 761 Intent intent = intents[i]; 762 if (intent == null) { 763 continue; 764 } 765 766 // Refuse possible leaked file descriptors 767 if (intent != null && intent.hasFileDescriptors()) { 768 throw new IllegalArgumentException("File descriptors passed in Intent"); 769 } 770 771 boolean componentSpecified = intent.getComponent() != null; 772 773 // Don't modify the client's object! 774 intent = new Intent(intent); 775 776 // Collect information about the target of the Intent. 777 ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 778 0, null, null, userId); 779 // TODO: New, check if this is correct 780 aInfo = mService.getActivityInfoForUser(aInfo, userId); 781 782 if (aInfo != null && 783 (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) 784 != 0) { 785 throw new IllegalArgumentException( 786 "FLAG_CANT_SAVE_STATE not supported here"); 787 } 788 789 Bundle theseOptions; 790 if (options != null && i == intents.length-1) { 791 theseOptions = options; 792 } else { 793 theseOptions = null; 794 } 795 int res = startActivityLocked(caller, intent, resolvedTypes[i], 796 aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, 797 0, theseOptions, componentSpecified, outActivity); 798 if (res < 0) { 799 return res; 800 } 801 802 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 803 } 804 } 805 } finally { 806 Binder.restoreCallingIdentity(origId); 807 } 808 809 return ActivityManager.START_SUCCESS; 810 } 811 812 final boolean realStartActivityLocked(ActivityRecord r, 813 ProcessRecord app, boolean andResume, boolean checkConfig) 814 throws RemoteException { 815 816 r.startFreezingScreenLocked(app, 0); 817 mWindowManager.setAppVisibility(r.appToken, true); 818 819 // schedule launch ticks to collect information about slow apps. 820 r.startLaunchTickingLocked(); 821 822 // Have the window manager re-evaluate the orientation of 823 // the screen based on the new activity order. Note that 824 // as a result of this, it can call back into the activity 825 // manager with a new orientation. We don't care about that, 826 // because the activity is not currently running so we are 827 // just restarting it anyway. 828 if (checkConfig) { 829 Configuration config = mWindowManager.updateOrientationFromAppTokens( 830 mService.mConfiguration, 831 r.mayFreezeScreenLocked(app) ? r.appToken : null); 832 mService.updateConfigurationLocked(config, r, false, false); 833 } 834 835 r.app = app; 836 app.waitingToKill = null; 837 r.launchCount++; 838 r.lastLaunchTime = SystemClock.uptimeMillis(); 839 840 if (localLOGV) Slog.v(TAG, "Launching: " + r); 841 842 int idx = app.activities.indexOf(r); 843 if (idx < 0) { 844 app.activities.add(r); 845 } 846 mService.updateLruProcessLocked(app, true); 847 848 final ActivityStack stack = r.task.stack; 849 try { 850 if (app.thread == null) { 851 throw new RemoteException(); 852 } 853 List<ResultInfo> results = null; 854 List<Intent> newIntents = null; 855 if (andResume) { 856 results = r.results; 857 newIntents = r.newIntents; 858 } 859 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 860 + " icicle=" + r.icicle 861 + " with results=" + results + " newIntents=" + newIntents 862 + " andResume=" + andResume); 863 if (andResume) { 864 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 865 r.userId, System.identityHashCode(r), 866 r.task.taskId, r.shortComponentName); 867 } 868 if (r.isHomeActivity()) { 869 mService.mHomeProcess = app; 870 } 871 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 872 r.sleeping = false; 873 r.forceNewConfig = false; 874 mService.showAskCompatModeDialogLocked(r); 875 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 876 String profileFile = null; 877 ParcelFileDescriptor profileFd = null; 878 boolean profileAutoStop = false; 879 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 880 if (mService.mProfileProc == null || mService.mProfileProc == app) { 881 mService.mProfileProc = app; 882 profileFile = mService.mProfileFile; 883 profileFd = mService.mProfileFd; 884 profileAutoStop = mService.mAutoStopProfiler; 885 } 886 } 887 app.hasShownUi = true; 888 app.pendingUiClean = true; 889 if (profileFd != null) { 890 try { 891 profileFd = profileFd.dup(); 892 } catch (IOException e) { 893 if (profileFd != null) { 894 try { 895 profileFd.close(); 896 } catch (IOException o) { 897 } 898 profileFd = null; 899 } 900 } 901 } 902 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 903 System.identityHashCode(r), r.info, 904 new Configuration(mService.mConfiguration), 905 r.compat, r.icicle, results, newIntents, !andResume, 906 mService.isNextTransitionForward(), profileFile, profileFd, 907 profileAutoStop); 908 909 if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { 910 // This may be a heavy-weight process! Note that the package 911 // manager will ensure that only activity can run in the main 912 // process of the .apk, which is the only thing that will be 913 // considered heavy-weight. 914 if (app.processName.equals(app.info.packageName)) { 915 if (mService.mHeavyWeightProcess != null 916 && mService.mHeavyWeightProcess != app) { 917 Slog.w(TAG, "Starting new heavy weight process " + app 918 + " when already running " 919 + mService.mHeavyWeightProcess); 920 } 921 mService.mHeavyWeightProcess = app; 922 Message msg = mService.mHandler.obtainMessage( 923 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 924 msg.obj = r; 925 mService.mHandler.sendMessage(msg); 926 } 927 } 928 929 } catch (RemoteException e) { 930 if (r.launchFailed) { 931 // This is the second time we failed -- finish activity 932 // and give up. 933 Slog.e(TAG, "Second failure launching " 934 + r.intent.getComponent().flattenToShortString() 935 + ", giving up", e); 936 mService.appDiedLocked(app, app.pid, app.thread); 937 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 938 "2nd-crash", false); 939 return false; 940 } 941 942 // This is the first time we failed -- restart process and 943 // retry. 944 app.activities.remove(r); 945 throw e; 946 } 947 948 r.launchFailed = false; 949 if (stack.updateLRUListLocked(r)) { 950 Slog.w(TAG, "Activity " + r 951 + " being launched, but already in LRU list"); 952 } 953 954 if (andResume) { 955 // As part of the process of launching, ActivityThread also performs 956 // a resume. 957 stack.minimalResumeActivityLocked(r); 958 } else { 959 // This activity is not starting in the resumed state... which 960 // should look like we asked it to pause+stop (but remain visible), 961 // and it has done so and reported back the current icicle and 962 // other state. 963 if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r 964 + " (starting in stopped state)"); 965 r.state = ActivityState.STOPPED; 966 r.stopped = true; 967 } 968 969 // Launch the new version setup screen if needed. We do this -after- 970 // launching the initial activity (that is, home), so that it can have 971 // a chance to initialize itself while in the background, making the 972 // switch back to it faster and look better. 973 if (isFrontStack(stack)) { 974 mService.startSetupActivityLocked(); 975 } 976 977 return true; 978 } 979 980 void startSpecificActivityLocked(ActivityRecord r, 981 boolean andResume, boolean checkConfig) { 982 // Is this activity's application already running? 983 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 984 r.info.applicationInfo.uid); 985 986 r.task.stack.setLaunchTime(r); 987 988 if (app != null && app.thread != null) { 989 try { 990 app.addPackage(r.info.packageName, mService.mProcessTracker); 991 realStartActivityLocked(r, app, andResume, checkConfig); 992 return; 993 } catch (RemoteException e) { 994 Slog.w(TAG, "Exception when starting activity " 995 + r.intent.getComponent().flattenToShortString(), e); 996 } 997 998 // If a dead object exception was thrown -- fall through to 999 // restart the application. 1000 } 1001 1002 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1003 "activity", r.intent.getComponent(), false, false); 1004 } 1005 1006 final int startActivityLocked(IApplicationThread caller, 1007 Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, 1008 String resultWho, int requestCode, 1009 int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, 1010 boolean componentSpecified, ActivityRecord[] outActivity) { 1011 int err = ActivityManager.START_SUCCESS; 1012 1013 ProcessRecord callerApp = null; 1014 if (caller != null) { 1015 callerApp = mService.getRecordForAppLocked(caller); 1016 if (callerApp != null) { 1017 callingPid = callerApp.pid; 1018 callingUid = callerApp.info.uid; 1019 } else { 1020 Slog.w(TAG, "Unable to find app for caller " + caller 1021 + " (pid=" + callingPid + ") when starting: " 1022 + intent.toString()); 1023 err = ActivityManager.START_PERMISSION_DENIED; 1024 } 1025 } 1026 1027 if (err == ActivityManager.START_SUCCESS) { 1028 final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 1029 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 1030 + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); 1031 } 1032 1033 ActivityRecord sourceRecord = null; 1034 ActivityRecord resultRecord = null; 1035 if (resultTo != null) { 1036 sourceRecord = isInAnyStackLocked(resultTo); 1037 if (DEBUG_RESULTS) Slog.v( 1038 TAG, "Will send result to " + resultTo + " " + sourceRecord); 1039 if (sourceRecord != null) { 1040 if (requestCode >= 0 && !sourceRecord.finishing) { 1041 resultRecord = sourceRecord; 1042 } 1043 } 1044 } 1045 ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; 1046 1047 int launchFlags = intent.getFlags(); 1048 1049 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 1050 && sourceRecord != null) { 1051 // Transfer the result target from the source activity to the new 1052 // one being started, including any failures. 1053 if (requestCode >= 0) { 1054 ActivityOptions.abort(options); 1055 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 1056 } 1057 resultRecord = sourceRecord.resultTo; 1058 resultWho = sourceRecord.resultWho; 1059 requestCode = sourceRecord.requestCode; 1060 sourceRecord.resultTo = null; 1061 if (resultRecord != null) { 1062 resultRecord.removeResultsLocked( 1063 sourceRecord, resultWho, requestCode); 1064 } 1065 } 1066 1067 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1068 // We couldn't find a class that can handle the given Intent. 1069 // That's the end of that! 1070 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1071 } 1072 1073 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1074 // We couldn't find the specific class specified in the Intent. 1075 // Also the end of the line. 1076 err = ActivityManager.START_CLASS_NOT_FOUND; 1077 } 1078 1079 if (err != ActivityManager.START_SUCCESS) { 1080 if (resultRecord != null) { 1081 resultStack.sendActivityResultLocked(-1, 1082 resultRecord, resultWho, requestCode, 1083 Activity.RESULT_CANCELED, null); 1084 } 1085 setDismissKeyguard(false); 1086 ActivityOptions.abort(options); 1087 return err; 1088 } 1089 1090 final int startAnyPerm = mService.checkPermission( 1091 START_ANY_ACTIVITY, callingPid, callingUid); 1092 final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, 1093 callingUid, aInfo.applicationInfo.uid, aInfo.exported); 1094 if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) { 1095 if (resultRecord != null) { 1096 resultStack.sendActivityResultLocked(-1, 1097 resultRecord, resultWho, requestCode, 1098 Activity.RESULT_CANCELED, null); 1099 } 1100 setDismissKeyguard(false); 1101 String msg; 1102 if (!aInfo.exported) { 1103 msg = "Permission Denial: starting " + intent.toString() 1104 + " from " + callerApp + " (pid=" + callingPid 1105 + ", uid=" + callingUid + ")" 1106 + " not exported from uid " + aInfo.applicationInfo.uid; 1107 } else { 1108 msg = "Permission Denial: starting " + intent.toString() 1109 + " from " + callerApp + " (pid=" + callingPid 1110 + ", uid=" + callingUid + ")" 1111 + " requires " + aInfo.permission; 1112 } 1113 Slog.w(TAG, msg); 1114 throw new SecurityException(msg); 1115 } 1116 1117 boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, 1118 callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo); 1119 1120 if (mService.mController != null) { 1121 try { 1122 // The Intent we give to the watcher has the extra data 1123 // stripped off, since it can contain private information. 1124 Intent watchIntent = intent.cloneFilter(); 1125 abort |= !mService.mController.activityStarting(watchIntent, 1126 aInfo.applicationInfo.packageName); 1127 } catch (RemoteException e) { 1128 mService.mController = null; 1129 } 1130 } 1131 1132 if (abort) { 1133 if (resultRecord != null) { 1134 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, 1135 Activity.RESULT_CANCELED, null); 1136 } 1137 // We pretend to the caller that it was really started, but 1138 // they will just get a cancel result. 1139 setDismissKeyguard(false); 1140 ActivityOptions.abort(options); 1141 return ActivityManager.START_SUCCESS; 1142 } 1143 1144 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 1145 intent, resolvedType, aInfo, mService.mConfiguration, 1146 resultRecord, resultWho, requestCode, componentSpecified, this); 1147 if (outActivity != null) { 1148 outActivity[0] = r; 1149 } 1150 1151 final ActivityStack stack = getFocusedStack(); 1152 if (stack.mResumedActivity == null 1153 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) { 1154 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 1155 PendingActivityLaunch pal = 1156 new PendingActivityLaunch(r, sourceRecord, startFlags, stack); 1157 mService.mPendingActivityLaunches.add(pal); 1158 setDismissKeyguard(false); 1159 ActivityOptions.abort(options); 1160 return ActivityManager.START_SWITCHES_CANCELED; 1161 } 1162 } 1163 1164 if (mService.mDidAppSwitch) { 1165 // This is the second allowed switch since we stopped switches, 1166 // so now just generally allow switches. Use case: user presses 1167 // home (switches disabled, switch to home, mDidAppSwitch now true); 1168 // user taps a home icon (coming from home so allowed, we hit here 1169 // and now allow anyone to switch again). 1170 mService.mAppSwitchesAllowedTime = 0; 1171 } else { 1172 mService.mDidAppSwitch = true; 1173 } 1174 1175 mService.doPendingActivityLaunchesLocked(false); 1176 1177 err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); 1178 if (stack.mPausingActivity == null) { 1179 // Someone asked to have the keyguard dismissed on the next 1180 // activity start, but we are not actually doing an activity 1181 // switch... just dismiss the keyguard now, because we 1182 // probably want to see whatever is behind it. 1183 dismissKeyguard(); 1184 } 1185 return err; 1186 } 1187 1188 ActivityStack getCorrectStack(ActivityRecord r) { 1189 final TaskRecord task = r.task; 1190 if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { 1191 int stackNdx; 1192 for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) { 1193 if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) { 1194 break; 1195 } 1196 } 1197 if (stackNdx == 0) { 1198 // Time to create the first app stack for this user. 1199 int stackId = mService.createStack(-1, HOME_STACK_ID, 1200 StackBox.TASK_STACK_GOES_OVER, 1.0f); 1201 mFocusedStack = getStack(stackId); 1202 } 1203 if (task != null) { 1204 mFocusedStack = task.stack; 1205 } 1206 return mFocusedStack; 1207 } 1208 return mHomeStack; 1209 } 1210 1211 void setFocusedStack(ActivityRecord r) { 1212 if (r == null) { 1213 return; 1214 } 1215 if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) { 1216 if (mStackState != STACK_STATE_HOME_IN_FRONT) { 1217 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1218 stackStateToString(mStackState) + " new=" + 1219 stackStateToString(STACK_STATE_HOME_TO_FRONT) + 1220 " Callers=" + Debug.getCallers(3)); 1221 mStackState = STACK_STATE_HOME_TO_FRONT; 1222 } 1223 } else { 1224 mFocusedStack = r.task.stack; 1225 if (mStackState != STACK_STATE_HOME_IN_BACK) { 1226 if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" + 1227 stackStateToString(mStackState) + " new=" + 1228 stackStateToString(STACK_STATE_HOME_TO_BACK) + 1229 " Callers=" + Debug.getCallers(3)); 1230 mStackState = STACK_STATE_HOME_TO_BACK; 1231 } 1232 } 1233 } 1234 1235 final int startActivityUncheckedLocked(ActivityRecord r, 1236 ActivityRecord sourceRecord, int startFlags, boolean doResume, 1237 Bundle options) { 1238 final Intent intent = r.intent; 1239 final int callingUid = r.launchedFromUid; 1240 1241 int launchFlags = intent.getFlags(); 1242 1243 // We'll invoke onUserLeaving before onPause only if the launching 1244 // activity did not explicitly state that this is an automated launch. 1245 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1246 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving); 1247 1248 // If the caller has asked not to resume at this point, we make note 1249 // of this in the record so that we can skip it when trying to find 1250 // the top running activity. 1251 if (!doResume) { 1252 r.delayedResume = true; 1253 } 1254 1255 ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1256 1257 // If the onlyIfNeeded flag is set, then we can do this if the activity 1258 // being launched is the same as the one making the call... or, as 1259 // a special case, if we do not know the caller then we count the 1260 // current top activity as the caller. 1261 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1262 ActivityRecord checkedCaller = sourceRecord; 1263 if (checkedCaller == null) { 1264 checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); 1265 } 1266 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1267 // Caller is not the same as launcher, so always needed. 1268 startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED; 1269 } 1270 } 1271 1272 if (sourceRecord == null) { 1273 // This activity is not being started from another... in this 1274 // case we -always- start a new task. 1275 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1276 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1277 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 1278 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1279 } 1280 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1281 // The original activity who is starting us is running as a single 1282 // instance... this new activity it is starting must go on its 1283 // own task. 1284 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1285 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 1286 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1287 // The activity being started is a single instance... it always 1288 // gets launched into its own task. 1289 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 1290 } 1291 1292 final ActivityStack sourceStack; 1293 TaskRecord sourceTask; 1294 if (sourceRecord != null) { 1295 sourceTask = sourceRecord.task; 1296 sourceStack = sourceTask.stack; 1297 } else { 1298 sourceTask = null; 1299 sourceStack = null; 1300 } 1301 1302 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1303 // For whatever reason this activity is being launched into a new 1304 // task... yet the caller has requested a result back. Well, that 1305 // is pretty messed up, so instead immediately send back a cancel 1306 // and let the new task continue launched as normal without a 1307 // dependency on its originator. 1308 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1309 r.resultTo.task.stack.sendActivityResultLocked(-1, 1310 r.resultTo, r.resultWho, r.requestCode, 1311 Activity.RESULT_CANCELED, null); 1312 r.resultTo = null; 1313 } 1314 1315 boolean addingToTask = false; 1316 boolean movedHome = false; 1317 TaskRecord reuseTask = null; 1318 ActivityStack targetStack; 1319 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 1320 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1321 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1322 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1323 // If bring to front is requested, and no result is requested, and 1324 // we can find a task that was started with this same 1325 // component, then instead of launching bring that one to the front. 1326 if (r.resultTo == null) { 1327 // See if there is a task to bring to the front. If this is 1328 // a SINGLE_INSTANCE activity, there can be one and only one 1329 // instance of it in the history, and it is always in its own 1330 // unique task, so we do a special search. 1331 ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 1332 ? findTaskLocked(intent, r.info) 1333 : findActivityLocked(intent, r.info); 1334 if (intentActivity != null) { 1335 if (r.task == null) { 1336 r.task = intentActivity.task; 1337 } 1338 targetStack = intentActivity.task.stack; 1339 moveHomeStack(targetStack.isHomeStack()); 1340 if (intentActivity.task.intent == null) { 1341 // This task was started because of movement of 1342 // the activity based on affinity... now that we 1343 // are actually launching it, we can assign the 1344 // base intent. 1345 intentActivity.task.setIntent(intent, r.info); 1346 } 1347 // If the target task is not in the front, then we need 1348 // to bring it to the front... except... well, with 1349 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 1350 // to have the same behavior as if a new instance was 1351 // being started, which means not bringing it to the front 1352 // if the caller is not itself in the front. 1353 final ActivityStack lastStack = getLastStack(); 1354 ActivityRecord curTop = lastStack == null? 1355 null : lastStack.topRunningNonDelayedActivityLocked(notTop); 1356 if (curTop != null && curTop.task != intentActivity.task) { 1357 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1358 if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) { 1359 // We really do want to push this one into the 1360 // user's face, right now. 1361 movedHome = true; 1362 if ((launchFlags & 1363 (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1364 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1365 // Caller wants to appear on home activity, so before starting 1366 // their own activity we will bring home to the front. 1367 r.mLaunchHomeTaskNext = true; 1368 } 1369 targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); 1370 options = null; 1371 } 1372 } 1373 // If the caller has requested that the target task be 1374 // reset, then do so. 1375 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1376 intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r); 1377 } 1378 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1379 // We don't need to start a new activity, and 1380 // the client said not to do anything if that 1381 // is the case, so this is it! And for paranoia, make 1382 // sure we have correctly resumed the top activity. 1383 if (doResume) { 1384 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1385 resumeTopActivitiesLocked(targetStack, null, options); 1386 } else { 1387 ActivityOptions.abort(options); 1388 } 1389 if (r.task == null) Slog.v(TAG, 1390 "startActivityUncheckedLocked: task left null", 1391 new RuntimeException("here").fillInStackTrace()); 1392 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1393 } 1394 if ((launchFlags & 1395 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) 1396 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { 1397 // The caller has requested to completely replace any 1398 // existing task with its new activity. Well that should 1399 // not be too hard... 1400 reuseTask = intentActivity.task; 1401 reuseTask.performClearTaskLocked(); 1402 reuseTask.setIntent(r.intent, r.info); 1403 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 1404 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 1405 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 1406 // In this situation we want to remove all activities 1407 // from the task up to the one being started. In most 1408 // cases this means we are resetting the task to its 1409 // initial state. 1410 ActivityRecord top = 1411 intentActivity.task.performClearTaskLocked(r, launchFlags); 1412 if (top != null) { 1413 if (top.frontOfTask) { 1414 // Activity aliases may mean we use different 1415 // intents for the top activity, so make sure 1416 // the task now has the identity of the new 1417 // intent. 1418 top.task.setIntent(r.intent, r.info); 1419 } 1420 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, 1421 r, top.task); 1422 top.deliverNewIntentLocked(callingUid, r.intent); 1423 } else { 1424 // A special case: we need to 1425 // start the activity because it is not currently 1426 // running, and the caller has asked to clear the 1427 // current task to have this activity at the top. 1428 addingToTask = true; 1429 // Now pretend like this activity is being started 1430 // by the top of its task, so it is put in the 1431 // right place. 1432 sourceRecord = intentActivity; 1433 } 1434 } else if (r.realActivity.equals(intentActivity.task.realActivity)) { 1435 // In this case the top activity on the task is the 1436 // same as the one being launched, so we take that 1437 // as a request to bring the task to the foreground. 1438 // If the top activity in the task is the root 1439 // activity, deliver this new intent to it if it 1440 // desires. 1441 if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1442 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) 1443 && intentActivity.realActivity.equals(r.realActivity)) { 1444 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, 1445 intentActivity.task); 1446 if (intentActivity.frontOfTask) { 1447 intentActivity.task.setIntent(r.intent, r.info); 1448 } 1449 intentActivity.deliverNewIntentLocked(callingUid, r.intent); 1450 } else if (!r.intent.filterEquals(intentActivity.task.intent)) { 1451 // In this case we are launching the root activity 1452 // of the task, but with a different intent. We 1453 // should start a new instance on top. 1454 addingToTask = true; 1455 sourceRecord = intentActivity; 1456 } 1457 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1458 // In this case an activity is being launched in to an 1459 // existing task, without resetting that task. This 1460 // is typically the situation of launching an activity 1461 // from a notification or shortcut. We want to place 1462 // the new activity on top of the current task. 1463 addingToTask = true; 1464 sourceRecord = intentActivity; 1465 } else if (!intentActivity.task.rootWasReset) { 1466 // In this case we are launching in to an existing task 1467 // that has not yet been started from its front door. 1468 // The current task has been brought to the front. 1469 // Ideally, we'd probably like to place this new task 1470 // at the bottom of its stack, but that's a little hard 1471 // to do with the current organization of the code so 1472 // for now we'll just drop it. 1473 intentActivity.task.setIntent(r.intent, r.info); 1474 } 1475 if (!addingToTask && reuseTask == null) { 1476 // We didn't do anything... but it was needed (a.k.a., client 1477 // don't use that intent!) And for paranoia, make 1478 // sure we have correctly resumed the top activity. 1479 if (doResume) { 1480 setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack); 1481 targetStack.resumeTopActivityLocked(null, options); 1482 } else { 1483 ActivityOptions.abort(options); 1484 } 1485 if (r.task == null) Slog.v(TAG, 1486 "startActivityUncheckedLocked: task left null", 1487 new RuntimeException("here").fillInStackTrace()); 1488 return ActivityManager.START_TASK_TO_FRONT; 1489 } 1490 } 1491 } 1492 } 1493 1494 //String uri = r.intent.toURI(); 1495 //Intent intent2 = new Intent(uri); 1496 //Slog.i(TAG, "Given intent: " + r.intent); 1497 //Slog.i(TAG, "URI is: " + uri); 1498 //Slog.i(TAG, "To intent: " + intent2); 1499 1500 if (r.packageName != null) { 1501 // If the activity being launched is the same as the one currently 1502 // at the top, then we need to check if it should only be launched 1503 // once. 1504 ActivityStack topStack = getFocusedStack(); 1505 ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); 1506 if (top != null && r.resultTo == null) { 1507 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { 1508 if (top.app != null && top.app.thread != null) { 1509 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 1510 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 1511 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 1512 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, 1513 top.task); 1514 // For paranoia, make sure we have correctly 1515 // resumed the top activity. 1516 if (doResume) { 1517 setLaunchHomeTaskNextFlag(sourceRecord, null, topStack); 1518 resumeTopActivitiesLocked(); 1519 } 1520 ActivityOptions.abort(options); 1521 if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { 1522 // We don't need to start a new activity, and 1523 // the client said not to do anything if that 1524 // is the case, so this is it! 1525 if (r.task == null) Slog.v(TAG, 1526 "startActivityUncheckedLocked: task left null", 1527 new RuntimeException("here").fillInStackTrace()); 1528 return ActivityManager.START_RETURN_INTENT_TO_CALLER; 1529 } 1530 top.deliverNewIntentLocked(callingUid, r.intent); 1531 if (r.task == null) Slog.v(TAG, 1532 "startActivityUncheckedLocked: task left null", 1533 new RuntimeException("here").fillInStackTrace()); 1534 return ActivityManager.START_DELIVERED_TO_TOP; 1535 } 1536 } 1537 } 1538 } 1539 1540 } else { 1541 if (r.resultTo != null) { 1542 r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 1543 r.requestCode, Activity.RESULT_CANCELED, null); 1544 } 1545 ActivityOptions.abort(options); 1546 if (r.task == null) Slog.v(TAG, 1547 "startActivityUncheckedLocked: task left null", 1548 new RuntimeException("here").fillInStackTrace()); 1549 return ActivityManager.START_CLASS_NOT_FOUND; 1550 } 1551 1552 boolean newTask = false; 1553 boolean keepCurTransition = false; 1554 1555 // Should this be considered a new task? 1556 if (r.resultTo == null && !addingToTask 1557 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 1558 targetStack = getCorrectStack(r); 1559 moveHomeStack(targetStack.isHomeStack()); 1560 if (reuseTask == null) { 1561 r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1562 null, true); 1563 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + 1564 r.task); 1565 } else { 1566 r.setTask(reuseTask, reuseTask, true); 1567 } 1568 newTask = true; 1569 if (!movedHome) { 1570 if ((launchFlags & 1571 (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) 1572 == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { 1573 // Caller wants to appear on home activity, so before starting 1574 // their own activity we will bring home to the front. 1575 r.mLaunchHomeTaskNext = true; 1576 } 1577 } 1578 } else if (sourceRecord != null) { 1579 sourceTask = sourceRecord.task; 1580 targetStack = sourceTask.stack; 1581 moveHomeStack(targetStack.isHomeStack()); 1582 if (!addingToTask && 1583 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1584 // In this case, we are adding the activity to an existing 1585 // task, but the caller has asked to clear that task if the 1586 // activity is already running. 1587 ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); 1588 keepCurTransition = true; 1589 if (top != null) { 1590 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 1591 top.deliverNewIntentLocked(callingUid, r.intent); 1592 // For paranoia, make sure we have correctly 1593 // resumed the top activity. 1594 if (doResume) { 1595 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1596 targetStack.resumeTopActivityLocked(null); 1597 } 1598 ActivityOptions.abort(options); 1599 if (r.task == null) Slog.v(TAG, 1600 "startActivityUncheckedLocked: task left null", 1601 new RuntimeException("here").fillInStackTrace()); 1602 return ActivityManager.START_DELIVERED_TO_TOP; 1603 } 1604 } else if (!addingToTask && 1605 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1606 // In this case, we are launching an activity in our own task 1607 // that may already be running somewhere in the history, and 1608 // we want to shuffle it to the front of the stack if so. 1609 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); 1610 if (top != null) { 1611 final TaskRecord task = top.task; 1612 task.moveActivityToFrontLocked(top); 1613 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); 1614 top.updateOptionsLocked(options); 1615 top.deliverNewIntentLocked(callingUid, r.intent); 1616 if (doResume) { 1617 setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack); 1618 targetStack.resumeTopActivityLocked(null); 1619 } 1620 if (r.task == null) Slog.v(TAG, 1621 "startActivityUncheckedLocked: task left null", 1622 new RuntimeException("here").fillInStackTrace()); 1623 return ActivityManager.START_DELIVERED_TO_TOP; 1624 } 1625 } 1626 // An existing activity is starting this new activity, so we want 1627 // to keep the new one in the same task as the one that is starting 1628 // it. 1629 r.setTask(sourceTask, sourceRecord.thumbHolder, false); 1630 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1631 + " in existing task " + r.task); 1632 1633 } else { 1634 // This not being started from an existing activity, and not part 1635 // of a new task... just put it in the top task, though these days 1636 // this case should never happen. 1637 targetStack = getCorrectStack(r); 1638 moveHomeStack(targetStack.isHomeStack()); 1639 ActivityRecord prev = targetStack.topActivity(); 1640 r.setTask(prev != null ? prev.task 1641 : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), 1642 null, true); 1643 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 1644 + " in new guessed " + r.task); 1645 } 1646 1647 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 1648 intent, r.getUriPermissionsLocked()); 1649 1650 if (newTask) { 1651 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId); 1652 } 1653 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 1654 setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack); 1655 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); 1656 mService.setFocusedActivityLocked(r); 1657 return ActivityManager.START_SUCCESS; 1658 } 1659 1660 // Checked. 1661 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1662 Configuration config) { 1663 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 1664 1665 ActivityRecord res = null; 1666 1667 ArrayList<ActivityRecord> stops = null; 1668 ArrayList<ActivityRecord> finishes = null; 1669 ArrayList<UserStartedState> startingUsers = null; 1670 int NS = 0; 1671 int NF = 0; 1672 IApplicationThread sendThumbnail = null; 1673 boolean booting = false; 1674 boolean enableScreen = false; 1675 boolean activityRemoved = false; 1676 1677 ActivityRecord r = ActivityRecord.forToken(token); 1678 if (r != null) { 1679 if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" + 1680 Debug.getCallers(4)); 1681 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1682 r.finishLaunchTickingLocked(); 1683 res = r.task.stack.activityIdleInternalLocked(token); 1684 if (res != null) { 1685 if (fromTimeout) { 1686 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1687 } 1688 1689 // This is a hack to semi-deal with a race condition 1690 // in the client where it can be constructed with a 1691 // newer configuration from when we asked it to launch. 1692 // We'll update with whatever configuration it now says 1693 // it used to launch. 1694 if (config != null) { 1695 r.configuration = config; 1696 } 1697 1698 // We are now idle. If someone is waiting for a thumbnail from 1699 // us, we can now deliver. 1700 r.idle = true; 1701 if (allResumedActivitiesIdle()) { 1702 mService.scheduleAppGcsLocked(); 1703 } 1704 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 1705 sendThumbnail = r.app.thread; 1706 r.thumbnailNeeded = false; 1707 } 1708 1709 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1710 if (!mService.mBooted && isFrontStack(r.task.stack)) { 1711 mService.mBooted = true; 1712 enableScreen = true; 1713 } 1714 } else if (fromTimeout) { 1715 reportActivityLaunchedLocked(fromTimeout, null, -1, -1); 1716 } 1717 } 1718 1719 // Atomically retrieve all of the other things to do. 1720 stops = processStoppingActivitiesLocked(true); 1721 NS = stops != null ? stops.size() : 0; 1722 if ((NF=mFinishingActivities.size()) > 0) { 1723 finishes = new ArrayList<ActivityRecord>(mFinishingActivities); 1724 mFinishingActivities.clear(); 1725 } 1726 1727 final ArrayList<ActivityRecord> thumbnails; 1728 final int NT = mCancelledThumbnails.size(); 1729 if (NT > 0) { 1730 thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails); 1731 mCancelledThumbnails.clear(); 1732 } else { 1733 thumbnails = null; 1734 } 1735 1736 if (isFrontStack(mHomeStack)) { 1737 booting = mService.mBooting; 1738 mService.mBooting = false; 1739 } 1740 1741 if (mStartingUsers.size() > 0) { 1742 startingUsers = new ArrayList<UserStartedState>(mStartingUsers); 1743 mStartingUsers.clear(); 1744 } 1745 1746 // Perform the following actions from unsynchronized state. 1747 final IApplicationThread thumbnailThread = sendThumbnail; 1748 mHandler.post(new Runnable() { 1749 @Override 1750 public void run() { 1751 if (thumbnailThread != null) { 1752 try { 1753 thumbnailThread.requestThumbnail(token); 1754 } catch (Exception e) { 1755 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 1756 mService.sendPendingThumbnail(null, token, null, null, true); 1757 } 1758 } 1759 1760 // Report back to any thumbnail receivers. 1761 for (int i = 0; i < NT; i++) { 1762 ActivityRecord r = thumbnails.get(i); 1763 mService.sendPendingThumbnail(r, null, null, null, true); 1764 } 1765 } 1766 }); 1767 1768 // Stop any activities that are scheduled to do so but have been 1769 // waiting for the next one to start. 1770 for (int i = 0; i < NS; i++) { 1771 r = stops.get(i); 1772 final ActivityStack stack = r.task.stack; 1773 if (r.finishing) { 1774 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1775 } else { 1776 stack.stopActivityLocked(r); 1777 } 1778 } 1779 1780 // Finish any activities that are scheduled to do so but have been 1781 // waiting for the next one to start. 1782 for (int i = 0; i < NF; i++) { 1783 r = finishes.get(i); 1784 activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle"); 1785 } 1786 1787 if (booting) { 1788 mService.finishBooting(); 1789 } else if (startingUsers != null) { 1790 for (int i = 0; i < startingUsers.size(); i++) { 1791 mService.finishUserSwitch(startingUsers.get(i)); 1792 } 1793 } 1794 1795 mService.trimApplications(); 1796 //dump(); 1797 //mWindowManager.dump(); 1798 1799 if (enableScreen) { 1800 mService.enableScreenAfterBoot(); 1801 } 1802 1803 if (activityRemoved) { 1804 resumeTopActivitiesLocked(); 1805 } 1806 1807 return res; 1808 } 1809 1810 void handleAppDiedLocked(ProcessRecord app, boolean restarting) { 1811 // Just in case. 1812 final int numStacks = mStacks.size(); 1813 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1814 mStacks.get(stackNdx).handleAppDiedLocked(app, restarting); 1815 } 1816 } 1817 1818 void closeSystemDialogsLocked() { 1819 final int numStacks = mStacks.size(); 1820 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1821 final ActivityStack stack = mStacks.get(stackNdx); 1822 stack.closeSystemDialogsLocked(); 1823 } 1824 } 1825 1826 /** 1827 * @return true if some activity was finished (or would have finished if doit were true). 1828 */ 1829 boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { 1830 boolean didSomething = false; 1831 final int numStacks = mStacks.size(); 1832 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1833 final ActivityStack stack = mStacks.get(stackNdx); 1834 if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 1835 didSomething = true; 1836 } 1837 } 1838 return didSomething; 1839 } 1840 1841 boolean resumeTopActivitiesLocked() { 1842 return resumeTopActivitiesLocked(null, null, null); 1843 } 1844 1845 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, 1846 Bundle targetOptions) { 1847 if (targetStack == null) { 1848 targetStack = getFocusedStack(); 1849 } 1850 boolean result = false; 1851 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1852 final ActivityStack stack = mStacks.get(stackNdx); 1853 if (isFrontStack(stack)) { 1854 if (stack == targetStack) { 1855 result = stack.resumeTopActivityLocked(target, targetOptions); 1856 } else { 1857 stack.resumeTopActivityLocked(null); 1858 } 1859 } 1860 } 1861 return result; 1862 } 1863 1864 void finishTopRunningActivityLocked(ProcessRecord app) { 1865 final int numStacks = mStacks.size(); 1866 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1867 final ActivityStack stack = mStacks.get(stackNdx); 1868 stack.finishTopRunningActivityLocked(app); 1869 } 1870 } 1871 1872 void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { 1873 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1874 if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { 1875 if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + 1876 mStacks.get(stackNdx)); 1877 return; 1878 } 1879 } 1880 } 1881 1882 ActivityStack getStack(int stackId) { 1883 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1884 final ActivityStack stack = mStacks.get(stackNdx); 1885 if (stack.getStackId() == stackId) { 1886 return stack; 1887 } 1888 } 1889 return null; 1890 } 1891 1892 ArrayList<ActivityStack> getStacks() { 1893 return new ArrayList<ActivityStack>(mStacks); 1894 } 1895 1896 int createStack() { 1897 while (true) { 1898 if (++mLastStackId <= HOME_STACK_ID) { 1899 mLastStackId = HOME_STACK_ID + 1; 1900 } 1901 if (getStack(mLastStackId) == null) { 1902 break; 1903 } 1904 } 1905 mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); 1906 return mLastStackId; 1907 } 1908 1909 void moveTaskToStack(int taskId, int stackId, boolean toTop) { 1910 final TaskRecord task = anyTaskForIdLocked(taskId); 1911 if (task == null) { 1912 return; 1913 } 1914 final ActivityStack stack = getStack(stackId); 1915 if (stack == null) { 1916 Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); 1917 return; 1918 } 1919 removeTask(task); 1920 stack.addTask(task, toTop); 1921 mWindowManager.addTask(taskId, stackId, toTop); 1922 resumeTopActivitiesLocked(); 1923 } 1924 1925 ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) { 1926 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1927 final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info); 1928 if (ar != null) { 1929 return ar; 1930 } 1931 } 1932 return null; 1933 } 1934 1935 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 1936 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1937 final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info); 1938 if (ar != null) { 1939 return ar; 1940 } 1941 } 1942 return null; 1943 } 1944 1945 void goingToSleepLocked() { 1946 scheduleSleepTimeout(); 1947 if (!mGoingToSleep.isHeld()) { 1948 mGoingToSleep.acquire(); 1949 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1950 final ActivityStack stack = mStacks.get(stackNdx); 1951 if (stack.mResumedActivity != null) { 1952 stack.stopIfSleepingLocked(); 1953 } 1954 } 1955 } 1956 } 1957 1958 boolean shutdownLocked(int timeout) { 1959 boolean timedout = false; 1960 goingToSleepLocked(); 1961 checkReadyForSleepLocked(); 1962 1963 final long endTime = System.currentTimeMillis() + timeout; 1964 while (true) { 1965 boolean cantShutdown = false; 1966 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1967 cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 1968 } 1969 if (cantShutdown) { 1970 long timeRemaining = endTime - System.currentTimeMillis(); 1971 if (timeRemaining > 0) { 1972 try { 1973 mService.wait(timeRemaining); 1974 } catch (InterruptedException e) { 1975 } 1976 } else { 1977 Slog.w(TAG, "Activity manager shutdown timed out"); 1978 timedout = true; 1979 break; 1980 } 1981 } else { 1982 break; 1983 } 1984 } 1985 1986 // Force checkReadyForSleep to complete. 1987 mSleepTimeout = true; 1988 checkReadyForSleepLocked(); 1989 1990 return timedout; 1991 } 1992 1993 void comeOutOfSleepIfNeededLocked() { 1994 removeSleepTimeouts(); 1995 if (mGoingToSleep.isHeld()) { 1996 mGoingToSleep.release(); 1997 } 1998 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1999 final ActivityStack stack = mStacks.get(stackNdx); 2000 stack.awakeFromSleepingLocked(); 2001 if (isFrontStack(stack)) { 2002 resumeTopActivitiesLocked(); 2003 } 2004 } 2005 mGoingToSleepActivities.clear(); 2006 } 2007 2008 void activitySleptLocked(ActivityRecord r) { 2009 mGoingToSleepActivities.remove(r); 2010 checkReadyForSleepLocked(); 2011 } 2012 2013 void checkReadyForSleepLocked() { 2014 if (!mService.isSleepingOrShuttingDown()) { 2015 // Do not care. 2016 return; 2017 } 2018 2019 if (!mSleepTimeout) { 2020 boolean dontSleep = false; 2021 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2022 dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked(); 2023 } 2024 2025 if (mStoppingActivities.size() > 0) { 2026 // Still need to tell some activities to stop; can't sleep yet. 2027 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " 2028 + mStoppingActivities.size() + " activities"); 2029 scheduleIdleLocked(); 2030 dontSleep = true; 2031 } 2032 2033 if (mGoingToSleepActivities.size() > 0) { 2034 // Still need to tell some activities to sleep; can't sleep yet. 2035 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep " 2036 + mGoingToSleepActivities.size() + " activities"); 2037 dontSleep = true; 2038 } 2039 2040 if (dontSleep) { 2041 return; 2042 } 2043 } 2044 2045 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2046 mStacks.get(stackNdx).goToSleep(); 2047 } 2048 2049 removeSleepTimeouts(); 2050 2051 if (mGoingToSleep.isHeld()) { 2052 mGoingToSleep.release(); 2053 } 2054 if (mService.mShuttingDown) { 2055 mService.notifyAll(); 2056 } 2057 } 2058 2059 boolean reportResumedActivityLocked(ActivityRecord r) { 2060 final ActivityStack stack = r.task.stack; 2061 if (isFrontStack(stack)) { 2062 mService.updateUsageStats(r, true); 2063 } 2064 if (allResumedActivitiesComplete()) { 2065 ensureActivitiesVisibleLocked(null, 0); 2066 mWindowManager.executeAppTransition(); 2067 return true; 2068 } 2069 return false; 2070 } 2071 2072 void handleAppCrashLocked(ProcessRecord app) { 2073 final int numStacks = mStacks.size(); 2074 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2075 final ActivityStack stack = mStacks.get(stackNdx); 2076 stack.handleAppCrashLocked(app); 2077 } 2078 } 2079 2080 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { 2081 // First the front stacks. In case any are not fullscreen and are in front of home. 2082 boolean showHomeBehindStack = false; 2083 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2084 final ActivityStack stack = mStacks.get(stackNdx); 2085 if (isFrontStack(stack)) { 2086 showHomeBehindStack = 2087 stack.ensureActivitiesVisibleLocked(starting, configChanges); 2088 } 2089 } 2090 // Now do back stacks. 2091 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2092 final ActivityStack stack = mStacks.get(stackNdx); 2093 if (!isFrontStack(stack)) { 2094 stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack); 2095 } 2096 } 2097 } 2098 2099 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2100 final int numStacks = mStacks.size(); 2101 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2102 final ActivityStack stack = mStacks.get(stackNdx); 2103 stack.scheduleDestroyActivities(app, false, reason); 2104 } 2105 } 2106 2107 boolean switchUserLocked(int userId, UserStartedState uss) { 2108 mUserStates.put(mCurrentUser, new UserState()); 2109 mCurrentUser = userId; 2110 UserState userState = mUserStates.get(userId); 2111 if (userState != null) { 2112 userState.restore(); 2113 mUserStates.delete(userId); 2114 } else { 2115 mFocusedStack = null; 2116 if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" + 2117 stackStateToString(STACK_STATE_HOME_IN_FRONT)); 2118 mStackState = STACK_STATE_HOME_IN_FRONT; 2119 } 2120 2121 mStartingUsers.add(uss); 2122 boolean haveActivities = mHomeStack.switchUserLocked(userId); 2123 2124 resumeTopActivitiesLocked(); 2125 2126 return haveActivities; 2127 } 2128 2129 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 2130 int N = mStoppingActivities.size(); 2131 if (N <= 0) return null; 2132 2133 ArrayList<ActivityRecord> stops = null; 2134 2135 final boolean nowVisible = allResumedActivitiesVisible(); 2136 for (int i=0; i<N; i++) { 2137 ActivityRecord s = mStoppingActivities.get(i); 2138 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 2139 + nowVisible + " waitingVisible=" + s.waitingVisible 2140 + " finishing=" + s.finishing); 2141 if (s.waitingVisible && nowVisible) { 2142 mWaitingVisibleActivities.remove(s); 2143 s.waitingVisible = false; 2144 if (s.finishing) { 2145 // If this activity is finishing, it is sitting on top of 2146 // everyone else but we now know it is no longer needed... 2147 // so get rid of it. Otherwise, we need to go through the 2148 // normal flow and hide it once we determine that it is 2149 // hidden by the activities in front of it. 2150 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 2151 mWindowManager.setAppVisibility(s.appToken, false); 2152 } 2153 } 2154 if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 2155 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 2156 if (stops == null) { 2157 stops = new ArrayList<ActivityRecord>(); 2158 } 2159 stops.add(s); 2160 mStoppingActivities.remove(i); 2161 N--; 2162 i--; 2163 } 2164 } 2165 2166 return stops; 2167 } 2168 2169 void validateTopActivitiesLocked() { 2170 for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { 2171 final ActivityStack stack = mStacks.get(stackNdx); 2172 final ActivityRecord r = stack.topRunningActivityLocked(null); 2173 final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; 2174 if (isFrontStack(stack)) { 2175 if (r == null) { 2176 Slog.e(TAG, "validateTop...: null top activity, stack=" + stack); 2177 } else { 2178 final ActivityRecord pausing = stack.mPausingActivity; 2179 if (pausing != null && pausing == r) { 2180 Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r + 2181 " state=" + state); 2182 } 2183 if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) { 2184 Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r + 2185 " state=" + state); 2186 } 2187 } 2188 } else { 2189 final ActivityRecord resumed = stack.mResumedActivity; 2190 if (resumed != null && resumed == r) { 2191 Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r + 2192 " state=" + state); 2193 } 2194 if (r != null && (state == ActivityState.INITIALIZING 2195 || state == ActivityState.RESUMED)) { 2196 Slog.e(TAG, "validateTop...: activity in back resumed r=" + r + 2197 " state=" + state); 2198 } 2199 } 2200 } 2201 } 2202 2203 private static String stackStateToString(int stackState) { 2204 switch (stackState) { 2205 case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT"; 2206 case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK"; 2207 case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK"; 2208 case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT"; 2209 default: return "Unknown stackState=" + stackState; 2210 } 2211 } 2212 2213 public void dump(PrintWriter pw, String prefix) { 2214 pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:"); 2215 pw.println(mDismissKeyguardOnNextActivity); 2216 pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState)); 2217 pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout); 2218 pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId); 2219 } 2220 2221 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 2222 return getFocusedStack().getDumpActivitiesLocked(name); 2223 } 2224 2225 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 2226 boolean needSep, String prefix) { 2227 if (activity != null) { 2228 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 2229 if (needSep) { 2230 pw.println(); 2231 } 2232 pw.print(prefix); 2233 pw.println(activity); 2234 return true; 2235 } 2236 } 2237 return false; 2238 } 2239 2240 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 2241 boolean dumpClient, String dumpPackage) { 2242 boolean printed = false; 2243 boolean needSep = false; 2244 final int numStacks = mStacks.size(); 2245 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2246 final ActivityStack stack = mStacks.get(stackNdx); 2247 StringBuilder stackHeader = new StringBuilder(128); 2248 stackHeader.append(" Stack #"); 2249 stackHeader.append(mStacks.indexOf(stack)); 2250 stackHeader.append(":"); 2251 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep, 2252 stackHeader.toString()); 2253 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, 2254 false, dumpPackage, true, " Running activities (most recent first):", null); 2255 2256 needSep = printed; 2257 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 2258 " mPausingActivity: "); 2259 if (pr) { 2260 printed = true; 2261 needSep = false; 2262 } 2263 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 2264 " mResumedActivity: "); 2265 if (pr) { 2266 printed = true; 2267 needSep = false; 2268 } 2269 if (dumpAll) { 2270 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 2271 " mLastPausedActivity: "); 2272 if (pr) { 2273 printed = true; 2274 } 2275 } 2276 needSep = printed; 2277 } 2278 2279 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 2280 false, dumpPackage, true, " Activities waiting to finish:", null); 2281 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 2282 false, dumpPackage, true, " Activities waiting to stop:", null); 2283 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 2284 false, dumpPackage, true, " Activities waiting for another to become visible:", 2285 null); 2286 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2287 false, dumpPackage, true, " Activities waiting to sleep:", null); 2288 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 2289 false, dumpPackage, true, " Activities waiting to sleep:", null); 2290 2291 return printed; 2292 } 2293 2294 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 2295 String prefix, String label, boolean complete, boolean brief, boolean client, 2296 String dumpPackage, boolean needNL, String header1, String header2) { 2297 TaskRecord lastTask = null; 2298 String innerPrefix = null; 2299 String[] args = null; 2300 boolean printed = false; 2301 for (int i=list.size()-1; i>=0; i--) { 2302 final ActivityRecord r = list.get(i); 2303 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2304 continue; 2305 } 2306 if (innerPrefix == null) { 2307 innerPrefix = prefix + " "; 2308 args = new String[0]; 2309 } 2310 printed = true; 2311 final boolean full = !brief && (complete || !r.isInHistory()); 2312 if (needNL) { 2313 pw.println(""); 2314 needNL = false; 2315 } 2316 if (header1 != null) { 2317 pw.println(header1); 2318 header1 = null; 2319 } 2320 if (header2 != null) { 2321 pw.println(header2); 2322 header2 = null; 2323 } 2324 if (lastTask != r.task) { 2325 lastTask = r.task; 2326 pw.print(prefix); 2327 pw.print(full ? "* " : " "); 2328 pw.println(lastTask); 2329 if (full) { 2330 lastTask.dump(pw, prefix + " "); 2331 } else if (complete) { 2332 // Complete + brief == give a summary. Isn't that obvious?!? 2333 if (lastTask.intent != null) { 2334 pw.print(prefix); pw.print(" "); 2335 pw.println(lastTask.intent.toInsecureStringWithClip()); 2336 } 2337 } 2338 } 2339 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2340 pw.print(" #"); pw.print(i); pw.print(": "); 2341 pw.println(r); 2342 if (full) { 2343 r.dump(pw, innerPrefix); 2344 } else if (complete) { 2345 // Complete + brief == give a summary. Isn't that obvious?!? 2346 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2347 if (r.app != null) { 2348 pw.print(innerPrefix); pw.println(r.app); 2349 } 2350 } 2351 if (client && r.app != null && r.app.thread != null) { 2352 // flush anything that is already in the PrintWriter since the thread is going 2353 // to write to the file descriptor directly 2354 pw.flush(); 2355 try { 2356 TransferPipe tp = new TransferPipe(); 2357 try { 2358 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 2359 r.appToken, innerPrefix, args); 2360 // Short timeout, since blocking here can 2361 // deadlock with the application. 2362 tp.go(fd, 2000); 2363 } finally { 2364 tp.kill(); 2365 } 2366 } catch (IOException e) { 2367 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2368 } catch (RemoteException e) { 2369 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2370 } 2371 needNL = true; 2372 } 2373 } 2374 return printed; 2375 } 2376 2377 void scheduleIdleTimeoutLocked(ActivityRecord next) { 2378 if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 2379 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2380 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2381 } 2382 2383 final void scheduleIdleLocked() { 2384 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2385 } 2386 2387 void removeTimeoutsForActivityLocked(ActivityRecord r) { 2388 if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4)); 2389 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2390 } 2391 2392 final void scheduleResumeTopActivities() { 2393 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2394 } 2395 2396 void removeSleepTimeouts() { 2397 mSleepTimeout = false; 2398 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2399 } 2400 2401 final void scheduleSleepTimeout() { 2402 removeSleepTimeouts(); 2403 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2404 } 2405 2406 private final class ActivityStackSupervisorHandler extends Handler { 2407 2408 public ActivityStackSupervisorHandler(Looper looper) { 2409 super(looper); 2410 } 2411 2412 void activityIdleInternal(ActivityRecord r) { 2413 synchronized (mService) { 2414 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 2415 } 2416 } 2417 2418 @Override 2419 public void handleMessage(Message msg) { 2420 switch (msg.what) { 2421 case IDLE_TIMEOUT_MSG: { 2422 if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" + 2423 Debug.getCallers(4)); 2424 if (mService.mDidDexOpt) { 2425 mService.mDidDexOpt = false; 2426 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2427 nmsg.obj = msg.obj; 2428 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 2429 return; 2430 } 2431 // We don't at this point know if the activity is fullscreen, 2432 // so we need to be conservative and assume it isn't. 2433 activityIdleInternal((ActivityRecord)msg.obj); 2434 } break; 2435 case IDLE_NOW_MSG: { 2436 activityIdleInternal((ActivityRecord)msg.obj); 2437 } break; 2438 case RESUME_TOP_ACTIVITY_MSG: { 2439 synchronized (mService) { 2440 resumeTopActivitiesLocked(); 2441 } 2442 } break; 2443 case SLEEP_TIMEOUT_MSG: { 2444 synchronized (mService) { 2445 if (mService.isSleepingOrShuttingDown()) { 2446 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2447 mSleepTimeout = true; 2448 checkReadyForSleepLocked(); 2449 } 2450 } 2451 } break; 2452 } 2453 } 2454 } 2455 2456 private final class UserState { 2457 final ActivityStack mSavedFocusedStack; 2458 final int mSavedStackState; 2459 2460 public UserState() { 2461 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this; 2462 mSavedFocusedStack = supervisor.mFocusedStack; 2463 mSavedStackState = supervisor.mStackState; 2464 } 2465 2466 void restore() { 2467 ActivityStackSupervisor supervisor = ActivityStackSupervisor.this; 2468 supervisor.mFocusedStack = mSavedFocusedStack; 2469 if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" + 2470 stackStateToString(mSavedStackState)); 2471 supervisor.mStackState = mSavedStackState; 2472 } 2473 } 2474} 2475