1 /* 2 * Copyright (C) 2006-2008 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 17 package com.android.server.am; 18 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import android.app.AppOpsManager; 22 import android.appwidget.AppWidgetManager; 23 import com.android.internal.R; 24 import com.android.internal.os.BatteryStatsImpl; 25 import com.android.internal.os.ProcessStats; 26 import com.android.server.AppOpsService; 27 import com.android.server.AttributeCache; 28 import com.android.server.IntentResolver; 29 import com.android.server.ProcessMap; 30 import com.android.server.SystemServer; 31 import com.android.server.Watchdog; 32 import com.android.server.am.ActivityStack.ActivityState; 33 import com.android.server.firewall.IntentFirewall; 34 import com.android.server.pm.UserManagerService; 35 import com.android.server.wm.AppTransition; 36 import com.android.server.wm.WindowManagerService; 37 38 import dalvik.system.Zygote; 39 40 import android.app.Activity; 41 import android.app.ActivityManager; 42 import android.app.ActivityManagerNative; 43 import android.app.ActivityOptions; 44 import android.app.ActivityThread; 45 import android.app.AlertDialog; 46 import android.app.AppGlobals; 47 import android.app.ApplicationErrorReport; 48 import android.app.Dialog; 49 import android.app.IActivityController; 50 import android.app.IApplicationThread; 51 import android.app.IInstrumentationWatcher; 52 import android.app.INotificationManager; 53 import android.app.IProcessObserver; 54 import android.app.IServiceConnection; 55 import android.app.IStopUserCallback; 56 import android.app.IThumbnailReceiver; 57 import android.app.IUiAutomationConnection; 58 import android.app.IUserSwitchObserver; 59 import android.app.Instrumentation; 60 import android.app.Notification; 61 import android.app.NotificationManager; 62 import android.app.PendingIntent; 63 import android.app.backup.IBackupManager; 64 import android.content.ActivityNotFoundException; 65 import android.content.BroadcastReceiver; 66 import android.content.ClipData; 67 import android.content.ComponentCallbacks2; 68 import android.content.ComponentName; 69 import android.content.ContentProvider; 70 import android.content.ContentResolver; 71 import android.content.Context; 72 import android.content.DialogInterface; 73 import android.content.IContentProvider; 74 import android.content.IIntentReceiver; 75 import android.content.IIntentSender; 76 import android.content.Intent; 77 import android.content.IntentFilter; 78 import android.content.IntentSender; 79 import android.content.pm.ActivityInfo; 80 import android.content.pm.ApplicationInfo; 81 import android.content.pm.ConfigurationInfo; 82 import android.content.pm.IPackageDataObserver; 83 import android.content.pm.IPackageManager; 84 import android.content.pm.InstrumentationInfo; 85 import android.content.pm.PackageInfo; 86 import android.content.pm.PackageManager; 87 import android.content.pm.UserInfo; 88 import android.content.pm.PackageManager.NameNotFoundException; 89 import android.content.pm.PathPermission; 90 import android.content.pm.ProviderInfo; 91 import android.content.pm.ResolveInfo; 92 import android.content.pm.ServiceInfo; 93 import android.content.res.CompatibilityInfo; 94 import android.content.res.Configuration; 95 import android.graphics.Bitmap; 96 import android.net.Proxy; 97 import android.net.ProxyProperties; 98 import android.net.Uri; 99 import android.os.Binder; 100 import android.os.Build; 101 import android.os.Bundle; 102 import android.os.Debug; 103 import android.os.DropBoxManager; 104 import android.os.Environment; 105 import android.os.FileObserver; 106 import android.os.FileUtils; 107 import android.os.Handler; 108 import android.os.IBinder; 109 import android.os.IPermissionController; 110 import android.os.IRemoteCallback; 111 import android.os.IUserManager; 112 import android.os.Looper; 113 import android.os.Message; 114 import android.os.Parcel; 115 import android.os.ParcelFileDescriptor; 116 import android.os.Process; 117 import android.os.RemoteCallbackList; 118 import android.os.RemoteException; 119 import android.os.SELinux; 120 import android.os.ServiceManager; 121 import android.os.StrictMode; 122 import android.os.SystemClock; 123 import android.os.SystemProperties; 124 import android.os.UpdateLock; 125 import android.os.UserHandle; 126 import android.provider.Settings; 127 import android.text.format.Time; 128 import android.util.EventLog; 129 import android.util.Log; 130 import android.util.Pair; 131 import android.util.PrintWriterPrinter; 132 import android.util.Slog; 133 import android.util.SparseArray; 134 import android.util.TimeUtils; 135 import android.view.Gravity; 136 import android.view.LayoutInflater; 137 import android.view.View; 138 import android.view.WindowManager; 139 140 import java.io.BufferedInputStream; 141 import java.io.BufferedOutputStream; 142 import java.io.BufferedReader; 143 import java.io.DataInputStream; 144 import java.io.DataOutputStream; 145 import java.io.File; 146 import java.io.FileDescriptor; 147 import java.io.FileInputStream; 148 import java.io.FileNotFoundException; 149 import java.io.FileOutputStream; 150 import java.io.IOException; 151 import java.io.InputStreamReader; 152 import java.io.PrintWriter; 153 import java.io.StringWriter; 154 import java.lang.ref.WeakReference; 155 import java.util.ArrayList; 156 import java.util.Arrays; 157 import java.util.Collections; 158 import java.util.Comparator; 159 import java.util.HashMap; 160 import java.util.HashSet; 161 import java.util.Iterator; 162 import java.util.List; 163 import java.util.Locale; 164 import java.util.Map; 165 import java.util.Set; 166 import java.util.concurrent.atomic.AtomicBoolean; 167 import java.util.concurrent.atomic.AtomicLong; 168 169 public final class ActivityManagerService extends ActivityManagerNative 170 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 171 private static final String USER_DATA_DIR = "/data/user/"; 172 static final String TAG = "ActivityManager"; 173 static final String TAG_MU = "ActivityManagerServiceMU"; 174 static final boolean DEBUG = false; 175 static final boolean localLOGV = DEBUG; 176 static final boolean DEBUG_SWITCH = localLOGV || false; 177 static final boolean DEBUG_TASKS = localLOGV || false; 178 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 179 static final boolean DEBUG_PAUSE = localLOGV || false; 180 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 181 static final boolean DEBUG_TRANSITION = localLOGV || false; 182 static final boolean DEBUG_BROADCAST = localLOGV || false; 183 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 184 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 185 static final boolean DEBUG_SERVICE = localLOGV || false; 186 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 187 static final boolean DEBUG_VISBILITY = localLOGV || false; 188 static final boolean DEBUG_PROCESSES = localLOGV || false; 189 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 190 static final boolean DEBUG_CLEANUP = localLOGV || false; 191 static final boolean DEBUG_PROVIDER = localLOGV || false; 192 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 193 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 194 static final boolean DEBUG_RESULTS = localLOGV || false; 195 static final boolean DEBUG_BACKUP = localLOGV || false; 196 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 197 static final boolean DEBUG_POWER = localLOGV || false; 198 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 199 static final boolean DEBUG_MU = localLOGV || false; 200 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 201 static final boolean VALIDATE_TOKENS = false; 202 static final boolean SHOW_ACTIVITY_START_TIME = true; 203 204 // Control over CPU and battery monitoring. 205 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 206 static final boolean MONITOR_CPU_USAGE = true; 207 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 208 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 209 static final boolean MONITOR_THREAD_CPU_USAGE = false; 210 211 // The flags that are set for all calls we make to the package manager. 212 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 213 214 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 215 216 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 217 218 // Maximum number of recent tasks that we can remember. 219 static final int MAX_RECENT_TASKS = 20; 220 221 // Amount of time after a call to stopAppSwitches() during which we will 222 // prevent further untrusted switches from happening. 223 static final long APP_SWITCH_DELAY_TIME = 5*1000; 224 225 // How long we wait for a launched process to attach to the activity manager 226 // before we decide it's never going to come up for real. 227 static final int PROC_START_TIMEOUT = 10*1000; 228 229 // How long we wait for a launched process to attach to the activity manager 230 // before we decide it's never going to come up for real, when the process was 231 // started with a wrapper for instrumentation (such as Valgrind) because it 232 // could take much longer than usual. 233 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 234 235 // How long to wait after going idle before forcing apps to GC. 236 static final int GC_TIMEOUT = 5*1000; 237 238 // The minimum amount of time between successive GC requests for a process. 239 static final int GC_MIN_INTERVAL = 60*1000; 240 241 // The rate at which we check for apps using excessive power -- 15 mins. 242 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 243 244 // The minimum sample duration we will allow before deciding we have 245 // enough data on wake locks to start killing things. 246 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 247 248 // The minimum sample duration we will allow before deciding we have 249 // enough data on CPU usage to start killing things. 250 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 251 252 // How long we allow a receiver to run before giving up on it. 253 static final int BROADCAST_FG_TIMEOUT = 10*1000; 254 static final int BROADCAST_BG_TIMEOUT = 60*1000; 255 256 // How long we wait until we timeout on key dispatching. 257 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 258 259 // How long we wait until we timeout on key dispatching during instrumentation. 260 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 261 262 // Amount of time we wait for observers to handle a user switch before 263 // giving up on them and unfreezing the screen. 264 static final int USER_SWITCH_TIMEOUT = 2*1000; 265 266 // Maximum number of users we allow to be running at a time. 267 static final int MAX_RUNNING_USERS = 3; 268 269 // How long to wait in getTopActivityExtras for the activity to respond with the result. 270 static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000; 271 272 static final int MY_PID = Process.myPid(); 273 274 static final String[] EMPTY_STRING_ARRAY = new String[0]; 275 276 public ActivityStack mMainStack; 277 278 public IntentFirewall mIntentFirewall; 279 280 private final boolean mHeadless; 281 282 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 283 // default actuion automatically. Important for devices without direct input 284 // devices. 285 private boolean mShowDialogs = true; 286 287 /** 288 * Description of a request to start a new activity, which has been held 289 * due to app switches being disabled. 290 */ 291 static class PendingActivityLaunch { 292 ActivityRecord r; 293 ActivityRecord sourceRecord; 294 int startFlags; 295 } 296 297 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 298 = new ArrayList<PendingActivityLaunch>(); 299 300 301 BroadcastQueue mFgBroadcastQueue; 302 BroadcastQueue mBgBroadcastQueue; 303 // Convenient for easy iteration over the queues. Foreground is first 304 // so that dispatch of foreground broadcasts gets precedence. 305 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 306 307 BroadcastQueue broadcastQueueForIntent(Intent intent) { 308 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 309 if (DEBUG_BACKGROUND_BROADCAST) { 310 Slog.i(TAG, "Broadcast intent " + intent + " on " 311 + (isFg ? "foreground" : "background") 312 + " queue"); 313 } 314 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 315 } 316 317 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 318 for (BroadcastQueue queue : mBroadcastQueues) { 319 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 320 if (r != null) { 321 return r; 322 } 323 } 324 return null; 325 } 326 327 /** 328 * Activity we have told the window manager to have key focus. 329 */ 330 ActivityRecord mFocusedActivity = null; 331 332 /** 333 * List of intents that were used to start the most recent tasks. 334 */ 335 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 336 337 public class PendingActivityExtras extends Binder implements Runnable { 338 public final ActivityRecord activity; 339 public boolean haveResult = false; 340 public Bundle result = null; 341 public PendingActivityExtras(ActivityRecord _activity) { 342 activity = _activity; 343 } 344 @Override 345 public void run() { 346 Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity); 347 synchronized (this) { 348 haveResult = true; 349 notifyAll(); 350 } 351 } 352 } 353 354 final ArrayList<PendingActivityExtras> mPendingActivityExtras 355 = new ArrayList<PendingActivityExtras>(); 356 357 /** 358 * Process management. 359 */ 360 final ProcessList mProcessList = new ProcessList(); 361 362 /** 363 * All of the applications we currently have running organized by name. 364 * The keys are strings of the application package name (as 365 * returned by the package manager), and the keys are ApplicationRecord 366 * objects. 367 */ 368 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 369 370 /** 371 * The currently running isolated processes. 372 */ 373 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 374 375 /** 376 * Counter for assigning isolated process uids, to avoid frequently reusing the 377 * same ones. 378 */ 379 int mNextIsolatedProcessUid = 0; 380 381 /** 382 * The currently running heavy-weight process, if any. 383 */ 384 ProcessRecord mHeavyWeightProcess = null; 385 386 /** 387 * The last time that various processes have crashed. 388 */ 389 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 390 391 /** 392 * Set of applications that we consider to be bad, and will reject 393 * incoming broadcasts from (which the user has no control over). 394 * Processes are added to this set when they have crashed twice within 395 * a minimum amount of time; they are removed from it when they are 396 * later restarted (hopefully due to some user action). The value is the 397 * time it was added to the list. 398 */ 399 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 400 401 /** 402 * All of the processes we currently have running organized by pid. 403 * The keys are the pid running the application. 404 * 405 * <p>NOTE: This object is protected by its own lock, NOT the global 406 * activity manager lock! 407 */ 408 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 409 410 /** 411 * All of the processes that have been forced to be foreground. The key 412 * is the pid of the caller who requested it (we hold a death 413 * link on it). 414 */ 415 abstract class ForegroundToken implements IBinder.DeathRecipient { 416 int pid; 417 IBinder token; 418 } 419 final SparseArray<ForegroundToken> mForegroundProcesses 420 = new SparseArray<ForegroundToken>(); 421 422 /** 423 * List of records for processes that someone had tried to start before the 424 * system was ready. We don't start them at that point, but ensure they 425 * are started by the time booting is complete. 426 */ 427 final ArrayList<ProcessRecord> mProcessesOnHold 428 = new ArrayList<ProcessRecord>(); 429 430 /** 431 * List of persistent applications that are in the process 432 * of being started. 433 */ 434 final ArrayList<ProcessRecord> mPersistentStartingProcesses 435 = new ArrayList<ProcessRecord>(); 436 437 /** 438 * Processes that are being forcibly torn down. 439 */ 440 final ArrayList<ProcessRecord> mRemovedProcesses 441 = new ArrayList<ProcessRecord>(); 442 443 /** 444 * List of running applications, sorted by recent usage. 445 * The first entry in the list is the least recently used. 446 * It contains ApplicationRecord objects. This list does NOT include 447 * any persistent application records (since we never want to exit them). 448 */ 449 final ArrayList<ProcessRecord> mLruProcesses 450 = new ArrayList<ProcessRecord>(); 451 452 /** 453 * List of processes that should gc as soon as things are idle. 454 */ 455 final ArrayList<ProcessRecord> mProcessesToGc 456 = new ArrayList<ProcessRecord>(); 457 458 /** 459 * This is the process holding what we currently consider to be 460 * the "home" activity. 461 */ 462 ProcessRecord mHomeProcess; 463 464 /** 465 * This is the process holding the activity the user last visited that 466 * is in a different process from the one they are currently in. 467 */ 468 ProcessRecord mPreviousProcess; 469 470 /** 471 * The time at which the previous process was last visible. 472 */ 473 long mPreviousProcessVisibleTime; 474 475 /** 476 * Which uses have been started, so are allowed to run code. 477 */ 478 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 479 480 /** 481 * LRU list of history of current users. Most recently current is at the end. 482 */ 483 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 484 485 /** 486 * Constant array of the users that are currently started. 487 */ 488 int[] mStartedUserArray = new int[] { 0 }; 489 490 /** 491 * Registered observers of the user switching mechanics. 492 */ 493 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 494 = new RemoteCallbackList<IUserSwitchObserver>(); 495 496 /** 497 * Currently active user switch. 498 */ 499 Object mCurUserSwitchCallback; 500 501 /** 502 * Packages that the user has asked to have run in screen size 503 * compatibility mode instead of filling the screen. 504 */ 505 final CompatModePackages mCompatModePackages; 506 507 /** 508 * Set of PendingResultRecord objects that are currently active. 509 */ 510 final HashSet mPendingResultRecords = new HashSet(); 511 512 /** 513 * Set of IntentSenderRecord objects that are currently active. 514 */ 515 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 516 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 517 518 /** 519 * Fingerprints (hashCode()) of stack traces that we've 520 * already logged DropBox entries for. Guarded by itself. If 521 * something (rogue user app) forces this over 522 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 523 */ 524 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 525 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 526 527 /** 528 * Strict Mode background batched logging state. 529 * 530 * The string buffer is guarded by itself, and its lock is also 531 * used to determine if another batched write is already 532 * in-flight. 533 */ 534 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 535 536 /** 537 * Keeps track of all IIntentReceivers that have been registered for 538 * broadcasts. Hash keys are the receiver IBinder, hash value is 539 * a ReceiverList. 540 */ 541 final HashMap mRegisteredReceivers = new HashMap(); 542 543 /** 544 * Resolver for broadcast intents to registered receivers. 545 * Holds BroadcastFilter (subclass of IntentFilter). 546 */ 547 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 548 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 549 @Override 550 protected boolean allowFilterResult( 551 BroadcastFilter filter, List<BroadcastFilter> dest) { 552 IBinder target = filter.receiverList.receiver.asBinder(); 553 for (int i=dest.size()-1; i>=0; i--) { 554 if (dest.get(i).receiverList.receiver.asBinder() == target) { 555 return false; 556 } 557 } 558 return true; 559 } 560 561 @Override 562 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 563 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 564 || userId == filter.owningUserId) { 565 return super.newResult(filter, match, userId); 566 } 567 return null; 568 } 569 570 @Override 571 protected BroadcastFilter[] newArray(int size) { 572 return new BroadcastFilter[size]; 573 } 574 575 @Override 576 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 577 return packageName.equals(filter.packageName); 578 } 579 }; 580 581 /** 582 * State of all active sticky broadcasts per user. Keys are the action of the 583 * sticky Intent, values are an ArrayList of all broadcasted intents with 584 * that action (which should usually be one). The SparseArray is keyed 585 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 586 * for stickies that are sent to all users. 587 */ 588 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 589 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 590 591 final ActiveServices mServices; 592 593 /** 594 * Backup/restore process management 595 */ 596 String mBackupAppName = null; 597 BackupRecord mBackupTarget = null; 598 599 /** 600 * List of PendingThumbnailsRecord objects of clients who are still 601 * waiting to receive all of the thumbnails for a task. 602 */ 603 final ArrayList mPendingThumbnails = new ArrayList(); 604 605 /** 606 * List of HistoryRecord objects that have been finished and must 607 * still report back to a pending thumbnail receiver. 608 */ 609 final ArrayList mCancelledThumbnails = new ArrayList(); 610 611 final ProviderMap mProviderMap; 612 613 /** 614 * List of content providers who have clients waiting for them. The 615 * application is currently being launched and the provider will be 616 * removed from this list once it is published. 617 */ 618 final ArrayList<ContentProviderRecord> mLaunchingProviders 619 = new ArrayList<ContentProviderRecord>(); 620 621 /** 622 * Global set of specific Uri permissions that have been granted. 623 */ 624 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 625 = new SparseArray<HashMap<Uri, UriPermission>>(); 626 627 CoreSettingsObserver mCoreSettingsObserver; 628 629 /** 630 * Thread-local storage used to carry caller permissions over through 631 * indirect content-provider access. 632 */ 633 private class Identity { 634 public int pid; 635 public int uid; 636 637 Identity(int _pid, int _uid) { 638 pid = _pid; 639 uid = _uid; 640 } 641 } 642 643 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 644 645 /** 646 * All information we have collected about the runtime performance of 647 * any user id that can impact battery performance. 648 */ 649 final BatteryStatsService mBatteryStatsService; 650 651 /** 652 * Information about component usage 653 */ 654 final UsageStatsService mUsageStatsService; 655 656 /** 657 * Information about and control over application operations 658 */ 659 final AppOpsService mAppOpsService; 660 661 /** 662 * Current configuration information. HistoryRecord objects are given 663 * a reference to this object to indicate which configuration they are 664 * currently running in, so this object must be kept immutable. 665 */ 666 Configuration mConfiguration = new Configuration(); 667 668 /** 669 * Current sequencing integer of the configuration, for skipping old 670 * configurations. 671 */ 672 int mConfigurationSeq = 0; 673 674 /** 675 * Hardware-reported OpenGLES version. 676 */ 677 final int GL_ES_VERSION; 678 679 /** 680 * List of initialization arguments to pass to all processes when binding applications to them. 681 * For example, references to the commonly used services. 682 */ 683 HashMap<String, IBinder> mAppBindArgs; 684 685 /** 686 * Temporary to avoid allocations. Protected by main lock. 687 */ 688 final StringBuilder mStringBuilder = new StringBuilder(256); 689 690 /** 691 * Used to control how we initialize the service. 692 */ 693 boolean mStartRunning = false; 694 ComponentName mTopComponent; 695 String mTopAction; 696 String mTopData; 697 boolean mProcessesReady = false; 698 boolean mSystemReady = false; 699 boolean mBooting = false; 700 boolean mWaitingUpdate = false; 701 boolean mDidUpdate = false; 702 boolean mOnBattery = false; 703 boolean mLaunchWarningShown = false; 704 705 Context mContext; 706 707 int mFactoryTest; 708 709 boolean mCheckedForSetup; 710 711 /** 712 * The time at which we will allow normal application switches again, 713 * after a call to {@link #stopAppSwitches()}. 714 */ 715 long mAppSwitchesAllowedTime; 716 717 /** 718 * This is set to true after the first switch after mAppSwitchesAllowedTime 719 * is set; any switches after that will clear the time. 720 */ 721 boolean mDidAppSwitch; 722 723 /** 724 * Last time (in realtime) at which we checked for power usage. 725 */ 726 long mLastPowerCheckRealtime; 727 728 /** 729 * Last time (in uptime) at which we checked for power usage. 730 */ 731 long mLastPowerCheckUptime; 732 733 /** 734 * Set while we are wanting to sleep, to prevent any 735 * activities from being started/resumed. 736 */ 737 boolean mSleeping = false; 738 739 /** 740 * State of external calls telling us if the device is asleep. 741 */ 742 boolean mWentToSleep = false; 743 744 /** 745 * State of external call telling us if the lock screen is shown. 746 */ 747 boolean mLockScreenShown = false; 748 749 /** 750 * Set if we are shutting down the system, similar to sleeping. 751 */ 752 boolean mShuttingDown = false; 753 754 /** 755 * Task identifier that activities are currently being started 756 * in. Incremented each time a new task is created. 757 * todo: Replace this with a TokenSpace class that generates non-repeating 758 * integers that won't wrap. 759 */ 760 int mCurTask = 1; 761 762 /** 763 * Current sequence id for oom_adj computation traversal. 764 */ 765 int mAdjSeq = 0; 766 767 /** 768 * Current sequence id for process LRU updating. 769 */ 770 int mLruSeq = 0; 771 772 /** 773 * Keep track of the non-hidden/empty process we last found, to help 774 * determine how to distribute hidden/empty processes next time. 775 */ 776 int mNumNonHiddenProcs = 0; 777 778 /** 779 * Keep track of the number of hidden procs, to balance oom adj 780 * distribution between those and empty procs. 781 */ 782 int mNumHiddenProcs = 0; 783 784 /** 785 * Keep track of the number of service processes we last found, to 786 * determine on the next iteration which should be B services. 787 */ 788 int mNumServiceProcs = 0; 789 int mNewNumServiceProcs = 0; 790 791 /** 792 * System monitoring: number of processes that died since the last 793 * N procs were started. 794 */ 795 int[] mProcDeaths = new int[20]; 796 797 /** 798 * This is set if we had to do a delayed dexopt of an app before launching 799 * it, to increasing the ANR timeouts in that case. 800 */ 801 boolean mDidDexOpt; 802 803 String mDebugApp = null; 804 boolean mWaitForDebugger = false; 805 boolean mDebugTransient = false; 806 String mOrigDebugApp = null; 807 boolean mOrigWaitForDebugger = false; 808 boolean mAlwaysFinishActivities = false; 809 IActivityController mController = null; 810 String mProfileApp = null; 811 ProcessRecord mProfileProc = null; 812 String mProfileFile; 813 ParcelFileDescriptor mProfileFd; 814 int mProfileType = 0; 815 boolean mAutoStopProfiler = false; 816 String mOpenGlTraceApp = null; 817 818 static class ProcessChangeItem { 819 static final int CHANGE_ACTIVITIES = 1<<0; 820 static final int CHANGE_IMPORTANCE= 1<<1; 821 int changes; 822 int uid; 823 int pid; 824 int importance; 825 boolean foregroundActivities; 826 } 827 828 final RemoteCallbackList<IProcessObserver> mProcessObservers 829 = new RemoteCallbackList<IProcessObserver>(); 830 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 831 832 final ArrayList<ProcessChangeItem> mPendingProcessChanges 833 = new ArrayList<ProcessChangeItem>(); 834 final ArrayList<ProcessChangeItem> mAvailProcessChanges 835 = new ArrayList<ProcessChangeItem>(); 836 837 /** 838 * Runtime statistics collection thread. This object's lock is used to 839 * protect all related state. 840 */ 841 final Thread mProcessStatsThread; 842 843 /** 844 * Used to collect process stats when showing not responding dialog. 845 * Protected by mProcessStatsThread. 846 */ 847 final ProcessStats mProcessStats = new ProcessStats( 848 MONITOR_THREAD_CPU_USAGE); 849 final AtomicLong mLastCpuTime = new AtomicLong(0); 850 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 851 852 long mLastWriteTime = 0; 853 854 /** 855 * Used to retain an update lock when the foreground activity is in 856 * immersive mode. 857 */ 858 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 859 860 /** 861 * Set to true after the system has finished booting. 862 */ 863 boolean mBooted = false; 864 865 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 866 int mProcessLimitOverride = -1; 867 868 WindowManagerService mWindowManager; 869 870 static ActivityManagerService mSelf; 871 static ActivityThread mSystemThread; 872 873 private int mCurrentUserId = 0; 874 private int[] mCurrentUserArray = new int[] { 0 }; 875 private UserManagerService mUserManager; 876 877 private final class AppDeathRecipient implements IBinder.DeathRecipient { 878 final ProcessRecord mApp; 879 final int mPid; 880 final IApplicationThread mAppThread; 881 882 AppDeathRecipient(ProcessRecord app, int pid, 883 IApplicationThread thread) { 884 if (localLOGV) Slog.v( 885 TAG, "New death recipient " + this 886 + " for thread " + thread.asBinder()); 887 mApp = app; 888 mPid = pid; 889 mAppThread = thread; 890 } 891 892 public void binderDied() { 893 if (localLOGV) Slog.v( 894 TAG, "Death received in " + this 895 + " for thread " + mAppThread.asBinder()); 896 synchronized(ActivityManagerService.this) { 897 appDiedLocked(mApp, mPid, mAppThread); 898 } 899 } 900 } 901 902 static final int SHOW_ERROR_MSG = 1; 903 static final int SHOW_NOT_RESPONDING_MSG = 2; 904 static final int SHOW_FACTORY_ERROR_MSG = 3; 905 static final int UPDATE_CONFIGURATION_MSG = 4; 906 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 907 static final int WAIT_FOR_DEBUGGER_MSG = 6; 908 static final int SERVICE_TIMEOUT_MSG = 12; 909 static final int UPDATE_TIME_ZONE = 13; 910 static final int SHOW_UID_ERROR_MSG = 14; 911 static final int IM_FEELING_LUCKY_MSG = 15; 912 static final int PROC_START_TIMEOUT_MSG = 20; 913 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 914 static final int KILL_APPLICATION_MSG = 22; 915 static final int FINALIZE_PENDING_INTENT_MSG = 23; 916 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 917 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 918 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 919 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 920 static final int CLEAR_DNS_CACHE = 28; 921 static final int UPDATE_HTTP_PROXY = 29; 922 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 923 static final int DISPATCH_PROCESSES_CHANGED = 31; 924 static final int DISPATCH_PROCESS_DIED = 32; 925 static final int REPORT_MEM_USAGE = 33; 926 static final int REPORT_USER_SWITCH_MSG = 34; 927 static final int CONTINUE_USER_SWITCH_MSG = 35; 928 static final int USER_SWITCH_TIMEOUT_MSG = 36; 929 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 930 931 static final int FIRST_ACTIVITY_STACK_MSG = 100; 932 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 933 static final int FIRST_COMPAT_MODE_MSG = 300; 934 935 AlertDialog mUidAlert; 936 CompatModeDialog mCompatModeDialog; 937 long mLastMemUsageReportTime = 0; 938 939 /** 940 * Flag whether the current user is a "monkey", i.e. whether 941 * the UI is driven by a UI automation tool. 942 */ 943 private boolean mUserIsMonkey; 944 945 final Handler mHandler = new Handler() { 946 //public Handler() { 947 // if (localLOGV) Slog.v(TAG, "Handler started!"); 948 //} 949 950 public void handleMessage(Message msg) { 951 switch (msg.what) { 952 case SHOW_ERROR_MSG: { 953 HashMap data = (HashMap) msg.obj; 954 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 955 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 956 synchronized (ActivityManagerService.this) { 957 ProcessRecord proc = (ProcessRecord)data.get("app"); 958 AppErrorResult res = (AppErrorResult) data.get("result"); 959 if (proc != null && proc.crashDialog != null) { 960 Slog.e(TAG, "App already has crash dialog: " + proc); 961 if (res != null) { 962 res.set(0); 963 } 964 return; 965 } 966 if (!showBackground && UserHandle.getAppId(proc.uid) 967 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 968 && proc.pid != MY_PID) { 969 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 970 if (res != null) { 971 res.set(0); 972 } 973 return; 974 } 975 if (mShowDialogs && !mSleeping && !mShuttingDown) { 976 Dialog d = new AppErrorDialog(mContext, 977 ActivityManagerService.this, res, proc); 978 d.show(); 979 proc.crashDialog = d; 980 } else { 981 // The device is asleep, so just pretend that the user 982 // saw a crash dialog and hit "force quit". 983 if (res != null) { 984 res.set(0); 985 } 986 } 987 } 988 989 ensureBootCompleted(); 990 } break; 991 case SHOW_NOT_RESPONDING_MSG: { 992 synchronized (ActivityManagerService.this) { 993 HashMap data = (HashMap) msg.obj; 994 ProcessRecord proc = (ProcessRecord)data.get("app"); 995 if (proc != null && proc.anrDialog != null) { 996 Slog.e(TAG, "App already has anr dialog: " + proc); 997 return; 998 } 999 1000 Intent intent = new Intent("android.intent.action.ANR"); 1001 if (!mProcessesReady) { 1002 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1003 | Intent.FLAG_RECEIVER_FOREGROUND); 1004 } 1005 broadcastIntentLocked(null, null, intent, 1006 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1007 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1008 1009 if (mShowDialogs) { 1010 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1011 mContext, proc, (ActivityRecord)data.get("activity"), 1012 msg.arg1 != 0); 1013 d.show(); 1014 proc.anrDialog = d; 1015 } else { 1016 // Just kill the app if there is no dialog to be shown. 1017 killAppAtUsersRequest(proc, null); 1018 } 1019 } 1020 1021 ensureBootCompleted(); 1022 } break; 1023 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1024 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1025 synchronized (ActivityManagerService.this) { 1026 ProcessRecord proc = (ProcessRecord) data.get("app"); 1027 if (proc == null) { 1028 Slog.e(TAG, "App not found when showing strict mode dialog."); 1029 break; 1030 } 1031 if (proc.crashDialog != null) { 1032 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1033 return; 1034 } 1035 AppErrorResult res = (AppErrorResult) data.get("result"); 1036 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1037 Dialog d = new StrictModeViolationDialog(mContext, 1038 ActivityManagerService.this, res, proc); 1039 d.show(); 1040 proc.crashDialog = d; 1041 } else { 1042 // The device is asleep, so just pretend that the user 1043 // saw a crash dialog and hit "force quit". 1044 res.set(0); 1045 } 1046 } 1047 ensureBootCompleted(); 1048 } break; 1049 case SHOW_FACTORY_ERROR_MSG: { 1050 Dialog d = new FactoryErrorDialog( 1051 mContext, msg.getData().getCharSequence("msg")); 1052 d.show(); 1053 ensureBootCompleted(); 1054 } break; 1055 case UPDATE_CONFIGURATION_MSG: { 1056 final ContentResolver resolver = mContext.getContentResolver(); 1057 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1058 } break; 1059 case GC_BACKGROUND_PROCESSES_MSG: { 1060 synchronized (ActivityManagerService.this) { 1061 performAppGcsIfAppropriateLocked(); 1062 } 1063 } break; 1064 case WAIT_FOR_DEBUGGER_MSG: { 1065 synchronized (ActivityManagerService.this) { 1066 ProcessRecord app = (ProcessRecord)msg.obj; 1067 if (msg.arg1 != 0) { 1068 if (!app.waitedForDebugger) { 1069 Dialog d = new AppWaitingForDebuggerDialog( 1070 ActivityManagerService.this, 1071 mContext, app); 1072 app.waitDialog = d; 1073 app.waitedForDebugger = true; 1074 d.show(); 1075 } 1076 } else { 1077 if (app.waitDialog != null) { 1078 app.waitDialog.dismiss(); 1079 app.waitDialog = null; 1080 } 1081 } 1082 } 1083 } break; 1084 case SERVICE_TIMEOUT_MSG: { 1085 if (mDidDexOpt) { 1086 mDidDexOpt = false; 1087 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1088 nmsg.obj = msg.obj; 1089 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1090 return; 1091 } 1092 mServices.serviceTimeout((ProcessRecord)msg.obj); 1093 } break; 1094 case UPDATE_TIME_ZONE: { 1095 synchronized (ActivityManagerService.this) { 1096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1097 ProcessRecord r = mLruProcesses.get(i); 1098 if (r.thread != null) { 1099 try { 1100 r.thread.updateTimeZone(); 1101 } catch (RemoteException ex) { 1102 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1103 } 1104 } 1105 } 1106 } 1107 } break; 1108 case CLEAR_DNS_CACHE: { 1109 synchronized (ActivityManagerService.this) { 1110 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1111 ProcessRecord r = mLruProcesses.get(i); 1112 if (r.thread != null) { 1113 try { 1114 r.thread.clearDnsCache(); 1115 } catch (RemoteException ex) { 1116 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1117 } 1118 } 1119 } 1120 } 1121 } break; 1122 case UPDATE_HTTP_PROXY: { 1123 ProxyProperties proxy = (ProxyProperties)msg.obj; 1124 String host = ""; 1125 String port = ""; 1126 String exclList = ""; 1127 if (proxy != null) { 1128 host = proxy.getHost(); 1129 port = Integer.toString(proxy.getPort()); 1130 exclList = proxy.getExclusionList(); 1131 } 1132 synchronized (ActivityManagerService.this) { 1133 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1134 ProcessRecord r = mLruProcesses.get(i); 1135 if (r.thread != null) { 1136 try { 1137 r.thread.setHttpProxy(host, port, exclList); 1138 } catch (RemoteException ex) { 1139 Slog.w(TAG, "Failed to update http proxy for: " + 1140 r.info.processName); 1141 } 1142 } 1143 } 1144 } 1145 } break; 1146 case SHOW_UID_ERROR_MSG: { 1147 String title = "System UIDs Inconsistent"; 1148 String text = "UIDs on the system are inconsistent, you need to wipe your" 1149 + " data partition or your device will be unstable."; 1150 Log.e(TAG, title + ": " + text); 1151 if (mShowDialogs) { 1152 // XXX This is a temporary dialog, no need to localize. 1153 AlertDialog d = new BaseErrorDialog(mContext); 1154 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1155 d.setCancelable(false); 1156 d.setTitle(title); 1157 d.setMessage(text); 1158 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1159 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1160 mUidAlert = d; 1161 d.show(); 1162 } 1163 } break; 1164 case IM_FEELING_LUCKY_MSG: { 1165 if (mUidAlert != null) { 1166 mUidAlert.dismiss(); 1167 mUidAlert = null; 1168 } 1169 } break; 1170 case PROC_START_TIMEOUT_MSG: { 1171 if (mDidDexOpt) { 1172 mDidDexOpt = false; 1173 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1174 nmsg.obj = msg.obj; 1175 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1176 return; 1177 } 1178 ProcessRecord app = (ProcessRecord)msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 processStartTimedOutLocked(app); 1181 } 1182 } break; 1183 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1184 synchronized (ActivityManagerService.this) { 1185 doPendingActivityLaunchesLocked(true); 1186 } 1187 } break; 1188 case KILL_APPLICATION_MSG: { 1189 synchronized (ActivityManagerService.this) { 1190 int appid = msg.arg1; 1191 boolean restart = (msg.arg2 == 1); 1192 String pkg = (String) msg.obj; 1193 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1194 UserHandle.USER_ALL); 1195 } 1196 } break; 1197 case FINALIZE_PENDING_INTENT_MSG: { 1198 ((PendingIntentRecord)msg.obj).completeFinalize(); 1199 } break; 1200 case POST_HEAVY_NOTIFICATION_MSG: { 1201 INotificationManager inm = NotificationManager.getService(); 1202 if (inm == null) { 1203 return; 1204 } 1205 1206 ActivityRecord root = (ActivityRecord)msg.obj; 1207 ProcessRecord process = root.app; 1208 if (process == null) { 1209 return; 1210 } 1211 1212 try { 1213 Context context = mContext.createPackageContext(process.info.packageName, 0); 1214 String text = mContext.getString(R.string.heavy_weight_notification, 1215 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1216 Notification notification = new Notification(); 1217 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1218 notification.when = 0; 1219 notification.flags = Notification.FLAG_ONGOING_EVENT; 1220 notification.tickerText = text; 1221 notification.defaults = 0; // please be quiet 1222 notification.sound = null; 1223 notification.vibrate = null; 1224 notification.setLatestEventInfo(context, text, 1225 mContext.getText(R.string.heavy_weight_notification_detail), 1226 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1227 PendingIntent.FLAG_CANCEL_CURRENT, null, 1228 new UserHandle(root.userId))); 1229 1230 try { 1231 int[] outId = new int[1]; 1232 inm.enqueueNotificationWithTag("android", "android", null, 1233 R.string.heavy_weight_notification, 1234 notification, outId, root.userId); 1235 } catch (RuntimeException e) { 1236 Slog.w(ActivityManagerService.TAG, 1237 "Error showing notification for heavy-weight app", e); 1238 } catch (RemoteException e) { 1239 } 1240 } catch (NameNotFoundException e) { 1241 Slog.w(TAG, "Unable to create context for heavy notification", e); 1242 } 1243 } break; 1244 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1245 INotificationManager inm = NotificationManager.getService(); 1246 if (inm == null) { 1247 return; 1248 } 1249 try { 1250 inm.cancelNotificationWithTag("android", null, 1251 R.string.heavy_weight_notification, msg.arg1); 1252 } catch (RuntimeException e) { 1253 Slog.w(ActivityManagerService.TAG, 1254 "Error canceling notification for service", e); 1255 } catch (RemoteException e) { 1256 } 1257 } break; 1258 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1259 synchronized (ActivityManagerService.this) { 1260 checkExcessivePowerUsageLocked(true); 1261 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1262 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1263 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1264 } 1265 } break; 1266 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1267 synchronized (ActivityManagerService.this) { 1268 ActivityRecord ar = (ActivityRecord)msg.obj; 1269 if (mCompatModeDialog != null) { 1270 if (mCompatModeDialog.mAppInfo.packageName.equals( 1271 ar.info.applicationInfo.packageName)) { 1272 return; 1273 } 1274 mCompatModeDialog.dismiss(); 1275 mCompatModeDialog = null; 1276 } 1277 if (ar != null && false) { 1278 if (mCompatModePackages.getPackageAskCompatModeLocked( 1279 ar.packageName)) { 1280 int mode = mCompatModePackages.computeCompatModeLocked( 1281 ar.info.applicationInfo); 1282 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1283 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1284 mCompatModeDialog = new CompatModeDialog( 1285 ActivityManagerService.this, mContext, 1286 ar.info.applicationInfo); 1287 mCompatModeDialog.show(); 1288 } 1289 } 1290 } 1291 } 1292 break; 1293 } 1294 case DISPATCH_PROCESSES_CHANGED: { 1295 dispatchProcessesChanged(); 1296 break; 1297 } 1298 case DISPATCH_PROCESS_DIED: { 1299 final int pid = msg.arg1; 1300 final int uid = msg.arg2; 1301 dispatchProcessDied(pid, uid); 1302 break; 1303 } 1304 case REPORT_MEM_USAGE: { 1305 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1306 if (!isDebuggable) { 1307 return; 1308 } 1309 synchronized (ActivityManagerService.this) { 1310 long now = SystemClock.uptimeMillis(); 1311 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1312 // Don't report more than every 5 minutes to somewhat 1313 // avoid spamming. 1314 return; 1315 } 1316 mLastMemUsageReportTime = now; 1317 } 1318 Thread thread = new Thread() { 1319 @Override public void run() { 1320 StringBuilder dropBuilder = new StringBuilder(1024); 1321 StringBuilder logBuilder = new StringBuilder(1024); 1322 StringWriter oomSw = new StringWriter(); 1323 PrintWriter oomPw = new PrintWriter(oomSw); 1324 StringWriter catSw = new StringWriter(); 1325 PrintWriter catPw = new PrintWriter(catSw); 1326 String[] emptyArgs = new String[] { }; 1327 StringBuilder tag = new StringBuilder(128); 1328 StringBuilder stack = new StringBuilder(128); 1329 tag.append("Low on memory -- "); 1330 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1331 tag, stack); 1332 dropBuilder.append(stack); 1333 dropBuilder.append('\n'); 1334 dropBuilder.append('\n'); 1335 String oomString = oomSw.toString(); 1336 dropBuilder.append(oomString); 1337 dropBuilder.append('\n'); 1338 logBuilder.append(oomString); 1339 try { 1340 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1341 "procrank", }); 1342 final InputStreamReader converter = new InputStreamReader( 1343 proc.getInputStream()); 1344 BufferedReader in = new BufferedReader(converter); 1345 String line; 1346 while (true) { 1347 line = in.readLine(); 1348 if (line == null) { 1349 break; 1350 } 1351 if (line.length() > 0) { 1352 logBuilder.append(line); 1353 logBuilder.append('\n'); 1354 } 1355 dropBuilder.append(line); 1356 dropBuilder.append('\n'); 1357 } 1358 converter.close(); 1359 } catch (IOException e) { 1360 } 1361 synchronized (ActivityManagerService.this) { 1362 catPw.println(); 1363 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1364 catPw.println(); 1365 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1366 false, false, null); 1367 catPw.println(); 1368 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1369 } 1370 dropBuilder.append(catSw.toString()); 1371 addErrorToDropBox("lowmem", null, "system_server", null, 1372 null, tag.toString(), dropBuilder.toString(), null, null); 1373 Slog.i(TAG, logBuilder.toString()); 1374 synchronized (ActivityManagerService.this) { 1375 long now = SystemClock.uptimeMillis(); 1376 if (mLastMemUsageReportTime < now) { 1377 mLastMemUsageReportTime = now; 1378 } 1379 } 1380 } 1381 }; 1382 thread.start(); 1383 break; 1384 } 1385 case REPORT_USER_SWITCH_MSG: { 1386 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1387 break; 1388 } 1389 case CONTINUE_USER_SWITCH_MSG: { 1390 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1391 break; 1392 } 1393 case USER_SWITCH_TIMEOUT_MSG: { 1394 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1395 break; 1396 } 1397 case IMMERSIVE_MODE_LOCK_MSG: { 1398 final boolean nextState = (msg.arg1 != 0); 1399 if (mUpdateLock.isHeld() != nextState) { 1400 if (DEBUG_IMMERSIVE) { 1401 final ActivityRecord r = (ActivityRecord) msg.obj; 1402 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1403 } 1404 if (nextState) { 1405 mUpdateLock.acquire(); 1406 } else { 1407 mUpdateLock.release(); 1408 } 1409 } 1410 break; 1411 } 1412 } 1413 } 1414 }; 1415 1416 public static void setSystemProcess() { 1417 try { 1418 ActivityManagerService m = mSelf; 1419 1420 ServiceManager.addService("activity", m, true); 1421 ServiceManager.addService("meminfo", new MemBinder(m)); 1422 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1423 ServiceManager.addService("dbinfo", new DbBinder(m)); 1424 if (MONITOR_CPU_USAGE) { 1425 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1426 } 1427 ServiceManager.addService("permission", new PermissionController(m)); 1428 1429 ApplicationInfo info = 1430 mSelf.mContext.getPackageManager().getApplicationInfo( 1431 "android", STOCK_PM_FLAGS); 1432 mSystemThread.installSystemApplicationInfo(info); 1433 1434 synchronized (mSelf) { 1435 ProcessRecord app = mSelf.newProcessRecordLocked( 1436 mSystemThread.getApplicationThread(), info, 1437 info.processName, false); 1438 app.persistent = true; 1439 app.pid = MY_PID; 1440 app.maxAdj = ProcessList.SYSTEM_ADJ; 1441 mSelf.mProcessNames.put(app.processName, app.uid, app); 1442 synchronized (mSelf.mPidsSelfLocked) { 1443 mSelf.mPidsSelfLocked.put(app.pid, app); 1444 } 1445 mSelf.updateLruProcessLocked(app, true); 1446 } 1447 } catch (PackageManager.NameNotFoundException e) { 1448 throw new RuntimeException( 1449 "Unable to find android system package", e); 1450 } 1451 } 1452 1453 public void setWindowManager(WindowManagerService wm) { 1454 mWindowManager = wm; 1455 } 1456 1457 public void startObservingNativeCrashes() { 1458 final NativeCrashListener ncl = new NativeCrashListener(); 1459 ncl.start(); 1460 } 1461 1462 public static final Context main(int factoryTest) { 1463 AThread thr = new AThread(); 1464 thr.start(); 1465 1466 synchronized (thr) { 1467 while (thr.mService == null) { 1468 try { 1469 thr.wait(); 1470 } catch (InterruptedException e) { 1471 } 1472 } 1473 } 1474 1475 ActivityManagerService m = thr.mService; 1476 mSelf = m; 1477 ActivityThread at = ActivityThread.systemMain(); 1478 mSystemThread = at; 1479 Context context = at.getSystemContext(); 1480 context.setTheme(android.R.style.Theme_Holo); 1481 m.mContext = context; 1482 m.mFactoryTest = factoryTest; 1483 m.mMainStack = new ActivityStack(m, context, true, thr.mLooper); 1484 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1485 1486 m.mBatteryStatsService.publish(context); 1487 m.mUsageStatsService.publish(context); 1488 m.mAppOpsService.publish(context); 1489 1490 synchronized (thr) { 1491 thr.mReady = true; 1492 thr.notifyAll(); 1493 } 1494 1495 m.startRunning(null, null, null, null); 1496 1497 return context; 1498 } 1499 1500 public static ActivityManagerService self() { 1501 return mSelf; 1502 } 1503 1504 static class AThread extends Thread { 1505 ActivityManagerService mService; 1506 Looper mLooper; 1507 boolean mReady = false; 1508 1509 public AThread() { 1510 super("ActivityManager"); 1511 } 1512 1513 public void run() { 1514 Looper.prepare(); 1515 1516 android.os.Process.setThreadPriority( 1517 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1518 android.os.Process.setCanSelfBackground(false); 1519 1520 ActivityManagerService m = new ActivityManagerService(); 1521 1522 synchronized (this) { 1523 mService = m; 1524 mLooper = Looper.myLooper(); 1525 notifyAll(); 1526 } 1527 1528 synchronized (this) { 1529 while (!mReady) { 1530 try { 1531 wait(); 1532 } catch (InterruptedException e) { 1533 } 1534 } 1535 } 1536 1537 // For debug builds, log event loop stalls to dropbox for analysis. 1538 if (StrictMode.conditionallyEnableDebugLogging()) { 1539 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1540 } 1541 1542 Looper.loop(); 1543 } 1544 } 1545 1546 static class MemBinder extends Binder { 1547 ActivityManagerService mActivityManagerService; 1548 MemBinder(ActivityManagerService activityManagerService) { 1549 mActivityManagerService = activityManagerService; 1550 } 1551 1552 @Override 1553 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1554 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1555 != PackageManager.PERMISSION_GRANTED) { 1556 pw.println("Permission Denial: can't dump meminfo from from pid=" 1557 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1558 + " without permission " + android.Manifest.permission.DUMP); 1559 return; 1560 } 1561 1562 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1563 false, null, null, null); 1564 } 1565 } 1566 1567 static class GraphicsBinder extends Binder { 1568 ActivityManagerService mActivityManagerService; 1569 GraphicsBinder(ActivityManagerService activityManagerService) { 1570 mActivityManagerService = activityManagerService; 1571 } 1572 1573 @Override 1574 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1575 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1576 != PackageManager.PERMISSION_GRANTED) { 1577 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1578 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1579 + " without permission " + android.Manifest.permission.DUMP); 1580 return; 1581 } 1582 1583 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1584 } 1585 } 1586 1587 static class DbBinder extends Binder { 1588 ActivityManagerService mActivityManagerService; 1589 DbBinder(ActivityManagerService activityManagerService) { 1590 mActivityManagerService = activityManagerService; 1591 } 1592 1593 @Override 1594 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1595 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1596 != PackageManager.PERMISSION_GRANTED) { 1597 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1598 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1599 + " without permission " + android.Manifest.permission.DUMP); 1600 return; 1601 } 1602 1603 mActivityManagerService.dumpDbInfo(fd, pw, args); 1604 } 1605 } 1606 1607 static class CpuBinder extends Binder { 1608 ActivityManagerService mActivityManagerService; 1609 CpuBinder(ActivityManagerService activityManagerService) { 1610 mActivityManagerService = activityManagerService; 1611 } 1612 1613 @Override 1614 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1615 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1616 != PackageManager.PERMISSION_GRANTED) { 1617 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1618 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1619 + " without permission " + android.Manifest.permission.DUMP); 1620 return; 1621 } 1622 1623 synchronized (mActivityManagerService.mProcessStatsThread) { 1624 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1625 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1626 SystemClock.uptimeMillis())); 1627 } 1628 } 1629 } 1630 1631 private ActivityManagerService() { 1632 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1633 1634 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1635 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1636 mBroadcastQueues[0] = mFgBroadcastQueue; 1637 mBroadcastQueues[1] = mBgBroadcastQueue; 1638 1639 mServices = new ActiveServices(this); 1640 mProviderMap = new ProviderMap(this); 1641 1642 File dataDir = Environment.getDataDirectory(); 1643 File systemDir = new File(dataDir, "system"); 1644 systemDir.mkdirs(); 1645 mBatteryStatsService = new BatteryStatsService(new File( 1646 systemDir, "batterystats.bin").toString()); 1647 mBatteryStatsService.getActiveStatistics().readLocked(); 1648 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1649 mOnBattery = DEBUG_POWER ? true 1650 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1651 mBatteryStatsService.getActiveStatistics().setCallback(this); 1652 1653 mUsageStatsService = new UsageStatsService(new File( 1654 systemDir, "usagestats").toString()); 1655 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1656 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1657 1658 // User 0 is the first and only user that runs at boot. 1659 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1660 mUserLru.add(Integer.valueOf(0)); 1661 updateStartedUserArrayLocked(); 1662 1663 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1664 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1665 1666 mConfiguration.setToDefaults(); 1667 mConfiguration.setLocale(Locale.getDefault()); 1668 1669 mConfigurationSeq = mConfiguration.seq = 1; 1670 mProcessStats.init(); 1671 1672 mCompatModePackages = new CompatModePackages(this, systemDir); 1673 1674 // Add ourself to the Watchdog monitors. 1675 Watchdog.getInstance().addMonitor(this); 1676 1677 mProcessStatsThread = new Thread("ProcessStats") { 1678 public void run() { 1679 while (true) { 1680 try { 1681 try { 1682 synchronized(this) { 1683 final long now = SystemClock.uptimeMillis(); 1684 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1685 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1686 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1687 // + ", write delay=" + nextWriteDelay); 1688 if (nextWriteDelay < nextCpuDelay) { 1689 nextCpuDelay = nextWriteDelay; 1690 } 1691 if (nextCpuDelay > 0) { 1692 mProcessStatsMutexFree.set(true); 1693 this.wait(nextCpuDelay); 1694 } 1695 } 1696 } catch (InterruptedException e) { 1697 } 1698 updateCpuStatsNow(); 1699 } catch (Exception e) { 1700 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1701 } 1702 } 1703 } 1704 }; 1705 mProcessStatsThread.start(); 1706 } 1707 1708 @Override 1709 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1710 throws RemoteException { 1711 if (code == SYSPROPS_TRANSACTION) { 1712 // We need to tell all apps about the system property change. 1713 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1714 synchronized(this) { 1715 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1716 final int NA = apps.size(); 1717 for (int ia=0; ia<NA; ia++) { 1718 ProcessRecord app = apps.valueAt(ia); 1719 if (app.thread != null) { 1720 procs.add(app.thread.asBinder()); 1721 } 1722 } 1723 } 1724 } 1725 1726 int N = procs.size(); 1727 for (int i=0; i<N; i++) { 1728 Parcel data2 = Parcel.obtain(); 1729 try { 1730 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1731 } catch (RemoteException e) { 1732 } 1733 data2.recycle(); 1734 } 1735 } 1736 try { 1737 return super.onTransact(code, data, reply, flags); 1738 } catch (RuntimeException e) { 1739 // The activity manager only throws security exceptions, so let's 1740 // log all others. 1741 if (!(e instanceof SecurityException)) { 1742 Slog.e(TAG, "Activity Manager Crash", e); 1743 } 1744 throw e; 1745 } 1746 } 1747 1748 void updateCpuStats() { 1749 final long now = SystemClock.uptimeMillis(); 1750 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1751 return; 1752 } 1753 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1754 synchronized (mProcessStatsThread) { 1755 mProcessStatsThread.notify(); 1756 } 1757 } 1758 } 1759 1760 void updateCpuStatsNow() { 1761 synchronized (mProcessStatsThread) { 1762 mProcessStatsMutexFree.set(false); 1763 final long now = SystemClock.uptimeMillis(); 1764 boolean haveNewCpuStats = false; 1765 1766 if (MONITOR_CPU_USAGE && 1767 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1768 mLastCpuTime.set(now); 1769 haveNewCpuStats = true; 1770 mProcessStats.update(); 1771 //Slog.i(TAG, mProcessStats.printCurrentState()); 1772 //Slog.i(TAG, "Total CPU usage: " 1773 // + mProcessStats.getTotalCpuPercent() + "%"); 1774 1775 // Slog the cpu usage if the property is set. 1776 if ("true".equals(SystemProperties.get("events.cpu"))) { 1777 int user = mProcessStats.getLastUserTime(); 1778 int system = mProcessStats.getLastSystemTime(); 1779 int iowait = mProcessStats.getLastIoWaitTime(); 1780 int irq = mProcessStats.getLastIrqTime(); 1781 int softIrq = mProcessStats.getLastSoftIrqTime(); 1782 int idle = mProcessStats.getLastIdleTime(); 1783 1784 int total = user + system + iowait + irq + softIrq + idle; 1785 if (total == 0) total = 1; 1786 1787 EventLog.writeEvent(EventLogTags.CPU, 1788 ((user+system+iowait+irq+softIrq) * 100) / total, 1789 (user * 100) / total, 1790 (system * 100) / total, 1791 (iowait * 100) / total, 1792 (irq * 100) / total, 1793 (softIrq * 100) / total); 1794 } 1795 } 1796 1797 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1798 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1799 synchronized(bstats) { 1800 synchronized(mPidsSelfLocked) { 1801 if (haveNewCpuStats) { 1802 if (mOnBattery) { 1803 int perc = bstats.startAddingCpuLocked(); 1804 int totalUTime = 0; 1805 int totalSTime = 0; 1806 final int N = mProcessStats.countStats(); 1807 for (int i=0; i<N; i++) { 1808 ProcessStats.Stats st = mProcessStats.getStats(i); 1809 if (!st.working) { 1810 continue; 1811 } 1812 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1813 int otherUTime = (st.rel_utime*perc)/100; 1814 int otherSTime = (st.rel_stime*perc)/100; 1815 totalUTime += otherUTime; 1816 totalSTime += otherSTime; 1817 if (pr != null) { 1818 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1819 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1820 st.rel_stime-otherSTime); 1821 ps.addSpeedStepTimes(cpuSpeedTimes); 1822 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1823 } else { 1824 BatteryStatsImpl.Uid.Proc ps = 1825 bstats.getProcessStatsLocked(st.name, st.pid); 1826 if (ps != null) { 1827 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1828 st.rel_stime-otherSTime); 1829 ps.addSpeedStepTimes(cpuSpeedTimes); 1830 } 1831 } 1832 } 1833 bstats.finishAddingCpuLocked(perc, totalUTime, 1834 totalSTime, cpuSpeedTimes); 1835 } 1836 } 1837 } 1838 1839 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1840 mLastWriteTime = now; 1841 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1842 } 1843 } 1844 } 1845 } 1846 1847 @Override 1848 public void batteryNeedsCpuUpdate() { 1849 updateCpuStatsNow(); 1850 } 1851 1852 @Override 1853 public void batteryPowerChanged(boolean onBattery) { 1854 // When plugging in, update the CPU stats first before changing 1855 // the plug state. 1856 updateCpuStatsNow(); 1857 synchronized (this) { 1858 synchronized(mPidsSelfLocked) { 1859 mOnBattery = DEBUG_POWER ? true : onBattery; 1860 } 1861 } 1862 } 1863 1864 /** 1865 * Initialize the application bind args. These are passed to each 1866 * process when the bindApplication() IPC is sent to the process. They're 1867 * lazily setup to make sure the services are running when they're asked for. 1868 */ 1869 private HashMap<String, IBinder> getCommonServicesLocked() { 1870 if (mAppBindArgs == null) { 1871 mAppBindArgs = new HashMap<String, IBinder>(); 1872 1873 // Setup the application init args 1874 mAppBindArgs.put("package", ServiceManager.getService("package")); 1875 mAppBindArgs.put("window", ServiceManager.getService("window")); 1876 mAppBindArgs.put(Context.ALARM_SERVICE, 1877 ServiceManager.getService(Context.ALARM_SERVICE)); 1878 } 1879 return mAppBindArgs; 1880 } 1881 1882 final void setFocusedActivityLocked(ActivityRecord r) { 1883 if (mFocusedActivity != r) { 1884 mFocusedActivity = r; 1885 if (r != null) { 1886 mWindowManager.setFocusedApp(r.appToken, true); 1887 } 1888 applyUpdateLockStateLocked(r); 1889 } 1890 } 1891 1892 final void applyUpdateLockStateLocked(ActivityRecord r) { 1893 // Modifications to the UpdateLock state are done on our handler, outside 1894 // the activity manager's locks. The new state is determined based on the 1895 // state *now* of the relevant activity record. The object is passed to 1896 // the handler solely for logging detail, not to be consulted/modified. 1897 final boolean nextState = r != null && r.immersive; 1898 mHandler.sendMessage( 1899 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 1900 } 1901 1902 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1903 // put it on the LRU to keep track of when it should be exited. 1904 int lrui = mLruProcesses.indexOf(app); 1905 if (lrui >= 0) mLruProcesses.remove(lrui); 1906 1907 int i = mLruProcesses.size()-1; 1908 int skipTop = 0; 1909 1910 app.lruSeq = mLruSeq; 1911 1912 // compute the new weight for this process. 1913 app.lastActivityTime = SystemClock.uptimeMillis(); 1914 if (app.activities.size() > 0) { 1915 // If this process has activities, we more strongly want to keep 1916 // it around. 1917 app.lruWeight = app.lastActivityTime; 1918 } else if (app.pubProviders.size() > 0) { 1919 // If this process contains content providers, we want to keep 1920 // it a little more strongly. 1921 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1922 // Also don't let it kick out the first few "real" hidden processes. 1923 skipTop = ProcessList.MIN_HIDDEN_APPS; 1924 } else { 1925 // If this process doesn't have activities, we less strongly 1926 // want to keep it around, and generally want to avoid getting 1927 // in front of any very recently used activities. 1928 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1929 // Also don't let it kick out the first few "real" hidden processes. 1930 skipTop = ProcessList.MIN_HIDDEN_APPS; 1931 } 1932 1933 while (i >= 0) { 1934 ProcessRecord p = mLruProcesses.get(i); 1935 // If this app shouldn't be in front of the first N background 1936 // apps, then skip over that many that are currently hidden. 1937 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1938 skipTop--; 1939 } 1940 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1941 mLruProcesses.add(i+1, app); 1942 break; 1943 } 1944 i--; 1945 } 1946 if (i < 0) { 1947 mLruProcesses.add(0, app); 1948 } 1949 1950 // If the app is currently using a content provider or service, 1951 // bump those processes as well. 1952 if (app.connections.size() > 0) { 1953 for (ConnectionRecord cr : app.connections) { 1954 if (cr.binding != null && cr.binding.service != null 1955 && cr.binding.service.app != null 1956 && cr.binding.service.app.lruSeq != mLruSeq) { 1957 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1958 } 1959 } 1960 } 1961 for (int j=app.conProviders.size()-1; j>=0; j--) { 1962 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1963 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1964 updateLruProcessInternalLocked(cpr.proc, i+1); 1965 } 1966 } 1967 } 1968 1969 final void updateLruProcessLocked(ProcessRecord app, 1970 boolean oomAdj) { 1971 mLruSeq++; 1972 updateLruProcessInternalLocked(app, 0); 1973 1974 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1975 if (oomAdj) { 1976 updateOomAdjLocked(); 1977 } 1978 } 1979 1980 final ProcessRecord getProcessRecordLocked( 1981 String processName, int uid) { 1982 if (uid == Process.SYSTEM_UID) { 1983 // The system gets to run in any process. If there are multiple 1984 // processes with the same uid, just pick the first (this 1985 // should never happen). 1986 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1987 processName); 1988 if (procs == null) return null; 1989 final int N = procs.size(); 1990 for (int i = 0; i < N; i++) { 1991 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1992 } 1993 } 1994 ProcessRecord proc = mProcessNames.get(processName, uid); 1995 return proc; 1996 } 1997 1998 void ensurePackageDexOpt(String packageName) { 1999 IPackageManager pm = AppGlobals.getPackageManager(); 2000 try { 2001 if (pm.performDexOpt(packageName)) { 2002 mDidDexOpt = true; 2003 } 2004 } catch (RemoteException e) { 2005 } 2006 } 2007 2008 boolean isNextTransitionForward() { 2009 int transit = mWindowManager.getPendingAppTransition(); 2010 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2011 || transit == AppTransition.TRANSIT_TASK_OPEN 2012 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2013 } 2014 2015 final ProcessRecord startProcessLocked(String processName, 2016 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2017 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2018 boolean isolated) { 2019 ProcessRecord app; 2020 if (!isolated) { 2021 app = getProcessRecordLocked(processName, info.uid); 2022 } else { 2023 // If this is an isolated process, it can't re-use an existing process. 2024 app = null; 2025 } 2026 // We don't have to do anything more if: 2027 // (1) There is an existing application record; and 2028 // (2) The caller doesn't think it is dead, OR there is no thread 2029 // object attached to it so we know it couldn't have crashed; and 2030 // (3) There is a pid assigned to it, so it is either starting or 2031 // already running. 2032 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2033 + " app=" + app + " knownToBeDead=" + knownToBeDead 2034 + " thread=" + (app != null ? app.thread : null) 2035 + " pid=" + (app != null ? app.pid : -1)); 2036 if (app != null && app.pid > 0) { 2037 if (!knownToBeDead || app.thread == null) { 2038 // We already have the app running, or are waiting for it to 2039 // come up (we have a pid but not yet its thread), so keep it. 2040 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2041 // If this is a new package in the process, add the package to the list 2042 app.addPackage(info.packageName); 2043 return app; 2044 } else { 2045 // An application record is attached to a previous process, 2046 // clean it up now. 2047 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2048 handleAppDiedLocked(app, true, true); 2049 } 2050 } 2051 2052 String hostingNameStr = hostingName != null 2053 ? hostingName.flattenToShortString() : null; 2054 2055 if (!isolated) { 2056 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2057 // If we are in the background, then check to see if this process 2058 // is bad. If so, we will just silently fail. 2059 if (mBadProcesses.get(info.processName, info.uid) != null) { 2060 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2061 + "/" + info.processName); 2062 return null; 2063 } 2064 } else { 2065 // When the user is explicitly starting a process, then clear its 2066 // crash count so that we won't make it bad until they see at 2067 // least one crash dialog again, and make the process good again 2068 // if it had been bad. 2069 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2070 + "/" + info.processName); 2071 mProcessCrashTimes.remove(info.processName, info.uid); 2072 if (mBadProcesses.get(info.processName, info.uid) != null) { 2073 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2074 UserHandle.getUserId(info.uid), info.uid, 2075 info.processName); 2076 mBadProcesses.remove(info.processName, info.uid); 2077 if (app != null) { 2078 app.bad = false; 2079 } 2080 } 2081 } 2082 } 2083 2084 if (app == null) { 2085 app = newProcessRecordLocked(null, info, processName, isolated); 2086 if (app == null) { 2087 Slog.w(TAG, "Failed making new process record for " 2088 + processName + "/" + info.uid + " isolated=" + isolated); 2089 return null; 2090 } 2091 mProcessNames.put(processName, app.uid, app); 2092 if (isolated) { 2093 mIsolatedProcesses.put(app.uid, app); 2094 } 2095 } else { 2096 // If this is a new package in the process, add the package to the list 2097 app.addPackage(info.packageName); 2098 } 2099 2100 // If the system is not ready yet, then hold off on starting this 2101 // process until it is. 2102 if (!mProcessesReady 2103 && !isAllowedWhileBooting(info) 2104 && !allowWhileBooting) { 2105 if (!mProcessesOnHold.contains(app)) { 2106 mProcessesOnHold.add(app); 2107 } 2108 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2109 return app; 2110 } 2111 2112 startProcessLocked(app, hostingType, hostingNameStr); 2113 return (app.pid != 0) ? app : null; 2114 } 2115 2116 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2117 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2118 } 2119 2120 private final void startProcessLocked(ProcessRecord app, 2121 String hostingType, String hostingNameStr) { 2122 if (app.pid > 0 && app.pid != MY_PID) { 2123 synchronized (mPidsSelfLocked) { 2124 mPidsSelfLocked.remove(app.pid); 2125 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2126 } 2127 app.setPid(0); 2128 } 2129 2130 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2131 "startProcessLocked removing on hold: " + app); 2132 mProcessesOnHold.remove(app); 2133 2134 updateCpuStats(); 2135 2136 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2137 mProcDeaths[0] = 0; 2138 2139 try { 2140 int uid = app.uid; 2141 2142 int[] gids = null; 2143 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2144 if (!app.isolated) { 2145 int[] permGids = null; 2146 try { 2147 final PackageManager pm = mContext.getPackageManager(); 2148 permGids = pm.getPackageGids(app.info.packageName); 2149 2150 if (Environment.isExternalStorageEmulated()) { 2151 if (pm.checkPermission( 2152 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2153 app.info.packageName) == PERMISSION_GRANTED) { 2154 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2155 } else { 2156 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2157 } 2158 } 2159 } catch (PackageManager.NameNotFoundException e) { 2160 Slog.w(TAG, "Unable to retrieve gids", e); 2161 } 2162 2163 /* 2164 * Add shared application GID so applications can share some 2165 * resources like shared libraries 2166 */ 2167 if (permGids == null) { 2168 gids = new int[1]; 2169 } else { 2170 gids = new int[permGids.length + 1]; 2171 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2172 } 2173 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2174 } 2175 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2176 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2177 && mTopComponent != null 2178 && app.processName.equals(mTopComponent.getPackageName())) { 2179 uid = 0; 2180 } 2181 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2182 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2183 uid = 0; 2184 } 2185 } 2186 int debugFlags = 0; 2187 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2188 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2189 // Also turn on CheckJNI for debuggable apps. It's quite 2190 // awkward to turn on otherwise. 2191 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2192 } 2193 // Run the app in safe mode if its manifest requests so or the 2194 // system is booted in safe mode. 2195 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2196 Zygote.systemInSafeMode == true) { 2197 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2198 } 2199 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2200 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2201 } 2202 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2203 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2204 } 2205 if ("1".equals(SystemProperties.get("debug.assert"))) { 2206 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2207 } 2208 2209 // Start the process. It will either succeed and return a result containing 2210 // the PID of the new process, or else throw a RuntimeException. 2211 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2212 app.processName, uid, uid, gids, debugFlags, mountExternal, 2213 app.info.targetSdkVersion, app.info.seinfo, null); 2214 2215 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2216 synchronized (bs) { 2217 if (bs.isOnBattery()) { 2218 app.batteryStats.incStartsLocked(); 2219 } 2220 } 2221 2222 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2223 UserHandle.getUserId(uid), startResult.pid, uid, 2224 app.processName, hostingType, 2225 hostingNameStr != null ? hostingNameStr : ""); 2226 2227 if (app.persistent) { 2228 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2229 } 2230 2231 StringBuilder buf = mStringBuilder; 2232 buf.setLength(0); 2233 buf.append("Start proc "); 2234 buf.append(app.processName); 2235 buf.append(" for "); 2236 buf.append(hostingType); 2237 if (hostingNameStr != null) { 2238 buf.append(" "); 2239 buf.append(hostingNameStr); 2240 } 2241 buf.append(": pid="); 2242 buf.append(startResult.pid); 2243 buf.append(" uid="); 2244 buf.append(uid); 2245 buf.append(" gids={"); 2246 if (gids != null) { 2247 for (int gi=0; gi<gids.length; gi++) { 2248 if (gi != 0) buf.append(", "); 2249 buf.append(gids[gi]); 2250 2251 } 2252 } 2253 buf.append("}"); 2254 Slog.i(TAG, buf.toString()); 2255 app.setPid(startResult.pid); 2256 app.usingWrapper = startResult.usingWrapper; 2257 app.removed = false; 2258 synchronized (mPidsSelfLocked) { 2259 this.mPidsSelfLocked.put(startResult.pid, app); 2260 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2261 msg.obj = app; 2262 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2263 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2264 } 2265 } catch (RuntimeException e) { 2266 // XXX do better error recovery. 2267 app.setPid(0); 2268 Slog.e(TAG, "Failure starting process " + app.processName, e); 2269 } 2270 } 2271 2272 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2273 if (resumed) { 2274 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2275 } else { 2276 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2277 } 2278 } 2279 2280 boolean startHomeActivityLocked(int userId) { 2281 if (mHeadless) { 2282 // Added because none of the other calls to ensureBootCompleted seem to fire 2283 // when running headless. 2284 ensureBootCompleted(); 2285 return false; 2286 } 2287 2288 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2289 && mTopAction == null) { 2290 // We are running in factory test mode, but unable to find 2291 // the factory test app, so just sit around displaying the 2292 // error message and don't try to start anything. 2293 return false; 2294 } 2295 Intent intent = new Intent( 2296 mTopAction, 2297 mTopData != null ? Uri.parse(mTopData) : null); 2298 intent.setComponent(mTopComponent); 2299 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2300 intent.addCategory(Intent.CATEGORY_HOME); 2301 } 2302 ActivityInfo aInfo = 2303 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2304 if (aInfo != null) { 2305 intent.setComponent(new ComponentName( 2306 aInfo.applicationInfo.packageName, aInfo.name)); 2307 // Don't do this if the home app is currently being 2308 // instrumented. 2309 aInfo = new ActivityInfo(aInfo); 2310 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2311 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2312 aInfo.applicationInfo.uid); 2313 if (app == null || app.instrumentationClass == null) { 2314 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2315 mMainStack.startActivityLocked(null, intent, null, aInfo, 2316 null, null, 0, 0, 0, null, 0, null, false, null); 2317 } 2318 } 2319 2320 return true; 2321 } 2322 2323 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2324 ActivityInfo ai = null; 2325 ComponentName comp = intent.getComponent(); 2326 try { 2327 if (comp != null) { 2328 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2329 } else { 2330 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2331 intent, 2332 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2333 flags, userId); 2334 2335 if (info != null) { 2336 ai = info.activityInfo; 2337 } 2338 } 2339 } catch (RemoteException e) { 2340 // ignore 2341 } 2342 2343 return ai; 2344 } 2345 2346 /** 2347 * Starts the "new version setup screen" if appropriate. 2348 */ 2349 void startSetupActivityLocked() { 2350 // Only do this once per boot. 2351 if (mCheckedForSetup) { 2352 return; 2353 } 2354 2355 // We will show this screen if the current one is a different 2356 // version than the last one shown, and we are not running in 2357 // low-level factory test mode. 2358 final ContentResolver resolver = mContext.getContentResolver(); 2359 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2360 Settings.Global.getInt(resolver, 2361 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2362 mCheckedForSetup = true; 2363 2364 // See if we should be showing the platform update setup UI. 2365 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2366 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2367 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2368 2369 // We don't allow third party apps to replace this. 2370 ResolveInfo ri = null; 2371 for (int i=0; ris != null && i<ris.size(); i++) { 2372 if ((ris.get(i).activityInfo.applicationInfo.flags 2373 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2374 ri = ris.get(i); 2375 break; 2376 } 2377 } 2378 2379 if (ri != null) { 2380 String vers = ri.activityInfo.metaData != null 2381 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2382 : null; 2383 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2384 vers = ri.activityInfo.applicationInfo.metaData.getString( 2385 Intent.METADATA_SETUP_VERSION); 2386 } 2387 String lastVers = Settings.Secure.getString( 2388 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2389 if (vers != null && !vers.equals(lastVers)) { 2390 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2391 intent.setComponent(new ComponentName( 2392 ri.activityInfo.packageName, ri.activityInfo.name)); 2393 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2394 null, null, 0, 0, 0, null, 0, null, false, null); 2395 } 2396 } 2397 } 2398 } 2399 2400 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2401 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2402 } 2403 2404 void enforceNotIsolatedCaller(String caller) { 2405 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2406 throw new SecurityException("Isolated process not allowed to call " + caller); 2407 } 2408 } 2409 2410 public int getFrontActivityScreenCompatMode() { 2411 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2412 synchronized (this) { 2413 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2414 } 2415 } 2416 2417 public void setFrontActivityScreenCompatMode(int mode) { 2418 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2419 "setFrontActivityScreenCompatMode"); 2420 synchronized (this) { 2421 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2422 } 2423 } 2424 2425 public int getPackageScreenCompatMode(String packageName) { 2426 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2427 synchronized (this) { 2428 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2429 } 2430 } 2431 2432 public void setPackageScreenCompatMode(String packageName, int mode) { 2433 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2434 "setPackageScreenCompatMode"); 2435 synchronized (this) { 2436 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2437 } 2438 } 2439 2440 public boolean getPackageAskScreenCompat(String packageName) { 2441 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2442 synchronized (this) { 2443 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2444 } 2445 } 2446 2447 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2448 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2449 "setPackageAskScreenCompat"); 2450 synchronized (this) { 2451 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2452 } 2453 } 2454 2455 void reportResumedActivityLocked(ActivityRecord r) { 2456 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2457 updateUsageStats(r, true); 2458 } 2459 2460 private void dispatchProcessesChanged() { 2461 int N; 2462 synchronized (this) { 2463 N = mPendingProcessChanges.size(); 2464 if (mActiveProcessChanges.length < N) { 2465 mActiveProcessChanges = new ProcessChangeItem[N]; 2466 } 2467 mPendingProcessChanges.toArray(mActiveProcessChanges); 2468 mAvailProcessChanges.addAll(mPendingProcessChanges); 2469 mPendingProcessChanges.clear(); 2470 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2471 } 2472 int i = mProcessObservers.beginBroadcast(); 2473 while (i > 0) { 2474 i--; 2475 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2476 if (observer != null) { 2477 try { 2478 for (int j=0; j<N; j++) { 2479 ProcessChangeItem item = mActiveProcessChanges[j]; 2480 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2481 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2482 + item.pid + " uid=" + item.uid + ": " 2483 + item.foregroundActivities); 2484 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2485 item.foregroundActivities); 2486 } 2487 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2488 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2489 + item.pid + " uid=" + item.uid + ": " + item.importance); 2490 observer.onImportanceChanged(item.pid, item.uid, 2491 item.importance); 2492 } 2493 } 2494 } catch (RemoteException e) { 2495 } 2496 } 2497 } 2498 mProcessObservers.finishBroadcast(); 2499 } 2500 2501 private void dispatchProcessDied(int pid, int uid) { 2502 int i = mProcessObservers.beginBroadcast(); 2503 while (i > 0) { 2504 i--; 2505 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2506 if (observer != null) { 2507 try { 2508 observer.onProcessDied(pid, uid); 2509 } catch (RemoteException e) { 2510 } 2511 } 2512 } 2513 mProcessObservers.finishBroadcast(); 2514 } 2515 2516 final void doPendingActivityLaunchesLocked(boolean doResume) { 2517 final int N = mPendingActivityLaunches.size(); 2518 if (N <= 0) { 2519 return; 2520 } 2521 for (int i=0; i<N; i++) { 2522 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2523 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2524 pal.startFlags, doResume && i == (N-1), null); 2525 } 2526 mPendingActivityLaunches.clear(); 2527 } 2528 2529 public final int startActivity(IApplicationThread caller, String callingPackage, 2530 Intent intent, String resolvedType, IBinder resultTo, 2531 String resultWho, int requestCode, int startFlags, 2532 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2533 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 2534 resultWho, requestCode, 2535 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2536 } 2537 2538 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 2539 Intent intent, String resolvedType, IBinder resultTo, 2540 String resultWho, int requestCode, int startFlags, 2541 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2542 enforceNotIsolatedCaller("startActivity"); 2543 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2544 false, true, "startActivity", null); 2545 return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 2546 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2547 null, null, options, userId); 2548 } 2549 2550 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 2551 Intent intent, String resolvedType, IBinder resultTo, 2552 String resultWho, int requestCode, int startFlags, String profileFile, 2553 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2554 enforceNotIsolatedCaller("startActivityAndWait"); 2555 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2556 false, true, "startActivityAndWait", null); 2557 WaitResult res = new WaitResult(); 2558 mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 2559 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2560 res, null, options, UserHandle.getCallingUserId()); 2561 return res; 2562 } 2563 2564 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 2565 Intent intent, String resolvedType, IBinder resultTo, 2566 String resultWho, int requestCode, int startFlags, Configuration config, 2567 Bundle options, int userId) { 2568 enforceNotIsolatedCaller("startActivityWithConfig"); 2569 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2570 false, true, "startActivityWithConfig", null); 2571 int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 2572 resultTo, resultWho, requestCode, startFlags, 2573 null, null, null, config, options, userId); 2574 return ret; 2575 } 2576 2577 public int startActivityIntentSender(IApplicationThread caller, 2578 IntentSender intent, Intent fillInIntent, String resolvedType, 2579 IBinder resultTo, String resultWho, int requestCode, 2580 int flagsMask, int flagsValues, Bundle options) { 2581 enforceNotIsolatedCaller("startActivityIntentSender"); 2582 // Refuse possible leaked file descriptors 2583 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2584 throw new IllegalArgumentException("File descriptors passed in Intent"); 2585 } 2586 2587 IIntentSender sender = intent.getTarget(); 2588 if (!(sender instanceof PendingIntentRecord)) { 2589 throw new IllegalArgumentException("Bad PendingIntent object"); 2590 } 2591 2592 PendingIntentRecord pir = (PendingIntentRecord)sender; 2593 2594 synchronized (this) { 2595 // If this is coming from the currently resumed activity, it is 2596 // effectively saying that app switches are allowed at this point. 2597 if (mMainStack.mResumedActivity != null 2598 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2599 Binder.getCallingUid()) { 2600 mAppSwitchesAllowedTime = 0; 2601 } 2602 } 2603 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2604 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2605 return ret; 2606 } 2607 2608 public boolean startNextMatchingActivity(IBinder callingActivity, 2609 Intent intent, Bundle options) { 2610 // Refuse possible leaked file descriptors 2611 if (intent != null && intent.hasFileDescriptors() == true) { 2612 throw new IllegalArgumentException("File descriptors passed in Intent"); 2613 } 2614 2615 synchronized (this) { 2616 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2617 if (r == null) { 2618 ActivityOptions.abort(options); 2619 return false; 2620 } 2621 if (r.app == null || r.app.thread == null) { 2622 // The caller is not running... d'oh! 2623 ActivityOptions.abort(options); 2624 return false; 2625 } 2626 intent = new Intent(intent); 2627 // The caller is not allowed to change the data. 2628 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2629 // And we are resetting to find the next component... 2630 intent.setComponent(null); 2631 2632 ActivityInfo aInfo = null; 2633 try { 2634 List<ResolveInfo> resolves = 2635 AppGlobals.getPackageManager().queryIntentActivities( 2636 intent, r.resolvedType, 2637 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2638 UserHandle.getCallingUserId()); 2639 2640 // Look for the original activity in the list... 2641 final int N = resolves != null ? resolves.size() : 0; 2642 for (int i=0; i<N; i++) { 2643 ResolveInfo rInfo = resolves.get(i); 2644 if (rInfo.activityInfo.packageName.equals(r.packageName) 2645 && rInfo.activityInfo.name.equals(r.info.name)) { 2646 // We found the current one... the next matching is 2647 // after it. 2648 i++; 2649 if (i<N) { 2650 aInfo = resolves.get(i).activityInfo; 2651 } 2652 break; 2653 } 2654 } 2655 } catch (RemoteException e) { 2656 } 2657 2658 if (aInfo == null) { 2659 // Nobody who is next! 2660 ActivityOptions.abort(options); 2661 return false; 2662 } 2663 2664 intent.setComponent(new ComponentName( 2665 aInfo.applicationInfo.packageName, aInfo.name)); 2666 intent.setFlags(intent.getFlags()&~( 2667 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2668 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2669 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2670 Intent.FLAG_ACTIVITY_NEW_TASK)); 2671 2672 // Okay now we need to start the new activity, replacing the 2673 // currently running activity. This is a little tricky because 2674 // we want to start the new one as if the current one is finished, 2675 // but not finish the current one first so that there is no flicker. 2676 // And thus... 2677 final boolean wasFinishing = r.finishing; 2678 r.finishing = true; 2679 2680 // Propagate reply information over to the new activity. 2681 final ActivityRecord resultTo = r.resultTo; 2682 final String resultWho = r.resultWho; 2683 final int requestCode = r.requestCode; 2684 r.resultTo = null; 2685 if (resultTo != null) { 2686 resultTo.removeResultsLocked(r, resultWho, requestCode); 2687 } 2688 2689 final long origId = Binder.clearCallingIdentity(); 2690 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2691 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2692 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 2693 options, false, null); 2694 Binder.restoreCallingIdentity(origId); 2695 2696 r.finishing = wasFinishing; 2697 if (res != ActivityManager.START_SUCCESS) { 2698 return false; 2699 } 2700 return true; 2701 } 2702 } 2703 2704 final int startActivityInPackage(int uid, String callingPackage, 2705 Intent intent, String resolvedType, IBinder resultTo, 2706 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2707 2708 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2709 false, true, "startActivityInPackage", null); 2710 2711 int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 2712 resultTo, resultWho, requestCode, startFlags, 2713 null, null, null, null, options, userId); 2714 return ret; 2715 } 2716 2717 public final int startActivities(IApplicationThread caller, String callingPackage, 2718 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2719 int userId) { 2720 enforceNotIsolatedCaller("startActivities"); 2721 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2722 false, true, "startActivity", null); 2723 int ret = mMainStack.startActivities(caller, -1, callingPackage, intents, 2724 resolvedTypes, resultTo, options, userId); 2725 return ret; 2726 } 2727 2728 final int startActivitiesInPackage(int uid, String callingPackage, 2729 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2730 Bundle options, int userId) { 2731 2732 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2733 false, true, "startActivityInPackage", null); 2734 int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes, 2735 resultTo, options, userId); 2736 return ret; 2737 } 2738 2739 final void addRecentTaskLocked(TaskRecord task) { 2740 int N = mRecentTasks.size(); 2741 // Quick case: check if the top-most recent task is the same. 2742 if (N > 0 && mRecentTasks.get(0) == task) { 2743 return; 2744 } 2745 // Remove any existing entries that are the same kind of task. 2746 for (int i=0; i<N; i++) { 2747 TaskRecord tr = mRecentTasks.get(i); 2748 if (task.userId == tr.userId 2749 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2750 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2751 mRecentTasks.remove(i); 2752 i--; 2753 N--; 2754 if (task.intent == null) { 2755 // If the new recent task we are adding is not fully 2756 // specified, then replace it with the existing recent task. 2757 task = tr; 2758 } 2759 } 2760 } 2761 if (N >= MAX_RECENT_TASKS) { 2762 mRecentTasks.remove(N-1); 2763 } 2764 mRecentTasks.add(0, task); 2765 } 2766 2767 public void setRequestedOrientation(IBinder token, 2768 int requestedOrientation) { 2769 synchronized (this) { 2770 ActivityRecord r = mMainStack.isInStackLocked(token); 2771 if (r == null) { 2772 return; 2773 } 2774 final long origId = Binder.clearCallingIdentity(); 2775 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2776 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2777 mConfiguration, 2778 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2779 if (config != null) { 2780 r.frozenBeforeDestroy = true; 2781 if (!updateConfigurationLocked(config, r, false, false)) { 2782 mMainStack.resumeTopActivityLocked(null); 2783 } 2784 } 2785 Binder.restoreCallingIdentity(origId); 2786 } 2787 } 2788 2789 public int getRequestedOrientation(IBinder token) { 2790 synchronized (this) { 2791 ActivityRecord r = mMainStack.isInStackLocked(token); 2792 if (r == null) { 2793 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2794 } 2795 return mWindowManager.getAppOrientation(r.appToken); 2796 } 2797 } 2798 2799 /** 2800 * This is the internal entry point for handling Activity.finish(). 2801 * 2802 * @param token The Binder token referencing the Activity we want to finish. 2803 * @param resultCode Result code, if any, from this Activity. 2804 * @param resultData Result data (Intent), if any, from this Activity. 2805 * 2806 * @return Returns true if the activity successfully finished, or false if it is still running. 2807 */ 2808 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2809 // Refuse possible leaked file descriptors 2810 if (resultData != null && resultData.hasFileDescriptors() == true) { 2811 throw new IllegalArgumentException("File descriptors passed in Intent"); 2812 } 2813 2814 synchronized(this) { 2815 if (mController != null) { 2816 // Find the first activity that is not finishing. 2817 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2818 if (next != null) { 2819 // ask watcher if this is allowed 2820 boolean resumeOK = true; 2821 try { 2822 resumeOK = mController.activityResuming(next.packageName); 2823 } catch (RemoteException e) { 2824 mController = null; 2825 Watchdog.getInstance().setActivityController(null); 2826 } 2827 2828 if (!resumeOK) { 2829 return false; 2830 } 2831 } 2832 } 2833 final long origId = Binder.clearCallingIdentity(); 2834 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2835 resultData, "app-request", true); 2836 Binder.restoreCallingIdentity(origId); 2837 return res; 2838 } 2839 } 2840 2841 public final void finishHeavyWeightApp() { 2842 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2843 != PackageManager.PERMISSION_GRANTED) { 2844 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2845 + Binder.getCallingPid() 2846 + ", uid=" + Binder.getCallingUid() 2847 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2848 Slog.w(TAG, msg); 2849 throw new SecurityException(msg); 2850 } 2851 2852 synchronized(this) { 2853 if (mHeavyWeightProcess == null) { 2854 return; 2855 } 2856 2857 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2858 mHeavyWeightProcess.activities); 2859 for (int i=0; i<activities.size(); i++) { 2860 ActivityRecord r = activities.get(i); 2861 if (!r.finishing) { 2862 int index = mMainStack.indexOfTokenLocked(r.appToken); 2863 if (index >= 0) { 2864 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2865 null, "finish-heavy", true); 2866 } 2867 } 2868 } 2869 2870 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2871 mHeavyWeightProcess.userId, 0)); 2872 mHeavyWeightProcess = null; 2873 } 2874 } 2875 2876 public void crashApplication(int uid, int initialPid, String packageName, 2877 String message) { 2878 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2879 != PackageManager.PERMISSION_GRANTED) { 2880 String msg = "Permission Denial: crashApplication() from pid=" 2881 + Binder.getCallingPid() 2882 + ", uid=" + Binder.getCallingUid() 2883 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2884 Slog.w(TAG, msg); 2885 throw new SecurityException(msg); 2886 } 2887 2888 synchronized(this) { 2889 ProcessRecord proc = null; 2890 2891 // Figure out which process to kill. We don't trust that initialPid 2892 // still has any relation to current pids, so must scan through the 2893 // list. 2894 synchronized (mPidsSelfLocked) { 2895 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2896 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2897 if (p.uid != uid) { 2898 continue; 2899 } 2900 if (p.pid == initialPid) { 2901 proc = p; 2902 break; 2903 } 2904 for (String str : p.pkgList) { 2905 if (str.equals(packageName)) { 2906 proc = p; 2907 } 2908 } 2909 } 2910 } 2911 2912 if (proc == null) { 2913 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2914 + " initialPid=" + initialPid 2915 + " packageName=" + packageName); 2916 return; 2917 } 2918 2919 if (proc.thread != null) { 2920 if (proc.pid == Process.myPid()) { 2921 Log.w(TAG, "crashApplication: trying to crash self!"); 2922 return; 2923 } 2924 long ident = Binder.clearCallingIdentity(); 2925 try { 2926 proc.thread.scheduleCrash(message); 2927 } catch (RemoteException e) { 2928 } 2929 Binder.restoreCallingIdentity(ident); 2930 } 2931 } 2932 } 2933 2934 public final void finishSubActivity(IBinder token, String resultWho, 2935 int requestCode) { 2936 synchronized(this) { 2937 final long origId = Binder.clearCallingIdentity(); 2938 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2939 Binder.restoreCallingIdentity(origId); 2940 } 2941 } 2942 2943 public boolean finishActivityAffinity(IBinder token) { 2944 synchronized(this) { 2945 final long origId = Binder.clearCallingIdentity(); 2946 boolean res = mMainStack.finishActivityAffinityLocked(token); 2947 Binder.restoreCallingIdentity(origId); 2948 return res; 2949 } 2950 } 2951 2952 public boolean willActivityBeVisible(IBinder token) { 2953 synchronized(this) { 2954 int i; 2955 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2956 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2957 if (r.appToken == token) { 2958 return true; 2959 } 2960 if (r.fullscreen && !r.finishing) { 2961 return false; 2962 } 2963 } 2964 return true; 2965 } 2966 } 2967 2968 public void overridePendingTransition(IBinder token, String packageName, 2969 int enterAnim, int exitAnim) { 2970 synchronized(this) { 2971 ActivityRecord self = mMainStack.isInStackLocked(token); 2972 if (self == null) { 2973 return; 2974 } 2975 2976 final long origId = Binder.clearCallingIdentity(); 2977 2978 if (self.state == ActivityState.RESUMED 2979 || self.state == ActivityState.PAUSING) { 2980 mWindowManager.overridePendingAppTransition(packageName, 2981 enterAnim, exitAnim, null); 2982 } 2983 2984 Binder.restoreCallingIdentity(origId); 2985 } 2986 } 2987 2988 /** 2989 * Main function for removing an existing process from the activity manager 2990 * as a result of that process going away. Clears out all connections 2991 * to the process. 2992 */ 2993 private final void handleAppDiedLocked(ProcessRecord app, 2994 boolean restarting, boolean allowRestart) { 2995 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2996 if (!restarting) { 2997 mLruProcesses.remove(app); 2998 } 2999 3000 if (mProfileProc == app) { 3001 clearProfilerLocked(); 3002 } 3003 3004 // Just in case... 3005 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 3006 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 3007 "App died while pausing: " + mMainStack.mPausingActivity); 3008 mMainStack.mPausingActivity = null; 3009 } 3010 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 3011 mMainStack.mLastPausedActivity = null; 3012 } 3013 3014 // Remove this application's activities from active lists. 3015 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 3016 3017 app.activities.clear(); 3018 3019 if (app.instrumentationClass != null) { 3020 Slog.w(TAG, "Crash of app " + app.processName 3021 + " running instrumentation " + app.instrumentationClass); 3022 Bundle info = new Bundle(); 3023 info.putString("shortMsg", "Process crashed."); 3024 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3025 } 3026 3027 if (!restarting) { 3028 if (!mMainStack.resumeTopActivityLocked(null)) { 3029 // If there was nothing to resume, and we are not already 3030 // restarting this process, but there is a visible activity that 3031 // is hosted by the process... then make sure all visible 3032 // activities are running, taking care of restarting this 3033 // process. 3034 if (hasVisibleActivities) { 3035 mMainStack.ensureActivitiesVisibleLocked(null, 0); 3036 } 3037 } 3038 } 3039 } 3040 3041 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3042 IBinder threadBinder = thread.asBinder(); 3043 // Find the application record. 3044 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3045 ProcessRecord rec = mLruProcesses.get(i); 3046 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3047 return i; 3048 } 3049 } 3050 return -1; 3051 } 3052 3053 final ProcessRecord getRecordForAppLocked( 3054 IApplicationThread thread) { 3055 if (thread == null) { 3056 return null; 3057 } 3058 3059 int appIndex = getLRURecordIndexForAppLocked(thread); 3060 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3061 } 3062 3063 final void appDiedLocked(ProcessRecord app, int pid, 3064 IApplicationThread thread) { 3065 3066 mProcDeaths[0]++; 3067 3068 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3069 synchronized (stats) { 3070 stats.noteProcessDiedLocked(app.info.uid, pid); 3071 } 3072 3073 // Clean up already done if the process has been re-started. 3074 if (app.pid == pid && app.thread != null && 3075 app.thread.asBinder() == thread.asBinder()) { 3076 if (!app.killedBackground) { 3077 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3078 + ") has died."); 3079 } 3080 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3081 if (DEBUG_CLEANUP) Slog.v( 3082 TAG, "Dying app: " + app + ", pid: " + pid 3083 + ", thread: " + thread.asBinder()); 3084 boolean doLowMem = app.instrumentationClass == null; 3085 handleAppDiedLocked(app, false, true); 3086 3087 if (doLowMem) { 3088 // If there are no longer any background processes running, 3089 // and the app that died was not running instrumentation, 3090 // then tell everyone we are now low on memory. 3091 boolean haveBg = false; 3092 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3093 ProcessRecord rec = mLruProcesses.get(i); 3094 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3095 haveBg = true; 3096 break; 3097 } 3098 } 3099 3100 if (!haveBg) { 3101 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3102 long now = SystemClock.uptimeMillis(); 3103 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3104 ProcessRecord rec = mLruProcesses.get(i); 3105 if (rec != app && rec.thread != null && 3106 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3107 // The low memory report is overriding any current 3108 // state for a GC request. Make sure to do 3109 // heavy/important/visible/foreground processes first. 3110 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3111 rec.lastRequestedGc = 0; 3112 } else { 3113 rec.lastRequestedGc = rec.lastLowMemory; 3114 } 3115 rec.reportLowMemory = true; 3116 rec.lastLowMemory = now; 3117 mProcessesToGc.remove(rec); 3118 addProcessToGcListLocked(rec); 3119 } 3120 } 3121 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3122 scheduleAppGcsLocked(); 3123 } 3124 } 3125 } else if (app.pid != pid) { 3126 // A new process has already been started. 3127 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3128 + ") has died and restarted (pid " + app.pid + ")."); 3129 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3130 } else if (DEBUG_PROCESSES) { 3131 Slog.d(TAG, "Received spurious death notification for thread " 3132 + thread.asBinder()); 3133 } 3134 } 3135 3136 /** 3137 * If a stack trace dump file is configured, dump process stack traces. 3138 * @param clearTraces causes the dump file to be erased prior to the new 3139 * traces being written, if true; when false, the new traces will be 3140 * appended to any existing file content. 3141 * @param firstPids of dalvik VM processes to dump stack traces for first 3142 * @param lastPids of dalvik VM processes to dump stack traces for last 3143 * @param nativeProcs optional list of native process names to dump stack crawls 3144 * @return file containing stack traces, or null if no dump file is configured 3145 */ 3146 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3147 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3148 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3149 if (tracesPath == null || tracesPath.length() == 0) { 3150 return null; 3151 } 3152 3153 File tracesFile = new File(tracesPath); 3154 try { 3155 File tracesDir = tracesFile.getParentFile(); 3156 if (!tracesDir.exists()) { 3157 tracesFile.mkdirs(); 3158 if (!SELinux.restorecon(tracesDir)) { 3159 return null; 3160 } 3161 } 3162 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3163 3164 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3165 tracesFile.createNewFile(); 3166 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3167 } catch (IOException e) { 3168 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3169 return null; 3170 } 3171 3172 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3173 return tracesFile; 3174 } 3175 3176 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3177 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3178 // Use a FileObserver to detect when traces finish writing. 3179 // The order of traces is considered important to maintain for legibility. 3180 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3181 public synchronized void onEvent(int event, String path) { notify(); } 3182 }; 3183 3184 try { 3185 observer.startWatching(); 3186 3187 // First collect all of the stacks of the most important pids. 3188 if (firstPids != null) { 3189 try { 3190 int num = firstPids.size(); 3191 for (int i = 0; i < num; i++) { 3192 synchronized (observer) { 3193 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3194 observer.wait(200); // Wait for write-close, give up after 200msec 3195 } 3196 } 3197 } catch (InterruptedException e) { 3198 Log.wtf(TAG, e); 3199 } 3200 } 3201 3202 // Next measure CPU usage. 3203 if (processStats != null) { 3204 processStats.init(); 3205 System.gc(); 3206 processStats.update(); 3207 try { 3208 synchronized (processStats) { 3209 processStats.wait(500); // measure over 1/2 second. 3210 } 3211 } catch (InterruptedException e) { 3212 } 3213 processStats.update(); 3214 3215 // We'll take the stack crawls of just the top apps using CPU. 3216 final int N = processStats.countWorkingStats(); 3217 int numProcs = 0; 3218 for (int i=0; i<N && numProcs<5; i++) { 3219 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3220 if (lastPids.indexOfKey(stats.pid) >= 0) { 3221 numProcs++; 3222 try { 3223 synchronized (observer) { 3224 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3225 observer.wait(200); // Wait for write-close, give up after 200msec 3226 } 3227 } catch (InterruptedException e) { 3228 Log.wtf(TAG, e); 3229 } 3230 3231 } 3232 } 3233 } 3234 3235 } finally { 3236 observer.stopWatching(); 3237 } 3238 3239 if (nativeProcs != null) { 3240 int[] pids = Process.getPidsForCommands(nativeProcs); 3241 if (pids != null) { 3242 for (int pid : pids) { 3243 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3244 } 3245 } 3246 } 3247 } 3248 3249 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3250 if (true || IS_USER_BUILD) { 3251 return; 3252 } 3253 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3254 if (tracesPath == null || tracesPath.length() == 0) { 3255 return; 3256 } 3257 3258 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3259 StrictMode.allowThreadDiskWrites(); 3260 try { 3261 final File tracesFile = new File(tracesPath); 3262 final File tracesDir = tracesFile.getParentFile(); 3263 final File tracesTmp = new File(tracesDir, "__tmp__"); 3264 try { 3265 if (!tracesDir.exists()) { 3266 tracesFile.mkdirs(); 3267 if (!SELinux.restorecon(tracesDir.getPath())) { 3268 return; 3269 } 3270 } 3271 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3272 3273 if (tracesFile.exists()) { 3274 tracesTmp.delete(); 3275 tracesFile.renameTo(tracesTmp); 3276 } 3277 StringBuilder sb = new StringBuilder(); 3278 Time tobj = new Time(); 3279 tobj.set(System.currentTimeMillis()); 3280 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3281 sb.append(": "); 3282 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3283 sb.append(" since "); 3284 sb.append(msg); 3285 FileOutputStream fos = new FileOutputStream(tracesFile); 3286 fos.write(sb.toString().getBytes()); 3287 if (app == null) { 3288 fos.write("\n*** No application process!".getBytes()); 3289 } 3290 fos.close(); 3291 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3292 } catch (IOException e) { 3293 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3294 return; 3295 } 3296 3297 if (app != null) { 3298 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3299 firstPids.add(app.pid); 3300 dumpStackTraces(tracesPath, firstPids, null, null, null); 3301 } 3302 3303 File lastTracesFile = null; 3304 File curTracesFile = null; 3305 for (int i=9; i>=0; i--) { 3306 String name = String.format("slow%02d.txt", i); 3307 curTracesFile = new File(tracesDir, name); 3308 if (curTracesFile.exists()) { 3309 if (lastTracesFile != null) { 3310 curTracesFile.renameTo(lastTracesFile); 3311 } else { 3312 curTracesFile.delete(); 3313 } 3314 } 3315 lastTracesFile = curTracesFile; 3316 } 3317 tracesFile.renameTo(curTracesFile); 3318 if (tracesTmp.exists()) { 3319 tracesTmp.renameTo(tracesFile); 3320 } 3321 } finally { 3322 StrictMode.setThreadPolicy(oldPolicy); 3323 } 3324 } 3325 3326 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3327 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3328 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3329 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3330 3331 if (mController != null) { 3332 try { 3333 // 0 == continue, -1 = kill process immediately 3334 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3335 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3336 } catch (RemoteException e) { 3337 mController = null; 3338 Watchdog.getInstance().setActivityController(null); 3339 } 3340 } 3341 3342 long anrTime = SystemClock.uptimeMillis(); 3343 if (MONITOR_CPU_USAGE) { 3344 updateCpuStatsNow(); 3345 } 3346 3347 synchronized (this) { 3348 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3349 if (mShuttingDown) { 3350 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3351 return; 3352 } else if (app.notResponding) { 3353 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3354 return; 3355 } else if (app.crashing) { 3356 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3357 return; 3358 } 3359 3360 // In case we come through here for the same app before completing 3361 // this one, mark as anring now so we will bail out. 3362 app.notResponding = true; 3363 3364 // Log the ANR to the event log. 3365 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3366 app.processName, app.info.flags, annotation); 3367 3368 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3369 firstPids.add(app.pid); 3370 3371 int parentPid = app.pid; 3372 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3373 if (parentPid != app.pid) firstPids.add(parentPid); 3374 3375 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3376 3377 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3378 ProcessRecord r = mLruProcesses.get(i); 3379 if (r != null && r.thread != null) { 3380 int pid = r.pid; 3381 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3382 if (r.persistent) { 3383 firstPids.add(pid); 3384 } else { 3385 lastPids.put(pid, Boolean.TRUE); 3386 } 3387 } 3388 } 3389 } 3390 } 3391 3392 // Log the ANR to the main log. 3393 StringBuilder info = new StringBuilder(); 3394 info.setLength(0); 3395 info.append("ANR in ").append(app.processName); 3396 if (activity != null && activity.shortComponentName != null) { 3397 info.append(" (").append(activity.shortComponentName).append(")"); 3398 } 3399 info.append("\n"); 3400 if (annotation != null) { 3401 info.append("Reason: ").append(annotation).append("\n"); 3402 } 3403 if (parent != null && parent != activity) { 3404 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3405 } 3406 3407 final ProcessStats processStats = new ProcessStats(true); 3408 3409 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3410 3411 String cpuInfo = null; 3412 if (MONITOR_CPU_USAGE) { 3413 updateCpuStatsNow(); 3414 synchronized (mProcessStatsThread) { 3415 cpuInfo = mProcessStats.printCurrentState(anrTime); 3416 } 3417 info.append(processStats.printCurrentLoad()); 3418 info.append(cpuInfo); 3419 } 3420 3421 info.append(processStats.printCurrentState(anrTime)); 3422 3423 Slog.e(TAG, info.toString()); 3424 if (tracesFile == null) { 3425 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3426 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3427 } 3428 3429 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3430 cpuInfo, tracesFile, null); 3431 3432 if (mController != null) { 3433 try { 3434 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3435 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3436 if (res != 0) { 3437 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3438 return; 3439 } 3440 } catch (RemoteException e) { 3441 mController = null; 3442 Watchdog.getInstance().setActivityController(null); 3443 } 3444 } 3445 3446 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3447 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3448 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3449 3450 synchronized (this) { 3451 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3452 Slog.w(TAG, "Killing " + app + ": background ANR"); 3453 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3454 app.processName, app.setAdj, "background ANR"); 3455 Process.killProcessQuiet(app.pid); 3456 return; 3457 } 3458 3459 // Set the app's notResponding state, and look up the errorReportReceiver 3460 makeAppNotRespondingLocked(app, 3461 activity != null ? activity.shortComponentName : null, 3462 annotation != null ? "ANR " + annotation : "ANR", 3463 info.toString()); 3464 3465 // Bring up the infamous App Not Responding dialog 3466 Message msg = Message.obtain(); 3467 HashMap map = new HashMap(); 3468 msg.what = SHOW_NOT_RESPONDING_MSG; 3469 msg.obj = map; 3470 msg.arg1 = aboveSystem ? 1 : 0; 3471 map.put("app", app); 3472 if (activity != null) { 3473 map.put("activity", activity); 3474 } 3475 3476 mHandler.sendMessage(msg); 3477 } 3478 } 3479 3480 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3481 if (!mLaunchWarningShown) { 3482 mLaunchWarningShown = true; 3483 mHandler.post(new Runnable() { 3484 @Override 3485 public void run() { 3486 synchronized (ActivityManagerService.this) { 3487 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3488 d.show(); 3489 mHandler.postDelayed(new Runnable() { 3490 @Override 3491 public void run() { 3492 synchronized (ActivityManagerService.this) { 3493 d.dismiss(); 3494 mLaunchWarningShown = false; 3495 } 3496 } 3497 }, 4000); 3498 } 3499 } 3500 }); 3501 } 3502 } 3503 3504 public boolean clearApplicationUserData(final String packageName, 3505 final IPackageDataObserver observer, int userId) { 3506 enforceNotIsolatedCaller("clearApplicationUserData"); 3507 int uid = Binder.getCallingUid(); 3508 int pid = Binder.getCallingPid(); 3509 userId = handleIncomingUser(pid, uid, 3510 userId, false, true, "clearApplicationUserData", null); 3511 long callingId = Binder.clearCallingIdentity(); 3512 try { 3513 IPackageManager pm = AppGlobals.getPackageManager(); 3514 int pkgUid = -1; 3515 synchronized(this) { 3516 try { 3517 pkgUid = pm.getPackageUid(packageName, userId); 3518 } catch (RemoteException e) { 3519 } 3520 if (pkgUid == -1) { 3521 Slog.w(TAG, "Invalid packageName: " + packageName); 3522 if (observer != null) { 3523 try { 3524 observer.onRemoveCompleted(packageName, false); 3525 } catch (RemoteException e) { 3526 Slog.i(TAG, "Observer no longer exists."); 3527 } 3528 } 3529 return false; 3530 } 3531 if (uid == pkgUid || checkComponentPermission( 3532 android.Manifest.permission.CLEAR_APP_USER_DATA, 3533 pid, uid, -1, true) 3534 == PackageManager.PERMISSION_GRANTED) { 3535 forceStopPackageLocked(packageName, pkgUid); 3536 } else { 3537 throw new SecurityException(pid+" does not have permission:"+ 3538 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3539 "for process:"+packageName); 3540 } 3541 } 3542 3543 try { 3544 //clear application user data 3545 pm.clearApplicationUserData(packageName, observer, userId); 3546 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3547 Uri.fromParts("package", packageName, null)); 3548 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3549 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3550 null, null, 0, null, null, null, false, false, userId); 3551 } catch (RemoteException e) { 3552 } 3553 } finally { 3554 Binder.restoreCallingIdentity(callingId); 3555 } 3556 return true; 3557 } 3558 3559 public void killBackgroundProcesses(final String packageName, int userId) { 3560 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3561 != PackageManager.PERMISSION_GRANTED && 3562 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3563 != PackageManager.PERMISSION_GRANTED) { 3564 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3565 + Binder.getCallingPid() 3566 + ", uid=" + Binder.getCallingUid() 3567 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3568 Slog.w(TAG, msg); 3569 throw new SecurityException(msg); 3570 } 3571 3572 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3573 userId, true, true, "killBackgroundProcesses", null); 3574 long callingId = Binder.clearCallingIdentity(); 3575 try { 3576 IPackageManager pm = AppGlobals.getPackageManager(); 3577 synchronized(this) { 3578 int appId = -1; 3579 try { 3580 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3581 } catch (RemoteException e) { 3582 } 3583 if (appId == -1) { 3584 Slog.w(TAG, "Invalid packageName: " + packageName); 3585 return; 3586 } 3587 killPackageProcessesLocked(packageName, appId, userId, 3588 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3589 } 3590 } finally { 3591 Binder.restoreCallingIdentity(callingId); 3592 } 3593 } 3594 3595 public void killAllBackgroundProcesses() { 3596 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3597 != PackageManager.PERMISSION_GRANTED) { 3598 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3599 + Binder.getCallingPid() 3600 + ", uid=" + Binder.getCallingUid() 3601 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3602 Slog.w(TAG, msg); 3603 throw new SecurityException(msg); 3604 } 3605 3606 long callingId = Binder.clearCallingIdentity(); 3607 try { 3608 synchronized(this) { 3609 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3610 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3611 final int NA = apps.size(); 3612 for (int ia=0; ia<NA; ia++) { 3613 ProcessRecord app = apps.valueAt(ia); 3614 if (app.persistent) { 3615 // we don't kill persistent processes 3616 continue; 3617 } 3618 if (app.removed) { 3619 procs.add(app); 3620 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3621 app.removed = true; 3622 procs.add(app); 3623 } 3624 } 3625 } 3626 3627 int N = procs.size(); 3628 for (int i=0; i<N; i++) { 3629 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3630 } 3631 } 3632 } finally { 3633 Binder.restoreCallingIdentity(callingId); 3634 } 3635 } 3636 3637 public void forceStopPackage(final String packageName, int userId) { 3638 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3639 != PackageManager.PERMISSION_GRANTED) { 3640 String msg = "Permission Denial: forceStopPackage() from pid=" 3641 + Binder.getCallingPid() 3642 + ", uid=" + Binder.getCallingUid() 3643 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3644 Slog.w(TAG, msg); 3645 throw new SecurityException(msg); 3646 } 3647 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3648 userId, true, true, "forceStopPackage", null); 3649 long callingId = Binder.clearCallingIdentity(); 3650 try { 3651 IPackageManager pm = AppGlobals.getPackageManager(); 3652 synchronized(this) { 3653 int[] users = userId == UserHandle.USER_ALL 3654 ? getUsersLocked() : new int[] { userId }; 3655 for (int user : users) { 3656 int pkgUid = -1; 3657 try { 3658 pkgUid = pm.getPackageUid(packageName, user); 3659 } catch (RemoteException e) { 3660 } 3661 if (pkgUid == -1) { 3662 Slog.w(TAG, "Invalid packageName: " + packageName); 3663 continue; 3664 } 3665 try { 3666 pm.setPackageStoppedState(packageName, true, user); 3667 } catch (RemoteException e) { 3668 } catch (IllegalArgumentException e) { 3669 Slog.w(TAG, "Failed trying to unstop package " 3670 + packageName + ": " + e); 3671 } 3672 if (isUserRunningLocked(user, false)) { 3673 forceStopPackageLocked(packageName, pkgUid); 3674 } 3675 } 3676 } 3677 } finally { 3678 Binder.restoreCallingIdentity(callingId); 3679 } 3680 } 3681 3682 /* 3683 * The pkg name and app id have to be specified. 3684 */ 3685 public void killApplicationWithAppId(String pkg, int appid) { 3686 if (pkg == null) { 3687 return; 3688 } 3689 // Make sure the uid is valid. 3690 if (appid < 0) { 3691 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3692 return; 3693 } 3694 int callerUid = Binder.getCallingUid(); 3695 // Only the system server can kill an application 3696 if (callerUid == Process.SYSTEM_UID) { 3697 // Post an aysnc message to kill the application 3698 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3699 msg.arg1 = appid; 3700 msg.arg2 = 0; 3701 msg.obj = pkg; 3702 mHandler.sendMessage(msg); 3703 } else { 3704 throw new SecurityException(callerUid + " cannot kill pkg: " + 3705 pkg); 3706 } 3707 } 3708 3709 public void closeSystemDialogs(String reason) { 3710 enforceNotIsolatedCaller("closeSystemDialogs"); 3711 3712 final int pid = Binder.getCallingPid(); 3713 final int uid = Binder.getCallingUid(); 3714 final long origId = Binder.clearCallingIdentity(); 3715 try { 3716 synchronized (this) { 3717 // Only allow this from foreground processes, so that background 3718 // applications can't abuse it to prevent system UI from being shown. 3719 if (uid >= Process.FIRST_APPLICATION_UID) { 3720 ProcessRecord proc; 3721 synchronized (mPidsSelfLocked) { 3722 proc = mPidsSelfLocked.get(pid); 3723 } 3724 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3725 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3726 + " from background process " + proc); 3727 return; 3728 } 3729 } 3730 closeSystemDialogsLocked(reason); 3731 } 3732 } finally { 3733 Binder.restoreCallingIdentity(origId); 3734 } 3735 } 3736 3737 void closeSystemDialogsLocked(String reason) { 3738 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3740 | Intent.FLAG_RECEIVER_FOREGROUND); 3741 if (reason != null) { 3742 intent.putExtra("reason", reason); 3743 } 3744 mWindowManager.closeSystemDialogs(reason); 3745 3746 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3747 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3748 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3749 r.stack.finishActivityLocked(r, i, 3750 Activity.RESULT_CANCELED, null, "close-sys", true); 3751 } 3752 } 3753 3754 broadcastIntentLocked(null, null, intent, null, 3755 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 3756 Process.SYSTEM_UID, UserHandle.USER_ALL); 3757 } 3758 3759 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3760 throws RemoteException { 3761 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3762 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3763 for (int i=pids.length-1; i>=0; i--) { 3764 infos[i] = new Debug.MemoryInfo(); 3765 Debug.getMemoryInfo(pids[i], infos[i]); 3766 } 3767 return infos; 3768 } 3769 3770 public long[] getProcessPss(int[] pids) throws RemoteException { 3771 enforceNotIsolatedCaller("getProcessPss"); 3772 long[] pss = new long[pids.length]; 3773 for (int i=pids.length-1; i>=0; i--) { 3774 pss[i] = Debug.getPss(pids[i]); 3775 } 3776 return pss; 3777 } 3778 3779 public void killApplicationProcess(String processName, int uid) { 3780 if (processName == null) { 3781 return; 3782 } 3783 3784 int callerUid = Binder.getCallingUid(); 3785 // Only the system server can kill an application 3786 if (callerUid == Process.SYSTEM_UID) { 3787 synchronized (this) { 3788 ProcessRecord app = getProcessRecordLocked(processName, uid); 3789 if (app != null && app.thread != null) { 3790 try { 3791 app.thread.scheduleSuicide(); 3792 } catch (RemoteException e) { 3793 // If the other end already died, then our work here is done. 3794 } 3795 } else { 3796 Slog.w(TAG, "Process/uid not found attempting kill of " 3797 + processName + " / " + uid); 3798 } 3799 } 3800 } else { 3801 throw new SecurityException(callerUid + " cannot kill app process: " + 3802 processName); 3803 } 3804 } 3805 3806 private void forceStopPackageLocked(final String packageName, int uid) { 3807 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3808 false, true, false, UserHandle.getUserId(uid)); 3809 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3810 Uri.fromParts("package", packageName, null)); 3811 if (!mProcessesReady) { 3812 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3813 | Intent.FLAG_RECEIVER_FOREGROUND); 3814 } 3815 intent.putExtra(Intent.EXTRA_UID, uid); 3816 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3817 broadcastIntentLocked(null, null, intent, 3818 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 3819 false, false, 3820 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3821 } 3822 3823 private void forceStopUserLocked(int userId) { 3824 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3825 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3826 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3827 | Intent.FLAG_RECEIVER_FOREGROUND); 3828 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3829 broadcastIntentLocked(null, null, intent, 3830 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 3831 false, false, 3832 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3833 } 3834 3835 private final boolean killPackageProcessesLocked(String packageName, int appId, 3836 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3837 boolean doit, boolean evenPersistent, String reason) { 3838 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3839 3840 // Remove all processes this package may have touched: all with the 3841 // same UID (except for the system or root user), and all whose name 3842 // matches the package name. 3843 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3844 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3845 final int NA = apps.size(); 3846 for (int ia=0; ia<NA; ia++) { 3847 ProcessRecord app = apps.valueAt(ia); 3848 if (app.persistent && !evenPersistent) { 3849 // we don't kill persistent processes 3850 continue; 3851 } 3852 if (app.removed) { 3853 if (doit) { 3854 procs.add(app); 3855 } 3856 continue; 3857 } 3858 3859 // Skip process if it doesn't meet our oom adj requirement. 3860 if (app.setAdj < minOomAdj) { 3861 continue; 3862 } 3863 3864 // If no package is specified, we call all processes under the 3865 // give user id. 3866 if (packageName == null) { 3867 if (app.userId != userId) { 3868 continue; 3869 } 3870 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 3871 continue; 3872 } 3873 // Package has been specified, we want to hit all processes 3874 // that match it. We need to qualify this by the processes 3875 // that are running under the specified app and user ID. 3876 } else { 3877 if (UserHandle.getAppId(app.uid) != appId) { 3878 continue; 3879 } 3880 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3881 continue; 3882 } 3883 if (!app.pkgList.contains(packageName)) { 3884 continue; 3885 } 3886 } 3887 3888 // Process has passed all conditions, kill it! 3889 if (!doit) { 3890 return true; 3891 } 3892 app.removed = true; 3893 procs.add(app); 3894 } 3895 } 3896 3897 int N = procs.size(); 3898 for (int i=0; i<N; i++) { 3899 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3900 } 3901 return N > 0; 3902 } 3903 3904 private final boolean forceStopPackageLocked(String name, int appId, 3905 boolean callerWillRestart, boolean purgeCache, boolean doit, 3906 boolean evenPersistent, int userId) { 3907 int i; 3908 int N; 3909 3910 if (userId == UserHandle.USER_ALL && name == null) { 3911 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3912 } 3913 3914 if (appId < 0 && name != null) { 3915 try { 3916 appId = UserHandle.getAppId( 3917 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3918 } catch (RemoteException e) { 3919 } 3920 } 3921 3922 if (doit) { 3923 if (name != null) { 3924 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3925 + " user=" + userId); 3926 } else { 3927 Slog.i(TAG, "Force stopping user " + userId); 3928 } 3929 3930 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3931 while (badApps.hasNext()) { 3932 SparseArray<Long> ba = badApps.next(); 3933 for (i=ba.size()-1; i>=0; i--) { 3934 boolean remove = false; 3935 final int entUid = ba.keyAt(i); 3936 if (name != null) { 3937 if (userId == UserHandle.USER_ALL) { 3938 if (UserHandle.getAppId(entUid) == appId) { 3939 remove = true; 3940 } 3941 } else { 3942 if (entUid == UserHandle.getUid(userId, appId)) { 3943 remove = true; 3944 } 3945 } 3946 } else if (UserHandle.getUserId(entUid) == userId) { 3947 remove = true; 3948 } 3949 if (remove) { 3950 ba.removeAt(i); 3951 } 3952 } 3953 if (ba.size() == 0) { 3954 badApps.remove(); 3955 } 3956 } 3957 } 3958 3959 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3960 -100, callerWillRestart, true, doit, evenPersistent, 3961 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3962 3963 TaskRecord lastTask = null; 3964 for (i=0; i<mMainStack.mHistory.size(); i++) { 3965 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3966 final boolean samePackage = r.packageName.equals(name) 3967 || (name == null && r.userId == userId); 3968 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3969 && (samePackage || r.task == lastTask) 3970 && (r.app == null || evenPersistent || !r.app.persistent)) { 3971 if (!doit) { 3972 if (r.finishing) { 3973 // If this activity is just finishing, then it is not 3974 // interesting as far as something to stop. 3975 continue; 3976 } 3977 return true; 3978 } 3979 didSomething = true; 3980 Slog.i(TAG, " Force finishing activity " + r); 3981 if (samePackage) { 3982 if (r.app != null) { 3983 r.app.removed = true; 3984 } 3985 r.app = null; 3986 } 3987 lastTask = r.task; 3988 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3989 null, "force-stop", true)) { 3990 i--; 3991 } 3992 } 3993 } 3994 3995 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3996 if (!doit) { 3997 return true; 3998 } 3999 didSomething = true; 4000 } 4001 4002 if (name == null) { 4003 // Remove all sticky broadcasts from this user. 4004 mStickyBroadcasts.remove(userId); 4005 } 4006 4007 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4008 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4009 userId, providers)) { 4010 if (!doit) { 4011 return true; 4012 } 4013 didSomething = true; 4014 } 4015 N = providers.size(); 4016 for (i=0; i<N; i++) { 4017 removeDyingProviderLocked(null, providers.get(i), true); 4018 } 4019 4020 if (name == null) { 4021 // Remove pending intents. For now we only do this when force 4022 // stopping users, because we have some problems when doing this 4023 // for packages -- app widgets are not currently cleaned up for 4024 // such packages, so they can be left with bad pending intents. 4025 if (mIntentSenderRecords.size() > 0) { 4026 Iterator<WeakReference<PendingIntentRecord>> it 4027 = mIntentSenderRecords.values().iterator(); 4028 while (it.hasNext()) { 4029 WeakReference<PendingIntentRecord> wpir = it.next(); 4030 if (wpir == null) { 4031 it.remove(); 4032 continue; 4033 } 4034 PendingIntentRecord pir = wpir.get(); 4035 if (pir == null) { 4036 it.remove(); 4037 continue; 4038 } 4039 if (name == null) { 4040 // Stopping user, remove all objects for the user. 4041 if (pir.key.userId != userId) { 4042 // Not the same user, skip it. 4043 continue; 4044 } 4045 } else { 4046 if (UserHandle.getAppId(pir.uid) != appId) { 4047 // Different app id, skip it. 4048 continue; 4049 } 4050 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4051 // Different user, skip it. 4052 continue; 4053 } 4054 if (!pir.key.packageName.equals(name)) { 4055 // Different package, skip it. 4056 continue; 4057 } 4058 } 4059 if (!doit) { 4060 return true; 4061 } 4062 didSomething = true; 4063 it.remove(); 4064 pir.canceled = true; 4065 if (pir.key.activity != null) { 4066 pir.key.activity.pendingResults.remove(pir.ref); 4067 } 4068 } 4069 } 4070 } 4071 4072 if (doit) { 4073 if (purgeCache && name != null) { 4074 AttributeCache ac = AttributeCache.instance(); 4075 if (ac != null) { 4076 ac.removePackage(name); 4077 } 4078 } 4079 if (mBooted) { 4080 mMainStack.resumeTopActivityLocked(null); 4081 mMainStack.scheduleIdleLocked(); 4082 } 4083 } 4084 4085 return didSomething; 4086 } 4087 4088 private final boolean removeProcessLocked(ProcessRecord app, 4089 boolean callerWillRestart, boolean allowRestart, String reason) { 4090 final String name = app.processName; 4091 final int uid = app.uid; 4092 if (DEBUG_PROCESSES) Slog.d( 4093 TAG, "Force removing proc " + app.toShortString() + " (" + name 4094 + "/" + uid + ")"); 4095 4096 mProcessNames.remove(name, uid); 4097 mIsolatedProcesses.remove(app.uid); 4098 if (mHeavyWeightProcess == app) { 4099 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4100 mHeavyWeightProcess.userId, 0)); 4101 mHeavyWeightProcess = null; 4102 } 4103 boolean needRestart = false; 4104 if (app.pid > 0 && app.pid != MY_PID) { 4105 int pid = app.pid; 4106 synchronized (mPidsSelfLocked) { 4107 mPidsSelfLocked.remove(pid); 4108 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4109 } 4110 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4111 handleAppDiedLocked(app, true, allowRestart); 4112 mLruProcesses.remove(app); 4113 Process.killProcessQuiet(pid); 4114 4115 if (app.persistent && !app.isolated) { 4116 if (!callerWillRestart) { 4117 addAppLocked(app.info, false); 4118 } else { 4119 needRestart = true; 4120 } 4121 } 4122 } else { 4123 mRemovedProcesses.add(app); 4124 } 4125 4126 return needRestart; 4127 } 4128 4129 private final void processStartTimedOutLocked(ProcessRecord app) { 4130 final int pid = app.pid; 4131 boolean gone = false; 4132 synchronized (mPidsSelfLocked) { 4133 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4134 if (knownApp != null && knownApp.thread == null) { 4135 mPidsSelfLocked.remove(pid); 4136 gone = true; 4137 } 4138 } 4139 4140 if (gone) { 4141 Slog.w(TAG, "Process " + app + " failed to attach"); 4142 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4143 pid, app.uid, app.processName); 4144 mProcessNames.remove(app.processName, app.uid); 4145 mIsolatedProcesses.remove(app.uid); 4146 if (mHeavyWeightProcess == app) { 4147 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4148 mHeavyWeightProcess.userId, 0)); 4149 mHeavyWeightProcess = null; 4150 } 4151 // Take care of any launching providers waiting for this process. 4152 checkAppInLaunchingProvidersLocked(app, true); 4153 // Take care of any services that are waiting for the process. 4154 mServices.processStartTimedOutLocked(app); 4155 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4156 app.processName, app.setAdj, "start timeout"); 4157 Process.killProcessQuiet(pid); 4158 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4159 Slog.w(TAG, "Unattached app died before backup, skipping"); 4160 try { 4161 IBackupManager bm = IBackupManager.Stub.asInterface( 4162 ServiceManager.getService(Context.BACKUP_SERVICE)); 4163 bm.agentDisconnected(app.info.packageName); 4164 } catch (RemoteException e) { 4165 // Can't happen; the backup manager is local 4166 } 4167 } 4168 if (isPendingBroadcastProcessLocked(pid)) { 4169 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4170 skipPendingBroadcastLocked(pid); 4171 } 4172 } else { 4173 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4174 } 4175 } 4176 4177 private final boolean attachApplicationLocked(IApplicationThread thread, 4178 int pid) { 4179 4180 // Find the application record that is being attached... either via 4181 // the pid if we are running in multiple processes, or just pull the 4182 // next app record if we are emulating process with anonymous threads. 4183 ProcessRecord app; 4184 if (pid != MY_PID && pid >= 0) { 4185 synchronized (mPidsSelfLocked) { 4186 app = mPidsSelfLocked.get(pid); 4187 } 4188 } else { 4189 app = null; 4190 } 4191 4192 if (app == null) { 4193 Slog.w(TAG, "No pending application record for pid " + pid 4194 + " (IApplicationThread " + thread + "); dropping process"); 4195 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4196 if (pid > 0 && pid != MY_PID) { 4197 Process.killProcessQuiet(pid); 4198 } else { 4199 try { 4200 thread.scheduleExit(); 4201 } catch (Exception e) { 4202 // Ignore exceptions. 4203 } 4204 } 4205 return false; 4206 } 4207 4208 // If this application record is still attached to a previous 4209 // process, clean it up now. 4210 if (app.thread != null) { 4211 handleAppDiedLocked(app, true, true); 4212 } 4213 4214 // Tell the process all about itself. 4215 4216 if (localLOGV) Slog.v( 4217 TAG, "Binding process pid " + pid + " to record " + app); 4218 4219 String processName = app.processName; 4220 try { 4221 AppDeathRecipient adr = new AppDeathRecipient( 4222 app, pid, thread); 4223 thread.asBinder().linkToDeath(adr, 0); 4224 app.deathRecipient = adr; 4225 } catch (RemoteException e) { 4226 app.resetPackageList(); 4227 startProcessLocked(app, "link fail", processName); 4228 return false; 4229 } 4230 4231 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4232 4233 app.thread = thread; 4234 app.curAdj = app.setAdj = -100; 4235 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4236 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4237 app.forcingToForeground = null; 4238 app.foregroundServices = false; 4239 app.hasShownUi = false; 4240 app.debugging = false; 4241 4242 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4243 4244 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4245 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4246 4247 if (!normalMode) { 4248 Slog.i(TAG, "Launching preboot mode app: " + app); 4249 } 4250 4251 if (localLOGV) Slog.v( 4252 TAG, "New app record " + app 4253 + " thread=" + thread.asBinder() + " pid=" + pid); 4254 try { 4255 int testMode = IApplicationThread.DEBUG_OFF; 4256 if (mDebugApp != null && mDebugApp.equals(processName)) { 4257 testMode = mWaitForDebugger 4258 ? IApplicationThread.DEBUG_WAIT 4259 : IApplicationThread.DEBUG_ON; 4260 app.debugging = true; 4261 if (mDebugTransient) { 4262 mDebugApp = mOrigDebugApp; 4263 mWaitForDebugger = mOrigWaitForDebugger; 4264 } 4265 } 4266 String profileFile = app.instrumentationProfileFile; 4267 ParcelFileDescriptor profileFd = null; 4268 boolean profileAutoStop = false; 4269 if (mProfileApp != null && mProfileApp.equals(processName)) { 4270 mProfileProc = app; 4271 profileFile = mProfileFile; 4272 profileFd = mProfileFd; 4273 profileAutoStop = mAutoStopProfiler; 4274 } 4275 boolean enableOpenGlTrace = false; 4276 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4277 enableOpenGlTrace = true; 4278 mOpenGlTraceApp = null; 4279 } 4280 4281 // If the app is being launched for restore or full backup, set it up specially 4282 boolean isRestrictedBackupMode = false; 4283 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4284 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4285 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4286 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4287 } 4288 4289 ensurePackageDexOpt(app.instrumentationInfo != null 4290 ? app.instrumentationInfo.packageName 4291 : app.info.packageName); 4292 if (app.instrumentationClass != null) { 4293 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4294 } 4295 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4296 + processName + " with config " + mConfiguration); 4297 ApplicationInfo appInfo = app.instrumentationInfo != null 4298 ? app.instrumentationInfo : app.info; 4299 app.compat = compatibilityInfoForPackageLocked(appInfo); 4300 if (profileFd != null) { 4301 profileFd = profileFd.dup(); 4302 } 4303 thread.bindApplication(processName, appInfo, providers, 4304 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4305 app.instrumentationArguments, app.instrumentationWatcher, 4306 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4307 isRestrictedBackupMode || !normalMode, app.persistent, 4308 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4309 mCoreSettingsObserver.getCoreSettingsLocked()); 4310 updateLruProcessLocked(app, false); 4311 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4312 } catch (Exception e) { 4313 // todo: Yikes! What should we do? For now we will try to 4314 // start another process, but that could easily get us in 4315 // an infinite loop of restarting processes... 4316 Slog.w(TAG, "Exception thrown during bind!", e); 4317 4318 app.resetPackageList(); 4319 app.unlinkDeathRecipient(); 4320 startProcessLocked(app, "bind fail", processName); 4321 return false; 4322 } 4323 4324 // Remove this record from the list of starting applications. 4325 mPersistentStartingProcesses.remove(app); 4326 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4327 "Attach application locked removing on hold: " + app); 4328 mProcessesOnHold.remove(app); 4329 4330 boolean badApp = false; 4331 boolean didSomething = false; 4332 4333 // See if the top visible activity is waiting to run in this process... 4334 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4335 if (hr != null && normalMode) { 4336 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4337 && processName.equals(hr.processName)) { 4338 try { 4339 if (mHeadless) { 4340 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4341 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4342 didSomething = true; 4343 } 4344 } catch (Exception e) { 4345 Slog.w(TAG, "Exception in new application when starting activity " 4346 + hr.intent.getComponent().flattenToShortString(), e); 4347 badApp = true; 4348 } 4349 } else { 4350 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4351 } 4352 } 4353 4354 // Find any services that should be running in this process... 4355 if (!badApp) { 4356 try { 4357 didSomething |= mServices.attachApplicationLocked(app, processName); 4358 } catch (Exception e) { 4359 badApp = true; 4360 } 4361 } 4362 4363 // Check if a next-broadcast receiver is in this process... 4364 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4365 try { 4366 didSomething = sendPendingBroadcastsLocked(app); 4367 } catch (Exception e) { 4368 // If the app died trying to launch the receiver we declare it 'bad' 4369 badApp = true; 4370 } 4371 } 4372 4373 // Check whether the next backup agent is in this process... 4374 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4375 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4376 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4377 try { 4378 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4379 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4380 mBackupTarget.backupMode); 4381 } catch (Exception e) { 4382 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4383 e.printStackTrace(); 4384 } 4385 } 4386 4387 if (badApp) { 4388 // todo: Also need to kill application to deal with all 4389 // kinds of exceptions. 4390 handleAppDiedLocked(app, false, true); 4391 return false; 4392 } 4393 4394 if (!didSomething) { 4395 updateOomAdjLocked(); 4396 } 4397 4398 return true; 4399 } 4400 4401 public final void attachApplication(IApplicationThread thread) { 4402 synchronized (this) { 4403 int callingPid = Binder.getCallingPid(); 4404 final long origId = Binder.clearCallingIdentity(); 4405 attachApplicationLocked(thread, callingPid); 4406 Binder.restoreCallingIdentity(origId); 4407 } 4408 } 4409 4410 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4411 final long origId = Binder.clearCallingIdentity(); 4412 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4413 if (stopProfiling) { 4414 synchronized (this) { 4415 if (mProfileProc == r.app) { 4416 if (mProfileFd != null) { 4417 try { 4418 mProfileFd.close(); 4419 } catch (IOException e) { 4420 } 4421 clearProfilerLocked(); 4422 } 4423 } 4424 } 4425 } 4426 Binder.restoreCallingIdentity(origId); 4427 } 4428 4429 void enableScreenAfterBoot() { 4430 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4431 SystemClock.uptimeMillis()); 4432 mWindowManager.enableScreenAfterBoot(); 4433 4434 synchronized (this) { 4435 updateEventDispatchingLocked(); 4436 } 4437 } 4438 4439 public void showBootMessage(final CharSequence msg, final boolean always) { 4440 enforceNotIsolatedCaller("showBootMessage"); 4441 mWindowManager.showBootMessage(msg, always); 4442 } 4443 4444 public void dismissKeyguardOnNextActivity() { 4445 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4446 final long token = Binder.clearCallingIdentity(); 4447 try { 4448 synchronized (this) { 4449 if (mLockScreenShown) { 4450 mLockScreenShown = false; 4451 comeOutOfSleepIfNeededLocked(); 4452 } 4453 mMainStack.dismissKeyguardOnNextActivityLocked(); 4454 } 4455 } finally { 4456 Binder.restoreCallingIdentity(token); 4457 } 4458 } 4459 4460 final void finishBooting() { 4461 IntentFilter pkgFilter = new IntentFilter(); 4462 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4463 pkgFilter.addDataScheme("package"); 4464 mContext.registerReceiver(new BroadcastReceiver() { 4465 @Override 4466 public void onReceive(Context context, Intent intent) { 4467 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4468 if (pkgs != null) { 4469 for (String pkg : pkgs) { 4470 synchronized (ActivityManagerService.this) { 4471 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4472 setResultCode(Activity.RESULT_OK); 4473 return; 4474 } 4475 } 4476 } 4477 } 4478 } 4479 }, pkgFilter); 4480 4481 synchronized (this) { 4482 // Ensure that any processes we had put on hold are now started 4483 // up. 4484 final int NP = mProcessesOnHold.size(); 4485 if (NP > 0) { 4486 ArrayList<ProcessRecord> procs = 4487 new ArrayList<ProcessRecord>(mProcessesOnHold); 4488 for (int ip=0; ip<NP; ip++) { 4489 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4490 + procs.get(ip)); 4491 startProcessLocked(procs.get(ip), "on-hold", null); 4492 } 4493 } 4494 4495 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4496 // Start looking for apps that are abusing wake locks. 4497 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4498 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4499 // Tell anyone interested that we are done booting! 4500 SystemProperties.set("sys.boot_completed", "1"); 4501 SystemProperties.set("dev.bootcomplete", "1"); 4502 for (int i=0; i<mStartedUsers.size(); i++) { 4503 UserStartedState uss = mStartedUsers.valueAt(i); 4504 if (uss.mState == UserStartedState.STATE_BOOTING) { 4505 uss.mState = UserStartedState.STATE_RUNNING; 4506 final int userId = mStartedUsers.keyAt(i); 4507 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4508 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4509 broadcastIntentLocked(null, null, intent, 4510 null, null, 0, null, null, 4511 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4512 AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, 4513 userId); 4514 } 4515 } 4516 } 4517 } 4518 } 4519 4520 final void ensureBootCompleted() { 4521 boolean booting; 4522 boolean enableScreen; 4523 synchronized (this) { 4524 booting = mBooting; 4525 mBooting = false; 4526 enableScreen = !mBooted; 4527 mBooted = true; 4528 } 4529 4530 if (booting) { 4531 finishBooting(); 4532 } 4533 4534 if (enableScreen) { 4535 enableScreenAfterBoot(); 4536 } 4537 } 4538 4539 public final void activityResumed(IBinder token) { 4540 final long origId = Binder.clearCallingIdentity(); 4541 mMainStack.activityResumed(token); 4542 Binder.restoreCallingIdentity(origId); 4543 } 4544 4545 public final void activityPaused(IBinder token) { 4546 final long origId = Binder.clearCallingIdentity(); 4547 mMainStack.activityPaused(token, false); 4548 Binder.restoreCallingIdentity(origId); 4549 } 4550 4551 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4552 CharSequence description) { 4553 if (localLOGV) Slog.v( 4554 TAG, "Activity stopped: token=" + token); 4555 4556 // Refuse possible leaked file descriptors 4557 if (icicle != null && icicle.hasFileDescriptors()) { 4558 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4559 } 4560 4561 ActivityRecord r = null; 4562 4563 final long origId = Binder.clearCallingIdentity(); 4564 4565 synchronized (this) { 4566 r = mMainStack.isInStackLocked(token); 4567 if (r != null) { 4568 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4569 } 4570 } 4571 4572 if (r != null) { 4573 sendPendingThumbnail(r, null, null, null, false); 4574 } 4575 4576 trimApplications(); 4577 4578 Binder.restoreCallingIdentity(origId); 4579 } 4580 4581 public final void activityDestroyed(IBinder token) { 4582 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4583 mMainStack.activityDestroyed(token); 4584 } 4585 4586 public String getCallingPackage(IBinder token) { 4587 synchronized (this) { 4588 ActivityRecord r = getCallingRecordLocked(token); 4589 return r != null ? r.info.packageName : null; 4590 } 4591 } 4592 4593 public ComponentName getCallingActivity(IBinder token) { 4594 synchronized (this) { 4595 ActivityRecord r = getCallingRecordLocked(token); 4596 return r != null ? r.intent.getComponent() : null; 4597 } 4598 } 4599 4600 private ActivityRecord getCallingRecordLocked(IBinder token) { 4601 ActivityRecord r = mMainStack.isInStackLocked(token); 4602 if (r == null) { 4603 return null; 4604 } 4605 return r.resultTo; 4606 } 4607 4608 public ComponentName getActivityClassForToken(IBinder token) { 4609 synchronized(this) { 4610 ActivityRecord r = mMainStack.isInStackLocked(token); 4611 if (r == null) { 4612 return null; 4613 } 4614 return r.intent.getComponent(); 4615 } 4616 } 4617 4618 public String getPackageForToken(IBinder token) { 4619 synchronized(this) { 4620 ActivityRecord r = mMainStack.isInStackLocked(token); 4621 if (r == null) { 4622 return null; 4623 } 4624 return r.packageName; 4625 } 4626 } 4627 4628 public IIntentSender getIntentSender(int type, 4629 String packageName, IBinder token, String resultWho, 4630 int requestCode, Intent[] intents, String[] resolvedTypes, 4631 int flags, Bundle options, int userId) { 4632 enforceNotIsolatedCaller("getIntentSender"); 4633 // Refuse possible leaked file descriptors 4634 if (intents != null) { 4635 if (intents.length < 1) { 4636 throw new IllegalArgumentException("Intents array length must be >= 1"); 4637 } 4638 for (int i=0; i<intents.length; i++) { 4639 Intent intent = intents[i]; 4640 if (intent != null) { 4641 if (intent.hasFileDescriptors()) { 4642 throw new IllegalArgumentException("File descriptors passed in Intent"); 4643 } 4644 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4645 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4646 throw new IllegalArgumentException( 4647 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4648 } 4649 intents[i] = new Intent(intent); 4650 } 4651 } 4652 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4653 throw new IllegalArgumentException( 4654 "Intent array length does not match resolvedTypes length"); 4655 } 4656 } 4657 if (options != null) { 4658 if (options.hasFileDescriptors()) { 4659 throw new IllegalArgumentException("File descriptors passed in options"); 4660 } 4661 } 4662 4663 synchronized(this) { 4664 int callingUid = Binder.getCallingUid(); 4665 int origUserId = userId; 4666 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4667 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 4668 "getIntentSender", null); 4669 if (origUserId == UserHandle.USER_CURRENT) { 4670 // We don't want to evaluate this until the pending intent is 4671 // actually executed. However, we do want to always do the 4672 // security checking for it above. 4673 userId = UserHandle.USER_CURRENT; 4674 } 4675 try { 4676 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4677 int uid = AppGlobals.getPackageManager() 4678 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4679 if (!UserHandle.isSameApp(callingUid, uid)) { 4680 String msg = "Permission Denial: getIntentSender() from pid=" 4681 + Binder.getCallingPid() 4682 + ", uid=" + Binder.getCallingUid() 4683 + ", (need uid=" + uid + ")" 4684 + " is not allowed to send as package " + packageName; 4685 Slog.w(TAG, msg); 4686 throw new SecurityException(msg); 4687 } 4688 } 4689 4690 return getIntentSenderLocked(type, packageName, callingUid, userId, 4691 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4692 4693 } catch (RemoteException e) { 4694 throw new SecurityException(e); 4695 } 4696 } 4697 } 4698 4699 IIntentSender getIntentSenderLocked(int type, String packageName, 4700 int callingUid, int userId, IBinder token, String resultWho, 4701 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4702 Bundle options) { 4703 if (DEBUG_MU) 4704 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4705 ActivityRecord activity = null; 4706 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4707 activity = mMainStack.isInStackLocked(token); 4708 if (activity == null) { 4709 return null; 4710 } 4711 if (activity.finishing) { 4712 return null; 4713 } 4714 } 4715 4716 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4717 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4718 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4719 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4720 |PendingIntent.FLAG_UPDATE_CURRENT); 4721 4722 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4723 type, packageName, activity, resultWho, 4724 requestCode, intents, resolvedTypes, flags, options, userId); 4725 WeakReference<PendingIntentRecord> ref; 4726 ref = mIntentSenderRecords.get(key); 4727 PendingIntentRecord rec = ref != null ? ref.get() : null; 4728 if (rec != null) { 4729 if (!cancelCurrent) { 4730 if (updateCurrent) { 4731 if (rec.key.requestIntent != null) { 4732 rec.key.requestIntent.replaceExtras(intents != null ? 4733 intents[intents.length - 1] : null); 4734 } 4735 if (intents != null) { 4736 intents[intents.length-1] = rec.key.requestIntent; 4737 rec.key.allIntents = intents; 4738 rec.key.allResolvedTypes = resolvedTypes; 4739 } else { 4740 rec.key.allIntents = null; 4741 rec.key.allResolvedTypes = null; 4742 } 4743 } 4744 return rec; 4745 } 4746 rec.canceled = true; 4747 mIntentSenderRecords.remove(key); 4748 } 4749 if (noCreate) { 4750 return rec; 4751 } 4752 rec = new PendingIntentRecord(this, key, callingUid); 4753 mIntentSenderRecords.put(key, rec.ref); 4754 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4755 if (activity.pendingResults == null) { 4756 activity.pendingResults 4757 = new HashSet<WeakReference<PendingIntentRecord>>(); 4758 } 4759 activity.pendingResults.add(rec.ref); 4760 } 4761 return rec; 4762 } 4763 4764 public void cancelIntentSender(IIntentSender sender) { 4765 if (!(sender instanceof PendingIntentRecord)) { 4766 return; 4767 } 4768 synchronized(this) { 4769 PendingIntentRecord rec = (PendingIntentRecord)sender; 4770 try { 4771 int uid = AppGlobals.getPackageManager() 4772 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4773 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4774 String msg = "Permission Denial: cancelIntentSender() from pid=" 4775 + Binder.getCallingPid() 4776 + ", uid=" + Binder.getCallingUid() 4777 + " is not allowed to cancel packges " 4778 + rec.key.packageName; 4779 Slog.w(TAG, msg); 4780 throw new SecurityException(msg); 4781 } 4782 } catch (RemoteException e) { 4783 throw new SecurityException(e); 4784 } 4785 cancelIntentSenderLocked(rec, true); 4786 } 4787 } 4788 4789 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4790 rec.canceled = true; 4791 mIntentSenderRecords.remove(rec.key); 4792 if (cleanActivity && rec.key.activity != null) { 4793 rec.key.activity.pendingResults.remove(rec.ref); 4794 } 4795 } 4796 4797 public String getPackageForIntentSender(IIntentSender pendingResult) { 4798 if (!(pendingResult instanceof PendingIntentRecord)) { 4799 return null; 4800 } 4801 try { 4802 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4803 return res.key.packageName; 4804 } catch (ClassCastException e) { 4805 } 4806 return null; 4807 } 4808 4809 public int getUidForIntentSender(IIntentSender sender) { 4810 if (sender instanceof PendingIntentRecord) { 4811 try { 4812 PendingIntentRecord res = (PendingIntentRecord)sender; 4813 return res.uid; 4814 } catch (ClassCastException e) { 4815 } 4816 } 4817 return -1; 4818 } 4819 4820 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4821 if (!(pendingResult instanceof PendingIntentRecord)) { 4822 return false; 4823 } 4824 try { 4825 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4826 if (res.key.allIntents == null) { 4827 return false; 4828 } 4829 for (int i=0; i<res.key.allIntents.length; i++) { 4830 Intent intent = res.key.allIntents[i]; 4831 if (intent.getPackage() != null && intent.getComponent() != null) { 4832 return false; 4833 } 4834 } 4835 return true; 4836 } catch (ClassCastException e) { 4837 } 4838 return false; 4839 } 4840 4841 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4842 if (!(pendingResult instanceof PendingIntentRecord)) { 4843 return false; 4844 } 4845 try { 4846 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4847 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4848 return true; 4849 } 4850 return false; 4851 } catch (ClassCastException e) { 4852 } 4853 return false; 4854 } 4855 4856 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 4857 if (!(pendingResult instanceof PendingIntentRecord)) { 4858 return null; 4859 } 4860 try { 4861 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4862 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 4863 } catch (ClassCastException e) { 4864 } 4865 return null; 4866 } 4867 4868 public void setProcessLimit(int max) { 4869 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4870 "setProcessLimit()"); 4871 synchronized (this) { 4872 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4873 mProcessLimitOverride = max; 4874 } 4875 trimApplications(); 4876 } 4877 4878 public int getProcessLimit() { 4879 synchronized (this) { 4880 return mProcessLimitOverride; 4881 } 4882 } 4883 4884 void foregroundTokenDied(ForegroundToken token) { 4885 synchronized (ActivityManagerService.this) { 4886 synchronized (mPidsSelfLocked) { 4887 ForegroundToken cur 4888 = mForegroundProcesses.get(token.pid); 4889 if (cur != token) { 4890 return; 4891 } 4892 mForegroundProcesses.remove(token.pid); 4893 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4894 if (pr == null) { 4895 return; 4896 } 4897 pr.forcingToForeground = null; 4898 pr.foregroundServices = false; 4899 } 4900 updateOomAdjLocked(); 4901 } 4902 } 4903 4904 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4905 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4906 "setProcessForeground()"); 4907 synchronized(this) { 4908 boolean changed = false; 4909 4910 synchronized (mPidsSelfLocked) { 4911 ProcessRecord pr = mPidsSelfLocked.get(pid); 4912 if (pr == null && isForeground) { 4913 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4914 return; 4915 } 4916 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4917 if (oldToken != null) { 4918 oldToken.token.unlinkToDeath(oldToken, 0); 4919 mForegroundProcesses.remove(pid); 4920 if (pr != null) { 4921 pr.forcingToForeground = null; 4922 } 4923 changed = true; 4924 } 4925 if (isForeground && token != null) { 4926 ForegroundToken newToken = new ForegroundToken() { 4927 public void binderDied() { 4928 foregroundTokenDied(this); 4929 } 4930 }; 4931 newToken.pid = pid; 4932 newToken.token = token; 4933 try { 4934 token.linkToDeath(newToken, 0); 4935 mForegroundProcesses.put(pid, newToken); 4936 pr.forcingToForeground = token; 4937 changed = true; 4938 } catch (RemoteException e) { 4939 // If the process died while doing this, we will later 4940 // do the cleanup with the process death link. 4941 } 4942 } 4943 } 4944 4945 if (changed) { 4946 updateOomAdjLocked(); 4947 } 4948 } 4949 } 4950 4951 // ========================================================= 4952 // PERMISSIONS 4953 // ========================================================= 4954 4955 static class PermissionController extends IPermissionController.Stub { 4956 ActivityManagerService mActivityManagerService; 4957 PermissionController(ActivityManagerService activityManagerService) { 4958 mActivityManagerService = activityManagerService; 4959 } 4960 4961 public boolean checkPermission(String permission, int pid, int uid) { 4962 return mActivityManagerService.checkPermission(permission, pid, 4963 uid) == PackageManager.PERMISSION_GRANTED; 4964 } 4965 } 4966 4967 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 4968 public int checkComponentPermission(String permission, int pid, int uid, 4969 int owningUid, boolean exported) { 4970 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 4971 owningUid, exported); 4972 } 4973 4974 public Object getAMSLock() { 4975 return ActivityManagerService.this; 4976 } 4977 } 4978 4979 /** 4980 * This can be called with or without the global lock held. 4981 */ 4982 int checkComponentPermission(String permission, int pid, int uid, 4983 int owningUid, boolean exported) { 4984 // We might be performing an operation on behalf of an indirect binder 4985 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4986 // client identity accordingly before proceeding. 4987 Identity tlsIdentity = sCallerIdentity.get(); 4988 if (tlsIdentity != null) { 4989 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4990 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4991 uid = tlsIdentity.uid; 4992 pid = tlsIdentity.pid; 4993 } 4994 4995 if (pid == MY_PID) { 4996 return PackageManager.PERMISSION_GRANTED; 4997 } 4998 4999 return ActivityManager.checkComponentPermission(permission, uid, 5000 owningUid, exported); 5001 } 5002 5003 /** 5004 * As the only public entry point for permissions checking, this method 5005 * can enforce the semantic that requesting a check on a null global 5006 * permission is automatically denied. (Internally a null permission 5007 * string is used when calling {@link #checkComponentPermission} in cases 5008 * when only uid-based security is needed.) 5009 * 5010 * This can be called with or without the global lock held. 5011 */ 5012 public int checkPermission(String permission, int pid, int uid) { 5013 if (permission == null) { 5014 return PackageManager.PERMISSION_DENIED; 5015 } 5016 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5017 } 5018 5019 /** 5020 * Binder IPC calls go through the public entry point. 5021 * This can be called with or without the global lock held. 5022 */ 5023 int checkCallingPermission(String permission) { 5024 return checkPermission(permission, 5025 Binder.getCallingPid(), 5026 UserHandle.getAppId(Binder.getCallingUid())); 5027 } 5028 5029 /** 5030 * This can be called with or without the global lock held. 5031 */ 5032 void enforceCallingPermission(String permission, String func) { 5033 if (checkCallingPermission(permission) 5034 == PackageManager.PERMISSION_GRANTED) { 5035 return; 5036 } 5037 5038 String msg = "Permission Denial: " + func + " from pid=" 5039 + Binder.getCallingPid() 5040 + ", uid=" + Binder.getCallingUid() 5041 + " requires " + permission; 5042 Slog.w(TAG, msg); 5043 throw new SecurityException(msg); 5044 } 5045 5046 /** 5047 * Determine if UID is holding permissions required to access {@link Uri} in 5048 * the given {@link ProviderInfo}. Final permission checking is always done 5049 * in {@link ContentProvider}. 5050 */ 5051 private final boolean checkHoldingPermissionsLocked( 5052 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5054 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5055 5056 if (pi.applicationInfo.uid == uid) { 5057 return true; 5058 } else if (!pi.exported) { 5059 return false; 5060 } 5061 5062 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5063 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5064 try { 5065 // check if target holds top-level <provider> permissions 5066 if (!readMet && pi.readPermission != null 5067 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5068 readMet = true; 5069 } 5070 if (!writeMet && pi.writePermission != null 5071 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5072 writeMet = true; 5073 } 5074 5075 // track if unprotected read/write is allowed; any denied 5076 // <path-permission> below removes this ability 5077 boolean allowDefaultRead = pi.readPermission == null; 5078 boolean allowDefaultWrite = pi.writePermission == null; 5079 5080 // check if target holds any <path-permission> that match uri 5081 final PathPermission[] pps = pi.pathPermissions; 5082 if (pps != null) { 5083 final String path = uri.getPath(); 5084 int i = pps.length; 5085 while (i > 0 && (!readMet || !writeMet)) { 5086 i--; 5087 PathPermission pp = pps[i]; 5088 if (pp.match(path)) { 5089 if (!readMet) { 5090 final String pprperm = pp.getReadPermission(); 5091 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5092 + pprperm + " for " + pp.getPath() 5093 + ": match=" + pp.match(path) 5094 + " check=" + pm.checkUidPermission(pprperm, uid)); 5095 if (pprperm != null) { 5096 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5097 readMet = true; 5098 } else { 5099 allowDefaultRead = false; 5100 } 5101 } 5102 } 5103 if (!writeMet) { 5104 final String ppwperm = pp.getWritePermission(); 5105 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5106 + ppwperm + " for " + pp.getPath() 5107 + ": match=" + pp.match(path) 5108 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5109 if (ppwperm != null) { 5110 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5111 writeMet = true; 5112 } else { 5113 allowDefaultWrite = false; 5114 } 5115 } 5116 } 5117 } 5118 } 5119 } 5120 5121 // grant unprotected <provider> read/write, if not blocked by 5122 // <path-permission> above 5123 if (allowDefaultRead) readMet = true; 5124 if (allowDefaultWrite) writeMet = true; 5125 5126 } catch (RemoteException e) { 5127 return false; 5128 } 5129 5130 return readMet && writeMet; 5131 } 5132 5133 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5134 int modeFlags) { 5135 // Root gets to do everything. 5136 if (uid == 0) { 5137 return true; 5138 } 5139 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5140 if (perms == null) return false; 5141 UriPermission perm = perms.get(uri); 5142 if (perm == null) return false; 5143 return (modeFlags&perm.modeFlags) == modeFlags; 5144 } 5145 5146 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5147 enforceNotIsolatedCaller("checkUriPermission"); 5148 5149 // Another redirected-binder-call permissions check as in 5150 // {@link checkComponentPermission}. 5151 Identity tlsIdentity = sCallerIdentity.get(); 5152 if (tlsIdentity != null) { 5153 uid = tlsIdentity.uid; 5154 pid = tlsIdentity.pid; 5155 } 5156 5157 // Our own process gets to do everything. 5158 if (pid == MY_PID) { 5159 return PackageManager.PERMISSION_GRANTED; 5160 } 5161 synchronized(this) { 5162 return checkUriPermissionLocked(uri, uid, modeFlags) 5163 ? PackageManager.PERMISSION_GRANTED 5164 : PackageManager.PERMISSION_DENIED; 5165 } 5166 } 5167 5168 /** 5169 * Check if the targetPkg can be granted permission to access uri by 5170 * the callingUid using the given modeFlags. Throws a security exception 5171 * if callingUid is not allowed to do this. Returns the uid of the target 5172 * if the URI permission grant should be performed; returns -1 if it is not 5173 * needed (for example targetPkg already has permission to access the URI). 5174 * If you already know the uid of the target, you can supply it in 5175 * lastTargetUid else set that to -1. 5176 */ 5177 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5178 Uri uri, int modeFlags, int lastTargetUid) { 5179 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5180 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5181 if (modeFlags == 0) { 5182 return -1; 5183 } 5184 5185 if (targetPkg != null) { 5186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5187 "Checking grant " + targetPkg + " permission to " + uri); 5188 } 5189 5190 final IPackageManager pm = AppGlobals.getPackageManager(); 5191 5192 // If this is not a content: uri, we can't do anything with it. 5193 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5195 "Can't grant URI permission for non-content URI: " + uri); 5196 return -1; 5197 } 5198 5199 String name = uri.getAuthority(); 5200 ProviderInfo pi = null; 5201 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5202 UserHandle.getUserId(callingUid)); 5203 if (cpr != null) { 5204 pi = cpr.info; 5205 } else { 5206 try { 5207 pi = pm.resolveContentProvider(name, 5208 PackageManager.GET_URI_PERMISSION_PATTERNS, 5209 UserHandle.getUserId(callingUid)); 5210 } catch (RemoteException ex) { 5211 } 5212 } 5213 if (pi == null) { 5214 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5215 return -1; 5216 } 5217 5218 int targetUid = lastTargetUid; 5219 if (targetUid < 0 && targetPkg != null) { 5220 try { 5221 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5222 if (targetUid < 0) { 5223 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5224 "Can't grant URI permission no uid for: " + targetPkg); 5225 return -1; 5226 } 5227 } catch (RemoteException ex) { 5228 return -1; 5229 } 5230 } 5231 5232 if (targetUid >= 0) { 5233 // First... does the target actually need this permission? 5234 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5235 // No need to grant the target this permission. 5236 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5237 "Target " + targetPkg + " already has full permission to " + uri); 5238 return -1; 5239 } 5240 } else { 5241 // First... there is no target package, so can anyone access it? 5242 boolean allowed = pi.exported; 5243 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5244 if (pi.readPermission != null) { 5245 allowed = false; 5246 } 5247 } 5248 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5249 if (pi.writePermission != null) { 5250 allowed = false; 5251 } 5252 } 5253 if (allowed) { 5254 return -1; 5255 } 5256 } 5257 5258 // Second... is the provider allowing granting of URI permissions? 5259 if (!pi.grantUriPermissions) { 5260 throw new SecurityException("Provider " + pi.packageName 5261 + "/" + pi.name 5262 + " does not allow granting of Uri permissions (uri " 5263 + uri + ")"); 5264 } 5265 if (pi.uriPermissionPatterns != null) { 5266 final int N = pi.uriPermissionPatterns.length; 5267 boolean allowed = false; 5268 for (int i=0; i<N; i++) { 5269 if (pi.uriPermissionPatterns[i] != null 5270 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5271 allowed = true; 5272 break; 5273 } 5274 } 5275 if (!allowed) { 5276 throw new SecurityException("Provider " + pi.packageName 5277 + "/" + pi.name 5278 + " does not allow granting of permission to path of Uri " 5279 + uri); 5280 } 5281 } 5282 5283 // Third... does the caller itself have permission to access 5284 // this uri? 5285 if (callingUid != Process.myUid()) { 5286 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5287 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5288 throw new SecurityException("Uid " + callingUid 5289 + " does not have permission to uri " + uri); 5290 } 5291 } 5292 } 5293 5294 return targetUid; 5295 } 5296 5297 public int checkGrantUriPermission(int callingUid, String targetPkg, 5298 Uri uri, int modeFlags) { 5299 enforceNotIsolatedCaller("checkGrantUriPermission"); 5300 synchronized(this) { 5301 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5302 } 5303 } 5304 5305 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5306 Uri uri, int modeFlags, UriPermissionOwner owner) { 5307 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5308 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5309 if (modeFlags == 0) { 5310 return; 5311 } 5312 5313 // So here we are: the caller has the assumed permission 5314 // to the uri, and the target doesn't. Let's now give this to 5315 // the target. 5316 5317 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5318 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5319 5320 HashMap<Uri, UriPermission> targetUris 5321 = mGrantedUriPermissions.get(targetUid); 5322 if (targetUris == null) { 5323 targetUris = new HashMap<Uri, UriPermission>(); 5324 mGrantedUriPermissions.put(targetUid, targetUris); 5325 } 5326 5327 UriPermission perm = targetUris.get(uri); 5328 if (perm == null) { 5329 perm = new UriPermission(targetUid, uri); 5330 targetUris.put(uri, perm); 5331 } 5332 5333 perm.modeFlags |= modeFlags; 5334 if (owner == null) { 5335 perm.globalModeFlags |= modeFlags; 5336 } else { 5337 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5338 perm.readOwners.add(owner); 5339 owner.addReadPermission(perm); 5340 } 5341 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5342 perm.writeOwners.add(owner); 5343 owner.addWritePermission(perm); 5344 } 5345 } 5346 } 5347 5348 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5349 int modeFlags, UriPermissionOwner owner) { 5350 if (targetPkg == null) { 5351 throw new NullPointerException("targetPkg"); 5352 } 5353 5354 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5355 if (targetUid < 0) { 5356 return; 5357 } 5358 5359 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5360 } 5361 5362 static class NeededUriGrants extends ArrayList<Uri> { 5363 final String targetPkg; 5364 final int targetUid; 5365 final int flags; 5366 5367 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5368 targetPkg = _targetPkg; 5369 targetUid = _targetUid; 5370 flags = _flags; 5371 } 5372 } 5373 5374 /** 5375 * Like checkGrantUriPermissionLocked, but takes an Intent. 5376 */ 5377 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5378 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5379 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5380 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5381 + " clip=" + (intent != null ? intent.getClipData() : null) 5382 + " from " + intent + "; flags=0x" 5383 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5384 5385 if (targetPkg == null) { 5386 throw new NullPointerException("targetPkg"); 5387 } 5388 5389 if (intent == null) { 5390 return null; 5391 } 5392 Uri data = intent.getData(); 5393 ClipData clip = intent.getClipData(); 5394 if (data == null && clip == null) { 5395 return null; 5396 } 5397 if (data != null) { 5398 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5399 mode, needed != null ? needed.targetUid : -1); 5400 if (target > 0) { 5401 if (needed == null) { 5402 needed = new NeededUriGrants(targetPkg, target, mode); 5403 } 5404 needed.add(data); 5405 } 5406 } 5407 if (clip != null) { 5408 for (int i=0; i<clip.getItemCount(); i++) { 5409 Uri uri = clip.getItemAt(i).getUri(); 5410 if (uri != null) { 5411 int target = -1; 5412 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5413 mode, needed != null ? needed.targetUid : -1); 5414 if (target > 0) { 5415 if (needed == null) { 5416 needed = new NeededUriGrants(targetPkg, target, mode); 5417 } 5418 needed.add(uri); 5419 } 5420 } else { 5421 Intent clipIntent = clip.getItemAt(i).getIntent(); 5422 if (clipIntent != null) { 5423 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5424 callingUid, targetPkg, clipIntent, mode, needed); 5425 if (newNeeded != null) { 5426 needed = newNeeded; 5427 } 5428 } 5429 } 5430 } 5431 } 5432 5433 return needed; 5434 } 5435 5436 /** 5437 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5438 */ 5439 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5440 UriPermissionOwner owner) { 5441 if (needed != null) { 5442 for (int i=0; i<needed.size(); i++) { 5443 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5444 needed.get(i), needed.flags, owner); 5445 } 5446 } 5447 } 5448 5449 void grantUriPermissionFromIntentLocked(int callingUid, 5450 String targetPkg, Intent intent, UriPermissionOwner owner) { 5451 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5452 intent, intent != null ? intent.getFlags() : 0, null); 5453 if (needed == null) { 5454 return; 5455 } 5456 5457 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5458 } 5459 5460 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5461 Uri uri, int modeFlags) { 5462 enforceNotIsolatedCaller("grantUriPermission"); 5463 synchronized(this) { 5464 final ProcessRecord r = getRecordForAppLocked(caller); 5465 if (r == null) { 5466 throw new SecurityException("Unable to find app for caller " 5467 + caller 5468 + " when granting permission to uri " + uri); 5469 } 5470 if (targetPkg == null) { 5471 throw new IllegalArgumentException("null target"); 5472 } 5473 if (uri == null) { 5474 throw new IllegalArgumentException("null uri"); 5475 } 5476 5477 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5478 null); 5479 } 5480 } 5481 5482 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5483 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5484 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5485 HashMap<Uri, UriPermission> perms 5486 = mGrantedUriPermissions.get(perm.uid); 5487 if (perms != null) { 5488 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5489 "Removing " + perm.uid + " permission to " + perm.uri); 5490 perms.remove(perm.uri); 5491 if (perms.size() == 0) { 5492 mGrantedUriPermissions.remove(perm.uid); 5493 } 5494 } 5495 } 5496 } 5497 5498 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5499 int modeFlags) { 5500 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5501 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5502 if (modeFlags == 0) { 5503 return; 5504 } 5505 5506 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5507 "Revoking all granted permissions to " + uri); 5508 5509 final IPackageManager pm = AppGlobals.getPackageManager(); 5510 5511 final String authority = uri.getAuthority(); 5512 ProviderInfo pi = null; 5513 int userId = UserHandle.getUserId(callingUid); 5514 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5515 if (cpr != null) { 5516 pi = cpr.info; 5517 } else { 5518 try { 5519 pi = pm.resolveContentProvider(authority, 5520 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5521 } catch (RemoteException ex) { 5522 } 5523 } 5524 if (pi == null) { 5525 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5526 return; 5527 } 5528 5529 // Does the caller have this permission on the URI? 5530 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5531 // Right now, if you are not the original owner of the permission, 5532 // you are not allowed to revoke it. 5533 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5534 throw new SecurityException("Uid " + callingUid 5535 + " does not have permission to uri " + uri); 5536 //} 5537 } 5538 5539 // Go through all of the permissions and remove any that match. 5540 final List<String> SEGMENTS = uri.getPathSegments(); 5541 if (SEGMENTS != null) { 5542 final int NS = SEGMENTS.size(); 5543 int N = mGrantedUriPermissions.size(); 5544 for (int i=0; i<N; i++) { 5545 HashMap<Uri, UriPermission> perms 5546 = mGrantedUriPermissions.valueAt(i); 5547 Iterator<UriPermission> it = perms.values().iterator(); 5548 toploop: 5549 while (it.hasNext()) { 5550 UriPermission perm = it.next(); 5551 Uri targetUri = perm.uri; 5552 if (!authority.equals(targetUri.getAuthority())) { 5553 continue; 5554 } 5555 List<String> targetSegments = targetUri.getPathSegments(); 5556 if (targetSegments == null) { 5557 continue; 5558 } 5559 if (targetSegments.size() < NS) { 5560 continue; 5561 } 5562 for (int j=0; j<NS; j++) { 5563 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5564 continue toploop; 5565 } 5566 } 5567 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5568 "Revoking " + perm.uid + " permission to " + perm.uri); 5569 perm.clearModes(modeFlags); 5570 if (perm.modeFlags == 0) { 5571 it.remove(); 5572 } 5573 } 5574 if (perms.size() == 0) { 5575 mGrantedUriPermissions.remove( 5576 mGrantedUriPermissions.keyAt(i)); 5577 N--; 5578 i--; 5579 } 5580 } 5581 } 5582 } 5583 5584 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5585 int modeFlags) { 5586 enforceNotIsolatedCaller("revokeUriPermission"); 5587 synchronized(this) { 5588 final ProcessRecord r = getRecordForAppLocked(caller); 5589 if (r == null) { 5590 throw new SecurityException("Unable to find app for caller " 5591 + caller 5592 + " when revoking permission to uri " + uri); 5593 } 5594 if (uri == null) { 5595 Slog.w(TAG, "revokeUriPermission: null uri"); 5596 return; 5597 } 5598 5599 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5600 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5601 if (modeFlags == 0) { 5602 return; 5603 } 5604 5605 final IPackageManager pm = AppGlobals.getPackageManager(); 5606 5607 final String authority = uri.getAuthority(); 5608 ProviderInfo pi = null; 5609 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5610 if (cpr != null) { 5611 pi = cpr.info; 5612 } else { 5613 try { 5614 pi = pm.resolveContentProvider(authority, 5615 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5616 } catch (RemoteException ex) { 5617 } 5618 } 5619 if (pi == null) { 5620 Slog.w(TAG, "No content provider found for permission revoke: " 5621 + uri.toSafeString()); 5622 return; 5623 } 5624 5625 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5626 } 5627 } 5628 5629 @Override 5630 public IBinder newUriPermissionOwner(String name) { 5631 enforceNotIsolatedCaller("newUriPermissionOwner"); 5632 synchronized(this) { 5633 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5634 return owner.getExternalTokenLocked(); 5635 } 5636 } 5637 5638 @Override 5639 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5640 Uri uri, int modeFlags) { 5641 synchronized(this) { 5642 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5643 if (owner == null) { 5644 throw new IllegalArgumentException("Unknown owner: " + token); 5645 } 5646 if (fromUid != Binder.getCallingUid()) { 5647 if (Binder.getCallingUid() != Process.myUid()) { 5648 // Only system code can grant URI permissions on behalf 5649 // of other users. 5650 throw new SecurityException("nice try"); 5651 } 5652 } 5653 if (targetPkg == null) { 5654 throw new IllegalArgumentException("null target"); 5655 } 5656 if (uri == null) { 5657 throw new IllegalArgumentException("null uri"); 5658 } 5659 5660 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5661 } 5662 } 5663 5664 @Override 5665 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5666 synchronized(this) { 5667 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5668 if (owner == null) { 5669 throw new IllegalArgumentException("Unknown owner: " + token); 5670 } 5671 5672 if (uri == null) { 5673 owner.removeUriPermissionsLocked(mode); 5674 } else { 5675 owner.removeUriPermissionLocked(uri, mode); 5676 } 5677 } 5678 } 5679 5680 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5681 synchronized (this) { 5682 ProcessRecord app = 5683 who != null ? getRecordForAppLocked(who) : null; 5684 if (app == null) return; 5685 5686 Message msg = Message.obtain(); 5687 msg.what = WAIT_FOR_DEBUGGER_MSG; 5688 msg.obj = app; 5689 msg.arg1 = waiting ? 1 : 0; 5690 mHandler.sendMessage(msg); 5691 } 5692 } 5693 5694 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5695 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5696 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5697 outInfo.availMem = Process.getFreeMemory(); 5698 outInfo.totalMem = Process.getTotalMemory(); 5699 outInfo.threshold = homeAppMem; 5700 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5701 outInfo.hiddenAppThreshold = hiddenAppMem; 5702 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5703 ProcessList.SERVICE_ADJ); 5704 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5705 ProcessList.VISIBLE_APP_ADJ); 5706 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5707 ProcessList.FOREGROUND_APP_ADJ); 5708 } 5709 5710 // ========================================================= 5711 // TASK MANAGEMENT 5712 // ========================================================= 5713 5714 public List getTasks(int maxNum, int flags, 5715 IThumbnailReceiver receiver) { 5716 ArrayList list = new ArrayList(); 5717 5718 PendingThumbnailsRecord pending = null; 5719 IApplicationThread topThumbnail = null; 5720 ActivityRecord topRecord = null; 5721 5722 synchronized(this) { 5723 if (localLOGV) Slog.v( 5724 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5725 + ", receiver=" + receiver); 5726 5727 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5728 != PackageManager.PERMISSION_GRANTED) { 5729 if (receiver != null) { 5730 // If the caller wants to wait for pending thumbnails, 5731 // it ain't gonna get them. 5732 try { 5733 receiver.finished(); 5734 } catch (RemoteException ex) { 5735 } 5736 } 5737 String msg = "Permission Denial: getTasks() from pid=" 5738 + Binder.getCallingPid() 5739 + ", uid=" + Binder.getCallingUid() 5740 + " requires " + android.Manifest.permission.GET_TASKS; 5741 Slog.w(TAG, msg); 5742 throw new SecurityException(msg); 5743 } 5744 5745 int pos = mMainStack.mHistory.size()-1; 5746 ActivityRecord next = 5747 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5748 ActivityRecord top = null; 5749 TaskRecord curTask = null; 5750 int numActivities = 0; 5751 int numRunning = 0; 5752 while (pos >= 0 && maxNum > 0) { 5753 final ActivityRecord r = next; 5754 pos--; 5755 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5756 5757 // Initialize state for next task if needed. 5758 if (top == null || 5759 (top.state == ActivityState.INITIALIZING 5760 && top.task == r.task)) { 5761 top = r; 5762 curTask = r.task; 5763 numActivities = numRunning = 0; 5764 } 5765 5766 // Add 'r' into the current task. 5767 numActivities++; 5768 if (r.app != null && r.app.thread != null) { 5769 numRunning++; 5770 } 5771 5772 if (localLOGV) Slog.v( 5773 TAG, r.intent.getComponent().flattenToShortString() 5774 + ": task=" + r.task); 5775 5776 // If the next one is a different task, generate a new 5777 // TaskInfo entry for what we have. 5778 if (next == null || next.task != curTask) { 5779 ActivityManager.RunningTaskInfo ci 5780 = new ActivityManager.RunningTaskInfo(); 5781 ci.id = curTask.taskId; 5782 ci.baseActivity = r.intent.getComponent(); 5783 ci.topActivity = top.intent.getComponent(); 5784 if (top.thumbHolder != null) { 5785 ci.description = top.thumbHolder.lastDescription; 5786 } 5787 ci.numActivities = numActivities; 5788 ci.numRunning = numRunning; 5789 //System.out.println( 5790 // "#" + maxNum + ": " + " descr=" + ci.description); 5791 if (ci.thumbnail == null && receiver != null) { 5792 if (localLOGV) Slog.v( 5793 TAG, "State=" + top.state + "Idle=" + top.idle 5794 + " app=" + top.app 5795 + " thr=" + (top.app != null ? top.app.thread : null)); 5796 if (top.state == ActivityState.RESUMED 5797 || top.state == ActivityState.PAUSING) { 5798 if (top.idle && top.app != null 5799 && top.app.thread != null) { 5800 topRecord = top; 5801 topThumbnail = top.app.thread; 5802 } else { 5803 top.thumbnailNeeded = true; 5804 } 5805 } 5806 if (pending == null) { 5807 pending = new PendingThumbnailsRecord(receiver); 5808 } 5809 pending.pendingRecords.add(top); 5810 } 5811 list.add(ci); 5812 maxNum--; 5813 top = null; 5814 } 5815 } 5816 5817 if (pending != null) { 5818 mPendingThumbnails.add(pending); 5819 } 5820 } 5821 5822 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5823 5824 if (topThumbnail != null) { 5825 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5826 try { 5827 topThumbnail.requestThumbnail(topRecord.appToken); 5828 } catch (Exception e) { 5829 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5830 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5831 } 5832 } 5833 5834 if (pending == null && receiver != null) { 5835 // In this case all thumbnails were available and the client 5836 // is being asked to be told when the remaining ones come in... 5837 // which is unusually, since the top-most currently running 5838 // activity should never have a canned thumbnail! Oh well. 5839 try { 5840 receiver.finished(); 5841 } catch (RemoteException ex) { 5842 } 5843 } 5844 5845 return list; 5846 } 5847 5848 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5849 int flags, int userId) { 5850 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5851 false, true, "getRecentTasks", null); 5852 5853 synchronized (this) { 5854 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5855 "getRecentTasks()"); 5856 final boolean detailed = checkCallingPermission( 5857 android.Manifest.permission.GET_DETAILED_TASKS) 5858 == PackageManager.PERMISSION_GRANTED; 5859 5860 IPackageManager pm = AppGlobals.getPackageManager(); 5861 5862 final int N = mRecentTasks.size(); 5863 ArrayList<ActivityManager.RecentTaskInfo> res 5864 = new ArrayList<ActivityManager.RecentTaskInfo>( 5865 maxNum < N ? maxNum : N); 5866 for (int i=0; i<N && maxNum > 0; i++) { 5867 TaskRecord tr = mRecentTasks.get(i); 5868 // Only add calling user's recent tasks 5869 if (tr.userId != userId) continue; 5870 // Return the entry if desired by the caller. We always return 5871 // the first entry, because callers always expect this to be the 5872 // foreground app. We may filter others if the caller has 5873 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5874 // we should exclude the entry. 5875 5876 if (i == 0 5877 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5878 || (tr.intent == null) 5879 || ((tr.intent.getFlags() 5880 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5881 ActivityManager.RecentTaskInfo rti 5882 = new ActivityManager.RecentTaskInfo(); 5883 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5884 rti.persistentId = tr.taskId; 5885 rti.baseIntent = new Intent( 5886 tr.intent != null ? tr.intent : tr.affinityIntent); 5887 if (!detailed) { 5888 rti.baseIntent.replaceExtras((Bundle)null); 5889 } 5890 rti.origActivity = tr.origActivity; 5891 rti.description = tr.lastDescription; 5892 5893 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5894 // Check whether this activity is currently available. 5895 try { 5896 if (rti.origActivity != null) { 5897 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5898 == null) { 5899 continue; 5900 } 5901 } else if (rti.baseIntent != null) { 5902 if (pm.queryIntentActivities(rti.baseIntent, 5903 null, 0, userId) == null) { 5904 continue; 5905 } 5906 } 5907 } catch (RemoteException e) { 5908 // Will never happen. 5909 } 5910 } 5911 5912 res.add(rti); 5913 maxNum--; 5914 } 5915 } 5916 return res; 5917 } 5918 } 5919 5920 private TaskRecord taskForIdLocked(int id) { 5921 final int N = mRecentTasks.size(); 5922 for (int i=0; i<N; i++) { 5923 TaskRecord tr = mRecentTasks.get(i); 5924 if (tr.taskId == id) { 5925 return tr; 5926 } 5927 } 5928 return null; 5929 } 5930 5931 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5932 synchronized (this) { 5933 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5934 "getTaskThumbnails()"); 5935 TaskRecord tr = taskForIdLocked(id); 5936 if (tr != null) { 5937 return mMainStack.getTaskThumbnailsLocked(tr); 5938 } 5939 } 5940 return null; 5941 } 5942 5943 public Bitmap getTaskTopThumbnail(int id) { 5944 synchronized (this) { 5945 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5946 "getTaskTopThumbnail()"); 5947 TaskRecord tr = taskForIdLocked(id); 5948 if (tr != null) { 5949 return mMainStack.getTaskTopThumbnailLocked(tr); 5950 } 5951 } 5952 return null; 5953 } 5954 5955 public boolean removeSubTask(int taskId, int subTaskIndex) { 5956 synchronized (this) { 5957 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5958 "removeSubTask()"); 5959 long ident = Binder.clearCallingIdentity(); 5960 try { 5961 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5962 true) != null; 5963 } finally { 5964 Binder.restoreCallingIdentity(ident); 5965 } 5966 } 5967 } 5968 5969 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5970 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5971 Intent baseIntent = new Intent( 5972 tr.intent != null ? tr.intent : tr.affinityIntent); 5973 ComponentName component = baseIntent.getComponent(); 5974 if (component == null) { 5975 Slog.w(TAG, "Now component for base intent of task: " + tr); 5976 return; 5977 } 5978 5979 // Find any running services associated with this app. 5980 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5981 5982 if (killProcesses) { 5983 // Find any running processes associated with this app. 5984 final String pkg = component.getPackageName(); 5985 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5986 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5987 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5988 for (int i=0; i<uids.size(); i++) { 5989 ProcessRecord proc = uids.valueAt(i); 5990 if (proc.userId != tr.userId) { 5991 continue; 5992 } 5993 if (!proc.pkgList.contains(pkg)) { 5994 continue; 5995 } 5996 procs.add(proc); 5997 } 5998 } 5999 6000 // Kill the running processes. 6001 for (int i=0; i<procs.size(); i++) { 6002 ProcessRecord pr = procs.get(i); 6003 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6004 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 6005 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6006 pr.processName, pr.setAdj, "remove task"); 6007 pr.killedBackground = true; 6008 Process.killProcessQuiet(pr.pid); 6009 } else { 6010 pr.waitingToKill = "remove task"; 6011 } 6012 } 6013 } 6014 } 6015 6016 public boolean removeTask(int taskId, int flags) { 6017 synchronized (this) { 6018 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6019 "removeTask()"); 6020 long ident = Binder.clearCallingIdentity(); 6021 try { 6022 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 6023 false); 6024 if (r != null) { 6025 mRecentTasks.remove(r.task); 6026 cleanUpRemovedTaskLocked(r.task, flags); 6027 return true; 6028 } else { 6029 TaskRecord tr = null; 6030 int i=0; 6031 while (i < mRecentTasks.size()) { 6032 TaskRecord t = mRecentTasks.get(i); 6033 if (t.taskId == taskId) { 6034 tr = t; 6035 break; 6036 } 6037 i++; 6038 } 6039 if (tr != null) { 6040 if (tr.numActivities <= 0) { 6041 // Caller is just removing a recent task that is 6042 // not actively running. That is easy! 6043 mRecentTasks.remove(i); 6044 cleanUpRemovedTaskLocked(tr, flags); 6045 return true; 6046 } else { 6047 Slog.w(TAG, "removeTask: task " + taskId 6048 + " does not have activities to remove, " 6049 + " but numActivities=" + tr.numActivities 6050 + ": " + tr); 6051 } 6052 } 6053 } 6054 } finally { 6055 Binder.restoreCallingIdentity(ident); 6056 } 6057 } 6058 return false; 6059 } 6060 6061 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6062 int j; 6063 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 6064 TaskRecord jt = startTask; 6065 6066 // First look backwards 6067 for (j=startIndex-1; j>=0; j--) { 6068 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 6069 if (r.task != jt) { 6070 jt = r.task; 6071 if (affinity.equals(jt.affinity)) { 6072 return j; 6073 } 6074 } 6075 } 6076 6077 // Now look forwards 6078 final int N = mMainStack.mHistory.size(); 6079 jt = startTask; 6080 for (j=startIndex+1; j<N; j++) { 6081 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 6082 if (r.task != jt) { 6083 if (affinity.equals(jt.affinity)) { 6084 return j; 6085 } 6086 jt = r.task; 6087 } 6088 } 6089 6090 // Might it be at the top? 6091 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 6092 return N-1; 6093 } 6094 6095 return -1; 6096 } 6097 6098 /** 6099 * TODO: Add mController hook 6100 */ 6101 public void moveTaskToFront(int task, int flags, Bundle options) { 6102 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6103 "moveTaskToFront()"); 6104 6105 synchronized(this) { 6106 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6107 Binder.getCallingUid(), "Task to front")) { 6108 ActivityOptions.abort(options); 6109 return; 6110 } 6111 final long origId = Binder.clearCallingIdentity(); 6112 try { 6113 TaskRecord tr = taskForIdLocked(task); 6114 if (tr != null) { 6115 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6116 mMainStack.mUserLeaving = true; 6117 } 6118 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6119 // Caller wants the home activity moved with it. To accomplish this, 6120 // we'll just move the home task to the top first. 6121 mMainStack.moveHomeToFrontLocked(); 6122 } 6123 mMainStack.moveTaskToFrontLocked(tr, null, options); 6124 return; 6125 } 6126 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6127 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6128 if (hr.task.taskId == task) { 6129 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6130 mMainStack.mUserLeaving = true; 6131 } 6132 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6133 // Caller wants the home activity moved with it. To accomplish this, 6134 // we'll just move the home task to the top first. 6135 mMainStack.moveHomeToFrontLocked(); 6136 } 6137 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6138 return; 6139 } 6140 } 6141 } finally { 6142 Binder.restoreCallingIdentity(origId); 6143 } 6144 ActivityOptions.abort(options); 6145 } 6146 } 6147 6148 public void moveTaskToBack(int task) { 6149 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6150 "moveTaskToBack()"); 6151 6152 synchronized(this) { 6153 if (mMainStack.mResumedActivity != null 6154 && mMainStack.mResumedActivity.task.taskId == task) { 6155 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6156 Binder.getCallingUid(), "Task to back")) { 6157 return; 6158 } 6159 } 6160 final long origId = Binder.clearCallingIdentity(); 6161 mMainStack.moveTaskToBackLocked(task, null); 6162 Binder.restoreCallingIdentity(origId); 6163 } 6164 } 6165 6166 /** 6167 * Moves an activity, and all of the other activities within the same task, to the bottom 6168 * of the history stack. The activity's order within the task is unchanged. 6169 * 6170 * @param token A reference to the activity we wish to move 6171 * @param nonRoot If false then this only works if the activity is the root 6172 * of a task; if true it will work for any activity in a task. 6173 * @return Returns true if the move completed, false if not. 6174 */ 6175 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6176 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6177 synchronized(this) { 6178 final long origId = Binder.clearCallingIdentity(); 6179 int taskId = getTaskForActivityLocked(token, !nonRoot); 6180 if (taskId >= 0) { 6181 return mMainStack.moveTaskToBackLocked(taskId, null); 6182 } 6183 Binder.restoreCallingIdentity(origId); 6184 } 6185 return false; 6186 } 6187 6188 public void moveTaskBackwards(int task) { 6189 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6190 "moveTaskBackwards()"); 6191 6192 synchronized(this) { 6193 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6194 Binder.getCallingUid(), "Task backwards")) { 6195 return; 6196 } 6197 final long origId = Binder.clearCallingIdentity(); 6198 moveTaskBackwardsLocked(task); 6199 Binder.restoreCallingIdentity(origId); 6200 } 6201 } 6202 6203 private final void moveTaskBackwardsLocked(int task) { 6204 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6205 } 6206 6207 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6208 synchronized(this) { 6209 return getTaskForActivityLocked(token, onlyRoot); 6210 } 6211 } 6212 6213 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6214 final int N = mMainStack.mHistory.size(); 6215 TaskRecord lastTask = null; 6216 for (int i=0; i<N; i++) { 6217 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6218 if (r.appToken == token) { 6219 if (!onlyRoot || lastTask != r.task) { 6220 return r.task.taskId; 6221 } 6222 return -1; 6223 } 6224 lastTask = r.task; 6225 } 6226 6227 return -1; 6228 } 6229 6230 // ========================================================= 6231 // THUMBNAILS 6232 // ========================================================= 6233 6234 public void reportThumbnail(IBinder token, 6235 Bitmap thumbnail, CharSequence description) { 6236 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6237 final long origId = Binder.clearCallingIdentity(); 6238 sendPendingThumbnail(null, token, thumbnail, description, true); 6239 Binder.restoreCallingIdentity(origId); 6240 } 6241 6242 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6243 Bitmap thumbnail, CharSequence description, boolean always) { 6244 TaskRecord task = null; 6245 ArrayList receivers = null; 6246 6247 //System.out.println("Send pending thumbnail: " + r); 6248 6249 synchronized(this) { 6250 if (r == null) { 6251 r = mMainStack.isInStackLocked(token); 6252 if (r == null) { 6253 return; 6254 } 6255 } 6256 if (thumbnail == null && r.thumbHolder != null) { 6257 thumbnail = r.thumbHolder.lastThumbnail; 6258 description = r.thumbHolder.lastDescription; 6259 } 6260 if (thumbnail == null && !always) { 6261 // If there is no thumbnail, and this entry is not actually 6262 // going away, then abort for now and pick up the next 6263 // thumbnail we get. 6264 return; 6265 } 6266 task = r.task; 6267 6268 int N = mPendingThumbnails.size(); 6269 int i=0; 6270 while (i<N) { 6271 PendingThumbnailsRecord pr = 6272 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6273 //System.out.println("Looking in " + pr.pendingRecords); 6274 if (pr.pendingRecords.remove(r)) { 6275 if (receivers == null) { 6276 receivers = new ArrayList(); 6277 } 6278 receivers.add(pr); 6279 if (pr.pendingRecords.size() == 0) { 6280 pr.finished = true; 6281 mPendingThumbnails.remove(i); 6282 N--; 6283 continue; 6284 } 6285 } 6286 i++; 6287 } 6288 } 6289 6290 if (receivers != null) { 6291 final int N = receivers.size(); 6292 for (int i=0; i<N; i++) { 6293 try { 6294 PendingThumbnailsRecord pr = 6295 (PendingThumbnailsRecord)receivers.get(i); 6296 pr.receiver.newThumbnail( 6297 task != null ? task.taskId : -1, thumbnail, description); 6298 if (pr.finished) { 6299 pr.receiver.finished(); 6300 } 6301 } catch (Exception e) { 6302 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6303 } 6304 } 6305 } 6306 } 6307 6308 // ========================================================= 6309 // CONTENT PROVIDERS 6310 // ========================================================= 6311 6312 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6313 List<ProviderInfo> providers = null; 6314 try { 6315 providers = AppGlobals.getPackageManager(). 6316 queryContentProviders(app.processName, app.uid, 6317 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6318 } catch (RemoteException ex) { 6319 } 6320 if (DEBUG_MU) 6321 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6322 int userId = app.userId; 6323 if (providers != null) { 6324 int N = providers.size(); 6325 for (int i=0; i<N; i++) { 6326 ProviderInfo cpi = 6327 (ProviderInfo)providers.get(i); 6328 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6329 cpi.name, cpi.flags); 6330 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6331 // This is a singleton provider, but a user besides the 6332 // default user is asking to initialize a process it runs 6333 // in... well, no, it doesn't actually run in this process, 6334 // it runs in the process of the default user. Get rid of it. 6335 providers.remove(i); 6336 N--; 6337 continue; 6338 } 6339 6340 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6341 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6342 if (cpr == null) { 6343 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6344 mProviderMap.putProviderByClass(comp, cpr); 6345 } 6346 if (DEBUG_MU) 6347 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6348 app.pubProviders.put(cpi.name, cpr); 6349 app.addPackage(cpi.applicationInfo.packageName); 6350 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6351 } 6352 } 6353 return providers; 6354 } 6355 6356 /** 6357 * Check if {@link ProcessRecord} has a possible chance at accessing the 6358 * given {@link ProviderInfo}. Final permission checking is always done 6359 * in {@link ContentProvider}. 6360 */ 6361 private final String checkContentProviderPermissionLocked( 6362 ProviderInfo cpi, ProcessRecord r) { 6363 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6364 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6365 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6366 cpi.applicationInfo.uid, cpi.exported) 6367 == PackageManager.PERMISSION_GRANTED) { 6368 return null; 6369 } 6370 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6371 cpi.applicationInfo.uid, cpi.exported) 6372 == PackageManager.PERMISSION_GRANTED) { 6373 return null; 6374 } 6375 6376 PathPermission[] pps = cpi.pathPermissions; 6377 if (pps != null) { 6378 int i = pps.length; 6379 while (i > 0) { 6380 i--; 6381 PathPermission pp = pps[i]; 6382 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6383 cpi.applicationInfo.uid, cpi.exported) 6384 == PackageManager.PERMISSION_GRANTED) { 6385 return null; 6386 } 6387 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6388 cpi.applicationInfo.uid, cpi.exported) 6389 == PackageManager.PERMISSION_GRANTED) { 6390 return null; 6391 } 6392 } 6393 } 6394 6395 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6396 if (perms != null) { 6397 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6398 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6399 return null; 6400 } 6401 } 6402 } 6403 6404 String msg; 6405 if (!cpi.exported) { 6406 msg = "Permission Denial: opening provider " + cpi.name 6407 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6408 + ", uid=" + callingUid + ") that is not exported from uid " 6409 + cpi.applicationInfo.uid; 6410 } else { 6411 msg = "Permission Denial: opening provider " + cpi.name 6412 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6413 + ", uid=" + callingUid + ") requires " 6414 + cpi.readPermission + " or " + cpi.writePermission; 6415 } 6416 Slog.w(TAG, msg); 6417 return msg; 6418 } 6419 6420 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6421 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6422 if (r != null) { 6423 for (int i=0; i<r.conProviders.size(); i++) { 6424 ContentProviderConnection conn = r.conProviders.get(i); 6425 if (conn.provider == cpr) { 6426 if (DEBUG_PROVIDER) Slog.v(TAG, 6427 "Adding provider requested by " 6428 + r.processName + " from process " 6429 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6430 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6431 if (stable) { 6432 conn.stableCount++; 6433 conn.numStableIncs++; 6434 } else { 6435 conn.unstableCount++; 6436 conn.numUnstableIncs++; 6437 } 6438 return conn; 6439 } 6440 } 6441 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6442 if (stable) { 6443 conn.stableCount = 1; 6444 conn.numStableIncs = 1; 6445 } else { 6446 conn.unstableCount = 1; 6447 conn.numUnstableIncs = 1; 6448 } 6449 cpr.connections.add(conn); 6450 r.conProviders.add(conn); 6451 return conn; 6452 } 6453 cpr.addExternalProcessHandleLocked(externalProcessToken); 6454 return null; 6455 } 6456 6457 boolean decProviderCountLocked(ContentProviderConnection conn, 6458 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6459 if (conn != null) { 6460 cpr = conn.provider; 6461 if (DEBUG_PROVIDER) Slog.v(TAG, 6462 "Removing provider requested by " 6463 + conn.client.processName + " from process " 6464 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6465 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6466 if (stable) { 6467 conn.stableCount--; 6468 } else { 6469 conn.unstableCount--; 6470 } 6471 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6472 cpr.connections.remove(conn); 6473 conn.client.conProviders.remove(conn); 6474 return true; 6475 } 6476 return false; 6477 } 6478 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6479 return false; 6480 } 6481 6482 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6483 String name, IBinder token, boolean stable, int userId) { 6484 ContentProviderRecord cpr; 6485 ContentProviderConnection conn = null; 6486 ProviderInfo cpi = null; 6487 6488 synchronized(this) { 6489 ProcessRecord r = null; 6490 if (caller != null) { 6491 r = getRecordForAppLocked(caller); 6492 if (r == null) { 6493 throw new SecurityException( 6494 "Unable to find app for caller " + caller 6495 + " (pid=" + Binder.getCallingPid() 6496 + ") when getting content provider " + name); 6497 } 6498 } 6499 6500 // First check if this content provider has been published... 6501 cpr = mProviderMap.getProviderByName(name, userId); 6502 boolean providerRunning = cpr != null; 6503 if (providerRunning) { 6504 cpi = cpr.info; 6505 String msg; 6506 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6507 throw new SecurityException(msg); 6508 } 6509 6510 if (r != null && cpr.canRunHere(r)) { 6511 // This provider has been published or is in the process 6512 // of being published... but it is also allowed to run 6513 // in the caller's process, so don't make a connection 6514 // and just let the caller instantiate its own instance. 6515 ContentProviderHolder holder = cpr.newHolder(null); 6516 // don't give caller the provider object, it needs 6517 // to make its own. 6518 holder.provider = null; 6519 return holder; 6520 } 6521 6522 final long origId = Binder.clearCallingIdentity(); 6523 6524 // In this case the provider instance already exists, so we can 6525 // return it right away. 6526 conn = incProviderCountLocked(r, cpr, token, stable); 6527 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6528 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6529 // If this is a perceptible app accessing the provider, 6530 // make sure to count it as being accessed and thus 6531 // back up on the LRU list. This is good because 6532 // content providers are often expensive to start. 6533 updateLruProcessLocked(cpr.proc, false); 6534 } 6535 } 6536 6537 if (cpr.proc != null) { 6538 if (false) { 6539 if (cpr.name.flattenToShortString().equals( 6540 "com.android.providers.calendar/.CalendarProvider2")) { 6541 Slog.v(TAG, "****************** KILLING " 6542 + cpr.name.flattenToShortString()); 6543 Process.killProcess(cpr.proc.pid); 6544 } 6545 } 6546 boolean success = updateOomAdjLocked(cpr.proc); 6547 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6548 // NOTE: there is still a race here where a signal could be 6549 // pending on the process even though we managed to update its 6550 // adj level. Not sure what to do about this, but at least 6551 // the race is now smaller. 6552 if (!success) { 6553 // Uh oh... it looks like the provider's process 6554 // has been killed on us. We need to wait for a new 6555 // process to be started, and make sure its death 6556 // doesn't kill our process. 6557 Slog.i(TAG, 6558 "Existing provider " + cpr.name.flattenToShortString() 6559 + " is crashing; detaching " + r); 6560 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6561 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6562 if (!lastRef) { 6563 // This wasn't the last ref our process had on 6564 // the provider... we have now been killed, bail. 6565 return null; 6566 } 6567 providerRunning = false; 6568 conn = null; 6569 } 6570 } 6571 6572 Binder.restoreCallingIdentity(origId); 6573 } 6574 6575 boolean singleton; 6576 if (!providerRunning) { 6577 try { 6578 cpi = AppGlobals.getPackageManager(). 6579 resolveContentProvider(name, 6580 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6581 } catch (RemoteException ex) { 6582 } 6583 if (cpi == null) { 6584 return null; 6585 } 6586 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6587 cpi.name, cpi.flags); 6588 if (singleton) { 6589 userId = 0; 6590 } 6591 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6592 6593 String msg; 6594 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6595 throw new SecurityException(msg); 6596 } 6597 6598 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6599 && !cpi.processName.equals("system")) { 6600 // If this content provider does not run in the system 6601 // process, and the system is not yet ready to run other 6602 // processes, then fail fast instead of hanging. 6603 throw new IllegalArgumentException( 6604 "Attempt to launch content provider before system ready"); 6605 } 6606 6607 // Make sure that the user who owns this provider is started. If not, 6608 // we don't want to allow it to run. 6609 if (mStartedUsers.get(userId) == null) { 6610 Slog.w(TAG, "Unable to launch app " 6611 + cpi.applicationInfo.packageName + "/" 6612 + cpi.applicationInfo.uid + " for provider " 6613 + name + ": user " + userId + " is stopped"); 6614 return null; 6615 } 6616 6617 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6618 cpr = mProviderMap.getProviderByClass(comp, userId); 6619 final boolean firstClass = cpr == null; 6620 if (firstClass) { 6621 try { 6622 ApplicationInfo ai = 6623 AppGlobals.getPackageManager(). 6624 getApplicationInfo( 6625 cpi.applicationInfo.packageName, 6626 STOCK_PM_FLAGS, userId); 6627 if (ai == null) { 6628 Slog.w(TAG, "No package info for content provider " 6629 + cpi.name); 6630 return null; 6631 } 6632 ai = getAppInfoForUser(ai, userId); 6633 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6634 } catch (RemoteException ex) { 6635 // pm is in same process, this will never happen. 6636 } 6637 } 6638 6639 if (r != null && cpr.canRunHere(r)) { 6640 // If this is a multiprocess provider, then just return its 6641 // info and allow the caller to instantiate it. Only do 6642 // this if the provider is the same user as the caller's 6643 // process, or can run as root (so can be in any process). 6644 return cpr.newHolder(null); 6645 } 6646 6647 if (DEBUG_PROVIDER) { 6648 RuntimeException e = new RuntimeException("here"); 6649 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6650 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6651 } 6652 6653 // This is single process, and our app is now connecting to it. 6654 // See if we are already in the process of launching this 6655 // provider. 6656 final int N = mLaunchingProviders.size(); 6657 int i; 6658 for (i=0; i<N; i++) { 6659 if (mLaunchingProviders.get(i) == cpr) { 6660 break; 6661 } 6662 } 6663 6664 // If the provider is not already being launched, then get it 6665 // started. 6666 if (i >= N) { 6667 final long origId = Binder.clearCallingIdentity(); 6668 6669 try { 6670 // Content provider is now in use, its package can't be stopped. 6671 try { 6672 AppGlobals.getPackageManager().setPackageStoppedState( 6673 cpr.appInfo.packageName, false, userId); 6674 } catch (RemoteException e) { 6675 } catch (IllegalArgumentException e) { 6676 Slog.w(TAG, "Failed trying to unstop package " 6677 + cpr.appInfo.packageName + ": " + e); 6678 } 6679 6680 ProcessRecord proc = startProcessLocked(cpi.processName, 6681 cpr.appInfo, false, 0, "content provider", 6682 new ComponentName(cpi.applicationInfo.packageName, 6683 cpi.name), false, false); 6684 if (proc == null) { 6685 Slog.w(TAG, "Unable to launch app " 6686 + cpi.applicationInfo.packageName + "/" 6687 + cpi.applicationInfo.uid + " for provider " 6688 + name + ": process is bad"); 6689 return null; 6690 } 6691 cpr.launchingApp = proc; 6692 mLaunchingProviders.add(cpr); 6693 } finally { 6694 Binder.restoreCallingIdentity(origId); 6695 } 6696 } 6697 6698 // Make sure the provider is published (the same provider class 6699 // may be published under multiple names). 6700 if (firstClass) { 6701 mProviderMap.putProviderByClass(comp, cpr); 6702 } 6703 6704 mProviderMap.putProviderByName(name, cpr); 6705 conn = incProviderCountLocked(r, cpr, token, stable); 6706 if (conn != null) { 6707 conn.waiting = true; 6708 } 6709 } 6710 } 6711 6712 // Wait for the provider to be published... 6713 synchronized (cpr) { 6714 while (cpr.provider == null) { 6715 if (cpr.launchingApp == null) { 6716 Slog.w(TAG, "Unable to launch app " 6717 + cpi.applicationInfo.packageName + "/" 6718 + cpi.applicationInfo.uid + " for provider " 6719 + name + ": launching app became null"); 6720 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6721 UserHandle.getUserId(cpi.applicationInfo.uid), 6722 cpi.applicationInfo.packageName, 6723 cpi.applicationInfo.uid, name); 6724 return null; 6725 } 6726 try { 6727 if (DEBUG_MU) { 6728 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6729 + cpr.launchingApp); 6730 } 6731 if (conn != null) { 6732 conn.waiting = true; 6733 } 6734 cpr.wait(); 6735 } catch (InterruptedException ex) { 6736 } finally { 6737 if (conn != null) { 6738 conn.waiting = false; 6739 } 6740 } 6741 } 6742 } 6743 return cpr != null ? cpr.newHolder(conn) : null; 6744 } 6745 6746 public final ContentProviderHolder getContentProvider( 6747 IApplicationThread caller, String name, int userId, boolean stable) { 6748 enforceNotIsolatedCaller("getContentProvider"); 6749 if (caller == null) { 6750 String msg = "null IApplicationThread when getting content provider " 6751 + name; 6752 Slog.w(TAG, msg); 6753 throw new SecurityException(msg); 6754 } 6755 6756 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6757 false, true, "getContentProvider", null); 6758 return getContentProviderImpl(caller, name, null, stable, userId); 6759 } 6760 6761 public ContentProviderHolder getContentProviderExternal( 6762 String name, int userId, IBinder token) { 6763 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6764 "Do not have permission in call getContentProviderExternal()"); 6765 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6766 false, true, "getContentProvider", null); 6767 return getContentProviderExternalUnchecked(name, token, userId); 6768 } 6769 6770 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6771 IBinder token, int userId) { 6772 return getContentProviderImpl(null, name, token, true, userId); 6773 } 6774 6775 /** 6776 * Drop a content provider from a ProcessRecord's bookkeeping 6777 */ 6778 public void removeContentProvider(IBinder connection, boolean stable) { 6779 enforceNotIsolatedCaller("removeContentProvider"); 6780 synchronized (this) { 6781 ContentProviderConnection conn; 6782 try { 6783 conn = (ContentProviderConnection)connection; 6784 } catch (ClassCastException e) { 6785 String msg ="removeContentProvider: " + connection 6786 + " not a ContentProviderConnection"; 6787 Slog.w(TAG, msg); 6788 throw new IllegalArgumentException(msg); 6789 } 6790 if (conn == null) { 6791 throw new NullPointerException("connection is null"); 6792 } 6793 if (decProviderCountLocked(conn, null, null, stable)) { 6794 updateOomAdjLocked(); 6795 } 6796 } 6797 } 6798 6799 public void removeContentProviderExternal(String name, IBinder token) { 6800 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6801 "Do not have permission in call removeContentProviderExternal()"); 6802 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6803 } 6804 6805 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6806 synchronized (this) { 6807 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6808 if(cpr == null) { 6809 //remove from mProvidersByClass 6810 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6811 return; 6812 } 6813 6814 //update content provider record entry info 6815 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6816 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6817 if (localCpr.hasExternalProcessHandles()) { 6818 if (localCpr.removeExternalProcessHandleLocked(token)) { 6819 updateOomAdjLocked(); 6820 } else { 6821 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6822 + " with no external reference for token: " 6823 + token + "."); 6824 } 6825 } else { 6826 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6827 + " with no external references."); 6828 } 6829 } 6830 } 6831 6832 public final void publishContentProviders(IApplicationThread caller, 6833 List<ContentProviderHolder> providers) { 6834 if (providers == null) { 6835 return; 6836 } 6837 6838 enforceNotIsolatedCaller("publishContentProviders"); 6839 synchronized (this) { 6840 final ProcessRecord r = getRecordForAppLocked(caller); 6841 if (DEBUG_MU) 6842 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6843 if (r == null) { 6844 throw new SecurityException( 6845 "Unable to find app for caller " + caller 6846 + " (pid=" + Binder.getCallingPid() 6847 + ") when publishing content providers"); 6848 } 6849 6850 final long origId = Binder.clearCallingIdentity(); 6851 6852 final int N = providers.size(); 6853 for (int i=0; i<N; i++) { 6854 ContentProviderHolder src = providers.get(i); 6855 if (src == null || src.info == null || src.provider == null) { 6856 continue; 6857 } 6858 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6859 if (DEBUG_MU) 6860 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6861 if (dst != null) { 6862 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6863 mProviderMap.putProviderByClass(comp, dst); 6864 String names[] = dst.info.authority.split(";"); 6865 for (int j = 0; j < names.length; j++) { 6866 mProviderMap.putProviderByName(names[j], dst); 6867 } 6868 6869 int NL = mLaunchingProviders.size(); 6870 int j; 6871 for (j=0; j<NL; j++) { 6872 if (mLaunchingProviders.get(j) == dst) { 6873 mLaunchingProviders.remove(j); 6874 j--; 6875 NL--; 6876 } 6877 } 6878 synchronized (dst) { 6879 dst.provider = src.provider; 6880 dst.proc = r; 6881 dst.notifyAll(); 6882 } 6883 updateOomAdjLocked(r); 6884 } 6885 } 6886 6887 Binder.restoreCallingIdentity(origId); 6888 } 6889 } 6890 6891 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6892 ContentProviderConnection conn; 6893 try { 6894 conn = (ContentProviderConnection)connection; 6895 } catch (ClassCastException e) { 6896 String msg ="refContentProvider: " + connection 6897 + " not a ContentProviderConnection"; 6898 Slog.w(TAG, msg); 6899 throw new IllegalArgumentException(msg); 6900 } 6901 if (conn == null) { 6902 throw new NullPointerException("connection is null"); 6903 } 6904 6905 synchronized (this) { 6906 if (stable > 0) { 6907 conn.numStableIncs += stable; 6908 } 6909 stable = conn.stableCount + stable; 6910 if (stable < 0) { 6911 throw new IllegalStateException("stableCount < 0: " + stable); 6912 } 6913 6914 if (unstable > 0) { 6915 conn.numUnstableIncs += unstable; 6916 } 6917 unstable = conn.unstableCount + unstable; 6918 if (unstable < 0) { 6919 throw new IllegalStateException("unstableCount < 0: " + unstable); 6920 } 6921 6922 if ((stable+unstable) <= 0) { 6923 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6924 + stable + " unstable=" + unstable); 6925 } 6926 conn.stableCount = stable; 6927 conn.unstableCount = unstable; 6928 return !conn.dead; 6929 } 6930 } 6931 6932 public void unstableProviderDied(IBinder connection) { 6933 ContentProviderConnection conn; 6934 try { 6935 conn = (ContentProviderConnection)connection; 6936 } catch (ClassCastException e) { 6937 String msg ="refContentProvider: " + connection 6938 + " not a ContentProviderConnection"; 6939 Slog.w(TAG, msg); 6940 throw new IllegalArgumentException(msg); 6941 } 6942 if (conn == null) { 6943 throw new NullPointerException("connection is null"); 6944 } 6945 6946 // Safely retrieve the content provider associated with the connection. 6947 IContentProvider provider; 6948 synchronized (this) { 6949 provider = conn.provider.provider; 6950 } 6951 6952 if (provider == null) { 6953 // Um, yeah, we're way ahead of you. 6954 return; 6955 } 6956 6957 // Make sure the caller is being honest with us. 6958 if (provider.asBinder().pingBinder()) { 6959 // Er, no, still looks good to us. 6960 synchronized (this) { 6961 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6962 + " says " + conn + " died, but we don't agree"); 6963 return; 6964 } 6965 } 6966 6967 // Well look at that! It's dead! 6968 synchronized (this) { 6969 if (conn.provider.provider != provider) { 6970 // But something changed... good enough. 6971 return; 6972 } 6973 6974 ProcessRecord proc = conn.provider.proc; 6975 if (proc == null || proc.thread == null) { 6976 // Seems like the process is already cleaned up. 6977 return; 6978 } 6979 6980 // As far as we're concerned, this is just like receiving a 6981 // death notification... just a bit prematurely. 6982 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6983 + ") early provider death"); 6984 final long ident = Binder.clearCallingIdentity(); 6985 try { 6986 appDiedLocked(proc, proc.pid, proc.thread); 6987 } finally { 6988 Binder.restoreCallingIdentity(ident); 6989 } 6990 } 6991 } 6992 6993 public static final void installSystemProviders() { 6994 List<ProviderInfo> providers; 6995 synchronized (mSelf) { 6996 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6997 providers = mSelf.generateApplicationProvidersLocked(app); 6998 if (providers != null) { 6999 for (int i=providers.size()-1; i>=0; i--) { 7000 ProviderInfo pi = (ProviderInfo)providers.get(i); 7001 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7002 Slog.w(TAG, "Not installing system proc provider " + pi.name 7003 + ": not system .apk"); 7004 providers.remove(i); 7005 } 7006 } 7007 } 7008 } 7009 if (providers != null) { 7010 mSystemThread.installSystemProviders(providers); 7011 } 7012 7013 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 7014 7015 mSelf.mUsageStatsService.monitorPackages(); 7016 } 7017 7018 /** 7019 * Allows app to retrieve the MIME type of a URI without having permission 7020 * to access its content provider. 7021 * 7022 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 7023 * 7024 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 7025 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 7026 */ 7027 public String getProviderMimeType(Uri uri, int userId) { 7028 enforceNotIsolatedCaller("getProviderMimeType"); 7029 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7030 userId, false, true, "getProviderMimeType", null); 7031 final String name = uri.getAuthority(); 7032 final long ident = Binder.clearCallingIdentity(); 7033 ContentProviderHolder holder = null; 7034 7035 try { 7036 holder = getContentProviderExternalUnchecked(name, null, userId); 7037 if (holder != null) { 7038 return holder.provider.getType(uri); 7039 } 7040 } catch (RemoteException e) { 7041 Log.w(TAG, "Content provider dead retrieving " + uri, e); 7042 return null; 7043 } finally { 7044 if (holder != null) { 7045 removeContentProviderExternalUnchecked(name, null, userId); 7046 } 7047 Binder.restoreCallingIdentity(ident); 7048 } 7049 7050 return null; 7051 } 7052 7053 // ========================================================= 7054 // GLOBAL MANAGEMENT 7055 // ========================================================= 7056 7057 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7058 ApplicationInfo info, String customProcess, boolean isolated) { 7059 String proc = customProcess != null ? customProcess : info.processName; 7060 BatteryStatsImpl.Uid.Proc ps = null; 7061 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7062 int uid = info.uid; 7063 if (isolated) { 7064 int userId = UserHandle.getUserId(uid); 7065 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 7066 uid = 0; 7067 while (true) { 7068 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 7069 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 7070 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 7071 } 7072 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 7073 mNextIsolatedProcessUid++; 7074 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 7075 // No process for this uid, use it. 7076 break; 7077 } 7078 stepsLeft--; 7079 if (stepsLeft <= 0) { 7080 return null; 7081 } 7082 } 7083 } 7084 synchronized (stats) { 7085 ps = stats.getProcessStatsLocked(info.uid, proc); 7086 } 7087 return new ProcessRecord(ps, thread, info, proc, uid); 7088 } 7089 7090 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 7091 ProcessRecord app; 7092 if (!isolated) { 7093 app = getProcessRecordLocked(info.processName, info.uid); 7094 } else { 7095 app = null; 7096 } 7097 7098 if (app == null) { 7099 app = newProcessRecordLocked(null, info, null, isolated); 7100 mProcessNames.put(info.processName, app.uid, app); 7101 if (isolated) { 7102 mIsolatedProcesses.put(app.uid, app); 7103 } 7104 updateLruProcessLocked(app, true); 7105 } 7106 7107 // This package really, really can not be stopped. 7108 try { 7109 AppGlobals.getPackageManager().setPackageStoppedState( 7110 info.packageName, false, UserHandle.getUserId(app.uid)); 7111 } catch (RemoteException e) { 7112 } catch (IllegalArgumentException e) { 7113 Slog.w(TAG, "Failed trying to unstop package " 7114 + info.packageName + ": " + e); 7115 } 7116 7117 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7118 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7119 app.persistent = true; 7120 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7121 } 7122 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7123 mPersistentStartingProcesses.add(app); 7124 startProcessLocked(app, "added application", app.processName); 7125 } 7126 7127 return app; 7128 } 7129 7130 public void unhandledBack() { 7131 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7132 "unhandledBack()"); 7133 7134 synchronized(this) { 7135 int count = mMainStack.mHistory.size(); 7136 if (DEBUG_SWITCH) Slog.d( 7137 TAG, "Performing unhandledBack(): stack size = " + count); 7138 if (count > 1) { 7139 final long origId = Binder.clearCallingIdentity(); 7140 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7141 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7142 Binder.restoreCallingIdentity(origId); 7143 } 7144 } 7145 } 7146 7147 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7148 enforceNotIsolatedCaller("openContentUri"); 7149 final int userId = UserHandle.getCallingUserId(); 7150 String name = uri.getAuthority(); 7151 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7152 ParcelFileDescriptor pfd = null; 7153 if (cph != null) { 7154 // We record the binder invoker's uid in thread-local storage before 7155 // going to the content provider to open the file. Later, in the code 7156 // that handles all permissions checks, we look for this uid and use 7157 // that rather than the Activity Manager's own uid. The effect is that 7158 // we do the check against the caller's permissions even though it looks 7159 // to the content provider like the Activity Manager itself is making 7160 // the request. 7161 sCallerIdentity.set(new Identity( 7162 Binder.getCallingPid(), Binder.getCallingUid())); 7163 try { 7164 pfd = cph.provider.openFile(null, uri, "r"); 7165 } catch (FileNotFoundException e) { 7166 // do nothing; pfd will be returned null 7167 } finally { 7168 // Ensure that whatever happens, we clean up the identity state 7169 sCallerIdentity.remove(); 7170 } 7171 7172 // We've got the fd now, so we're done with the provider. 7173 removeContentProviderExternalUnchecked(name, null, userId); 7174 } else { 7175 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7176 } 7177 return pfd; 7178 } 7179 7180 // Actually is sleeping or shutting down or whatever else in the future 7181 // is an inactive state. 7182 public boolean isSleeping() { 7183 return mSleeping || mShuttingDown; 7184 } 7185 7186 public void goingToSleep() { 7187 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7188 != PackageManager.PERMISSION_GRANTED) { 7189 throw new SecurityException("Requires permission " 7190 + android.Manifest.permission.DEVICE_POWER); 7191 } 7192 7193 synchronized(this) { 7194 mWentToSleep = true; 7195 updateEventDispatchingLocked(); 7196 7197 if (!mSleeping) { 7198 mSleeping = true; 7199 mMainStack.stopIfSleepingLocked(); 7200 7201 // Initialize the wake times of all processes. 7202 checkExcessivePowerUsageLocked(false); 7203 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7204 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7205 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7206 } 7207 } 7208 } 7209 7210 public boolean shutdown(int timeout) { 7211 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7212 != PackageManager.PERMISSION_GRANTED) { 7213 throw new SecurityException("Requires permission " 7214 + android.Manifest.permission.SHUTDOWN); 7215 } 7216 7217 boolean timedout = false; 7218 7219 synchronized(this) { 7220 mShuttingDown = true; 7221 updateEventDispatchingLocked(); 7222 7223 if (mMainStack.mResumedActivity != null) { 7224 mMainStack.stopIfSleepingLocked(); 7225 final long endTime = System.currentTimeMillis() + timeout; 7226 while (mMainStack.mResumedActivity != null 7227 || mMainStack.mPausingActivity != null) { 7228 long delay = endTime - System.currentTimeMillis(); 7229 if (delay <= 0) { 7230 Slog.w(TAG, "Activity manager shutdown timed out"); 7231 timedout = true; 7232 break; 7233 } 7234 try { 7235 this.wait(); 7236 } catch (InterruptedException e) { 7237 } 7238 } 7239 } 7240 } 7241 7242 mAppOpsService.shutdown(); 7243 mUsageStatsService.shutdown(); 7244 mBatteryStatsService.shutdown(); 7245 7246 return timedout; 7247 } 7248 7249 public final void activitySlept(IBinder token) { 7250 if (localLOGV) Slog.v( 7251 TAG, "Activity slept: token=" + token); 7252 7253 ActivityRecord r = null; 7254 7255 final long origId = Binder.clearCallingIdentity(); 7256 7257 synchronized (this) { 7258 r = mMainStack.isInStackLocked(token); 7259 if (r != null) { 7260 mMainStack.activitySleptLocked(r); 7261 } 7262 } 7263 7264 Binder.restoreCallingIdentity(origId); 7265 } 7266 7267 private void comeOutOfSleepIfNeededLocked() { 7268 if (!mWentToSleep && !mLockScreenShown) { 7269 if (mSleeping) { 7270 mSleeping = false; 7271 mMainStack.awakeFromSleepingLocked(); 7272 mMainStack.resumeTopActivityLocked(null); 7273 } 7274 } 7275 } 7276 7277 public void wakingUp() { 7278 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7279 != PackageManager.PERMISSION_GRANTED) { 7280 throw new SecurityException("Requires permission " 7281 + android.Manifest.permission.DEVICE_POWER); 7282 } 7283 7284 synchronized(this) { 7285 mWentToSleep = false; 7286 updateEventDispatchingLocked(); 7287 comeOutOfSleepIfNeededLocked(); 7288 } 7289 } 7290 7291 private void updateEventDispatchingLocked() { 7292 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7293 } 7294 7295 public void setLockScreenShown(boolean shown) { 7296 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7297 != PackageManager.PERMISSION_GRANTED) { 7298 throw new SecurityException("Requires permission " 7299 + android.Manifest.permission.DEVICE_POWER); 7300 } 7301 7302 synchronized(this) { 7303 mLockScreenShown = shown; 7304 comeOutOfSleepIfNeededLocked(); 7305 } 7306 } 7307 7308 public void stopAppSwitches() { 7309 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7310 != PackageManager.PERMISSION_GRANTED) { 7311 throw new SecurityException("Requires permission " 7312 + android.Manifest.permission.STOP_APP_SWITCHES); 7313 } 7314 7315 synchronized(this) { 7316 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7317 + APP_SWITCH_DELAY_TIME; 7318 mDidAppSwitch = false; 7319 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7320 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7321 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7322 } 7323 } 7324 7325 public void resumeAppSwitches() { 7326 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7327 != PackageManager.PERMISSION_GRANTED) { 7328 throw new SecurityException("Requires permission " 7329 + android.Manifest.permission.STOP_APP_SWITCHES); 7330 } 7331 7332 synchronized(this) { 7333 // Note that we don't execute any pending app switches... we will 7334 // let those wait until either the timeout, or the next start 7335 // activity request. 7336 mAppSwitchesAllowedTime = 0; 7337 } 7338 } 7339 7340 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7341 String name) { 7342 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7343 return true; 7344 } 7345 7346 final int perm = checkComponentPermission( 7347 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7348 callingUid, -1, true); 7349 if (perm == PackageManager.PERMISSION_GRANTED) { 7350 return true; 7351 } 7352 7353 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7354 return false; 7355 } 7356 7357 public void setDebugApp(String packageName, boolean waitForDebugger, 7358 boolean persistent) { 7359 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7360 "setDebugApp()"); 7361 7362 // Note that this is not really thread safe if there are multiple 7363 // callers into it at the same time, but that's not a situation we 7364 // care about. 7365 if (persistent) { 7366 final ContentResolver resolver = mContext.getContentResolver(); 7367 Settings.Global.putString( 7368 resolver, Settings.Global.DEBUG_APP, 7369 packageName); 7370 Settings.Global.putInt( 7371 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 7372 waitForDebugger ? 1 : 0); 7373 } 7374 7375 synchronized (this) { 7376 if (!persistent) { 7377 mOrigDebugApp = mDebugApp; 7378 mOrigWaitForDebugger = mWaitForDebugger; 7379 } 7380 mDebugApp = packageName; 7381 mWaitForDebugger = waitForDebugger; 7382 mDebugTransient = !persistent; 7383 if (packageName != null) { 7384 final long origId = Binder.clearCallingIdentity(); 7385 forceStopPackageLocked(packageName, -1, false, false, true, true, 7386 UserHandle.USER_ALL); 7387 Binder.restoreCallingIdentity(origId); 7388 } 7389 } 7390 } 7391 7392 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7393 synchronized (this) { 7394 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7395 if (!isDebuggable) { 7396 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7397 throw new SecurityException("Process not debuggable: " + app.packageName); 7398 } 7399 } 7400 7401 mOpenGlTraceApp = processName; 7402 } 7403 } 7404 7405 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7406 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7407 synchronized (this) { 7408 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7409 if (!isDebuggable) { 7410 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7411 throw new SecurityException("Process not debuggable: " + app.packageName); 7412 } 7413 } 7414 mProfileApp = processName; 7415 mProfileFile = profileFile; 7416 if (mProfileFd != null) { 7417 try { 7418 mProfileFd.close(); 7419 } catch (IOException e) { 7420 } 7421 mProfileFd = null; 7422 } 7423 mProfileFd = profileFd; 7424 mProfileType = 0; 7425 mAutoStopProfiler = autoStopProfiler; 7426 } 7427 } 7428 7429 public void setAlwaysFinish(boolean enabled) { 7430 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7431 "setAlwaysFinish()"); 7432 7433 Settings.Global.putInt( 7434 mContext.getContentResolver(), 7435 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7436 7437 synchronized (this) { 7438 mAlwaysFinishActivities = enabled; 7439 } 7440 } 7441 7442 public void setActivityController(IActivityController controller) { 7443 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7444 "setActivityController()"); 7445 synchronized (this) { 7446 mController = controller; 7447 Watchdog.getInstance().setActivityController(controller); 7448 } 7449 } 7450 7451 public void setUserIsMonkey(boolean userIsMonkey) { 7452 synchronized (this) { 7453 synchronized (mPidsSelfLocked) { 7454 final int callingPid = Binder.getCallingPid(); 7455 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 7456 if (precessRecord == null) { 7457 throw new SecurityException("Unknown process: " + callingPid); 7458 } 7459 if (precessRecord.instrumentationUiAutomationConnection == null) { 7460 throw new SecurityException("Only an instrumentation process " 7461 + "with a UiAutomation can call setUserIsMonkey"); 7462 } 7463 } 7464 mUserIsMonkey = userIsMonkey; 7465 } 7466 } 7467 7468 public boolean isUserAMonkey() { 7469 synchronized (this) { 7470 // If there is a controller also implies the user is a monkey. 7471 return (mUserIsMonkey || mController != null); 7472 } 7473 } 7474 7475 public void requestBugReport() { 7476 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 7477 SystemProperties.set("ctl.start", "bugreport"); 7478 } 7479 7480 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 7481 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 7482 } 7483 7484 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 7485 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 7486 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 7487 } 7488 return KEY_DISPATCHING_TIMEOUT; 7489 } 7490 7491 7492 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) { 7493 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7494 != PackageManager.PERMISSION_GRANTED) { 7495 throw new SecurityException("Requires permission " 7496 + android.Manifest.permission.FILTER_EVENTS); 7497 } 7498 ProcessRecord proc; 7499 long timeout; 7500 synchronized (this) { 7501 synchronized (mPidsSelfLocked) { 7502 proc = mPidsSelfLocked.get(pid); 7503 } 7504 timeout = getInputDispatchingTimeoutLocked(proc); 7505 } 7506 7507 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) { 7508 return -1; 7509 } 7510 7511 return timeout; 7512 } 7513 7514 /** 7515 * Handle input dispatching timeouts. 7516 * Returns whether input dispatching should be aborted or not. 7517 */ 7518 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 7519 final ActivityRecord activity, final ActivityRecord parent, 7520 final boolean aboveSystem) { 7521 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7522 != PackageManager.PERMISSION_GRANTED) { 7523 throw new SecurityException("Requires permission " 7524 + android.Manifest.permission.FILTER_EVENTS); 7525 } 7526 7527 if (proc != null) { 7528 synchronized (this) { 7529 if (proc.debugging) { 7530 return false; 7531 } 7532 7533 if (mDidDexOpt) { 7534 // Give more time since we were dexopting. 7535 mDidDexOpt = false; 7536 return false; 7537 } 7538 7539 if (proc.instrumentationClass != null) { 7540 Bundle info = new Bundle(); 7541 info.putString("shortMsg", "keyDispatchingTimedOut"); 7542 info.putString("longMsg", "Timed out while dispatching key event"); 7543 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 7544 return true; 7545 } 7546 } 7547 mHandler.post(new Runnable() { 7548 @Override 7549 public void run() { 7550 appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut"); 7551 } 7552 }); 7553 } 7554 7555 return true; 7556 } 7557 7558 public Bundle getTopActivityExtras(int requestType) { 7559 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 7560 "getTopActivityExtras()"); 7561 PendingActivityExtras pae; 7562 Bundle extras = new Bundle(); 7563 synchronized (this) { 7564 ActivityRecord activity = mMainStack.mResumedActivity; 7565 if (activity == null) { 7566 Slog.w(TAG, "getTopActivityExtras failed: no resumed activity"); 7567 return null; 7568 } 7569 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 7570 if (activity.app == null || activity.app.thread == null) { 7571 Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity); 7572 return extras; 7573 } 7574 if (activity.app.pid == Binder.getCallingPid()) { 7575 Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity); 7576 return extras; 7577 } 7578 pae = new PendingActivityExtras(activity); 7579 try { 7580 activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType); 7581 mPendingActivityExtras.add(pae); 7582 mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT); 7583 } catch (RemoteException e) { 7584 Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity); 7585 return extras; 7586 } 7587 } 7588 synchronized (pae) { 7589 while (!pae.haveResult) { 7590 try { 7591 pae.wait(); 7592 } catch (InterruptedException e) { 7593 } 7594 } 7595 if (pae.result != null) { 7596 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 7597 } 7598 } 7599 synchronized (this) { 7600 mPendingActivityExtras.remove(pae); 7601 mHandler.removeCallbacks(pae); 7602 } 7603 return extras; 7604 } 7605 7606 public void reportTopActivityExtras(IBinder token, Bundle extras) { 7607 PendingActivityExtras pae = (PendingActivityExtras)token; 7608 synchronized (pae) { 7609 pae.result = extras; 7610 pae.haveResult = true; 7611 pae.notifyAll(); 7612 } 7613 } 7614 7615 public void registerProcessObserver(IProcessObserver observer) { 7616 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7617 "registerProcessObserver()"); 7618 synchronized (this) { 7619 mProcessObservers.register(observer); 7620 } 7621 } 7622 7623 public void unregisterProcessObserver(IProcessObserver observer) { 7624 synchronized (this) { 7625 mProcessObservers.unregister(observer); 7626 } 7627 } 7628 7629 public void setImmersive(IBinder token, boolean immersive) { 7630 synchronized(this) { 7631 final ActivityRecord r = mMainStack.isInStackLocked(token); 7632 if (r == null) { 7633 throw new IllegalArgumentException(); 7634 } 7635 r.immersive = immersive; 7636 7637 // update associated state if we're frontmost 7638 if (r == mFocusedActivity) { 7639 if (DEBUG_IMMERSIVE) { 7640 Slog.d(TAG, "Frontmost changed immersion: "+ r); 7641 } 7642 applyUpdateLockStateLocked(r); 7643 } 7644 } 7645 } 7646 7647 public boolean isImmersive(IBinder token) { 7648 synchronized (this) { 7649 ActivityRecord r = mMainStack.isInStackLocked(token); 7650 if (r == null) { 7651 throw new IllegalArgumentException(); 7652 } 7653 return r.immersive; 7654 } 7655 } 7656 7657 public boolean isTopActivityImmersive() { 7658 enforceNotIsolatedCaller("startActivity"); 7659 synchronized (this) { 7660 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7661 return (r != null) ? r.immersive : false; 7662 } 7663 } 7664 7665 public final void enterSafeMode() { 7666 synchronized(this) { 7667 // It only makes sense to do this before the system is ready 7668 // and started launching other packages. 7669 if (!mSystemReady) { 7670 try { 7671 AppGlobals.getPackageManager().enterSafeMode(); 7672 } catch (RemoteException e) { 7673 } 7674 } 7675 } 7676 } 7677 7678 public final void showSafeModeOverlay() { 7679 View v = LayoutInflater.from(mContext).inflate( 7680 com.android.internal.R.layout.safe_mode, null); 7681 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7682 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7683 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7684 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7685 lp.gravity = Gravity.BOTTOM | Gravity.START; 7686 lp.format = v.getBackground().getOpacity(); 7687 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7688 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7689 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 7690 ((WindowManager)mContext.getSystemService( 7691 Context.WINDOW_SERVICE)).addView(v, lp); 7692 } 7693 7694 public void noteWakeupAlarm(IIntentSender sender) { 7695 if (!(sender instanceof PendingIntentRecord)) { 7696 return; 7697 } 7698 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7699 synchronized (stats) { 7700 if (mBatteryStatsService.isOnBattery()) { 7701 mBatteryStatsService.enforceCallingPermission(); 7702 PendingIntentRecord rec = (PendingIntentRecord)sender; 7703 int MY_UID = Binder.getCallingUid(); 7704 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7705 BatteryStatsImpl.Uid.Pkg pkg = 7706 stats.getPackageStatsLocked(uid, rec.key.packageName); 7707 pkg.incWakeupsLocked(); 7708 } 7709 } 7710 } 7711 7712 public boolean killPids(int[] pids, String pReason, boolean secure) { 7713 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7714 throw new SecurityException("killPids only available to the system"); 7715 } 7716 String reason = (pReason == null) ? "Unknown" : pReason; 7717 // XXX Note: don't acquire main activity lock here, because the window 7718 // manager calls in with its locks held. 7719 7720 boolean killed = false; 7721 synchronized (mPidsSelfLocked) { 7722 int[] types = new int[pids.length]; 7723 int worstType = 0; 7724 for (int i=0; i<pids.length; i++) { 7725 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7726 if (proc != null) { 7727 int type = proc.setAdj; 7728 types[i] = type; 7729 if (type > worstType) { 7730 worstType = type; 7731 } 7732 } 7733 } 7734 7735 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7736 // then constrain it so we will kill all hidden procs. 7737 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7738 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7739 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7740 } 7741 7742 // If this is not a secure call, don't let it kill processes that 7743 // are important. 7744 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7745 worstType = ProcessList.SERVICE_ADJ; 7746 } 7747 7748 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7749 for (int i=0; i<pids.length; i++) { 7750 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7751 if (proc == null) { 7752 continue; 7753 } 7754 int adj = proc.setAdj; 7755 if (adj >= worstType && !proc.killedBackground) { 7756 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7757 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7758 proc.processName, adj, reason); 7759 killed = true; 7760 proc.killedBackground = true; 7761 Process.killProcessQuiet(pids[i]); 7762 } 7763 } 7764 } 7765 return killed; 7766 } 7767 7768 @Override 7769 public void killUid(int uid, String reason) { 7770 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7771 throw new SecurityException("killUid only available to the system"); 7772 } 7773 synchronized (this) { 7774 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 7775 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 7776 reason != null ? reason : "kill uid"); 7777 } 7778 } 7779 7780 @Override 7781 public boolean killProcessesBelowForeground(String reason) { 7782 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7783 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7784 } 7785 7786 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7787 } 7788 7789 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7790 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7791 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7792 } 7793 7794 boolean killed = false; 7795 synchronized (mPidsSelfLocked) { 7796 final int size = mPidsSelfLocked.size(); 7797 for (int i = 0; i < size; i++) { 7798 final int pid = mPidsSelfLocked.keyAt(i); 7799 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7800 if (proc == null) continue; 7801 7802 final int adj = proc.setAdj; 7803 if (adj > belowAdj && !proc.killedBackground) { 7804 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7805 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7806 proc.pid, proc.processName, adj, reason); 7807 killed = true; 7808 proc.killedBackground = true; 7809 Process.killProcessQuiet(pid); 7810 } 7811 } 7812 } 7813 return killed; 7814 } 7815 7816 @Override 7817 public void hang(final IBinder who, boolean allowRestart) { 7818 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 7819 != PackageManager.PERMISSION_GRANTED) { 7820 throw new SecurityException("Requires permission " 7821 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 7822 } 7823 7824 final IBinder.DeathRecipient death = new DeathRecipient() { 7825 @Override 7826 public void binderDied() { 7827 synchronized (this) { 7828 notifyAll(); 7829 } 7830 } 7831 }; 7832 7833 try { 7834 who.linkToDeath(death, 0); 7835 } catch (RemoteException e) { 7836 Slog.w(TAG, "hang: given caller IBinder is already dead."); 7837 return; 7838 } 7839 7840 synchronized (this) { 7841 Watchdog.getInstance().setAllowRestart(allowRestart); 7842 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 7843 synchronized (death) { 7844 while (who.isBinderAlive()) { 7845 try { 7846 death.wait(); 7847 } catch (InterruptedException e) { 7848 } 7849 } 7850 } 7851 Watchdog.getInstance().setAllowRestart(true); 7852 } 7853 } 7854 7855 public final void startRunning(String pkg, String cls, String action, 7856 String data) { 7857 synchronized(this) { 7858 if (mStartRunning) { 7859 return; 7860 } 7861 mStartRunning = true; 7862 mTopComponent = pkg != null && cls != null 7863 ? new ComponentName(pkg, cls) : null; 7864 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7865 mTopData = data; 7866 if (!mSystemReady) { 7867 return; 7868 } 7869 } 7870 7871 systemReady(null); 7872 } 7873 7874 private void retrieveSettings() { 7875 final ContentResolver resolver = mContext.getContentResolver(); 7876 String debugApp = Settings.Global.getString( 7877 resolver, Settings.Global.DEBUG_APP); 7878 boolean waitForDebugger = Settings.Global.getInt( 7879 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 7880 boolean alwaysFinishActivities = Settings.Global.getInt( 7881 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7882 7883 Configuration configuration = new Configuration(); 7884 Settings.System.getConfiguration(resolver, configuration); 7885 7886 synchronized (this) { 7887 mDebugApp = mOrigDebugApp = debugApp; 7888 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7889 mAlwaysFinishActivities = alwaysFinishActivities; 7890 // This happens before any activities are started, so we can 7891 // change mConfiguration in-place. 7892 updateConfigurationLocked(configuration, null, false, true); 7893 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7894 } 7895 } 7896 7897 public boolean testIsSystemReady() { 7898 // no need to synchronize(this) just to read & return the value 7899 return mSystemReady; 7900 } 7901 7902 private static File getCalledPreBootReceiversFile() { 7903 File dataDir = Environment.getDataDirectory(); 7904 File systemDir = new File(dataDir, "system"); 7905 File fname = new File(systemDir, "called_pre_boots.dat"); 7906 return fname; 7907 } 7908 7909 static final int LAST_DONE_VERSION = 10000; 7910 7911 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7912 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7913 File file = getCalledPreBootReceiversFile(); 7914 FileInputStream fis = null; 7915 try { 7916 fis = new FileInputStream(file); 7917 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7918 int fvers = dis.readInt(); 7919 if (fvers == LAST_DONE_VERSION) { 7920 String vers = dis.readUTF(); 7921 String codename = dis.readUTF(); 7922 String build = dis.readUTF(); 7923 if (android.os.Build.VERSION.RELEASE.equals(vers) 7924 && android.os.Build.VERSION.CODENAME.equals(codename) 7925 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7926 int num = dis.readInt(); 7927 while (num > 0) { 7928 num--; 7929 String pkg = dis.readUTF(); 7930 String cls = dis.readUTF(); 7931 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7932 } 7933 } 7934 } 7935 } catch (FileNotFoundException e) { 7936 } catch (IOException e) { 7937 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7938 } finally { 7939 if (fis != null) { 7940 try { 7941 fis.close(); 7942 } catch (IOException e) { 7943 } 7944 } 7945 } 7946 return lastDoneReceivers; 7947 } 7948 7949 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7950 File file = getCalledPreBootReceiversFile(); 7951 FileOutputStream fos = null; 7952 DataOutputStream dos = null; 7953 try { 7954 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7955 fos = new FileOutputStream(file); 7956 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7957 dos.writeInt(LAST_DONE_VERSION); 7958 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7959 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7960 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7961 dos.writeInt(list.size()); 7962 for (int i=0; i<list.size(); i++) { 7963 dos.writeUTF(list.get(i).getPackageName()); 7964 dos.writeUTF(list.get(i).getClassName()); 7965 } 7966 } catch (IOException e) { 7967 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7968 file.delete(); 7969 } finally { 7970 FileUtils.sync(fos); 7971 if (dos != null) { 7972 try { 7973 dos.close(); 7974 } catch (IOException e) { 7975 // TODO Auto-generated catch block 7976 e.printStackTrace(); 7977 } 7978 } 7979 } 7980 } 7981 7982 public void systemReady(final Runnable goingCallback) { 7983 synchronized(this) { 7984 if (mSystemReady) { 7985 if (goingCallback != null) goingCallback.run(); 7986 return; 7987 } 7988 7989 // Check to see if there are any update receivers to run. 7990 if (!mDidUpdate) { 7991 if (mWaitingUpdate) { 7992 return; 7993 } 7994 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7995 List<ResolveInfo> ris = null; 7996 try { 7997 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7998 intent, null, 0, 0); 7999 } catch (RemoteException e) { 8000 } 8001 if (ris != null) { 8002 for (int i=ris.size()-1; i>=0; i--) { 8003 if ((ris.get(i).activityInfo.applicationInfo.flags 8004 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8005 ris.remove(i); 8006 } 8007 } 8008 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8009 8010 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 8011 8012 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 8013 for (int i=0; i<ris.size(); i++) { 8014 ActivityInfo ai = ris.get(i).activityInfo; 8015 ComponentName comp = new ComponentName(ai.packageName, ai.name); 8016 if (lastDoneReceivers.contains(comp)) { 8017 ris.remove(i); 8018 i--; 8019 } 8020 } 8021 8022 final int[] users = getUsersLocked(); 8023 for (int i=0; i<ris.size(); i++) { 8024 ActivityInfo ai = ris.get(i).activityInfo; 8025 ComponentName comp = new ComponentName(ai.packageName, ai.name); 8026 doneReceivers.add(comp); 8027 intent.setComponent(comp); 8028 for (int j=0; j<users.length; j++) { 8029 IIntentReceiver finisher = null; 8030 if (i == ris.size()-1 && j == users.length-1) { 8031 finisher = new IIntentReceiver.Stub() { 8032 public void performReceive(Intent intent, int resultCode, 8033 String data, Bundle extras, boolean ordered, 8034 boolean sticky, int sendingUser) { 8035 // The raw IIntentReceiver interface is called 8036 // with the AM lock held, so redispatch to 8037 // execute our code without the lock. 8038 mHandler.post(new Runnable() { 8039 public void run() { 8040 synchronized (ActivityManagerService.this) { 8041 mDidUpdate = true; 8042 } 8043 writeLastDonePreBootReceivers(doneReceivers); 8044 showBootMessage(mContext.getText( 8045 R.string.android_upgrading_complete), 8046 false); 8047 systemReady(goingCallback); 8048 } 8049 }); 8050 } 8051 }; 8052 } 8053 Slog.i(TAG, "Sending system update to " + intent.getComponent() 8054 + " for user " + users[j]); 8055 broadcastIntentLocked(null, null, intent, null, finisher, 8056 0, null, null, null, AppOpsManager.OP_NONE, 8057 true, false, MY_PID, Process.SYSTEM_UID, 8058 users[j]); 8059 if (finisher != null) { 8060 mWaitingUpdate = true; 8061 } 8062 } 8063 } 8064 } 8065 if (mWaitingUpdate) { 8066 return; 8067 } 8068 mDidUpdate = true; 8069 } 8070 8071 mAppOpsService.systemReady(); 8072 mSystemReady = true; 8073 if (!mStartRunning) { 8074 return; 8075 } 8076 } 8077 8078 ArrayList<ProcessRecord> procsToKill = null; 8079 synchronized(mPidsSelfLocked) { 8080 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8081 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8082 if (!isAllowedWhileBooting(proc.info)){ 8083 if (procsToKill == null) { 8084 procsToKill = new ArrayList<ProcessRecord>(); 8085 } 8086 procsToKill.add(proc); 8087 } 8088 } 8089 } 8090 8091 synchronized(this) { 8092 if (procsToKill != null) { 8093 for (int i=procsToKill.size()-1; i>=0; i--) { 8094 ProcessRecord proc = procsToKill.get(i); 8095 Slog.i(TAG, "Removing system update proc: " + proc); 8096 removeProcessLocked(proc, true, false, "system update done"); 8097 } 8098 } 8099 8100 // Now that we have cleaned up any update processes, we 8101 // are ready to start launching real processes and know that 8102 // we won't trample on them any more. 8103 mProcessesReady = true; 8104 } 8105 8106 Slog.i(TAG, "System now ready"); 8107 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 8108 SystemClock.uptimeMillis()); 8109 8110 synchronized(this) { 8111 // Make sure we have no pre-ready processes sitting around. 8112 8113 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8114 ResolveInfo ri = mContext.getPackageManager() 8115 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8116 STOCK_PM_FLAGS); 8117 CharSequence errorMsg = null; 8118 if (ri != null) { 8119 ActivityInfo ai = ri.activityInfo; 8120 ApplicationInfo app = ai.applicationInfo; 8121 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8122 mTopAction = Intent.ACTION_FACTORY_TEST; 8123 mTopData = null; 8124 mTopComponent = new ComponentName(app.packageName, 8125 ai.name); 8126 } else { 8127 errorMsg = mContext.getResources().getText( 8128 com.android.internal.R.string.factorytest_not_system); 8129 } 8130 } else { 8131 errorMsg = mContext.getResources().getText( 8132 com.android.internal.R.string.factorytest_no_action); 8133 } 8134 if (errorMsg != null) { 8135 mTopAction = null; 8136 mTopData = null; 8137 mTopComponent = null; 8138 Message msg = Message.obtain(); 8139 msg.what = SHOW_FACTORY_ERROR_MSG; 8140 msg.getData().putCharSequence("msg", errorMsg); 8141 mHandler.sendMessage(msg); 8142 } 8143 } 8144 } 8145 8146 retrieveSettings(); 8147 8148 if (goingCallback != null) goingCallback.run(); 8149 8150 synchronized (this) { 8151 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8152 try { 8153 List apps = AppGlobals.getPackageManager(). 8154 getPersistentApplications(STOCK_PM_FLAGS); 8155 if (apps != null) { 8156 int N = apps.size(); 8157 int i; 8158 for (i=0; i<N; i++) { 8159 ApplicationInfo info 8160 = (ApplicationInfo)apps.get(i); 8161 if (info != null && 8162 !info.packageName.equals("android")) { 8163 addAppLocked(info, false); 8164 } 8165 } 8166 } 8167 } catch (RemoteException ex) { 8168 // pm is in same process, this will never happen. 8169 } 8170 } 8171 8172 // Start up initial activity. 8173 mBooting = true; 8174 8175 try { 8176 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 8177 Message msg = Message.obtain(); 8178 msg.what = SHOW_UID_ERROR_MSG; 8179 mHandler.sendMessage(msg); 8180 } 8181 } catch (RemoteException e) { 8182 } 8183 8184 long ident = Binder.clearCallingIdentity(); 8185 try { 8186 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 8187 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 8188 | Intent.FLAG_RECEIVER_FOREGROUND); 8189 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 8190 broadcastIntentLocked(null, null, intent, 8191 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 8192 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 8193 intent = new Intent(Intent.ACTION_USER_STARTING); 8194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 8195 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 8196 broadcastIntentLocked(null, null, intent, 8197 null, new IIntentReceiver.Stub() { 8198 @Override 8199 public void performReceive(Intent intent, int resultCode, String data, 8200 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 8201 throws RemoteException { 8202 } 8203 }, 0, null, null, 8204 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 8205 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 8206 } finally { 8207 Binder.restoreCallingIdentity(ident); 8208 } 8209 mMainStack.resumeTopActivityLocked(null); 8210 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 8211 } 8212 } 8213 8214 private boolean makeAppCrashingLocked(ProcessRecord app, 8215 String shortMsg, String longMsg, String stackTrace) { 8216 app.crashing = true; 8217 app.crashingReport = generateProcessError(app, 8218 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 8219 startAppProblemLocked(app); 8220 app.stopFreezingAllLocked(); 8221 return handleAppCrashLocked(app); 8222 } 8223 8224 private void makeAppNotRespondingLocked(ProcessRecord app, 8225 String activity, String shortMsg, String longMsg) { 8226 app.notResponding = true; 8227 app.notRespondingReport = generateProcessError(app, 8228 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 8229 activity, shortMsg, longMsg, null); 8230 startAppProblemLocked(app); 8231 app.stopFreezingAllLocked(); 8232 } 8233 8234 /** 8235 * Generate a process error record, suitable for attachment to a ProcessRecord. 8236 * 8237 * @param app The ProcessRecord in which the error occurred. 8238 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8239 * ActivityManager.AppErrorStateInfo 8240 * @param activity The activity associated with the crash, if known. 8241 * @param shortMsg Short message describing the crash. 8242 * @param longMsg Long message describing the crash. 8243 * @param stackTrace Full crash stack trace, may be null. 8244 * 8245 * @return Returns a fully-formed AppErrorStateInfo record. 8246 */ 8247 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8248 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 8249 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8250 8251 report.condition = condition; 8252 report.processName = app.processName; 8253 report.pid = app.pid; 8254 report.uid = app.info.uid; 8255 report.tag = activity; 8256 report.shortMsg = shortMsg; 8257 report.longMsg = longMsg; 8258 report.stackTrace = stackTrace; 8259 8260 return report; 8261 } 8262 8263 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 8264 synchronized (this) { 8265 app.crashing = false; 8266 app.crashingReport = null; 8267 app.notResponding = false; 8268 app.notRespondingReport = null; 8269 if (app.anrDialog == fromDialog) { 8270 app.anrDialog = null; 8271 } 8272 if (app.waitDialog == fromDialog) { 8273 app.waitDialog = null; 8274 } 8275 if (app.pid > 0 && app.pid != MY_PID) { 8276 handleAppCrashLocked(app); 8277 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 8278 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 8279 app.processName, app.setAdj, "user's request after error"); 8280 Process.killProcessQuiet(app.pid); 8281 } 8282 } 8283 } 8284 8285 private boolean handleAppCrashLocked(ProcessRecord app) { 8286 if (mHeadless) { 8287 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 8288 return false; 8289 } 8290 long now = SystemClock.uptimeMillis(); 8291 8292 Long crashTime; 8293 if (!app.isolated) { 8294 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 8295 } else { 8296 crashTime = null; 8297 } 8298 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 8299 // This process loses! 8300 Slog.w(TAG, "Process " + app.info.processName 8301 + " has crashed too many times: killing!"); 8302 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8303 app.userId, app.info.processName, app.uid); 8304 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8305 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8306 if (r.app == app) { 8307 Slog.w(TAG, " Force finishing activity " 8308 + r.intent.getComponent().flattenToShortString()); 8309 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8310 null, "crashed", false); 8311 } 8312 } 8313 if (!app.persistent) { 8314 // We don't want to start this process again until the user 8315 // explicitly does so... but for persistent process, we really 8316 // need to keep it running. If a persistent process is actually 8317 // repeatedly crashing, then badness for everyone. 8318 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 8319 app.info.processName); 8320 if (!app.isolated) { 8321 // XXX We don't have a way to mark isolated processes 8322 // as bad, since they don't have a peristent identity. 8323 mBadProcesses.put(app.info.processName, app.uid, now); 8324 mProcessCrashTimes.remove(app.info.processName, app.uid); 8325 } 8326 app.bad = true; 8327 app.removed = true; 8328 // Don't let services in this process be restarted and potentially 8329 // annoy the user repeatedly. Unless it is persistent, since those 8330 // processes run critical code. 8331 removeProcessLocked(app, false, false, "crash"); 8332 mMainStack.resumeTopActivityLocked(null); 8333 return false; 8334 } 8335 mMainStack.resumeTopActivityLocked(null); 8336 } else { 8337 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8338 if (r != null && r.app == app) { 8339 // If the top running activity is from this crashing 8340 // process, then terminate it to avoid getting in a loop. 8341 Slog.w(TAG, " Force finishing activity " 8342 + r.intent.getComponent().flattenToShortString()); 8343 int index = mMainStack.indexOfActivityLocked(r); 8344 r.stack.finishActivityLocked(r, index, 8345 Activity.RESULT_CANCELED, null, "crashed", false); 8346 // Also terminate any activities below it that aren't yet 8347 // stopped, to avoid a situation where one will get 8348 // re-start our crashing activity once it gets resumed again. 8349 index--; 8350 if (index >= 0) { 8351 r = (ActivityRecord)mMainStack.mHistory.get(index); 8352 if (r.state == ActivityState.RESUMED 8353 || r.state == ActivityState.PAUSING 8354 || r.state == ActivityState.PAUSED) { 8355 if (!r.isHomeActivity || mHomeProcess != r.app) { 8356 Slog.w(TAG, " Force finishing activity " 8357 + r.intent.getComponent().flattenToShortString()); 8358 r.stack.finishActivityLocked(r, index, 8359 Activity.RESULT_CANCELED, null, "crashed", false); 8360 } 8361 } 8362 } 8363 } 8364 } 8365 8366 // Bump up the crash count of any services currently running in the proc. 8367 if (app.services.size() != 0) { 8368 // Any services running in the application need to be placed 8369 // back in the pending list. 8370 Iterator<ServiceRecord> it = app.services.iterator(); 8371 while (it.hasNext()) { 8372 ServiceRecord sr = it.next(); 8373 sr.crashCount++; 8374 } 8375 } 8376 8377 // If the crashing process is what we consider to be the "home process" and it has been 8378 // replaced by a third-party app, clear the package preferred activities from packages 8379 // with a home activity running in the process to prevent a repeatedly crashing app 8380 // from blocking the user to manually clear the list. 8381 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8382 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8383 Iterator it = mHomeProcess.activities.iterator(); 8384 while (it.hasNext()) { 8385 ActivityRecord r = (ActivityRecord)it.next(); 8386 if (r.isHomeActivity) { 8387 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8388 try { 8389 ActivityThread.getPackageManager() 8390 .clearPackagePreferredActivities(r.packageName); 8391 } catch (RemoteException c) { 8392 // pm is in same process, this will never happen. 8393 } 8394 } 8395 } 8396 } 8397 8398 if (!app.isolated) { 8399 // XXX Can't keep track of crash times for isolated processes, 8400 // because they don't have a perisistent identity. 8401 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8402 } 8403 8404 return true; 8405 } 8406 8407 void startAppProblemLocked(ProcessRecord app) { 8408 if (app.userId == mCurrentUserId) { 8409 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8410 mContext, app.info.packageName, app.info.flags); 8411 } else { 8412 // If this app is not running under the current user, then we 8413 // can't give it a report button because that would require 8414 // launching the report UI under a different user. 8415 app.errorReportReceiver = null; 8416 } 8417 skipCurrentReceiverLocked(app); 8418 } 8419 8420 void skipCurrentReceiverLocked(ProcessRecord app) { 8421 for (BroadcastQueue queue : mBroadcastQueues) { 8422 queue.skipCurrentReceiverLocked(app); 8423 } 8424 } 8425 8426 /** 8427 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8428 * The application process will exit immediately after this call returns. 8429 * @param app object of the crashing app, null for the system server 8430 * @param crashInfo describing the exception 8431 */ 8432 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8433 ProcessRecord r = findAppProcess(app, "Crash"); 8434 final String processName = app == null ? "system_server" 8435 : (r == null ? "unknown" : r.processName); 8436 8437 handleApplicationCrashInner("crash", r, processName, crashInfo); 8438 } 8439 8440 /* Native crash reporting uses this inner version because it needs to be somewhat 8441 * decoupled from the AM-managed cleanup lifecycle 8442 */ 8443 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 8444 ApplicationErrorReport.CrashInfo crashInfo) { 8445 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8446 UserHandle.getUserId(Binder.getCallingUid()), processName, 8447 r == null ? -1 : r.info.flags, 8448 crashInfo.exceptionClassName, 8449 crashInfo.exceptionMessage, 8450 crashInfo.throwFileName, 8451 crashInfo.throwLineNumber); 8452 8453 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 8454 8455 crashApplication(r, crashInfo); 8456 } 8457 8458 public void handleApplicationStrictModeViolation( 8459 IBinder app, 8460 int violationMask, 8461 StrictMode.ViolationInfo info) { 8462 ProcessRecord r = findAppProcess(app, "StrictMode"); 8463 if (r == null) { 8464 return; 8465 } 8466 8467 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8468 Integer stackFingerprint = info.hashCode(); 8469 boolean logIt = true; 8470 synchronized (mAlreadyLoggedViolatedStacks) { 8471 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8472 logIt = false; 8473 // TODO: sub-sample into EventLog for these, with 8474 // the info.durationMillis? Then we'd get 8475 // the relative pain numbers, without logging all 8476 // the stack traces repeatedly. We'd want to do 8477 // likewise in the client code, which also does 8478 // dup suppression, before the Binder call. 8479 } else { 8480 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8481 mAlreadyLoggedViolatedStacks.clear(); 8482 } 8483 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8484 } 8485 } 8486 if (logIt) { 8487 logStrictModeViolationToDropBox(r, info); 8488 } 8489 } 8490 8491 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8492 AppErrorResult result = new AppErrorResult(); 8493 synchronized (this) { 8494 final long origId = Binder.clearCallingIdentity(); 8495 8496 Message msg = Message.obtain(); 8497 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8498 HashMap<String, Object> data = new HashMap<String, Object>(); 8499 data.put("result", result); 8500 data.put("app", r); 8501 data.put("violationMask", violationMask); 8502 data.put("info", info); 8503 msg.obj = data; 8504 mHandler.sendMessage(msg); 8505 8506 Binder.restoreCallingIdentity(origId); 8507 } 8508 int res = result.get(); 8509 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8510 } 8511 } 8512 8513 // Depending on the policy in effect, there could be a bunch of 8514 // these in quick succession so we try to batch these together to 8515 // minimize disk writes, number of dropbox entries, and maximize 8516 // compression, by having more fewer, larger records. 8517 private void logStrictModeViolationToDropBox( 8518 ProcessRecord process, 8519 StrictMode.ViolationInfo info) { 8520 if (info == null) { 8521 return; 8522 } 8523 final boolean isSystemApp = process == null || 8524 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8525 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8526 final String processName = process == null ? "unknown" : process.processName; 8527 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8528 final DropBoxManager dbox = (DropBoxManager) 8529 mContext.getSystemService(Context.DROPBOX_SERVICE); 8530 8531 // Exit early if the dropbox isn't configured to accept this report type. 8532 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8533 8534 boolean bufferWasEmpty; 8535 boolean needsFlush; 8536 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8537 synchronized (sb) { 8538 bufferWasEmpty = sb.length() == 0; 8539 appendDropBoxProcessHeaders(process, processName, sb); 8540 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8541 sb.append("System-App: ").append(isSystemApp).append("\n"); 8542 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8543 if (info.violationNumThisLoop != 0) { 8544 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8545 } 8546 if (info.numAnimationsRunning != 0) { 8547 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8548 } 8549 if (info.broadcastIntentAction != null) { 8550 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8551 } 8552 if (info.durationMillis != -1) { 8553 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8554 } 8555 if (info.numInstances != -1) { 8556 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8557 } 8558 if (info.tags != null) { 8559 for (String tag : info.tags) { 8560 sb.append("Span-Tag: ").append(tag).append("\n"); 8561 } 8562 } 8563 sb.append("\n"); 8564 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8565 sb.append(info.crashInfo.stackTrace); 8566 } 8567 sb.append("\n"); 8568 8569 // Only buffer up to ~64k. Various logging bits truncate 8570 // things at 128k. 8571 needsFlush = (sb.length() > 64 * 1024); 8572 } 8573 8574 // Flush immediately if the buffer's grown too large, or this 8575 // is a non-system app. Non-system apps are isolated with a 8576 // different tag & policy and not batched. 8577 // 8578 // Batching is useful during internal testing with 8579 // StrictMode settings turned up high. Without batching, 8580 // thousands of separate files could be created on boot. 8581 if (!isSystemApp || needsFlush) { 8582 new Thread("Error dump: " + dropboxTag) { 8583 @Override 8584 public void run() { 8585 String report; 8586 synchronized (sb) { 8587 report = sb.toString(); 8588 sb.delete(0, sb.length()); 8589 sb.trimToSize(); 8590 } 8591 if (report.length() != 0) { 8592 dbox.addText(dropboxTag, report); 8593 } 8594 } 8595 }.start(); 8596 return; 8597 } 8598 8599 // System app batching: 8600 if (!bufferWasEmpty) { 8601 // An existing dropbox-writing thread is outstanding, so 8602 // we don't need to start it up. The existing thread will 8603 // catch the buffer appends we just did. 8604 return; 8605 } 8606 8607 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8608 // (After this point, we shouldn't access AMS internal data structures.) 8609 new Thread("Error dump: " + dropboxTag) { 8610 @Override 8611 public void run() { 8612 // 5 second sleep to let stacks arrive and be batched together 8613 try { 8614 Thread.sleep(5000); // 5 seconds 8615 } catch (InterruptedException e) {} 8616 8617 String errorReport; 8618 synchronized (mStrictModeBuffer) { 8619 errorReport = mStrictModeBuffer.toString(); 8620 if (errorReport.length() == 0) { 8621 return; 8622 } 8623 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8624 mStrictModeBuffer.trimToSize(); 8625 } 8626 dbox.addText(dropboxTag, errorReport); 8627 } 8628 }.start(); 8629 } 8630 8631 /** 8632 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8633 * @param app object of the crashing app, null for the system server 8634 * @param tag reported by the caller 8635 * @param crashInfo describing the context of the error 8636 * @return true if the process should exit immediately (WTF is fatal) 8637 */ 8638 public boolean handleApplicationWtf(IBinder app, String tag, 8639 ApplicationErrorReport.CrashInfo crashInfo) { 8640 ProcessRecord r = findAppProcess(app, "WTF"); 8641 final String processName = app == null ? "system_server" 8642 : (r == null ? "unknown" : r.processName); 8643 8644 EventLog.writeEvent(EventLogTags.AM_WTF, 8645 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8646 processName, 8647 r == null ? -1 : r.info.flags, 8648 tag, crashInfo.exceptionMessage); 8649 8650 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8651 8652 if (r != null && r.pid != Process.myPid() && 8653 Settings.Global.getInt(mContext.getContentResolver(), 8654 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8655 crashApplication(r, crashInfo); 8656 return true; 8657 } else { 8658 return false; 8659 } 8660 } 8661 8662 /** 8663 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8664 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8665 */ 8666 private ProcessRecord findAppProcess(IBinder app, String reason) { 8667 if (app == null) { 8668 return null; 8669 } 8670 8671 synchronized (this) { 8672 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8673 final int NA = apps.size(); 8674 for (int ia=0; ia<NA; ia++) { 8675 ProcessRecord p = apps.valueAt(ia); 8676 if (p.thread != null && p.thread.asBinder() == app) { 8677 return p; 8678 } 8679 } 8680 } 8681 8682 Slog.w(TAG, "Can't find mystery application for " + reason 8683 + " from pid=" + Binder.getCallingPid() 8684 + " uid=" + Binder.getCallingUid() + ": " + app); 8685 return null; 8686 } 8687 } 8688 8689 /** 8690 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8691 * to append various headers to the dropbox log text. 8692 */ 8693 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8694 StringBuilder sb) { 8695 // Watchdog thread ends up invoking this function (with 8696 // a null ProcessRecord) to add the stack file to dropbox. 8697 // Do not acquire a lock on this (am) in such cases, as it 8698 // could cause a potential deadlock, if and when watchdog 8699 // is invoked due to unavailability of lock on am and it 8700 // would prevent watchdog from killing system_server. 8701 if (process == null) { 8702 sb.append("Process: ").append(processName).append("\n"); 8703 return; 8704 } 8705 // Note: ProcessRecord 'process' is guarded by the service 8706 // instance. (notably process.pkgList, which could otherwise change 8707 // concurrently during execution of this method) 8708 synchronized (this) { 8709 sb.append("Process: ").append(processName).append("\n"); 8710 int flags = process.info.flags; 8711 IPackageManager pm = AppGlobals.getPackageManager(); 8712 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8713 for (String pkg : process.pkgList) { 8714 sb.append("Package: ").append(pkg); 8715 try { 8716 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8717 if (pi != null) { 8718 sb.append(" v").append(pi.versionCode); 8719 if (pi.versionName != null) { 8720 sb.append(" (").append(pi.versionName).append(")"); 8721 } 8722 } 8723 } catch (RemoteException e) { 8724 Slog.e(TAG, "Error getting package info: " + pkg, e); 8725 } 8726 sb.append("\n"); 8727 } 8728 } 8729 } 8730 8731 private static String processClass(ProcessRecord process) { 8732 if (process == null || process.pid == MY_PID) { 8733 return "system_server"; 8734 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8735 return "system_app"; 8736 } else { 8737 return "data_app"; 8738 } 8739 } 8740 8741 /** 8742 * Write a description of an error (crash, WTF, ANR) to the drop box. 8743 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8744 * @param process which caused the error, null means the system server 8745 * @param activity which triggered the error, null if unknown 8746 * @param parent activity related to the error, null if unknown 8747 * @param subject line related to the error, null if absent 8748 * @param report in long form describing the error, null if absent 8749 * @param logFile to include in the report, null if none 8750 * @param crashInfo giving an application stack trace, null if absent 8751 */ 8752 public void addErrorToDropBox(String eventType, 8753 ProcessRecord process, String processName, ActivityRecord activity, 8754 ActivityRecord parent, String subject, 8755 final String report, final File logFile, 8756 final ApplicationErrorReport.CrashInfo crashInfo) { 8757 // NOTE -- this must never acquire the ActivityManagerService lock, 8758 // otherwise the watchdog may be prevented from resetting the system. 8759 8760 final String dropboxTag = processClass(process) + "_" + eventType; 8761 final DropBoxManager dbox = (DropBoxManager) 8762 mContext.getSystemService(Context.DROPBOX_SERVICE); 8763 8764 // Exit early if the dropbox isn't configured to accept this report type. 8765 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8766 8767 final StringBuilder sb = new StringBuilder(1024); 8768 appendDropBoxProcessHeaders(process, processName, sb); 8769 if (activity != null) { 8770 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8771 } 8772 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8773 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8774 } 8775 if (parent != null && parent != activity) { 8776 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8777 } 8778 if (subject != null) { 8779 sb.append("Subject: ").append(subject).append("\n"); 8780 } 8781 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8782 if (Debug.isDebuggerConnected()) { 8783 sb.append("Debugger: Connected\n"); 8784 } 8785 sb.append("\n"); 8786 8787 // Do the rest in a worker thread to avoid blocking the caller on I/O 8788 // (After this point, we shouldn't access AMS internal data structures.) 8789 Thread worker = new Thread("Error dump: " + dropboxTag) { 8790 @Override 8791 public void run() { 8792 if (report != null) { 8793 sb.append(report); 8794 } 8795 if (logFile != null) { 8796 try { 8797 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8798 } catch (IOException e) { 8799 Slog.e(TAG, "Error reading " + logFile, e); 8800 } 8801 } 8802 if (crashInfo != null && crashInfo.stackTrace != null) { 8803 sb.append(crashInfo.stackTrace); 8804 } 8805 8806 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8807 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8808 if (lines > 0) { 8809 sb.append("\n"); 8810 8811 // Merge several logcat streams, and take the last N lines 8812 InputStreamReader input = null; 8813 try { 8814 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8815 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8816 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8817 8818 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8819 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8820 input = new InputStreamReader(logcat.getInputStream()); 8821 8822 int num; 8823 char[] buf = new char[8192]; 8824 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8825 } catch (IOException e) { 8826 Slog.e(TAG, "Error running logcat", e); 8827 } finally { 8828 if (input != null) try { input.close(); } catch (IOException e) {} 8829 } 8830 } 8831 8832 dbox.addText(dropboxTag, sb.toString()); 8833 } 8834 }; 8835 8836 if (process == null) { 8837 // If process is null, we are being called from some internal code 8838 // and may be about to die -- run this synchronously. 8839 worker.run(); 8840 } else { 8841 worker.start(); 8842 } 8843 } 8844 8845 /** 8846 * Bring up the "unexpected error" dialog box for a crashing app. 8847 * Deal with edge cases (intercepts from instrumented applications, 8848 * ActivityController, error intent receivers, that sort of thing). 8849 * @param r the application crashing 8850 * @param crashInfo describing the failure 8851 */ 8852 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8853 long timeMillis = System.currentTimeMillis(); 8854 String shortMsg = crashInfo.exceptionClassName; 8855 String longMsg = crashInfo.exceptionMessage; 8856 String stackTrace = crashInfo.stackTrace; 8857 if (shortMsg != null && longMsg != null) { 8858 longMsg = shortMsg + ": " + longMsg; 8859 } else if (shortMsg != null) { 8860 longMsg = shortMsg; 8861 } 8862 8863 AppErrorResult result = new AppErrorResult(); 8864 synchronized (this) { 8865 if (mController != null) { 8866 try { 8867 String name = r != null ? r.processName : null; 8868 int pid = r != null ? r.pid : Binder.getCallingPid(); 8869 if (!mController.appCrashed(name, pid, 8870 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8871 Slog.w(TAG, "Force-killing crashed app " + name 8872 + " at watcher's request"); 8873 Process.killProcess(pid); 8874 return; 8875 } 8876 } catch (RemoteException e) { 8877 mController = null; 8878 Watchdog.getInstance().setActivityController(null); 8879 } 8880 } 8881 8882 final long origId = Binder.clearCallingIdentity(); 8883 8884 // If this process is running instrumentation, finish it. 8885 if (r != null && r.instrumentationClass != null) { 8886 Slog.w(TAG, "Error in app " + r.processName 8887 + " running instrumentation " + r.instrumentationClass + ":"); 8888 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8889 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8890 Bundle info = new Bundle(); 8891 info.putString("shortMsg", shortMsg); 8892 info.putString("longMsg", longMsg); 8893 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8894 Binder.restoreCallingIdentity(origId); 8895 return; 8896 } 8897 8898 // If we can't identify the process or it's already exceeded its crash quota, 8899 // quit right away without showing a crash dialog. 8900 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8901 Binder.restoreCallingIdentity(origId); 8902 return; 8903 } 8904 8905 Message msg = Message.obtain(); 8906 msg.what = SHOW_ERROR_MSG; 8907 HashMap data = new HashMap(); 8908 data.put("result", result); 8909 data.put("app", r); 8910 msg.obj = data; 8911 mHandler.sendMessage(msg); 8912 8913 Binder.restoreCallingIdentity(origId); 8914 } 8915 8916 int res = result.get(); 8917 8918 Intent appErrorIntent = null; 8919 synchronized (this) { 8920 if (r != null && !r.isolated) { 8921 // XXX Can't keep track of crash time for isolated processes, 8922 // since they don't have a persistent identity. 8923 mProcessCrashTimes.put(r.info.processName, r.uid, 8924 SystemClock.uptimeMillis()); 8925 } 8926 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8927 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8928 } 8929 } 8930 8931 if (appErrorIntent != null) { 8932 try { 8933 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8934 } catch (ActivityNotFoundException e) { 8935 Slog.w(TAG, "bug report receiver dissappeared", e); 8936 } 8937 } 8938 } 8939 8940 Intent createAppErrorIntentLocked(ProcessRecord r, 8941 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8942 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8943 if (report == null) { 8944 return null; 8945 } 8946 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8947 result.setComponent(r.errorReportReceiver); 8948 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8949 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8950 return result; 8951 } 8952 8953 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8954 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8955 if (r.errorReportReceiver == null) { 8956 return null; 8957 } 8958 8959 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 8960 return null; 8961 } 8962 8963 ApplicationErrorReport report = new ApplicationErrorReport(); 8964 report.packageName = r.info.packageName; 8965 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8966 report.processName = r.processName; 8967 report.time = timeMillis; 8968 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8969 8970 if (r.crashing || r.forceCrashReport) { 8971 report.type = ApplicationErrorReport.TYPE_CRASH; 8972 report.crashInfo = crashInfo; 8973 } else if (r.notResponding) { 8974 report.type = ApplicationErrorReport.TYPE_ANR; 8975 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8976 8977 report.anrInfo.activity = r.notRespondingReport.tag; 8978 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8979 report.anrInfo.info = r.notRespondingReport.longMsg; 8980 } 8981 8982 return report; 8983 } 8984 8985 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8986 enforceNotIsolatedCaller("getProcessesInErrorState"); 8987 // assume our apps are happy - lazy create the list 8988 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8989 8990 final boolean allUsers = ActivityManager.checkUidPermission( 8991 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8992 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8993 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8994 8995 synchronized (this) { 8996 8997 // iterate across all processes 8998 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8999 ProcessRecord app = mLruProcesses.get(i); 9000 if (!allUsers && app.userId != userId) { 9001 continue; 9002 } 9003 if ((app.thread != null) && (app.crashing || app.notResponding)) { 9004 // This one's in trouble, so we'll generate a report for it 9005 // crashes are higher priority (in case there's a crash *and* an anr) 9006 ActivityManager.ProcessErrorStateInfo report = null; 9007 if (app.crashing) { 9008 report = app.crashingReport; 9009 } else if (app.notResponding) { 9010 report = app.notRespondingReport; 9011 } 9012 9013 if (report != null) { 9014 if (errList == null) { 9015 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 9016 } 9017 errList.add(report); 9018 } else { 9019 Slog.w(TAG, "Missing app error report, app = " + app.processName + 9020 " crashing = " + app.crashing + 9021 " notResponding = " + app.notResponding); 9022 } 9023 } 9024 } 9025 } 9026 9027 return errList; 9028 } 9029 9030 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 9031 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9032 if (currApp != null) { 9033 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 9034 } 9035 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9036 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 9037 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9038 } else if (adj >= ProcessList.HOME_APP_ADJ) { 9039 if (currApp != null) { 9040 currApp.lru = 0; 9041 } 9042 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9043 } else if (adj >= ProcessList.SERVICE_ADJ) { 9044 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9045 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9046 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 9047 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9048 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 9049 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 9050 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9051 } else { 9052 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9053 } 9054 } 9055 9056 private void fillInProcMemInfo(ProcessRecord app, 9057 ActivityManager.RunningAppProcessInfo outInfo) { 9058 outInfo.pid = app.pid; 9059 outInfo.uid = app.info.uid; 9060 if (mHeavyWeightProcess == app) { 9061 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 9062 } 9063 if (app.persistent) { 9064 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 9065 } 9066 if (app.hasActivities) { 9067 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 9068 } 9069 outInfo.lastTrimLevel = app.trimMemoryLevel; 9070 int adj = app.curAdj; 9071 outInfo.importance = oomAdjToImportance(adj, outInfo); 9072 outInfo.importanceReasonCode = app.adjTypeCode; 9073 } 9074 9075 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9076 enforceNotIsolatedCaller("getRunningAppProcesses"); 9077 // Lazy instantiation of list 9078 List<ActivityManager.RunningAppProcessInfo> runList = null; 9079 final boolean allUsers = ActivityManager.checkUidPermission( 9080 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 9081 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 9082 int userId = UserHandle.getUserId(Binder.getCallingUid()); 9083 synchronized (this) { 9084 // Iterate across all processes 9085 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9086 ProcessRecord app = mLruProcesses.get(i); 9087 if (!allUsers && app.userId != userId) { 9088 continue; 9089 } 9090 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9091 // Generate process state info for running application 9092 ActivityManager.RunningAppProcessInfo currApp = 9093 new ActivityManager.RunningAppProcessInfo(app.processName, 9094 app.pid, app.getPackageList()); 9095 fillInProcMemInfo(app, currApp); 9096 if (app.adjSource instanceof ProcessRecord) { 9097 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9098 currApp.importanceReasonImportance = oomAdjToImportance( 9099 app.adjSourceOom, null); 9100 } else if (app.adjSource instanceof ActivityRecord) { 9101 ActivityRecord r = (ActivityRecord)app.adjSource; 9102 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9103 } 9104 if (app.adjTarget instanceof ComponentName) { 9105 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9106 } 9107 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9108 // + " lru=" + currApp.lru); 9109 if (runList == null) { 9110 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9111 } 9112 runList.add(currApp); 9113 } 9114 } 9115 } 9116 return runList; 9117 } 9118 9119 public List<ApplicationInfo> getRunningExternalApplications() { 9120 enforceNotIsolatedCaller("getRunningExternalApplications"); 9121 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 9122 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 9123 if (runningApps != null && runningApps.size() > 0) { 9124 Set<String> extList = new HashSet<String>(); 9125 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 9126 if (app.pkgList != null) { 9127 for (String pkg : app.pkgList) { 9128 extList.add(pkg); 9129 } 9130 } 9131 } 9132 IPackageManager pm = AppGlobals.getPackageManager(); 9133 for (String pkg : extList) { 9134 try { 9135 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 9136 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 9137 retList.add(info); 9138 } 9139 } catch (RemoteException e) { 9140 } 9141 } 9142 } 9143 return retList; 9144 } 9145 9146 @Override 9147 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 9148 enforceNotIsolatedCaller("getMyMemoryState"); 9149 synchronized (this) { 9150 ProcessRecord proc; 9151 synchronized (mPidsSelfLocked) { 9152 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 9153 } 9154 fillInProcMemInfo(proc, outInfo); 9155 } 9156 } 9157 9158 @Override 9159 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9160 if (checkCallingPermission(android.Manifest.permission.DUMP) 9161 != PackageManager.PERMISSION_GRANTED) { 9162 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9163 + Binder.getCallingPid() 9164 + ", uid=" + Binder.getCallingUid() 9165 + " without permission " 9166 + android.Manifest.permission.DUMP); 9167 return; 9168 } 9169 9170 boolean dumpAll = false; 9171 boolean dumpClient = false; 9172 String dumpPackage = null; 9173 9174 int opti = 0; 9175 while (opti < args.length) { 9176 String opt = args[opti]; 9177 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9178 break; 9179 } 9180 opti++; 9181 if ("-a".equals(opt)) { 9182 dumpAll = true; 9183 } else if ("-c".equals(opt)) { 9184 dumpClient = true; 9185 } else if ("-h".equals(opt)) { 9186 pw.println("Activity manager dump options:"); 9187 pw.println(" [-a] [-c] [-h] [cmd] ..."); 9188 pw.println(" cmd may be one of:"); 9189 pw.println(" a[ctivities]: activity stack state"); 9190 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 9191 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 9192 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 9193 pw.println(" o[om]: out of memory management"); 9194 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 9195 pw.println(" provider [COMP_SPEC]: provider client-side state"); 9196 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 9197 pw.println(" service [COMP_SPEC]: service client-side state"); 9198 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 9199 pw.println(" all: dump all activities"); 9200 pw.println(" top: dump the top activity"); 9201 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 9202 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 9203 pw.println(" a partial substring in a component name, a"); 9204 pw.println(" hex object identifier."); 9205 pw.println(" -a: include all available server state."); 9206 pw.println(" -c: include client state."); 9207 return; 9208 } else { 9209 pw.println("Unknown argument: " + opt + "; use -h for help"); 9210 } 9211 } 9212 9213 long origId = Binder.clearCallingIdentity(); 9214 boolean more = false; 9215 // Is the caller requesting to dump a particular piece of data? 9216 if (opti < args.length) { 9217 String cmd = args[opti]; 9218 opti++; 9219 if ("activities".equals(cmd) || "a".equals(cmd)) { 9220 synchronized (this) { 9221 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 9222 } 9223 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 9224 String[] newArgs; 9225 String name; 9226 if (opti >= args.length) { 9227 name = null; 9228 newArgs = EMPTY_STRING_ARRAY; 9229 } else { 9230 name = args[opti]; 9231 opti++; 9232 newArgs = new String[args.length - opti]; 9233 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9234 args.length - opti); 9235 } 9236 synchronized (this) { 9237 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 9238 } 9239 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 9240 String[] newArgs; 9241 String name; 9242 if (opti >= args.length) { 9243 name = null; 9244 newArgs = EMPTY_STRING_ARRAY; 9245 } else { 9246 name = args[opti]; 9247 opti++; 9248 newArgs = new String[args.length - opti]; 9249 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9250 args.length - opti); 9251 } 9252 synchronized (this) { 9253 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 9254 } 9255 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 9256 String[] newArgs; 9257 String name; 9258 if (opti >= args.length) { 9259 name = null; 9260 newArgs = EMPTY_STRING_ARRAY; 9261 } else { 9262 name = args[opti]; 9263 opti++; 9264 newArgs = new String[args.length - opti]; 9265 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9266 args.length - opti); 9267 } 9268 synchronized (this) { 9269 dumpProcessesLocked(fd, pw, args, opti, true, name); 9270 } 9271 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 9272 synchronized (this) { 9273 dumpOomLocked(fd, pw, args, opti, true); 9274 } 9275 } else if ("provider".equals(cmd)) { 9276 String[] newArgs; 9277 String name; 9278 if (opti >= args.length) { 9279 name = null; 9280 newArgs = EMPTY_STRING_ARRAY; 9281 } else { 9282 name = args[opti]; 9283 opti++; 9284 newArgs = new String[args.length - opti]; 9285 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9286 } 9287 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 9288 pw.println("No providers match: " + name); 9289 pw.println("Use -h for help."); 9290 } 9291 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9292 synchronized (this) { 9293 dumpProvidersLocked(fd, pw, args, opti, true, null); 9294 } 9295 } else if ("service".equals(cmd)) { 9296 String[] newArgs; 9297 String name; 9298 if (opti >= args.length) { 9299 name = null; 9300 newArgs = EMPTY_STRING_ARRAY; 9301 } else { 9302 name = args[opti]; 9303 opti++; 9304 newArgs = new String[args.length - opti]; 9305 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9306 args.length - opti); 9307 } 9308 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 9309 pw.println("No services match: " + name); 9310 pw.println("Use -h for help."); 9311 } 9312 } else if ("package".equals(cmd)) { 9313 String[] newArgs; 9314 if (opti >= args.length) { 9315 pw.println("package: no package name specified"); 9316 pw.println("Use -h for help."); 9317 } else { 9318 dumpPackage = args[opti]; 9319 opti++; 9320 newArgs = new String[args.length - opti]; 9321 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9322 args.length - opti); 9323 args = newArgs; 9324 opti = 0; 9325 more = true; 9326 } 9327 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9328 synchronized (this) { 9329 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9330 } 9331 } else { 9332 // Dumping a single activity? 9333 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9334 pw.println("Bad activity command, or no activities match: " + cmd); 9335 pw.println("Use -h for help."); 9336 } 9337 } 9338 if (!more) { 9339 Binder.restoreCallingIdentity(origId); 9340 return; 9341 } 9342 } 9343 9344 // No piece of data specified, dump everything. 9345 synchronized (this) { 9346 boolean needSep; 9347 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9348 if (needSep) { 9349 pw.println(" "); 9350 } 9351 if (dumpAll) { 9352 pw.println("-------------------------------------------------------------------------------"); 9353 } 9354 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9355 if (needSep) { 9356 pw.println(" "); 9357 } 9358 if (dumpAll) { 9359 pw.println("-------------------------------------------------------------------------------"); 9360 } 9361 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9362 if (needSep) { 9363 pw.println(" "); 9364 } 9365 if (dumpAll) { 9366 pw.println("-------------------------------------------------------------------------------"); 9367 } 9368 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9369 if (needSep) { 9370 pw.println(" "); 9371 } 9372 if (dumpAll) { 9373 pw.println("-------------------------------------------------------------------------------"); 9374 } 9375 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9376 if (needSep) { 9377 pw.println(" "); 9378 } 9379 if (dumpAll) { 9380 pw.println("-------------------------------------------------------------------------------"); 9381 } 9382 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9383 } 9384 Binder.restoreCallingIdentity(origId); 9385 } 9386 9387 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9388 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9389 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9390 pw.println(" Main stack:"); 9391 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9392 dumpPackage); 9393 pw.println(" "); 9394 pw.println(" Running activities (most recent first):"); 9395 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9396 dumpPackage); 9397 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9398 pw.println(" "); 9399 pw.println(" Activities waiting for another to become visible:"); 9400 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9401 !dumpAll, false, dumpPackage); 9402 } 9403 if (mMainStack.mStoppingActivities.size() > 0) { 9404 pw.println(" "); 9405 pw.println(" Activities waiting to stop:"); 9406 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9407 !dumpAll, false, dumpPackage); 9408 } 9409 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9410 pw.println(" "); 9411 pw.println(" Activities waiting to sleep:"); 9412 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9413 !dumpAll, false, dumpPackage); 9414 } 9415 if (mMainStack.mFinishingActivities.size() > 0) { 9416 pw.println(" "); 9417 pw.println(" Activities waiting to finish:"); 9418 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9419 !dumpAll, false, dumpPackage); 9420 } 9421 9422 pw.println(" "); 9423 if (mMainStack.mPausingActivity != null) { 9424 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9425 } 9426 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9427 pw.println(" mFocusedActivity: " + mFocusedActivity); 9428 if (dumpAll) { 9429 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9430 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9431 pw.println(" mDismissKeyguardOnNextActivity: " 9432 + mMainStack.mDismissKeyguardOnNextActivity); 9433 } 9434 9435 if (mRecentTasks.size() > 0) { 9436 pw.println(); 9437 pw.println(" Recent tasks:"); 9438 9439 final int N = mRecentTasks.size(); 9440 for (int i=0; i<N; i++) { 9441 TaskRecord tr = mRecentTasks.get(i); 9442 if (dumpPackage != null) { 9443 if (tr.realActivity == null || 9444 !dumpPackage.equals(tr.realActivity)) { 9445 continue; 9446 } 9447 } 9448 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9449 pw.println(tr); 9450 if (dumpAll) { 9451 mRecentTasks.get(i).dump(pw, " "); 9452 } 9453 } 9454 } 9455 9456 if (dumpAll) { 9457 pw.println(" "); 9458 pw.println(" mCurTask: " + mCurTask); 9459 } 9460 9461 return true; 9462 } 9463 9464 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9465 int opti, boolean dumpAll, String dumpPackage) { 9466 boolean needSep = false; 9467 int numPers = 0; 9468 9469 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9470 9471 if (dumpAll) { 9472 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9473 final int NA = procs.size(); 9474 for (int ia=0; ia<NA; ia++) { 9475 ProcessRecord r = procs.valueAt(ia); 9476 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9477 continue; 9478 } 9479 if (!needSep) { 9480 pw.println(" All known processes:"); 9481 needSep = true; 9482 } 9483 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9484 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9485 pw.print(" "); pw.println(r); 9486 r.dump(pw, " "); 9487 if (r.persistent) { 9488 numPers++; 9489 } 9490 } 9491 } 9492 } 9493 9494 if (mIsolatedProcesses.size() > 0) { 9495 if (needSep) pw.println(" "); 9496 needSep = true; 9497 pw.println(" Isolated process list (sorted by uid):"); 9498 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9499 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9500 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9501 continue; 9502 } 9503 pw.println(String.format("%sIsolated #%2d: %s", 9504 " ", i, r.toString())); 9505 } 9506 } 9507 9508 if (mLruProcesses.size() > 0) { 9509 if (needSep) pw.println(" "); 9510 needSep = true; 9511 pw.println(" Process LRU list (sorted by oom_adj):"); 9512 dumpProcessOomList(pw, this, mLruProcesses, " ", 9513 "Proc", "PERS", false, dumpPackage); 9514 needSep = true; 9515 } 9516 9517 if (dumpAll) { 9518 synchronized (mPidsSelfLocked) { 9519 boolean printed = false; 9520 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9521 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9522 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9523 continue; 9524 } 9525 if (!printed) { 9526 if (needSep) pw.println(" "); 9527 needSep = true; 9528 pw.println(" PID mappings:"); 9529 printed = true; 9530 } 9531 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9532 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9533 } 9534 } 9535 } 9536 9537 if (mForegroundProcesses.size() > 0) { 9538 synchronized (mPidsSelfLocked) { 9539 boolean printed = false; 9540 for (int i=0; i<mForegroundProcesses.size(); i++) { 9541 ProcessRecord r = mPidsSelfLocked.get( 9542 mForegroundProcesses.valueAt(i).pid); 9543 if (dumpPackage != null && (r == null 9544 || !dumpPackage.equals(r.info.packageName))) { 9545 continue; 9546 } 9547 if (!printed) { 9548 if (needSep) pw.println(" "); 9549 needSep = true; 9550 pw.println(" Foreground Processes:"); 9551 printed = true; 9552 } 9553 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9554 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9555 } 9556 } 9557 } 9558 9559 if (mPersistentStartingProcesses.size() > 0) { 9560 if (needSep) pw.println(" "); 9561 needSep = true; 9562 pw.println(" Persisent processes that are starting:"); 9563 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9564 "Starting Norm", "Restarting PERS", dumpPackage); 9565 } 9566 9567 if (mRemovedProcesses.size() > 0) { 9568 if (needSep) pw.println(" "); 9569 needSep = true; 9570 pw.println(" Processes that are being removed:"); 9571 dumpProcessList(pw, this, mRemovedProcesses, " ", 9572 "Removed Norm", "Removed PERS", dumpPackage); 9573 } 9574 9575 if (mProcessesOnHold.size() > 0) { 9576 if (needSep) pw.println(" "); 9577 needSep = true; 9578 pw.println(" Processes that are on old until the system is ready:"); 9579 dumpProcessList(pw, this, mProcessesOnHold, " ", 9580 "OnHold Norm", "OnHold PERS", dumpPackage); 9581 } 9582 9583 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9584 9585 if (mProcessCrashTimes.getMap().size() > 0) { 9586 boolean printed = false; 9587 long now = SystemClock.uptimeMillis(); 9588 for (Map.Entry<String, SparseArray<Long>> procs 9589 : mProcessCrashTimes.getMap().entrySet()) { 9590 String pname = procs.getKey(); 9591 SparseArray<Long> uids = procs.getValue(); 9592 final int N = uids.size(); 9593 for (int i=0; i<N; i++) { 9594 int puid = uids.keyAt(i); 9595 ProcessRecord r = mProcessNames.get(pname, puid); 9596 if (dumpPackage != null && (r == null 9597 || !dumpPackage.equals(r.info.packageName))) { 9598 continue; 9599 } 9600 if (!printed) { 9601 if (needSep) pw.println(" "); 9602 needSep = true; 9603 pw.println(" Time since processes crashed:"); 9604 printed = true; 9605 } 9606 pw.print(" Process "); pw.print(pname); 9607 pw.print(" uid "); pw.print(puid); 9608 pw.print(": last crashed "); 9609 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9610 pw.println(" ago"); 9611 } 9612 } 9613 } 9614 9615 if (mBadProcesses.getMap().size() > 0) { 9616 boolean printed = false; 9617 for (Map.Entry<String, SparseArray<Long>> procs 9618 : mBadProcesses.getMap().entrySet()) { 9619 String pname = procs.getKey(); 9620 SparseArray<Long> uids = procs.getValue(); 9621 final int N = uids.size(); 9622 for (int i=0; i<N; i++) { 9623 int puid = uids.keyAt(i); 9624 ProcessRecord r = mProcessNames.get(pname, puid); 9625 if (dumpPackage != null && (r == null 9626 || !dumpPackage.equals(r.info.packageName))) { 9627 continue; 9628 } 9629 if (!printed) { 9630 if (needSep) pw.println(" "); 9631 needSep = true; 9632 pw.println(" Bad processes:"); 9633 } 9634 pw.print(" Bad process "); pw.print(pname); 9635 pw.print(" uid "); pw.print(puid); 9636 pw.print(": crashed at time "); 9637 pw.println(uids.valueAt(i)); 9638 } 9639 } 9640 } 9641 9642 pw.println(); 9643 pw.println(" mStartedUsers:"); 9644 for (int i=0; i<mStartedUsers.size(); i++) { 9645 UserStartedState uss = mStartedUsers.valueAt(i); 9646 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9647 pw.print(": "); uss.dump("", pw); 9648 } 9649 pw.print(" mStartedUserArray: ["); 9650 for (int i=0; i<mStartedUserArray.length; i++) { 9651 if (i > 0) pw.print(", "); 9652 pw.print(mStartedUserArray[i]); 9653 } 9654 pw.println("]"); 9655 pw.print(" mUserLru: ["); 9656 for (int i=0; i<mUserLru.size(); i++) { 9657 if (i > 0) pw.print(", "); 9658 pw.print(mUserLru.get(i)); 9659 } 9660 pw.println("]"); 9661 if (dumpAll) { 9662 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9663 } 9664 pw.println(" mHomeProcess: " + mHomeProcess); 9665 pw.println(" mPreviousProcess: " + mPreviousProcess); 9666 if (dumpAll) { 9667 StringBuilder sb = new StringBuilder(128); 9668 sb.append(" mPreviousProcessVisibleTime: "); 9669 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9670 pw.println(sb); 9671 } 9672 if (mHeavyWeightProcess != null) { 9673 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9674 } 9675 pw.println(" mConfiguration: " + mConfiguration); 9676 if (dumpAll) { 9677 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9678 if (mCompatModePackages.getPackages().size() > 0) { 9679 boolean printed = false; 9680 for (Map.Entry<String, Integer> entry 9681 : mCompatModePackages.getPackages().entrySet()) { 9682 String pkg = entry.getKey(); 9683 int mode = entry.getValue(); 9684 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9685 continue; 9686 } 9687 if (!printed) { 9688 pw.println(" mScreenCompatPackages:"); 9689 printed = true; 9690 } 9691 pw.print(" "); pw.print(pkg); pw.print(": "); 9692 pw.print(mode); pw.println(); 9693 } 9694 } 9695 } 9696 if (mSleeping || mWentToSleep || mLockScreenShown) { 9697 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9698 + " mLockScreenShown " + mLockScreenShown); 9699 } 9700 if (mShuttingDown) { 9701 pw.println(" mShuttingDown=" + mShuttingDown); 9702 } 9703 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9704 || mOrigWaitForDebugger) { 9705 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9706 + " mDebugTransient=" + mDebugTransient 9707 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9708 } 9709 if (mOpenGlTraceApp != null) { 9710 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9711 } 9712 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9713 || mProfileFd != null) { 9714 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9715 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9716 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9717 + mAutoStopProfiler); 9718 } 9719 if (mAlwaysFinishActivities || mController != null) { 9720 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9721 + " mController=" + mController); 9722 } 9723 if (dumpAll) { 9724 pw.println(" Total persistent processes: " + numPers); 9725 pw.println(" mStartRunning=" + mStartRunning 9726 + " mProcessesReady=" + mProcessesReady 9727 + " mSystemReady=" + mSystemReady); 9728 pw.println(" mBooting=" + mBooting 9729 + " mBooted=" + mBooted 9730 + " mFactoryTest=" + mFactoryTest); 9731 pw.print(" mLastPowerCheckRealtime="); 9732 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9733 pw.println(""); 9734 pw.print(" mLastPowerCheckUptime="); 9735 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9736 pw.println(""); 9737 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9738 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9739 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9740 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9741 + " mNumHiddenProcs=" + mNumHiddenProcs 9742 + " mNumServiceProcs=" + mNumServiceProcs 9743 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9744 } 9745 9746 return true; 9747 } 9748 9749 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9750 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9751 if (mProcessesToGc.size() > 0) { 9752 boolean printed = false; 9753 long now = SystemClock.uptimeMillis(); 9754 for (int i=0; i<mProcessesToGc.size(); i++) { 9755 ProcessRecord proc = mProcessesToGc.get(i); 9756 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9757 continue; 9758 } 9759 if (!printed) { 9760 if (needSep) pw.println(" "); 9761 needSep = true; 9762 pw.println(" Processes that are waiting to GC:"); 9763 printed = true; 9764 } 9765 pw.print(" Process "); pw.println(proc); 9766 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9767 pw.print(", last gced="); 9768 pw.print(now-proc.lastRequestedGc); 9769 pw.print(" ms ago, last lowMem="); 9770 pw.print(now-proc.lastLowMemory); 9771 pw.println(" ms ago"); 9772 9773 } 9774 } 9775 return needSep; 9776 } 9777 9778 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9779 int opti, boolean dumpAll) { 9780 boolean needSep = false; 9781 9782 if (mLruProcesses.size() > 0) { 9783 if (needSep) pw.println(" "); 9784 needSep = true; 9785 pw.println(" OOM levels:"); 9786 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9787 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9788 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9789 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9790 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9791 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9792 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9793 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9794 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9795 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9796 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9797 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9798 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9799 9800 if (needSep) pw.println(" "); 9801 needSep = true; 9802 pw.println(" Process OOM control:"); 9803 dumpProcessOomList(pw, this, mLruProcesses, " ", 9804 "Proc", "PERS", true, null); 9805 needSep = true; 9806 } 9807 9808 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9809 9810 pw.println(); 9811 pw.println(" mHomeProcess: " + mHomeProcess); 9812 pw.println(" mPreviousProcess: " + mPreviousProcess); 9813 if (mHeavyWeightProcess != null) { 9814 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9815 } 9816 9817 return true; 9818 } 9819 9820 /** 9821 * There are three ways to call this: 9822 * - no provider specified: dump all the providers 9823 * - a flattened component name that matched an existing provider was specified as the 9824 * first arg: dump that one provider 9825 * - the first arg isn't the flattened component name of an existing provider: 9826 * dump all providers whose component contains the first arg as a substring 9827 */ 9828 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9829 int opti, boolean dumpAll) { 9830 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9831 } 9832 9833 static class ItemMatcher { 9834 ArrayList<ComponentName> components; 9835 ArrayList<String> strings; 9836 ArrayList<Integer> objects; 9837 boolean all; 9838 9839 ItemMatcher() { 9840 all = true; 9841 } 9842 9843 void build(String name) { 9844 ComponentName componentName = ComponentName.unflattenFromString(name); 9845 if (componentName != null) { 9846 if (components == null) { 9847 components = new ArrayList<ComponentName>(); 9848 } 9849 components.add(componentName); 9850 all = false; 9851 } else { 9852 int objectId = 0; 9853 // Not a '/' separated full component name; maybe an object ID? 9854 try { 9855 objectId = Integer.parseInt(name, 16); 9856 if (objects == null) { 9857 objects = new ArrayList<Integer>(); 9858 } 9859 objects.add(objectId); 9860 all = false; 9861 } catch (RuntimeException e) { 9862 // Not an integer; just do string match. 9863 if (strings == null) { 9864 strings = new ArrayList<String>(); 9865 } 9866 strings.add(name); 9867 all = false; 9868 } 9869 } 9870 } 9871 9872 int build(String[] args, int opti) { 9873 for (; opti<args.length; opti++) { 9874 String name = args[opti]; 9875 if ("--".equals(name)) { 9876 return opti+1; 9877 } 9878 build(name); 9879 } 9880 return opti; 9881 } 9882 9883 boolean match(Object object, ComponentName comp) { 9884 if (all) { 9885 return true; 9886 } 9887 if (components != null) { 9888 for (int i=0; i<components.size(); i++) { 9889 if (components.get(i).equals(comp)) { 9890 return true; 9891 } 9892 } 9893 } 9894 if (objects != null) { 9895 for (int i=0; i<objects.size(); i++) { 9896 if (System.identityHashCode(object) == objects.get(i)) { 9897 return true; 9898 } 9899 } 9900 } 9901 if (strings != null) { 9902 String flat = comp.flattenToString(); 9903 for (int i=0; i<strings.size(); i++) { 9904 if (flat.contains(strings.get(i))) { 9905 return true; 9906 } 9907 } 9908 } 9909 return false; 9910 } 9911 } 9912 9913 /** 9914 * There are three things that cmd can be: 9915 * - a flattened component name that matches an existing activity 9916 * - the cmd arg isn't the flattened component name of an existing activity: 9917 * dump all activity whose component contains the cmd as a substring 9918 * - A hex number of the ActivityRecord object instance. 9919 */ 9920 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9921 int opti, boolean dumpAll) { 9922 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9923 9924 if ("all".equals(name)) { 9925 synchronized (this) { 9926 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9927 activities.add(r1); 9928 } 9929 } 9930 } else if ("top".equals(name)) { 9931 synchronized (this) { 9932 final int N = mMainStack.mHistory.size(); 9933 if (N > 0) { 9934 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9935 } 9936 } 9937 } else { 9938 ItemMatcher matcher = new ItemMatcher(); 9939 matcher.build(name); 9940 9941 synchronized (this) { 9942 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9943 if (matcher.match(r1, r1.intent.getComponent())) { 9944 activities.add(r1); 9945 } 9946 } 9947 } 9948 } 9949 9950 if (activities.size() <= 0) { 9951 return false; 9952 } 9953 9954 String[] newArgs = new String[args.length - opti]; 9955 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9956 9957 TaskRecord lastTask = null; 9958 boolean needSep = false; 9959 for (int i=activities.size()-1; i>=0; i--) { 9960 ActivityRecord r = (ActivityRecord)activities.get(i); 9961 if (needSep) { 9962 pw.println(); 9963 } 9964 needSep = true; 9965 synchronized (this) { 9966 if (lastTask != r.task) { 9967 lastTask = r.task; 9968 pw.print("TASK "); pw.print(lastTask.affinity); 9969 pw.print(" id="); pw.println(lastTask.taskId); 9970 if (dumpAll) { 9971 lastTask.dump(pw, " "); 9972 } 9973 } 9974 } 9975 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9976 } 9977 return true; 9978 } 9979 9980 /** 9981 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9982 * there is a thread associated with the activity. 9983 */ 9984 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9985 final ActivityRecord r, String[] args, boolean dumpAll) { 9986 String innerPrefix = prefix + " "; 9987 synchronized (this) { 9988 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9989 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9990 pw.print(" pid="); 9991 if (r.app != null) pw.println(r.app.pid); 9992 else pw.println("(not running)"); 9993 if (dumpAll) { 9994 r.dump(pw, innerPrefix); 9995 } 9996 } 9997 if (r.app != null && r.app.thread != null) { 9998 // flush anything that is already in the PrintWriter since the thread is going 9999 // to write to the file descriptor directly 10000 pw.flush(); 10001 try { 10002 TransferPipe tp = new TransferPipe(); 10003 try { 10004 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 10005 r.appToken, innerPrefix, args); 10006 tp.go(fd); 10007 } finally { 10008 tp.kill(); 10009 } 10010 } catch (IOException e) { 10011 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 10012 } catch (RemoteException e) { 10013 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 10014 } 10015 } 10016 } 10017 10018 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10019 int opti, boolean dumpAll, String dumpPackage) { 10020 boolean needSep = false; 10021 boolean onlyHistory = false; 10022 10023 if ("history".equals(dumpPackage)) { 10024 if (opti < args.length && "-s".equals(args[opti])) { 10025 dumpAll = false; 10026 } 10027 onlyHistory = true; 10028 dumpPackage = null; 10029 } 10030 10031 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 10032 if (!onlyHistory && dumpAll) { 10033 if (mRegisteredReceivers.size() > 0) { 10034 boolean printed = false; 10035 Iterator it = mRegisteredReceivers.values().iterator(); 10036 while (it.hasNext()) { 10037 ReceiverList r = (ReceiverList)it.next(); 10038 if (dumpPackage != null && (r.app == null || 10039 !dumpPackage.equals(r.app.info.packageName))) { 10040 continue; 10041 } 10042 if (!printed) { 10043 pw.println(" Registered Receivers:"); 10044 needSep = true; 10045 printed = true; 10046 } 10047 pw.print(" * "); pw.println(r); 10048 r.dump(pw, " "); 10049 } 10050 } 10051 10052 if (mReceiverResolver.dump(pw, needSep ? 10053 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 10054 " ", dumpPackage, false)) { 10055 needSep = true; 10056 } 10057 } 10058 10059 for (BroadcastQueue q : mBroadcastQueues) { 10060 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 10061 } 10062 10063 needSep = true; 10064 10065 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 10066 for (int user=0; user<mStickyBroadcasts.size(); user++) { 10067 if (needSep) { 10068 pw.println(); 10069 } 10070 needSep = true; 10071 pw.print(" Sticky broadcasts for user "); 10072 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 10073 StringBuilder sb = new StringBuilder(128); 10074 for (Map.Entry<String, ArrayList<Intent>> ent 10075 : mStickyBroadcasts.valueAt(user).entrySet()) { 10076 pw.print(" * Sticky action "); pw.print(ent.getKey()); 10077 if (dumpAll) { 10078 pw.println(":"); 10079 ArrayList<Intent> intents = ent.getValue(); 10080 final int N = intents.size(); 10081 for (int i=0; i<N; i++) { 10082 sb.setLength(0); 10083 sb.append(" Intent: "); 10084 intents.get(i).toShortString(sb, false, true, false, false); 10085 pw.println(sb.toString()); 10086 Bundle bundle = intents.get(i).getExtras(); 10087 if (bundle != null) { 10088 pw.print(" "); 10089 pw.println(bundle.toString()); 10090 } 10091 } 10092 } else { 10093 pw.println(""); 10094 } 10095 } 10096 } 10097 } 10098 10099 if (!onlyHistory && dumpAll) { 10100 pw.println(); 10101 for (BroadcastQueue queue : mBroadcastQueues) { 10102 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 10103 + queue.mBroadcastsScheduled); 10104 } 10105 pw.println(" mHandler:"); 10106 mHandler.dump(new PrintWriterPrinter(pw), " "); 10107 needSep = true; 10108 } 10109 10110 return needSep; 10111 } 10112 10113 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10114 int opti, boolean dumpAll, String dumpPackage) { 10115 boolean needSep = true; 10116 10117 ItemMatcher matcher = new ItemMatcher(); 10118 matcher.build(args, opti); 10119 10120 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 10121 10122 mProviderMap.dumpProvidersLocked(pw, dumpAll); 10123 10124 if (mLaunchingProviders.size() > 0) { 10125 boolean printed = false; 10126 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 10127 ContentProviderRecord r = mLaunchingProviders.get(i); 10128 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 10129 continue; 10130 } 10131 if (!printed) { 10132 if (needSep) pw.println(" "); 10133 needSep = true; 10134 pw.println(" Launching content providers:"); 10135 printed = true; 10136 } 10137 pw.print(" Launching #"); pw.print(i); pw.print(": "); 10138 pw.println(r); 10139 } 10140 } 10141 10142 if (mGrantedUriPermissions.size() > 0) { 10143 if (needSep) pw.println(); 10144 needSep = true; 10145 pw.println("Granted Uri Permissions:"); 10146 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 10147 int uid = mGrantedUriPermissions.keyAt(i); 10148 HashMap<Uri, UriPermission> perms 10149 = mGrantedUriPermissions.valueAt(i); 10150 pw.print(" * UID "); pw.print(uid); 10151 pw.println(" holds:"); 10152 for (UriPermission perm : perms.values()) { 10153 pw.print(" "); pw.println(perm); 10154 if (dumpAll) { 10155 perm.dump(pw, " "); 10156 } 10157 } 10158 } 10159 needSep = true; 10160 } 10161 10162 return needSep; 10163 } 10164 10165 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10166 int opti, boolean dumpAll, String dumpPackage) { 10167 boolean needSep = false; 10168 10169 if (mIntentSenderRecords.size() > 0) { 10170 boolean printed = false; 10171 Iterator<WeakReference<PendingIntentRecord>> it 10172 = mIntentSenderRecords.values().iterator(); 10173 while (it.hasNext()) { 10174 WeakReference<PendingIntentRecord> ref = it.next(); 10175 PendingIntentRecord rec = ref != null ? ref.get(): null; 10176 if (dumpPackage != null && (rec == null 10177 || !dumpPackage.equals(rec.key.packageName))) { 10178 continue; 10179 } 10180 if (!printed) { 10181 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 10182 printed = true; 10183 } 10184 needSep = true; 10185 if (rec != null) { 10186 pw.print(" * "); pw.println(rec); 10187 if (dumpAll) { 10188 rec.dump(pw, " "); 10189 } 10190 } else { 10191 pw.print(" * "); pw.println(ref); 10192 } 10193 } 10194 } 10195 10196 return needSep; 10197 } 10198 10199 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 10200 String prefix, String label, boolean complete, boolean brief, boolean client, 10201 String dumpPackage) { 10202 TaskRecord lastTask = null; 10203 boolean needNL = false; 10204 final String innerPrefix = prefix + " "; 10205 final String[] args = new String[0]; 10206 for (int i=list.size()-1; i>=0; i--) { 10207 final ActivityRecord r = (ActivityRecord)list.get(i); 10208 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 10209 continue; 10210 } 10211 final boolean full = !brief && (complete || !r.isInHistory()); 10212 if (needNL) { 10213 pw.println(" "); 10214 needNL = false; 10215 } 10216 if (lastTask != r.task) { 10217 lastTask = r.task; 10218 pw.print(prefix); 10219 pw.print(full ? "* " : " "); 10220 pw.println(lastTask); 10221 if (full) { 10222 lastTask.dump(pw, prefix + " "); 10223 } else if (complete) { 10224 // Complete + brief == give a summary. Isn't that obvious?!? 10225 if (lastTask.intent != null) { 10226 pw.print(prefix); pw.print(" "); 10227 pw.println(lastTask.intent.toInsecureStringWithClip()); 10228 } 10229 } 10230 } 10231 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 10232 pw.print(" #"); pw.print(i); pw.print(": "); 10233 pw.println(r); 10234 if (full) { 10235 r.dump(pw, innerPrefix); 10236 } else if (complete) { 10237 // Complete + brief == give a summary. Isn't that obvious?!? 10238 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 10239 if (r.app != null) { 10240 pw.print(innerPrefix); pw.println(r.app); 10241 } 10242 } 10243 if (client && r.app != null && r.app.thread != null) { 10244 // flush anything that is already in the PrintWriter since the thread is going 10245 // to write to the file descriptor directly 10246 pw.flush(); 10247 try { 10248 TransferPipe tp = new TransferPipe(); 10249 try { 10250 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 10251 r.appToken, innerPrefix, args); 10252 // Short timeout, since blocking here can 10253 // deadlock with the application. 10254 tp.go(fd, 2000); 10255 } finally { 10256 tp.kill(); 10257 } 10258 } catch (IOException e) { 10259 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 10260 } catch (RemoteException e) { 10261 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 10262 } 10263 needNL = true; 10264 } 10265 } 10266 } 10267 10268 private static String buildOomTag(String prefix, String space, int val, int base) { 10269 if (val == base) { 10270 if (space == null) return prefix; 10271 return prefix + " "; 10272 } 10273 return prefix + "+" + Integer.toString(val-base); 10274 } 10275 10276 private static final int dumpProcessList(PrintWriter pw, 10277 ActivityManagerService service, List list, 10278 String prefix, String normalLabel, String persistentLabel, 10279 String dumpPackage) { 10280 int numPers = 0; 10281 final int N = list.size()-1; 10282 for (int i=N; i>=0; i--) { 10283 ProcessRecord r = (ProcessRecord)list.get(i); 10284 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10285 continue; 10286 } 10287 pw.println(String.format("%s%s #%2d: %s", 10288 prefix, (r.persistent ? persistentLabel : normalLabel), 10289 i, r.toString())); 10290 if (r.persistent) { 10291 numPers++; 10292 } 10293 } 10294 return numPers; 10295 } 10296 10297 private static final boolean dumpProcessOomList(PrintWriter pw, 10298 ActivityManagerService service, List<ProcessRecord> origList, 10299 String prefix, String normalLabel, String persistentLabel, 10300 boolean inclDetails, String dumpPackage) { 10301 10302 ArrayList<Pair<ProcessRecord, Integer>> list 10303 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 10304 for (int i=0; i<origList.size(); i++) { 10305 ProcessRecord r = origList.get(i); 10306 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10307 continue; 10308 } 10309 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 10310 } 10311 10312 if (list.size() <= 0) { 10313 return false; 10314 } 10315 10316 Comparator<Pair<ProcessRecord, Integer>> comparator 10317 = new Comparator<Pair<ProcessRecord, Integer>>() { 10318 @Override 10319 public int compare(Pair<ProcessRecord, Integer> object1, 10320 Pair<ProcessRecord, Integer> object2) { 10321 if (object1.first.setAdj != object2.first.setAdj) { 10322 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10323 } 10324 if (object1.second.intValue() != object2.second.intValue()) { 10325 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10326 } 10327 return 0; 10328 } 10329 }; 10330 10331 Collections.sort(list, comparator); 10332 10333 final long curRealtime = SystemClock.elapsedRealtime(); 10334 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10335 final long curUptime = SystemClock.uptimeMillis(); 10336 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10337 10338 for (int i=list.size()-1; i>=0; i--) { 10339 ProcessRecord r = list.get(i).first; 10340 String oomAdj; 10341 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10342 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10343 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10344 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10345 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10346 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10347 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10348 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10349 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10350 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10351 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10352 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10353 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10354 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10355 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10356 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10357 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10358 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10359 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10360 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10361 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10362 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10363 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10364 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10365 } else { 10366 oomAdj = Integer.toString(r.setAdj); 10367 } 10368 String schedGroup; 10369 switch (r.setSchedGroup) { 10370 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10371 schedGroup = "B"; 10372 break; 10373 case Process.THREAD_GROUP_DEFAULT: 10374 schedGroup = "F"; 10375 break; 10376 default: 10377 schedGroup = Integer.toString(r.setSchedGroup); 10378 break; 10379 } 10380 String foreground; 10381 if (r.foregroundActivities) { 10382 foreground = "A"; 10383 } else if (r.foregroundServices) { 10384 foreground = "S"; 10385 } else { 10386 foreground = " "; 10387 } 10388 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10389 prefix, (r.persistent ? persistentLabel : normalLabel), 10390 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10391 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10392 if (r.adjSource != null || r.adjTarget != null) { 10393 pw.print(prefix); 10394 pw.print(" "); 10395 if (r.adjTarget instanceof ComponentName) { 10396 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10397 } else if (r.adjTarget != null) { 10398 pw.print(r.adjTarget.toString()); 10399 } else { 10400 pw.print("{null}"); 10401 } 10402 pw.print("<="); 10403 if (r.adjSource instanceof ProcessRecord) { 10404 pw.print("Proc{"); 10405 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10406 pw.println("}"); 10407 } else if (r.adjSource != null) { 10408 pw.println(r.adjSource.toString()); 10409 } else { 10410 pw.println("{null}"); 10411 } 10412 } 10413 if (inclDetails) { 10414 pw.print(prefix); 10415 pw.print(" "); 10416 pw.print("oom: max="); pw.print(r.maxAdj); 10417 pw.print(" hidden="); pw.print(r.hiddenAdj); 10418 pw.print(" client="); pw.print(r.clientHiddenAdj); 10419 pw.print(" empty="); pw.print(r.emptyAdj); 10420 pw.print(" curRaw="); pw.print(r.curRawAdj); 10421 pw.print(" setRaw="); pw.print(r.setRawAdj); 10422 pw.print(" cur="); pw.print(r.curAdj); 10423 pw.print(" set="); pw.println(r.setAdj); 10424 pw.print(prefix); 10425 pw.print(" "); 10426 pw.print("keeping="); pw.print(r.keeping); 10427 pw.print(" hidden="); pw.print(r.hidden); 10428 pw.print(" empty="); pw.print(r.empty); 10429 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10430 10431 if (!r.keeping) { 10432 if (r.lastWakeTime != 0) { 10433 long wtime; 10434 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10435 synchronized (stats) { 10436 wtime = stats.getProcessWakeTime(r.info.uid, 10437 r.pid, curRealtime); 10438 } 10439 long timeUsed = wtime - r.lastWakeTime; 10440 pw.print(prefix); 10441 pw.print(" "); 10442 pw.print("keep awake over "); 10443 TimeUtils.formatDuration(realtimeSince, pw); 10444 pw.print(" used "); 10445 TimeUtils.formatDuration(timeUsed, pw); 10446 pw.print(" ("); 10447 pw.print((timeUsed*100)/realtimeSince); 10448 pw.println("%)"); 10449 } 10450 if (r.lastCpuTime != 0) { 10451 long timeUsed = r.curCpuTime - r.lastCpuTime; 10452 pw.print(prefix); 10453 pw.print(" "); 10454 pw.print("run cpu over "); 10455 TimeUtils.formatDuration(uptimeSince, pw); 10456 pw.print(" used "); 10457 TimeUtils.formatDuration(timeUsed, pw); 10458 pw.print(" ("); 10459 pw.print((timeUsed*100)/uptimeSince); 10460 pw.println("%)"); 10461 } 10462 } 10463 } 10464 } 10465 return true; 10466 } 10467 10468 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10469 ArrayList<ProcessRecord> procs; 10470 synchronized (this) { 10471 if (args != null && args.length > start 10472 && args[start].charAt(0) != '-') { 10473 procs = new ArrayList<ProcessRecord>(); 10474 int pid = -1; 10475 try { 10476 pid = Integer.parseInt(args[start]); 10477 } catch (NumberFormatException e) { 10478 10479 } 10480 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10481 ProcessRecord proc = mLruProcesses.get(i); 10482 if (proc.pid == pid) { 10483 procs.add(proc); 10484 } else if (proc.processName.equals(args[start])) { 10485 procs.add(proc); 10486 } 10487 } 10488 if (procs.size() <= 0) { 10489 pw.println("No process found for: " + args[start]); 10490 return null; 10491 } 10492 } else { 10493 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10494 } 10495 } 10496 return procs; 10497 } 10498 10499 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10500 PrintWriter pw, String[] args) { 10501 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10502 if (procs == null) { 10503 return; 10504 } 10505 10506 long uptime = SystemClock.uptimeMillis(); 10507 long realtime = SystemClock.elapsedRealtime(); 10508 pw.println("Applications Graphics Acceleration Info:"); 10509 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10510 10511 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10512 ProcessRecord r = procs.get(i); 10513 if (r.thread != null) { 10514 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10515 pw.flush(); 10516 try { 10517 TransferPipe tp = new TransferPipe(); 10518 try { 10519 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10520 tp.go(fd); 10521 } finally { 10522 tp.kill(); 10523 } 10524 } catch (IOException e) { 10525 pw.println("Failure while dumping the app: " + r); 10526 pw.flush(); 10527 } catch (RemoteException e) { 10528 pw.println("Got a RemoteException while dumping the app " + r); 10529 pw.flush(); 10530 } 10531 } 10532 } 10533 } 10534 10535 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10536 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10537 if (procs == null) { 10538 return; 10539 } 10540 10541 pw.println("Applications Database Info:"); 10542 10543 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10544 ProcessRecord r = procs.get(i); 10545 if (r.thread != null) { 10546 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10547 pw.flush(); 10548 try { 10549 TransferPipe tp = new TransferPipe(); 10550 try { 10551 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10552 tp.go(fd); 10553 } finally { 10554 tp.kill(); 10555 } 10556 } catch (IOException e) { 10557 pw.println("Failure while dumping the app: " + r); 10558 pw.flush(); 10559 } catch (RemoteException e) { 10560 pw.println("Got a RemoteException while dumping the app " + r); 10561 pw.flush(); 10562 } 10563 } 10564 } 10565 } 10566 10567 final static class MemItem { 10568 final String label; 10569 final String shortLabel; 10570 final long pss; 10571 final int id; 10572 ArrayList<MemItem> subitems; 10573 10574 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10575 label = _label; 10576 shortLabel = _shortLabel; 10577 pss = _pss; 10578 id = _id; 10579 } 10580 } 10581 10582 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10583 boolean sort) { 10584 if (sort) { 10585 Collections.sort(items, new Comparator<MemItem>() { 10586 @Override 10587 public int compare(MemItem lhs, MemItem rhs) { 10588 if (lhs.pss < rhs.pss) { 10589 return 1; 10590 } else if (lhs.pss > rhs.pss) { 10591 return -1; 10592 } 10593 return 0; 10594 } 10595 }); 10596 } 10597 10598 for (int i=0; i<items.size(); i++) { 10599 MemItem mi = items.get(i); 10600 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10601 if (mi.subitems != null) { 10602 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10603 } 10604 } 10605 } 10606 10607 // These are in KB. 10608 static final long[] DUMP_MEM_BUCKETS = new long[] { 10609 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10610 120*1024, 160*1024, 200*1024, 10611 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10612 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10613 }; 10614 10615 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10616 boolean stackLike) { 10617 int start = label.lastIndexOf('.'); 10618 if (start >= 0) start++; 10619 else start = 0; 10620 int end = label.length(); 10621 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10622 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10623 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10624 out.append(bucket); 10625 out.append(stackLike ? "MB." : "MB "); 10626 out.append(label, start, end); 10627 return; 10628 } 10629 } 10630 out.append(memKB/1024); 10631 out.append(stackLike ? "MB." : "MB "); 10632 out.append(label, start, end); 10633 } 10634 10635 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10636 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10637 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10638 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10639 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10640 }; 10641 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10642 "System", "Persistent", "Foreground", 10643 "Visible", "Perceptible", "Heavy Weight", 10644 "Backup", "A Services", "Home", "Previous", 10645 "B Services", "Background" 10646 }; 10647 10648 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10649 PrintWriter pw, String prefix, String[] args, boolean brief, 10650 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10651 boolean dumpAll = false; 10652 boolean oomOnly = false; 10653 10654 int opti = 0; 10655 while (opti < args.length) { 10656 String opt = args[opti]; 10657 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10658 break; 10659 } 10660 opti++; 10661 if ("-a".equals(opt)) { 10662 dumpAll = true; 10663 } else if ("--oom".equals(opt)) { 10664 oomOnly = true; 10665 } else if ("-h".equals(opt)) { 10666 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10667 pw.println(" -a: include all available information for each process."); 10668 pw.println(" --oom: only show processes organized by oom adj."); 10669 pw.println("If [process] is specified it can be the name or "); 10670 pw.println("pid of a specific process to dump."); 10671 return; 10672 } else { 10673 pw.println("Unknown argument: " + opt + "; use -h for help"); 10674 } 10675 } 10676 10677 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10678 if (procs == null) { 10679 return; 10680 } 10681 10682 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10683 long uptime = SystemClock.uptimeMillis(); 10684 long realtime = SystemClock.elapsedRealtime(); 10685 10686 if (procs.size() == 1 || isCheckinRequest) { 10687 dumpAll = true; 10688 } 10689 10690 if (isCheckinRequest) { 10691 // short checkin version 10692 pw.println(uptime + "," + realtime); 10693 pw.flush(); 10694 } else { 10695 pw.println("Applications Memory Usage (kB):"); 10696 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10697 } 10698 10699 String[] innerArgs = new String[args.length-opti]; 10700 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10701 10702 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10703 long nativePss=0, dalvikPss=0, otherPss=0; 10704 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10705 10706 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10707 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10708 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10709 10710 long totalPss = 0; 10711 10712 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10713 ProcessRecord r = procs.get(i); 10714 if (r.thread != null) { 10715 if (!isCheckinRequest && dumpAll) { 10716 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10717 pw.flush(); 10718 } 10719 Debug.MemoryInfo mi = null; 10720 if (dumpAll) { 10721 try { 10722 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10723 } catch (RemoteException e) { 10724 if (!isCheckinRequest) { 10725 pw.println("Got RemoteException!"); 10726 pw.flush(); 10727 } 10728 } 10729 } else { 10730 mi = new Debug.MemoryInfo(); 10731 Debug.getMemoryInfo(r.pid, mi); 10732 } 10733 10734 if (!isCheckinRequest && mi != null) { 10735 long myTotalPss = mi.getTotalPss(); 10736 totalPss += myTotalPss; 10737 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10738 r.processName, myTotalPss, 0); 10739 procMems.add(pssItem); 10740 10741 nativePss += mi.nativePss; 10742 dalvikPss += mi.dalvikPss; 10743 otherPss += mi.otherPss; 10744 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10745 long mem = mi.getOtherPss(j); 10746 miscPss[j] += mem; 10747 otherPss -= mem; 10748 } 10749 10750 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10751 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10752 || oomIndex == (oomPss.length-1)) { 10753 oomPss[oomIndex] += myTotalPss; 10754 if (oomProcs[oomIndex] == null) { 10755 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10756 } 10757 oomProcs[oomIndex].add(pssItem); 10758 break; 10759 } 10760 } 10761 } 10762 } 10763 } 10764 10765 if (!isCheckinRequest && procs.size() > 1) { 10766 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10767 10768 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10769 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10770 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10771 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10772 String label = Debug.MemoryInfo.getOtherLabel(j); 10773 catMems.add(new MemItem(label, label, miscPss[j], j)); 10774 } 10775 10776 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10777 for (int j=0; j<oomPss.length; j++) { 10778 if (oomPss[j] != 0) { 10779 String label = DUMP_MEM_OOM_LABEL[j]; 10780 MemItem item = new MemItem(label, label, oomPss[j], 10781 DUMP_MEM_OOM_ADJ[j]); 10782 item.subitems = oomProcs[j]; 10783 oomMems.add(item); 10784 } 10785 } 10786 10787 if (outTag != null || outStack != null) { 10788 if (outTag != null) { 10789 appendMemBucket(outTag, totalPss, "total", false); 10790 } 10791 if (outStack != null) { 10792 appendMemBucket(outStack, totalPss, "total", true); 10793 } 10794 boolean firstLine = true; 10795 for (int i=0; i<oomMems.size(); i++) { 10796 MemItem miCat = oomMems.get(i); 10797 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10798 continue; 10799 } 10800 if (miCat.id < ProcessList.SERVICE_ADJ 10801 || miCat.id == ProcessList.HOME_APP_ADJ 10802 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10803 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10804 outTag.append(" / "); 10805 } 10806 if (outStack != null) { 10807 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10808 if (firstLine) { 10809 outStack.append(":"); 10810 firstLine = false; 10811 } 10812 outStack.append("\n\t at "); 10813 } else { 10814 outStack.append("$"); 10815 } 10816 } 10817 for (int j=0; j<miCat.subitems.size(); j++) { 10818 MemItem mi = miCat.subitems.get(j); 10819 if (j > 0) { 10820 if (outTag != null) { 10821 outTag.append(" "); 10822 } 10823 if (outStack != null) { 10824 outStack.append("$"); 10825 } 10826 } 10827 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10828 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10829 } 10830 if (outStack != null) { 10831 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10832 } 10833 } 10834 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10835 outStack.append("("); 10836 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10837 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10838 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10839 outStack.append(":"); 10840 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10841 } 10842 } 10843 outStack.append(")"); 10844 } 10845 } 10846 } 10847 } 10848 10849 if (!brief && !oomOnly) { 10850 pw.println(); 10851 pw.println("Total PSS by process:"); 10852 dumpMemItems(pw, " ", procMems, true); 10853 pw.println(); 10854 } 10855 pw.println("Total PSS by OOM adjustment:"); 10856 dumpMemItems(pw, " ", oomMems, false); 10857 if (!oomOnly) { 10858 PrintWriter out = categoryPw != null ? categoryPw : pw; 10859 out.println(); 10860 out.println("Total PSS by category:"); 10861 dumpMemItems(out, " ", catMems, true); 10862 } 10863 pw.println(); 10864 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10865 final int[] SINGLE_LONG_FORMAT = new int[] { 10866 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10867 }; 10868 long[] longOut = new long[1]; 10869 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10870 SINGLE_LONG_FORMAT, null, longOut, null); 10871 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10872 longOut[0] = 0; 10873 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10874 SINGLE_LONG_FORMAT, null, longOut, null); 10875 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10876 longOut[0] = 0; 10877 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10878 SINGLE_LONG_FORMAT, null, longOut, null); 10879 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10880 longOut[0] = 0; 10881 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10882 SINGLE_LONG_FORMAT, null, longOut, null); 10883 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10884 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10885 pw.print(shared); pw.println(" kB"); 10886 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10887 pw.print(voltile); pw.println(" kB volatile"); 10888 } 10889 } 10890 10891 /** 10892 * Searches array of arguments for the specified string 10893 * @param args array of argument strings 10894 * @param value value to search for 10895 * @return true if the value is contained in the array 10896 */ 10897 private static boolean scanArgs(String[] args, String value) { 10898 if (args != null) { 10899 for (String arg : args) { 10900 if (value.equals(arg)) { 10901 return true; 10902 } 10903 } 10904 } 10905 return false; 10906 } 10907 10908 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10909 ContentProviderRecord cpr, boolean always) { 10910 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10911 10912 if (!inLaunching || always) { 10913 synchronized (cpr) { 10914 cpr.launchingApp = null; 10915 cpr.notifyAll(); 10916 } 10917 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10918 String names[] = cpr.info.authority.split(";"); 10919 for (int j = 0; j < names.length; j++) { 10920 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10921 } 10922 } 10923 10924 for (int i=0; i<cpr.connections.size(); i++) { 10925 ContentProviderConnection conn = cpr.connections.get(i); 10926 if (conn.waiting) { 10927 // If this connection is waiting for the provider, then we don't 10928 // need to mess with its process unless we are always removing 10929 // or for some reason the provider is not currently launching. 10930 if (inLaunching && !always) { 10931 continue; 10932 } 10933 } 10934 ProcessRecord capp = conn.client; 10935 conn.dead = true; 10936 if (conn.stableCount > 0) { 10937 if (!capp.persistent && capp.thread != null 10938 && capp.pid != 0 10939 && capp.pid != MY_PID) { 10940 Slog.i(TAG, "Kill " + capp.processName 10941 + " (pid " + capp.pid + "): provider " + cpr.info.name 10942 + " in dying process " + (proc != null ? proc.processName : "??")); 10943 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10944 capp.processName, capp.setAdj, "dying provider " 10945 + cpr.name.toShortString()); 10946 Process.killProcessQuiet(capp.pid); 10947 } 10948 } else if (capp.thread != null && conn.provider.provider != null) { 10949 try { 10950 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10951 } catch (RemoteException e) { 10952 } 10953 // In the protocol here, we don't expect the client to correctly 10954 // clean up this connection, we'll just remove it. 10955 cpr.connections.remove(i); 10956 conn.client.conProviders.remove(conn); 10957 } 10958 } 10959 10960 if (inLaunching && always) { 10961 mLaunchingProviders.remove(cpr); 10962 } 10963 return inLaunching; 10964 } 10965 10966 /** 10967 * Main code for cleaning up a process when it has gone away. This is 10968 * called both as a result of the process dying, or directly when stopping 10969 * a process when running in single process mode. 10970 */ 10971 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10972 boolean restarting, boolean allowRestart, int index) { 10973 if (index >= 0) { 10974 mLruProcesses.remove(index); 10975 } 10976 10977 mProcessesToGc.remove(app); 10978 10979 // Dismiss any open dialogs. 10980 if (app.crashDialog != null && !app.forceCrashReport) { 10981 app.crashDialog.dismiss(); 10982 app.crashDialog = null; 10983 } 10984 if (app.anrDialog != null) { 10985 app.anrDialog.dismiss(); 10986 app.anrDialog = null; 10987 } 10988 if (app.waitDialog != null) { 10989 app.waitDialog.dismiss(); 10990 app.waitDialog = null; 10991 } 10992 10993 app.crashing = false; 10994 app.notResponding = false; 10995 10996 app.resetPackageList(); 10997 app.unlinkDeathRecipient(); 10998 app.thread = null; 10999 app.forcingToForeground = null; 11000 app.foregroundServices = false; 11001 app.foregroundActivities = false; 11002 app.hasShownUi = false; 11003 app.hasAboveClient = false; 11004 11005 mServices.killServicesLocked(app, allowRestart); 11006 11007 boolean restart = false; 11008 11009 // Remove published content providers. 11010 if (!app.pubProviders.isEmpty()) { 11011 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 11012 while (it.hasNext()) { 11013 ContentProviderRecord cpr = it.next(); 11014 11015 final boolean always = app.bad || !allowRestart; 11016 if (removeDyingProviderLocked(app, cpr, always) || always) { 11017 // We left the provider in the launching list, need to 11018 // restart it. 11019 restart = true; 11020 } 11021 11022 cpr.provider = null; 11023 cpr.proc = null; 11024 } 11025 app.pubProviders.clear(); 11026 } 11027 11028 // Take care of any launching providers waiting for this process. 11029 if (checkAppInLaunchingProvidersLocked(app, false)) { 11030 restart = true; 11031 } 11032 11033 // Unregister from connected content providers. 11034 if (!app.conProviders.isEmpty()) { 11035 for (int i=0; i<app.conProviders.size(); i++) { 11036 ContentProviderConnection conn = app.conProviders.get(i); 11037 conn.provider.connections.remove(conn); 11038 } 11039 app.conProviders.clear(); 11040 } 11041 11042 // At this point there may be remaining entries in mLaunchingProviders 11043 // where we were the only one waiting, so they are no longer of use. 11044 // Look for these and clean up if found. 11045 // XXX Commented out for now. Trying to figure out a way to reproduce 11046 // the actual situation to identify what is actually going on. 11047 if (false) { 11048 for (int i=0; i<mLaunchingProviders.size(); i++) { 11049 ContentProviderRecord cpr = (ContentProviderRecord) 11050 mLaunchingProviders.get(i); 11051 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 11052 synchronized (cpr) { 11053 cpr.launchingApp = null; 11054 cpr.notifyAll(); 11055 } 11056 } 11057 } 11058 } 11059 11060 skipCurrentReceiverLocked(app); 11061 11062 // Unregister any receivers. 11063 if (app.receivers.size() > 0) { 11064 Iterator<ReceiverList> it = app.receivers.iterator(); 11065 while (it.hasNext()) { 11066 removeReceiverLocked(it.next()); 11067 } 11068 app.receivers.clear(); 11069 } 11070 11071 // If the app is undergoing backup, tell the backup manager about it 11072 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 11073 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 11074 + mBackupTarget.appInfo + " died during backup"); 11075 try { 11076 IBackupManager bm = IBackupManager.Stub.asInterface( 11077 ServiceManager.getService(Context.BACKUP_SERVICE)); 11078 bm.agentDisconnected(app.info.packageName); 11079 } catch (RemoteException e) { 11080 // can't happen; backup manager is local 11081 } 11082 } 11083 11084 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 11085 ProcessChangeItem item = mPendingProcessChanges.get(i); 11086 if (item.pid == app.pid) { 11087 mPendingProcessChanges.remove(i); 11088 mAvailProcessChanges.add(item); 11089 } 11090 } 11091 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 11092 11093 // If the caller is restarting this app, then leave it in its 11094 // current lists and let the caller take care of it. 11095 if (restarting) { 11096 return; 11097 } 11098 11099 if (!app.persistent || app.isolated) { 11100 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 11101 "Removing non-persistent process during cleanup: " + app); 11102 mProcessNames.remove(app.processName, app.uid); 11103 mIsolatedProcesses.remove(app.uid); 11104 if (mHeavyWeightProcess == app) { 11105 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 11106 mHeavyWeightProcess.userId, 0)); 11107 mHeavyWeightProcess = null; 11108 } 11109 } else if (!app.removed) { 11110 // This app is persistent, so we need to keep its record around. 11111 // If it is not already on the pending app list, add it there 11112 // and start a new process for it. 11113 if (mPersistentStartingProcesses.indexOf(app) < 0) { 11114 mPersistentStartingProcesses.add(app); 11115 restart = true; 11116 } 11117 } 11118 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 11119 "Clean-up removing on hold: " + app); 11120 mProcessesOnHold.remove(app); 11121 11122 if (app == mHomeProcess) { 11123 mHomeProcess = null; 11124 } 11125 if (app == mPreviousProcess) { 11126 mPreviousProcess = null; 11127 } 11128 11129 if (restart && !app.isolated) { 11130 // We have components that still need to be running in the 11131 // process, so re-launch it. 11132 mProcessNames.put(app.processName, app.uid, app); 11133 startProcessLocked(app, "restart", app.processName); 11134 } else if (app.pid > 0 && app.pid != MY_PID) { 11135 // Goodbye! 11136 synchronized (mPidsSelfLocked) { 11137 mPidsSelfLocked.remove(app.pid); 11138 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 11139 } 11140 app.setPid(0); 11141 } 11142 } 11143 11144 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 11145 // Look through the content providers we are waiting to have launched, 11146 // and if any run in this process then either schedule a restart of 11147 // the process or kill the client waiting for it if this process has 11148 // gone bad. 11149 int NL = mLaunchingProviders.size(); 11150 boolean restart = false; 11151 for (int i=0; i<NL; i++) { 11152 ContentProviderRecord cpr = mLaunchingProviders.get(i); 11153 if (cpr.launchingApp == app) { 11154 if (!alwaysBad && !app.bad) { 11155 restart = true; 11156 } else { 11157 removeDyingProviderLocked(app, cpr, true); 11158 // cpr should have been removed from mLaunchingProviders 11159 NL = mLaunchingProviders.size(); 11160 i--; 11161 } 11162 } 11163 } 11164 return restart; 11165 } 11166 11167 // ========================================================= 11168 // SERVICES 11169 // ========================================================= 11170 11171 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 11172 int flags) { 11173 enforceNotIsolatedCaller("getServices"); 11174 synchronized (this) { 11175 return mServices.getRunningServiceInfoLocked(maxNum, flags); 11176 } 11177 } 11178 11179 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 11180 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 11181 synchronized (this) { 11182 return mServices.getRunningServiceControlPanelLocked(name); 11183 } 11184 } 11185 11186 public ComponentName startService(IApplicationThread caller, Intent service, 11187 String resolvedType, int userId) { 11188 enforceNotIsolatedCaller("startService"); 11189 // Refuse possible leaked file descriptors 11190 if (service != null && service.hasFileDescriptors() == true) { 11191 throw new IllegalArgumentException("File descriptors passed in Intent"); 11192 } 11193 11194 if (DEBUG_SERVICE) 11195 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 11196 synchronized(this) { 11197 final int callingPid = Binder.getCallingPid(); 11198 final int callingUid = Binder.getCallingUid(); 11199 checkValidCaller(callingUid, userId); 11200 final long origId = Binder.clearCallingIdentity(); 11201 ComponentName res = mServices.startServiceLocked(caller, service, 11202 resolvedType, callingPid, callingUid, userId); 11203 Binder.restoreCallingIdentity(origId); 11204 return res; 11205 } 11206 } 11207 11208 ComponentName startServiceInPackage(int uid, 11209 Intent service, String resolvedType, int userId) { 11210 synchronized(this) { 11211 if (DEBUG_SERVICE) 11212 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 11213 final long origId = Binder.clearCallingIdentity(); 11214 ComponentName res = mServices.startServiceLocked(null, service, 11215 resolvedType, -1, uid, userId); 11216 Binder.restoreCallingIdentity(origId); 11217 return res; 11218 } 11219 } 11220 11221 public int stopService(IApplicationThread caller, Intent service, 11222 String resolvedType, int userId) { 11223 enforceNotIsolatedCaller("stopService"); 11224 // Refuse possible leaked file descriptors 11225 if (service != null && service.hasFileDescriptors() == true) { 11226 throw new IllegalArgumentException("File descriptors passed in Intent"); 11227 } 11228 11229 checkValidCaller(Binder.getCallingUid(), userId); 11230 11231 synchronized(this) { 11232 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 11233 } 11234 } 11235 11236 public IBinder peekService(Intent service, String resolvedType) { 11237 enforceNotIsolatedCaller("peekService"); 11238 // Refuse possible leaked file descriptors 11239 if (service != null && service.hasFileDescriptors() == true) { 11240 throw new IllegalArgumentException("File descriptors passed in Intent"); 11241 } 11242 synchronized(this) { 11243 return mServices.peekServiceLocked(service, resolvedType); 11244 } 11245 } 11246 11247 public boolean stopServiceToken(ComponentName className, IBinder token, 11248 int startId) { 11249 synchronized(this) { 11250 return mServices.stopServiceTokenLocked(className, token, startId); 11251 } 11252 } 11253 11254 public void setServiceForeground(ComponentName className, IBinder token, 11255 int id, Notification notification, boolean removeNotification) { 11256 synchronized(this) { 11257 mServices.setServiceForegroundLocked(className, token, id, notification, 11258 removeNotification); 11259 } 11260 } 11261 11262 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 11263 boolean requireFull, String name, String callerPackage) { 11264 final int callingUserId = UserHandle.getUserId(callingUid); 11265 if (callingUserId != userId) { 11266 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 11267 if ((requireFull || checkComponentPermission( 11268 android.Manifest.permission.INTERACT_ACROSS_USERS, 11269 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 11270 && checkComponentPermission( 11271 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11272 callingPid, callingUid, -1, true) 11273 != PackageManager.PERMISSION_GRANTED) { 11274 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 11275 // In this case, they would like to just execute as their 11276 // owner user instead of failing. 11277 userId = callingUserId; 11278 } else { 11279 StringBuilder builder = new StringBuilder(128); 11280 builder.append("Permission Denial: "); 11281 builder.append(name); 11282 if (callerPackage != null) { 11283 builder.append(" from "); 11284 builder.append(callerPackage); 11285 } 11286 builder.append(" asks to run as user "); 11287 builder.append(userId); 11288 builder.append(" but is calling from user "); 11289 builder.append(UserHandle.getUserId(callingUid)); 11290 builder.append("; this requires "); 11291 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 11292 if (!requireFull) { 11293 builder.append(" or "); 11294 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 11295 } 11296 String msg = builder.toString(); 11297 Slog.w(TAG, msg); 11298 throw new SecurityException(msg); 11299 } 11300 } 11301 } 11302 if (userId == UserHandle.USER_CURRENT 11303 || userId == UserHandle.USER_CURRENT_OR_SELF) { 11304 // Note that we may be accessing this outside of a lock... 11305 // shouldn't be a big deal, if this is being called outside 11306 // of a locked context there is intrinsically a race with 11307 // the value the caller will receive and someone else changing it. 11308 userId = mCurrentUserId; 11309 } 11310 if (!allowAll && userId < 0) { 11311 throw new IllegalArgumentException( 11312 "Call does not support special user #" + userId); 11313 } 11314 } 11315 return userId; 11316 } 11317 11318 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11319 String className, int flags) { 11320 boolean result = false; 11321 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11322 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11323 if (ActivityManager.checkUidPermission( 11324 android.Manifest.permission.INTERACT_ACROSS_USERS, 11325 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11326 ComponentName comp = new ComponentName(aInfo.packageName, className); 11327 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11328 + " requests FLAG_SINGLE_USER, but app does not hold " 11329 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11330 Slog.w(TAG, msg); 11331 throw new SecurityException(msg); 11332 } 11333 result = true; 11334 } 11335 } else if (componentProcessName == aInfo.packageName) { 11336 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11337 } else if ("system".equals(componentProcessName)) { 11338 result = true; 11339 } 11340 if (DEBUG_MU) { 11341 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11342 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11343 } 11344 return result; 11345 } 11346 11347 public int bindService(IApplicationThread caller, IBinder token, 11348 Intent service, String resolvedType, 11349 IServiceConnection connection, int flags, int userId) { 11350 enforceNotIsolatedCaller("bindService"); 11351 // Refuse possible leaked file descriptors 11352 if (service != null && service.hasFileDescriptors() == true) { 11353 throw new IllegalArgumentException("File descriptors passed in Intent"); 11354 } 11355 11356 synchronized(this) { 11357 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11358 connection, flags, userId); 11359 } 11360 } 11361 11362 public boolean unbindService(IServiceConnection connection) { 11363 synchronized (this) { 11364 return mServices.unbindServiceLocked(connection); 11365 } 11366 } 11367 11368 public void publishService(IBinder token, Intent intent, IBinder service) { 11369 // Refuse possible leaked file descriptors 11370 if (intent != null && intent.hasFileDescriptors() == true) { 11371 throw new IllegalArgumentException("File descriptors passed in Intent"); 11372 } 11373 11374 synchronized(this) { 11375 if (!(token instanceof ServiceRecord)) { 11376 throw new IllegalArgumentException("Invalid service token"); 11377 } 11378 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11379 } 11380 } 11381 11382 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11383 // Refuse possible leaked file descriptors 11384 if (intent != null && intent.hasFileDescriptors() == true) { 11385 throw new IllegalArgumentException("File descriptors passed in Intent"); 11386 } 11387 11388 synchronized(this) { 11389 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11390 } 11391 } 11392 11393 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11394 synchronized(this) { 11395 if (!(token instanceof ServiceRecord)) { 11396 throw new IllegalArgumentException("Invalid service token"); 11397 } 11398 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11399 } 11400 } 11401 11402 // ========================================================= 11403 // BACKUP AND RESTORE 11404 // ========================================================= 11405 11406 // Cause the target app to be launched if necessary and its backup agent 11407 // instantiated. The backup agent will invoke backupAgentCreated() on the 11408 // activity manager to announce its creation. 11409 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11410 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 11411 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 11412 11413 synchronized(this) { 11414 // !!! TODO: currently no check here that we're already bound 11415 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11416 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11417 synchronized (stats) { 11418 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11419 } 11420 11421 // Backup agent is now in use, its package can't be stopped. 11422 try { 11423 AppGlobals.getPackageManager().setPackageStoppedState( 11424 app.packageName, false, UserHandle.getUserId(app.uid)); 11425 } catch (RemoteException e) { 11426 } catch (IllegalArgumentException e) { 11427 Slog.w(TAG, "Failed trying to unstop package " 11428 + app.packageName + ": " + e); 11429 } 11430 11431 BackupRecord r = new BackupRecord(ss, app, backupMode); 11432 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11433 ? new ComponentName(app.packageName, app.backupAgentName) 11434 : new ComponentName("android", "FullBackupAgent"); 11435 // startProcessLocked() returns existing proc's record if it's already running 11436 ProcessRecord proc = startProcessLocked(app.processName, app, 11437 false, 0, "backup", hostingName, false, false); 11438 if (proc == null) { 11439 Slog.e(TAG, "Unable to start backup agent process " + r); 11440 return false; 11441 } 11442 11443 r.app = proc; 11444 mBackupTarget = r; 11445 mBackupAppName = app.packageName; 11446 11447 // Try not to kill the process during backup 11448 updateOomAdjLocked(proc); 11449 11450 // If the process is already attached, schedule the creation of the backup agent now. 11451 // If it is not yet live, this will be done when it attaches to the framework. 11452 if (proc.thread != null) { 11453 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11454 try { 11455 proc.thread.scheduleCreateBackupAgent(app, 11456 compatibilityInfoForPackageLocked(app), backupMode); 11457 } catch (RemoteException e) { 11458 // Will time out on the backup manager side 11459 } 11460 } else { 11461 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11462 } 11463 // Invariants: at this point, the target app process exists and the application 11464 // is either already running or in the process of coming up. mBackupTarget and 11465 // mBackupAppName describe the app, so that when it binds back to the AM we 11466 // know that it's scheduled for a backup-agent operation. 11467 } 11468 11469 return true; 11470 } 11471 11472 @Override 11473 public void clearPendingBackup() { 11474 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 11475 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 11476 11477 synchronized (this) { 11478 mBackupTarget = null; 11479 mBackupAppName = null; 11480 } 11481 } 11482 11483 // A backup agent has just come up 11484 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11485 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11486 + " = " + agent); 11487 11488 synchronized(this) { 11489 if (!agentPackageName.equals(mBackupAppName)) { 11490 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11491 return; 11492 } 11493 } 11494 11495 long oldIdent = Binder.clearCallingIdentity(); 11496 try { 11497 IBackupManager bm = IBackupManager.Stub.asInterface( 11498 ServiceManager.getService(Context.BACKUP_SERVICE)); 11499 bm.agentConnected(agentPackageName, agent); 11500 } catch (RemoteException e) { 11501 // can't happen; the backup manager service is local 11502 } catch (Exception e) { 11503 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11504 e.printStackTrace(); 11505 } finally { 11506 Binder.restoreCallingIdentity(oldIdent); 11507 } 11508 } 11509 11510 // done with this agent 11511 public void unbindBackupAgent(ApplicationInfo appInfo) { 11512 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11513 if (appInfo == null) { 11514 Slog.w(TAG, "unbind backup agent for null app"); 11515 return; 11516 } 11517 11518 synchronized(this) { 11519 try { 11520 if (mBackupAppName == null) { 11521 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11522 return; 11523 } 11524 11525 if (!mBackupAppName.equals(appInfo.packageName)) { 11526 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11527 return; 11528 } 11529 11530 // Not backing this app up any more; reset its OOM adjustment 11531 final ProcessRecord proc = mBackupTarget.app; 11532 updateOomAdjLocked(proc); 11533 11534 // If the app crashed during backup, 'thread' will be null here 11535 if (proc.thread != null) { 11536 try { 11537 proc.thread.scheduleDestroyBackupAgent(appInfo, 11538 compatibilityInfoForPackageLocked(appInfo)); 11539 } catch (Exception e) { 11540 Slog.e(TAG, "Exception when unbinding backup agent:"); 11541 e.printStackTrace(); 11542 } 11543 } 11544 } finally { 11545 mBackupTarget = null; 11546 mBackupAppName = null; 11547 } 11548 } 11549 } 11550 // ========================================================= 11551 // BROADCASTS 11552 // ========================================================= 11553 11554 private final List getStickiesLocked(String action, IntentFilter filter, 11555 List cur, int userId) { 11556 final ContentResolver resolver = mContext.getContentResolver(); 11557 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11558 if (stickies == null) { 11559 return cur; 11560 } 11561 final ArrayList<Intent> list = stickies.get(action); 11562 if (list == null) { 11563 return cur; 11564 } 11565 int N = list.size(); 11566 for (int i=0; i<N; i++) { 11567 Intent intent = list.get(i); 11568 if (filter.match(resolver, intent, true, TAG) >= 0) { 11569 if (cur == null) { 11570 cur = new ArrayList<Intent>(); 11571 } 11572 cur.add(intent); 11573 } 11574 } 11575 return cur; 11576 } 11577 11578 boolean isPendingBroadcastProcessLocked(int pid) { 11579 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11580 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11581 } 11582 11583 void skipPendingBroadcastLocked(int pid) { 11584 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11585 for (BroadcastQueue queue : mBroadcastQueues) { 11586 queue.skipPendingBroadcastLocked(pid); 11587 } 11588 } 11589 11590 // The app just attached; send any pending broadcasts that it should receive 11591 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11592 boolean didSomething = false; 11593 for (BroadcastQueue queue : mBroadcastQueues) { 11594 didSomething |= queue.sendPendingBroadcastsLocked(app); 11595 } 11596 return didSomething; 11597 } 11598 11599 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11600 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11601 enforceNotIsolatedCaller("registerReceiver"); 11602 int callingUid; 11603 int callingPid; 11604 synchronized(this) { 11605 ProcessRecord callerApp = null; 11606 if (caller != null) { 11607 callerApp = getRecordForAppLocked(caller); 11608 if (callerApp == null) { 11609 throw new SecurityException( 11610 "Unable to find app for caller " + caller 11611 + " (pid=" + Binder.getCallingPid() 11612 + ") when registering receiver " + receiver); 11613 } 11614 if (callerApp.info.uid != Process.SYSTEM_UID && 11615 !callerApp.pkgList.contains(callerPackage)) { 11616 throw new SecurityException("Given caller package " + callerPackage 11617 + " is not running in process " + callerApp); 11618 } 11619 callingUid = callerApp.info.uid; 11620 callingPid = callerApp.pid; 11621 } else { 11622 callerPackage = null; 11623 callingUid = Binder.getCallingUid(); 11624 callingPid = Binder.getCallingPid(); 11625 } 11626 11627 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11628 true, true, "registerReceiver", callerPackage); 11629 11630 List allSticky = null; 11631 11632 // Look for any matching sticky broadcasts... 11633 Iterator actions = filter.actionsIterator(); 11634 if (actions != null) { 11635 while (actions.hasNext()) { 11636 String action = (String)actions.next(); 11637 allSticky = getStickiesLocked(action, filter, allSticky, 11638 UserHandle.USER_ALL); 11639 allSticky = getStickiesLocked(action, filter, allSticky, 11640 UserHandle.getUserId(callingUid)); 11641 } 11642 } else { 11643 allSticky = getStickiesLocked(null, filter, allSticky, 11644 UserHandle.USER_ALL); 11645 allSticky = getStickiesLocked(null, filter, allSticky, 11646 UserHandle.getUserId(callingUid)); 11647 } 11648 11649 // The first sticky in the list is returned directly back to 11650 // the client. 11651 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11652 11653 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11654 + ": " + sticky); 11655 11656 if (receiver == null) { 11657 return sticky; 11658 } 11659 11660 ReceiverList rl 11661 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11662 if (rl == null) { 11663 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11664 userId, receiver); 11665 if (rl.app != null) { 11666 rl.app.receivers.add(rl); 11667 } else { 11668 try { 11669 receiver.asBinder().linkToDeath(rl, 0); 11670 } catch (RemoteException e) { 11671 return sticky; 11672 } 11673 rl.linkedToDeath = true; 11674 } 11675 mRegisteredReceivers.put(receiver.asBinder(), rl); 11676 } else if (rl.uid != callingUid) { 11677 throw new IllegalArgumentException( 11678 "Receiver requested to register for uid " + callingUid 11679 + " was previously registered for uid " + rl.uid); 11680 } else if (rl.pid != callingPid) { 11681 throw new IllegalArgumentException( 11682 "Receiver requested to register for pid " + callingPid 11683 + " was previously registered for pid " + rl.pid); 11684 } else if (rl.userId != userId) { 11685 throw new IllegalArgumentException( 11686 "Receiver requested to register for user " + userId 11687 + " was previously registered for user " + rl.userId); 11688 } 11689 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11690 permission, callingUid, userId); 11691 rl.add(bf); 11692 if (!bf.debugCheck()) { 11693 Slog.w(TAG, "==> For Dynamic broadast"); 11694 } 11695 mReceiverResolver.addFilter(bf); 11696 11697 // Enqueue broadcasts for all existing stickies that match 11698 // this filter. 11699 if (allSticky != null) { 11700 ArrayList receivers = new ArrayList(); 11701 receivers.add(bf); 11702 11703 int N = allSticky.size(); 11704 for (int i=0; i<N; i++) { 11705 Intent intent = (Intent)allSticky.get(i); 11706 BroadcastQueue queue = broadcastQueueForIntent(intent); 11707 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11708 null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0, 11709 null, null, false, true, true, -1); 11710 queue.enqueueParallelBroadcastLocked(r); 11711 queue.scheduleBroadcastsLocked(); 11712 } 11713 } 11714 11715 return sticky; 11716 } 11717 } 11718 11719 public void unregisterReceiver(IIntentReceiver receiver) { 11720 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11721 11722 final long origId = Binder.clearCallingIdentity(); 11723 try { 11724 boolean doTrim = false; 11725 11726 synchronized(this) { 11727 ReceiverList rl 11728 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11729 if (rl != null) { 11730 if (rl.curBroadcast != null) { 11731 BroadcastRecord r = rl.curBroadcast; 11732 final boolean doNext = finishReceiverLocked( 11733 receiver.asBinder(), r.resultCode, r.resultData, 11734 r.resultExtras, r.resultAbort, true); 11735 if (doNext) { 11736 doTrim = true; 11737 r.queue.processNextBroadcast(false); 11738 } 11739 } 11740 11741 if (rl.app != null) { 11742 rl.app.receivers.remove(rl); 11743 } 11744 removeReceiverLocked(rl); 11745 if (rl.linkedToDeath) { 11746 rl.linkedToDeath = false; 11747 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11748 } 11749 } 11750 } 11751 11752 // If we actually concluded any broadcasts, we might now be able 11753 // to trim the recipients' apps from our working set 11754 if (doTrim) { 11755 trimApplications(); 11756 return; 11757 } 11758 11759 } finally { 11760 Binder.restoreCallingIdentity(origId); 11761 } 11762 } 11763 11764 void removeReceiverLocked(ReceiverList rl) { 11765 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11766 int N = rl.size(); 11767 for (int i=0; i<N; i++) { 11768 mReceiverResolver.removeFilter(rl.get(i)); 11769 } 11770 } 11771 11772 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11773 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11774 ProcessRecord r = mLruProcesses.get(i); 11775 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11776 try { 11777 r.thread.dispatchPackageBroadcast(cmd, packages); 11778 } catch (RemoteException ex) { 11779 } 11780 } 11781 } 11782 } 11783 11784 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11785 int[] users) { 11786 List<ResolveInfo> receivers = null; 11787 try { 11788 HashSet<ComponentName> singleUserReceivers = null; 11789 boolean scannedFirstReceivers = false; 11790 for (int user : users) { 11791 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11792 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11793 if (user != 0 && newReceivers != null) { 11794 // If this is not the primary user, we need to check for 11795 // any receivers that should be filtered out. 11796 for (int i=0; i<newReceivers.size(); i++) { 11797 ResolveInfo ri = newReceivers.get(i); 11798 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11799 newReceivers.remove(i); 11800 i--; 11801 } 11802 } 11803 } 11804 if (newReceivers != null && newReceivers.size() == 0) { 11805 newReceivers = null; 11806 } 11807 if (receivers == null) { 11808 receivers = newReceivers; 11809 } else if (newReceivers != null) { 11810 // We need to concatenate the additional receivers 11811 // found with what we have do far. This would be easy, 11812 // but we also need to de-dup any receivers that are 11813 // singleUser. 11814 if (!scannedFirstReceivers) { 11815 // Collect any single user receivers we had already retrieved. 11816 scannedFirstReceivers = true; 11817 for (int i=0; i<receivers.size(); i++) { 11818 ResolveInfo ri = receivers.get(i); 11819 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11820 ComponentName cn = new ComponentName( 11821 ri.activityInfo.packageName, ri.activityInfo.name); 11822 if (singleUserReceivers == null) { 11823 singleUserReceivers = new HashSet<ComponentName>(); 11824 } 11825 singleUserReceivers.add(cn); 11826 } 11827 } 11828 } 11829 // Add the new results to the existing results, tracking 11830 // and de-dupping single user receivers. 11831 for (int i=0; i<newReceivers.size(); i++) { 11832 ResolveInfo ri = newReceivers.get(i); 11833 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11834 ComponentName cn = new ComponentName( 11835 ri.activityInfo.packageName, ri.activityInfo.name); 11836 if (singleUserReceivers == null) { 11837 singleUserReceivers = new HashSet<ComponentName>(); 11838 } 11839 if (!singleUserReceivers.contains(cn)) { 11840 singleUserReceivers.add(cn); 11841 receivers.add(ri); 11842 } 11843 } else { 11844 receivers.add(ri); 11845 } 11846 } 11847 } 11848 } 11849 } catch (RemoteException ex) { 11850 // pm is in same process, this will never happen. 11851 } 11852 return receivers; 11853 } 11854 11855 private final int broadcastIntentLocked(ProcessRecord callerApp, 11856 String callerPackage, Intent intent, String resolvedType, 11857 IIntentReceiver resultTo, int resultCode, String resultData, 11858 Bundle map, String requiredPermission, int appOp, 11859 boolean ordered, boolean sticky, int callingPid, int callingUid, 11860 int userId) { 11861 intent = new Intent(intent); 11862 11863 // By default broadcasts do not go to stopped apps. 11864 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11865 11866 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11867 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11868 + " ordered=" + ordered + " userid=" + userId); 11869 if ((resultTo != null) && !ordered) { 11870 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11871 } 11872 11873 userId = handleIncomingUser(callingPid, callingUid, userId, 11874 true, false, "broadcast", callerPackage); 11875 11876 // Make sure that the user who is receiving this broadcast is started. 11877 // If not, we will just skip it. 11878 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11879 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11880 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11881 Slog.w(TAG, "Skipping broadcast of " + intent 11882 + ": user " + userId + " is stopped"); 11883 return ActivityManager.BROADCAST_SUCCESS; 11884 } 11885 } 11886 11887 /* 11888 * Prevent non-system code (defined here to be non-persistent 11889 * processes) from sending protected broadcasts. 11890 */ 11891 int callingAppId = UserHandle.getAppId(callingUid); 11892 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11893 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11894 callingUid == 0) { 11895 // Always okay. 11896 } else if (callerApp == null || !callerApp.persistent) { 11897 try { 11898 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11899 intent.getAction())) { 11900 String msg = "Permission Denial: not allowed to send broadcast " 11901 + intent.getAction() + " from pid=" 11902 + callingPid + ", uid=" + callingUid; 11903 Slog.w(TAG, msg); 11904 throw new SecurityException(msg); 11905 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 11906 // Special case for compatibility: we don't want apps to send this, 11907 // but historically it has not been protected and apps may be using it 11908 // to poke their own app widget. So, instead of making it protected, 11909 // just limit it to the caller. 11910 if (callerApp == null) { 11911 String msg = "Permission Denial: not allowed to send broadcast " 11912 + intent.getAction() + " from unknown caller."; 11913 Slog.w(TAG, msg); 11914 throw new SecurityException(msg); 11915 } else if (intent.getComponent() != null) { 11916 // They are good enough to send to an explicit component... verify 11917 // it is being sent to the calling app. 11918 if (!intent.getComponent().getPackageName().equals( 11919 callerApp.info.packageName)) { 11920 String msg = "Permission Denial: not allowed to send broadcast " 11921 + intent.getAction() + " to " 11922 + intent.getComponent().getPackageName() + " from " 11923 + callerApp.info.packageName; 11924 Slog.w(TAG, msg); 11925 throw new SecurityException(msg); 11926 } 11927 } else { 11928 // Limit broadcast to their own package. 11929 intent.setPackage(callerApp.info.packageName); 11930 } 11931 } 11932 } catch (RemoteException e) { 11933 Slog.w(TAG, "Remote exception", e); 11934 return ActivityManager.BROADCAST_SUCCESS; 11935 } 11936 } 11937 11938 // Handle special intents: if this broadcast is from the package 11939 // manager about a package being removed, we need to remove all of 11940 // its activities from the history stack. 11941 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11942 intent.getAction()); 11943 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11944 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11945 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11946 || uidRemoved) { 11947 if (checkComponentPermission( 11948 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11949 callingPid, callingUid, -1, true) 11950 == PackageManager.PERMISSION_GRANTED) { 11951 if (uidRemoved) { 11952 final Bundle intentExtras = intent.getExtras(); 11953 final int uid = intentExtras != null 11954 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11955 if (uid >= 0) { 11956 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11957 synchronized (bs) { 11958 bs.removeUidStatsLocked(uid); 11959 } 11960 mAppOpsService.uidRemoved(uid); 11961 } 11962 } else { 11963 // If resources are unavailable just force stop all 11964 // those packages and flush the attribute cache as well. 11965 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11966 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11967 if (list != null && (list.length > 0)) { 11968 for (String pkg : list) { 11969 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11970 } 11971 sendPackageBroadcastLocked( 11972 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11973 } 11974 } else { 11975 Uri data = intent.getData(); 11976 String ssp; 11977 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11978 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11979 forceStopPackageLocked(ssp, 11980 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11981 false, userId); 11982 } 11983 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11984 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11985 new String[] {ssp}, userId); 11986 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 11987 mAppOpsService.packageRemoved( 11988 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 11989 } 11990 } 11991 } 11992 } 11993 } 11994 } else { 11995 String msg = "Permission Denial: " + intent.getAction() 11996 + " broadcast from " + callerPackage + " (pid=" + callingPid 11997 + ", uid=" + callingUid + ")" 11998 + " requires " 11999 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12000 Slog.w(TAG, msg); 12001 throw new SecurityException(msg); 12002 } 12003 12004 // Special case for adding a package: by default turn on compatibility 12005 // mode. 12006 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12007 Uri data = intent.getData(); 12008 String ssp; 12009 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12010 mCompatModePackages.handlePackageAddedLocked(ssp, 12011 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12012 } 12013 } 12014 12015 /* 12016 * If this is the time zone changed action, queue up a message that will reset the timezone 12017 * of all currently running processes. This message will get queued up before the broadcast 12018 * happens. 12019 */ 12020 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12021 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12022 } 12023 12024 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12025 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12026 } 12027 12028 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12029 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12030 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12031 } 12032 12033 // Add to the sticky list if requested. 12034 if (sticky) { 12035 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12036 callingPid, callingUid) 12037 != PackageManager.PERMISSION_GRANTED) { 12038 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12039 + callingPid + ", uid=" + callingUid 12040 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12041 Slog.w(TAG, msg); 12042 throw new SecurityException(msg); 12043 } 12044 if (requiredPermission != null) { 12045 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12046 + " and enforce permission " + requiredPermission); 12047 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12048 } 12049 if (intent.getComponent() != null) { 12050 throw new SecurityException( 12051 "Sticky broadcasts can't target a specific component"); 12052 } 12053 // We use userId directly here, since the "all" target is maintained 12054 // as a separate set of sticky broadcasts. 12055 if (userId != UserHandle.USER_ALL) { 12056 // But first, if this is not a broadcast to all users, then 12057 // make sure it doesn't conflict with an existing broadcast to 12058 // all users. 12059 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 12060 UserHandle.USER_ALL); 12061 if (stickies != null) { 12062 ArrayList<Intent> list = stickies.get(intent.getAction()); 12063 if (list != null) { 12064 int N = list.size(); 12065 int i; 12066 for (i=0; i<N; i++) { 12067 if (intent.filterEquals(list.get(i))) { 12068 throw new IllegalArgumentException( 12069 "Sticky broadcast " + intent + " for user " 12070 + userId + " conflicts with existing global broadcast"); 12071 } 12072 } 12073 } 12074 } 12075 } 12076 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12077 if (stickies == null) { 12078 stickies = new HashMap<String, ArrayList<Intent>>(); 12079 mStickyBroadcasts.put(userId, stickies); 12080 } 12081 ArrayList<Intent> list = stickies.get(intent.getAction()); 12082 if (list == null) { 12083 list = new ArrayList<Intent>(); 12084 stickies.put(intent.getAction(), list); 12085 } 12086 int N = list.size(); 12087 int i; 12088 for (i=0; i<N; i++) { 12089 if (intent.filterEquals(list.get(i))) { 12090 // This sticky already exists, replace it. 12091 list.set(i, new Intent(intent)); 12092 break; 12093 } 12094 } 12095 if (i >= N) { 12096 list.add(new Intent(intent)); 12097 } 12098 } 12099 12100 int[] users; 12101 if (userId == UserHandle.USER_ALL) { 12102 // Caller wants broadcast to go to all started users. 12103 users = mStartedUserArray; 12104 } else { 12105 // Caller wants broadcast to go to one specific user. 12106 users = new int[] {userId}; 12107 } 12108 12109 // Figure out who all will receive this broadcast. 12110 List receivers = null; 12111 List<BroadcastFilter> registeredReceivers = null; 12112 // Need to resolve the intent to interested receivers... 12113 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12114 == 0) { 12115 receivers = collectReceiverComponents(intent, resolvedType, users); 12116 } 12117 if (intent.getComponent() == null) { 12118 registeredReceivers = mReceiverResolver.queryIntent(intent, 12119 resolvedType, false, userId); 12120 } 12121 12122 final boolean replacePending = 12123 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12124 12125 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 12126 + " replacePending=" + replacePending); 12127 12128 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12129 if (!ordered && NR > 0) { 12130 // If we are not serializing this broadcast, then send the 12131 // registered receivers separately so they don't wait for the 12132 // components to be launched. 12133 final BroadcastQueue queue = broadcastQueueForIntent(intent); 12134 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 12135 callerPackage, callingPid, callingUid, requiredPermission, appOp, 12136 registeredReceivers, resultTo, resultCode, resultData, map, 12137 ordered, sticky, false, userId); 12138 if (DEBUG_BROADCAST) Slog.v( 12139 TAG, "Enqueueing parallel broadcast " + r); 12140 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 12141 if (!replaced) { 12142 queue.enqueueParallelBroadcastLocked(r); 12143 queue.scheduleBroadcastsLocked(); 12144 } 12145 registeredReceivers = null; 12146 NR = 0; 12147 } 12148 12149 // Merge into one list. 12150 int ir = 0; 12151 if (receivers != null) { 12152 // A special case for PACKAGE_ADDED: do not allow the package 12153 // being added to see this broadcast. This prevents them from 12154 // using this as a back door to get run as soon as they are 12155 // installed. Maybe in the future we want to have a special install 12156 // broadcast or such for apps, but we'd like to deliberately make 12157 // this decision. 12158 String skipPackages[] = null; 12159 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12160 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12161 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12162 Uri data = intent.getData(); 12163 if (data != null) { 12164 String pkgName = data.getSchemeSpecificPart(); 12165 if (pkgName != null) { 12166 skipPackages = new String[] { pkgName }; 12167 } 12168 } 12169 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12170 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12171 } 12172 if (skipPackages != null && (skipPackages.length > 0)) { 12173 for (String skipPackage : skipPackages) { 12174 if (skipPackage != null) { 12175 int NT = receivers.size(); 12176 for (int it=0; it<NT; it++) { 12177 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12178 if (curt.activityInfo.packageName.equals(skipPackage)) { 12179 receivers.remove(it); 12180 it--; 12181 NT--; 12182 } 12183 } 12184 } 12185 } 12186 } 12187 12188 int NT = receivers != null ? receivers.size() : 0; 12189 int it = 0; 12190 ResolveInfo curt = null; 12191 BroadcastFilter curr = null; 12192 while (it < NT && ir < NR) { 12193 if (curt == null) { 12194 curt = (ResolveInfo)receivers.get(it); 12195 } 12196 if (curr == null) { 12197 curr = registeredReceivers.get(ir); 12198 } 12199 if (curr.getPriority() >= curt.priority) { 12200 // Insert this broadcast record into the final list. 12201 receivers.add(it, curr); 12202 ir++; 12203 curr = null; 12204 it++; 12205 NT++; 12206 } else { 12207 // Skip to the next ResolveInfo in the final list. 12208 it++; 12209 curt = null; 12210 } 12211 } 12212 } 12213 while (ir < NR) { 12214 if (receivers == null) { 12215 receivers = new ArrayList(); 12216 } 12217 receivers.add(registeredReceivers.get(ir)); 12218 ir++; 12219 } 12220 12221 if ((receivers != null && receivers.size() > 0) 12222 || resultTo != null) { 12223 BroadcastQueue queue = broadcastQueueForIntent(intent); 12224 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 12225 callerPackage, callingPid, callingUid, requiredPermission, appOp, 12226 receivers, resultTo, resultCode, resultData, map, ordered, 12227 sticky, false, userId); 12228 if (DEBUG_BROADCAST) Slog.v( 12229 TAG, "Enqueueing ordered broadcast " + r 12230 + ": prev had " + queue.mOrderedBroadcasts.size()); 12231 if (DEBUG_BROADCAST) { 12232 int seq = r.intent.getIntExtra("seq", -1); 12233 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12234 } 12235 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 12236 if (!replaced) { 12237 queue.enqueueOrderedBroadcastLocked(r); 12238 queue.scheduleBroadcastsLocked(); 12239 } 12240 } 12241 12242 return ActivityManager.BROADCAST_SUCCESS; 12243 } 12244 12245 final Intent verifyBroadcastLocked(Intent intent) { 12246 // Refuse possible leaked file descriptors 12247 if (intent != null && intent.hasFileDescriptors() == true) { 12248 throw new IllegalArgumentException("File descriptors passed in Intent"); 12249 } 12250 12251 int flags = intent.getFlags(); 12252 12253 if (!mProcessesReady) { 12254 // if the caller really truly claims to know what they're doing, go 12255 // ahead and allow the broadcast without launching any receivers 12256 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12257 intent = new Intent(intent); 12258 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12259 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 12260 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12261 + " before boot completion"); 12262 throw new IllegalStateException("Cannot broadcast before boot completed"); 12263 } 12264 } 12265 12266 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12267 throw new IllegalArgumentException( 12268 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12269 } 12270 12271 return intent; 12272 } 12273 12274 public final int broadcastIntent(IApplicationThread caller, 12275 Intent intent, String resolvedType, IIntentReceiver resultTo, 12276 int resultCode, String resultData, Bundle map, 12277 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 12278 enforceNotIsolatedCaller("broadcastIntent"); 12279 synchronized(this) { 12280 intent = verifyBroadcastLocked(intent); 12281 12282 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12283 final int callingPid = Binder.getCallingPid(); 12284 final int callingUid = Binder.getCallingUid(); 12285 final long origId = Binder.clearCallingIdentity(); 12286 int res = broadcastIntentLocked(callerApp, 12287 callerApp != null ? callerApp.info.packageName : null, 12288 intent, resolvedType, resultTo, 12289 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 12290 callingPid, callingUid, userId); 12291 Binder.restoreCallingIdentity(origId); 12292 return res; 12293 } 12294 } 12295 12296 int broadcastIntentInPackage(String packageName, int uid, 12297 Intent intent, String resolvedType, IIntentReceiver resultTo, 12298 int resultCode, String resultData, Bundle map, 12299 String requiredPermission, boolean serialized, boolean sticky, int userId) { 12300 synchronized(this) { 12301 intent = verifyBroadcastLocked(intent); 12302 12303 final long origId = Binder.clearCallingIdentity(); 12304 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12305 resultTo, resultCode, resultData, map, requiredPermission, 12306 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 12307 Binder.restoreCallingIdentity(origId); 12308 return res; 12309 } 12310 } 12311 12312 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 12313 // Refuse possible leaked file descriptors 12314 if (intent != null && intent.hasFileDescriptors() == true) { 12315 throw new IllegalArgumentException("File descriptors passed in Intent"); 12316 } 12317 12318 userId = handleIncomingUser(Binder.getCallingPid(), 12319 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 12320 12321 synchronized(this) { 12322 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12323 != PackageManager.PERMISSION_GRANTED) { 12324 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12325 + Binder.getCallingPid() 12326 + ", uid=" + Binder.getCallingUid() 12327 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12328 Slog.w(TAG, msg); 12329 throw new SecurityException(msg); 12330 } 12331 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12332 if (stickies != null) { 12333 ArrayList<Intent> list = stickies.get(intent.getAction()); 12334 if (list != null) { 12335 int N = list.size(); 12336 int i; 12337 for (i=0; i<N; i++) { 12338 if (intent.filterEquals(list.get(i))) { 12339 list.remove(i); 12340 break; 12341 } 12342 } 12343 if (list.size() <= 0) { 12344 stickies.remove(intent.getAction()); 12345 } 12346 } 12347 if (stickies.size() <= 0) { 12348 mStickyBroadcasts.remove(userId); 12349 } 12350 } 12351 } 12352 } 12353 12354 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12355 String resultData, Bundle resultExtras, boolean resultAbort, 12356 boolean explicit) { 12357 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 12358 if (r == null) { 12359 Slog.w(TAG, "finishReceiver called but not found on queue"); 12360 return false; 12361 } 12362 12363 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12364 explicit); 12365 } 12366 12367 public void finishReceiver(IBinder who, int resultCode, String resultData, 12368 Bundle resultExtras, boolean resultAbort) { 12369 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12370 12371 // Refuse possible leaked file descriptors 12372 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12373 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12374 } 12375 12376 final long origId = Binder.clearCallingIdentity(); 12377 try { 12378 boolean doNext = false; 12379 BroadcastRecord r = null; 12380 12381 synchronized(this) { 12382 r = broadcastRecordForReceiverLocked(who); 12383 if (r != null) { 12384 doNext = r.queue.finishReceiverLocked(r, resultCode, 12385 resultData, resultExtras, resultAbort, true); 12386 } 12387 } 12388 12389 if (doNext) { 12390 r.queue.processNextBroadcast(false); 12391 } 12392 trimApplications(); 12393 } finally { 12394 Binder.restoreCallingIdentity(origId); 12395 } 12396 } 12397 12398 // ========================================================= 12399 // INSTRUMENTATION 12400 // ========================================================= 12401 12402 public boolean startInstrumentation(ComponentName className, 12403 String profileFile, int flags, Bundle arguments, 12404 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 12405 int userId) { 12406 enforceNotIsolatedCaller("startInstrumentation"); 12407 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12408 userId, false, true, "startInstrumentation", null); 12409 // Refuse possible leaked file descriptors 12410 if (arguments != null && arguments.hasFileDescriptors()) { 12411 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12412 } 12413 12414 synchronized(this) { 12415 InstrumentationInfo ii = null; 12416 ApplicationInfo ai = null; 12417 try { 12418 ii = mContext.getPackageManager().getInstrumentationInfo( 12419 className, STOCK_PM_FLAGS); 12420 ai = AppGlobals.getPackageManager().getApplicationInfo( 12421 ii.targetPackage, STOCK_PM_FLAGS, userId); 12422 } catch (PackageManager.NameNotFoundException e) { 12423 } catch (RemoteException e) { 12424 } 12425 if (ii == null) { 12426 reportStartInstrumentationFailure(watcher, className, 12427 "Unable to find instrumentation info for: " + className); 12428 return false; 12429 } 12430 if (ai == null) { 12431 reportStartInstrumentationFailure(watcher, className, 12432 "Unable to find instrumentation target package: " + ii.targetPackage); 12433 return false; 12434 } 12435 12436 int match = mContext.getPackageManager().checkSignatures( 12437 ii.targetPackage, ii.packageName); 12438 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12439 String msg = "Permission Denial: starting instrumentation " 12440 + className + " from pid=" 12441 + Binder.getCallingPid() 12442 + ", uid=" + Binder.getCallingPid() 12443 + " not allowed because package " + ii.packageName 12444 + " does not have a signature matching the target " 12445 + ii.targetPackage; 12446 reportStartInstrumentationFailure(watcher, className, msg); 12447 throw new SecurityException(msg); 12448 } 12449 12450 final long origId = Binder.clearCallingIdentity(); 12451 // Instrumentation can kill and relaunch even persistent processes 12452 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12453 ProcessRecord app = addAppLocked(ai, false); 12454 app.instrumentationClass = className; 12455 app.instrumentationInfo = ai; 12456 app.instrumentationProfileFile = profileFile; 12457 app.instrumentationArguments = arguments; 12458 app.instrumentationWatcher = watcher; 12459 app.instrumentationUiAutomationConnection = uiAutomationConnection; 12460 app.instrumentationResultClass = className; 12461 Binder.restoreCallingIdentity(origId); 12462 } 12463 12464 return true; 12465 } 12466 12467 /** 12468 * Report errors that occur while attempting to start Instrumentation. Always writes the 12469 * error to the logs, but if somebody is watching, send the report there too. This enables 12470 * the "am" command to report errors with more information. 12471 * 12472 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12473 * @param cn The component name of the instrumentation. 12474 * @param report The error report. 12475 */ 12476 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12477 ComponentName cn, String report) { 12478 Slog.w(TAG, report); 12479 try { 12480 if (watcher != null) { 12481 Bundle results = new Bundle(); 12482 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12483 results.putString("Error", report); 12484 watcher.instrumentationStatus(cn, -1, results); 12485 } 12486 } catch (RemoteException e) { 12487 Slog.w(TAG, e); 12488 } 12489 } 12490 12491 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12492 if (app.instrumentationWatcher != null) { 12493 try { 12494 // NOTE: IInstrumentationWatcher *must* be oneway here 12495 app.instrumentationWatcher.instrumentationFinished( 12496 app.instrumentationClass, 12497 resultCode, 12498 results); 12499 } catch (RemoteException e) { 12500 } 12501 } 12502 if (app.instrumentationUiAutomationConnection != null) { 12503 try { 12504 app.instrumentationUiAutomationConnection.shutdown(); 12505 } catch (RemoteException re) { 12506 /* ignore */ 12507 } 12508 // Only a UiAutomation can set this flag and now that 12509 // it is finished we make sure it is reset to its default. 12510 mUserIsMonkey = false; 12511 } 12512 app.instrumentationWatcher = null; 12513 app.instrumentationUiAutomationConnection = null; 12514 app.instrumentationClass = null; 12515 app.instrumentationInfo = null; 12516 app.instrumentationProfileFile = null; 12517 app.instrumentationArguments = null; 12518 12519 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12520 } 12521 12522 public void finishInstrumentation(IApplicationThread target, 12523 int resultCode, Bundle results) { 12524 int userId = UserHandle.getCallingUserId(); 12525 // Refuse possible leaked file descriptors 12526 if (results != null && results.hasFileDescriptors()) { 12527 throw new IllegalArgumentException("File descriptors passed in Intent"); 12528 } 12529 12530 synchronized(this) { 12531 ProcessRecord app = getRecordForAppLocked(target); 12532 if (app == null) { 12533 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12534 return; 12535 } 12536 final long origId = Binder.clearCallingIdentity(); 12537 finishInstrumentationLocked(app, resultCode, results); 12538 Binder.restoreCallingIdentity(origId); 12539 } 12540 } 12541 12542 // ========================================================= 12543 // CONFIGURATION 12544 // ========================================================= 12545 12546 public ConfigurationInfo getDeviceConfigurationInfo() { 12547 ConfigurationInfo config = new ConfigurationInfo(); 12548 synchronized (this) { 12549 config.reqTouchScreen = mConfiguration.touchscreen; 12550 config.reqKeyboardType = mConfiguration.keyboard; 12551 config.reqNavigation = mConfiguration.navigation; 12552 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12553 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12554 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12555 } 12556 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12557 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12558 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12559 } 12560 config.reqGlEsVersion = GL_ES_VERSION; 12561 } 12562 return config; 12563 } 12564 12565 public Configuration getConfiguration() { 12566 Configuration ci; 12567 synchronized(this) { 12568 ci = new Configuration(mConfiguration); 12569 } 12570 return ci; 12571 } 12572 12573 public void updatePersistentConfiguration(Configuration values) { 12574 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12575 "updateConfiguration()"); 12576 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12577 "updateConfiguration()"); 12578 if (values == null) { 12579 throw new NullPointerException("Configuration must not be null"); 12580 } 12581 12582 synchronized(this) { 12583 final long origId = Binder.clearCallingIdentity(); 12584 updateConfigurationLocked(values, null, true, false); 12585 Binder.restoreCallingIdentity(origId); 12586 } 12587 } 12588 12589 public void updateConfiguration(Configuration values) { 12590 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12591 "updateConfiguration()"); 12592 12593 synchronized(this) { 12594 if (values == null && mWindowManager != null) { 12595 // sentinel: fetch the current configuration from the window manager 12596 values = mWindowManager.computeNewConfiguration(); 12597 } 12598 12599 if (mWindowManager != null) { 12600 mProcessList.applyDisplaySize(mWindowManager); 12601 } 12602 12603 final long origId = Binder.clearCallingIdentity(); 12604 if (values != null) { 12605 Settings.System.clearConfiguration(values); 12606 } 12607 updateConfigurationLocked(values, null, false, false); 12608 Binder.restoreCallingIdentity(origId); 12609 } 12610 } 12611 12612 /** 12613 * Do either or both things: (1) change the current configuration, and (2) 12614 * make sure the given activity is running with the (now) current 12615 * configuration. Returns true if the activity has been left running, or 12616 * false if <var>starting</var> is being destroyed to match the new 12617 * configuration. 12618 * @param persistent TODO 12619 */ 12620 boolean updateConfigurationLocked(Configuration values, 12621 ActivityRecord starting, boolean persistent, boolean initLocale) { 12622 // do nothing if we are headless 12623 if (mHeadless) return true; 12624 12625 int changes = 0; 12626 12627 boolean kept = true; 12628 12629 if (values != null) { 12630 Configuration newConfig = new Configuration(mConfiguration); 12631 changes = newConfig.updateFrom(values); 12632 if (changes != 0) { 12633 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12634 Slog.i(TAG, "Updating configuration to: " + values); 12635 } 12636 12637 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12638 12639 if (values.locale != null && !initLocale) { 12640 saveLocaleLocked(values.locale, 12641 !values.locale.equals(mConfiguration.locale), 12642 values.userSetLocale); 12643 } 12644 12645 mConfigurationSeq++; 12646 if (mConfigurationSeq <= 0) { 12647 mConfigurationSeq = 1; 12648 } 12649 newConfig.seq = mConfigurationSeq; 12650 mConfiguration = newConfig; 12651 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 12652 12653 final Configuration configCopy = new Configuration(mConfiguration); 12654 12655 // TODO: If our config changes, should we auto dismiss any currently 12656 // showing dialogs? 12657 mShowDialogs = shouldShowDialogs(newConfig); 12658 12659 AttributeCache ac = AttributeCache.instance(); 12660 if (ac != null) { 12661 ac.updateConfiguration(configCopy); 12662 } 12663 12664 // Make sure all resources in our process are updated 12665 // right now, so that anyone who is going to retrieve 12666 // resource values after we return will be sure to get 12667 // the new ones. This is especially important during 12668 // boot, where the first config change needs to guarantee 12669 // all resources have that config before following boot 12670 // code is executed. 12671 mSystemThread.applyConfigurationToResources(configCopy); 12672 12673 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12674 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12675 msg.obj = new Configuration(configCopy); 12676 mHandler.sendMessage(msg); 12677 } 12678 12679 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12680 ProcessRecord app = mLruProcesses.get(i); 12681 try { 12682 if (app.thread != null) { 12683 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12684 + app.processName + " new config " + mConfiguration); 12685 app.thread.scheduleConfigurationChanged(configCopy); 12686 } 12687 } catch (Exception e) { 12688 } 12689 } 12690 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12692 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12693 | Intent.FLAG_RECEIVER_FOREGROUND); 12694 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12695 null, AppOpsManager.OP_NONE, false, false, MY_PID, 12696 Process.SYSTEM_UID, UserHandle.USER_ALL); 12697 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12698 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12699 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12700 broadcastIntentLocked(null, null, intent, 12701 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 12702 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12703 } 12704 } 12705 } 12706 12707 if (changes != 0 && starting == null) { 12708 // If the configuration changed, and the caller is not already 12709 // in the process of starting an activity, then find the top 12710 // activity to check if its configuration needs to change. 12711 starting = mMainStack.topRunningActivityLocked(null); 12712 } 12713 12714 if (starting != null) { 12715 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12716 // And we need to make sure at this point that all other activities 12717 // are made visible with the correct configuration. 12718 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12719 } 12720 12721 if (values != null && mWindowManager != null) { 12722 mWindowManager.setNewConfiguration(mConfiguration); 12723 } 12724 12725 return kept; 12726 } 12727 12728 /** 12729 * Decide based on the configuration whether we should shouw the ANR, 12730 * crash, etc dialogs. The idea is that if there is no affordnace to 12731 * press the on-screen buttons, we shouldn't show the dialog. 12732 * 12733 * A thought: SystemUI might also want to get told about this, the Power 12734 * dialog / global actions also might want different behaviors. 12735 */ 12736 private static final boolean shouldShowDialogs(Configuration config) { 12737 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12738 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12739 } 12740 12741 /** 12742 * Save the locale. You must be inside a synchronized (this) block. 12743 */ 12744 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12745 if(isDiff) { 12746 SystemProperties.set("user.language", l.getLanguage()); 12747 SystemProperties.set("user.region", l.getCountry()); 12748 } 12749 12750 if(isPersist) { 12751 SystemProperties.set("persist.sys.language", l.getLanguage()); 12752 SystemProperties.set("persist.sys.country", l.getCountry()); 12753 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12754 } 12755 } 12756 12757 @Override 12758 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12759 ActivityRecord srec = ActivityRecord.forToken(token); 12760 return srec != null && srec.task.affinity != null && 12761 srec.task.affinity.equals(destAffinity); 12762 } 12763 12764 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12765 Intent resultData) { 12766 ComponentName dest = destIntent.getComponent(); 12767 12768 synchronized (this) { 12769 ActivityRecord srec = ActivityRecord.forToken(token); 12770 if (srec == null) { 12771 return false; 12772 } 12773 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12774 final int start = history.indexOf(srec); 12775 if (start < 0) { 12776 // Current activity is not in history stack; do nothing. 12777 return false; 12778 } 12779 int finishTo = start - 1; 12780 ActivityRecord parent = null; 12781 boolean foundParentInTask = false; 12782 if (dest != null) { 12783 TaskRecord tr = srec.task; 12784 for (int i = start - 1; i >= 0; i--) { 12785 ActivityRecord r = history.get(i); 12786 if (tr != r.task) { 12787 // Couldn't find parent in the same task; stop at the one above this. 12788 // (Root of current task; in-app "home" behavior) 12789 // Always at least finish the current activity. 12790 finishTo = Math.min(start - 1, i + 1); 12791 parent = history.get(finishTo); 12792 break; 12793 } else if (r.info.packageName.equals(dest.getPackageName()) && 12794 r.info.name.equals(dest.getClassName())) { 12795 finishTo = i; 12796 parent = r; 12797 foundParentInTask = true; 12798 break; 12799 } 12800 } 12801 } 12802 12803 if (mController != null) { 12804 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12805 if (next != null) { 12806 // ask watcher if this is allowed 12807 boolean resumeOK = true; 12808 try { 12809 resumeOK = mController.activityResuming(next.packageName); 12810 } catch (RemoteException e) { 12811 mController = null; 12812 Watchdog.getInstance().setActivityController(null); 12813 } 12814 12815 if (!resumeOK) { 12816 return false; 12817 } 12818 } 12819 } 12820 final long origId = Binder.clearCallingIdentity(); 12821 for (int i = start; i > finishTo; i--) { 12822 ActivityRecord r = history.get(i); 12823 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12824 "navigate-up", true); 12825 // Only return the supplied result for the first activity finished 12826 resultCode = Activity.RESULT_CANCELED; 12827 resultData = null; 12828 } 12829 12830 if (parent != null && foundParentInTask) { 12831 final int parentLaunchMode = parent.info.launchMode; 12832 final int destIntentFlags = destIntent.getFlags(); 12833 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12834 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12835 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12836 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12837 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12838 } else { 12839 try { 12840 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12841 destIntent.getComponent(), 0, srec.userId); 12842 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12843 null, aInfo, parent.appToken, null, 12844 0, -1, parent.launchedFromUid, parent.launchedFromPackage, 12845 0, null, true, null); 12846 foundParentInTask = res == ActivityManager.START_SUCCESS; 12847 } catch (RemoteException e) { 12848 foundParentInTask = false; 12849 } 12850 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12851 resultData, "navigate-up", true); 12852 } 12853 } 12854 Binder.restoreCallingIdentity(origId); 12855 return foundParentInTask; 12856 } 12857 } 12858 12859 public int getLaunchedFromUid(IBinder activityToken) { 12860 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12861 if (srec == null) { 12862 return -1; 12863 } 12864 return srec.launchedFromUid; 12865 } 12866 12867 public String getLaunchedFromPackage(IBinder activityToken) { 12868 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12869 if (srec == null) { 12870 return null; 12871 } 12872 return srec.launchedFromPackage; 12873 } 12874 12875 // ========================================================= 12876 // LIFETIME MANAGEMENT 12877 // ========================================================= 12878 12879 // Returns which broadcast queue the app is the current [or imminent] receiver 12880 // on, or 'null' if the app is not an active broadcast recipient. 12881 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12882 BroadcastRecord r = app.curReceiver; 12883 if (r != null) { 12884 return r.queue; 12885 } 12886 12887 // It's not the current receiver, but it might be starting up to become one 12888 synchronized (this) { 12889 for (BroadcastQueue queue : mBroadcastQueues) { 12890 r = queue.mPendingBroadcast; 12891 if (r != null && r.curApp == app) { 12892 // found it; report which queue it's in 12893 return queue; 12894 } 12895 } 12896 } 12897 12898 return null; 12899 } 12900 12901 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12902 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12903 if (mAdjSeq == app.adjSeq) { 12904 // This adjustment has already been computed. If we are calling 12905 // from the top, we may have already computed our adjustment with 12906 // an earlier hidden adjustment that isn't really for us... if 12907 // so, use the new hidden adjustment. 12908 if (!recursed && app.hidden) { 12909 if (app.hasActivities) { 12910 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12911 } else if (app.hasClientActivities) { 12912 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12913 } else { 12914 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12915 } 12916 } 12917 return app.curRawAdj; 12918 } 12919 12920 if (app.thread == null) { 12921 app.adjSeq = mAdjSeq; 12922 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12923 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12924 } 12925 12926 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12927 app.adjSource = null; 12928 app.adjTarget = null; 12929 app.empty = false; 12930 app.hidden = false; 12931 app.hasClientActivities = false; 12932 12933 final int activitiesSize = app.activities.size(); 12934 12935 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12936 // The max adjustment doesn't allow this app to be anything 12937 // below foreground, so it is not worth doing work for it. 12938 app.adjType = "fixed"; 12939 app.adjSeq = mAdjSeq; 12940 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12941 app.hasActivities = false; 12942 app.foregroundActivities = false; 12943 app.keeping = true; 12944 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12945 // System process can do UI, and when they do we want to have 12946 // them trim their memory after the user leaves the UI. To 12947 // facilitate this, here we need to determine whether or not it 12948 // is currently showing UI. 12949 app.systemNoUi = true; 12950 if (app == TOP_APP) { 12951 app.systemNoUi = false; 12952 app.hasActivities = true; 12953 } else if (activitiesSize > 0) { 12954 for (int j = 0; j < activitiesSize; j++) { 12955 final ActivityRecord r = app.activities.get(j); 12956 if (r.visible) { 12957 app.systemNoUi = false; 12958 } 12959 if (r.app == app) { 12960 app.hasActivities = true; 12961 } 12962 } 12963 } 12964 return (app.curAdj=app.maxAdj); 12965 } 12966 12967 app.keeping = false; 12968 app.systemNoUi = false; 12969 app.hasActivities = false; 12970 12971 // Determine the importance of the process, starting with most 12972 // important to least, and assign an appropriate OOM adjustment. 12973 int adj; 12974 int schedGroup; 12975 boolean foregroundActivities = false; 12976 boolean interesting = false; 12977 BroadcastQueue queue; 12978 if (app == TOP_APP) { 12979 // The last app on the list is the foreground app. 12980 adj = ProcessList.FOREGROUND_APP_ADJ; 12981 schedGroup = Process.THREAD_GROUP_DEFAULT; 12982 app.adjType = "top-activity"; 12983 foregroundActivities = true; 12984 interesting = true; 12985 app.hasActivities = true; 12986 } else if (app.instrumentationClass != null) { 12987 // Don't want to kill running instrumentation. 12988 adj = ProcessList.FOREGROUND_APP_ADJ; 12989 schedGroup = Process.THREAD_GROUP_DEFAULT; 12990 app.adjType = "instrumentation"; 12991 interesting = true; 12992 } else if ((queue = isReceivingBroadcast(app)) != null) { 12993 // An app that is currently receiving a broadcast also 12994 // counts as being in the foreground for OOM killer purposes. 12995 // It's placed in a sched group based on the nature of the 12996 // broadcast as reflected by which queue it's active in. 12997 adj = ProcessList.FOREGROUND_APP_ADJ; 12998 schedGroup = (queue == mFgBroadcastQueue) 12999 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 13000 app.adjType = "broadcast"; 13001 } else if (app.executingServices.size() > 0) { 13002 // An app that is currently executing a service callback also 13003 // counts as being in the foreground. 13004 adj = ProcessList.FOREGROUND_APP_ADJ; 13005 schedGroup = Process.THREAD_GROUP_DEFAULT; 13006 app.adjType = "exec-service"; 13007 } else { 13008 // Assume process is hidden (has activities); we will correct 13009 // later if this is not the case. 13010 adj = hiddenAdj; 13011 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13012 app.hidden = true; 13013 app.adjType = "bg-act"; 13014 } 13015 13016 boolean hasStoppingActivities = false; 13017 13018 // Examine all activities if not already foreground. 13019 if (!foregroundActivities && activitiesSize > 0) { 13020 for (int j = 0; j < activitiesSize; j++) { 13021 final ActivityRecord r = app.activities.get(j); 13022 if (r.visible) { 13023 // App has a visible activity; only upgrade adjustment. 13024 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13025 adj = ProcessList.VISIBLE_APP_ADJ; 13026 app.adjType = "visible"; 13027 } 13028 schedGroup = Process.THREAD_GROUP_DEFAULT; 13029 app.hidden = false; 13030 app.hasActivities = true; 13031 foregroundActivities = true; 13032 break; 13033 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 13034 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13035 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13036 app.adjType = "pausing"; 13037 } 13038 app.hidden = false; 13039 foregroundActivities = true; 13040 } else if (r.state == ActivityState.STOPPING) { 13041 // We will apply the actual adjustment later, because 13042 // we want to allow this process to immediately go through 13043 // any memory trimming that is in effect. 13044 app.hidden = false; 13045 foregroundActivities = true; 13046 hasStoppingActivities = true; 13047 } 13048 if (r.app == app) { 13049 app.hasActivities = true; 13050 } 13051 } 13052 } 13053 13054 if (adj == hiddenAdj && !app.hasActivities) { 13055 if (app.hasClientActivities) { 13056 adj = clientHiddenAdj; 13057 app.adjType = "bg-client-act"; 13058 } else { 13059 // Whoops, this process is completely empty as far as we know 13060 // at this point. 13061 adj = emptyAdj; 13062 app.empty = true; 13063 app.adjType = "bg-empty"; 13064 } 13065 } 13066 13067 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13068 if (app.foregroundServices) { 13069 // The user is aware of this app, so make it visible. 13070 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13071 app.hidden = false; 13072 app.adjType = "fg-service"; 13073 schedGroup = Process.THREAD_GROUP_DEFAULT; 13074 } else if (app.forcingToForeground != null) { 13075 // The user is aware of this app, so make it visible. 13076 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13077 app.hidden = false; 13078 app.adjType = "force-fg"; 13079 app.adjSource = app.forcingToForeground; 13080 schedGroup = Process.THREAD_GROUP_DEFAULT; 13081 } 13082 } 13083 13084 if (app.foregroundServices) { 13085 interesting = true; 13086 } 13087 13088 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13089 // We don't want to kill the current heavy-weight process. 13090 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13091 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13092 app.hidden = false; 13093 app.adjType = "heavy"; 13094 } 13095 13096 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13097 // This process is hosting what we currently consider to be the 13098 // home app, so we don't want to let it go into the background. 13099 adj = ProcessList.HOME_APP_ADJ; 13100 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13101 app.hidden = false; 13102 app.adjType = "home"; 13103 } 13104 13105 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13106 && app.activities.size() > 0) { 13107 // This was the previous process that showed UI to the user. 13108 // We want to try to keep it around more aggressively, to give 13109 // a good experience around switching between two apps. 13110 adj = ProcessList.PREVIOUS_APP_ADJ; 13111 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13112 app.hidden = false; 13113 app.adjType = "previous"; 13114 } 13115 13116 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13117 + " reason=" + app.adjType); 13118 13119 // By default, we use the computed adjustment. It may be changed if 13120 // there are applications dependent on our services or providers, but 13121 // this gives us a baseline and makes sure we don't get into an 13122 // infinite recursion. 13123 app.adjSeq = mAdjSeq; 13124 app.curRawAdj = app.nonStoppingAdj = adj; 13125 13126 if (mBackupTarget != null && app == mBackupTarget.app) { 13127 // If possible we want to avoid killing apps while they're being backed up 13128 if (adj > ProcessList.BACKUP_APP_ADJ) { 13129 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13130 adj = ProcessList.BACKUP_APP_ADJ; 13131 app.adjType = "backup"; 13132 app.hidden = false; 13133 } 13134 } 13135 13136 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13137 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13138 final long now = SystemClock.uptimeMillis(); 13139 // This process is more important if the top activity is 13140 // bound to the service. 13141 Iterator<ServiceRecord> jt = app.services.iterator(); 13142 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13143 ServiceRecord s = jt.next(); 13144 if (s.startRequested) { 13145 if (app.hasShownUi && app != mHomeProcess) { 13146 // If this process has shown some UI, let it immediately 13147 // go to the LRU list because it may be pretty heavy with 13148 // UI stuff. We'll tag it with a label just to help 13149 // debug and understand what is going on. 13150 if (adj > ProcessList.SERVICE_ADJ) { 13151 app.adjType = "started-bg-ui-services"; 13152 } 13153 } else { 13154 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 13155 // This service has seen some activity within 13156 // recent memory, so we will keep its process ahead 13157 // of the background processes. 13158 if (adj > ProcessList.SERVICE_ADJ) { 13159 adj = ProcessList.SERVICE_ADJ; 13160 app.adjType = "started-services"; 13161 app.hidden = false; 13162 } 13163 } 13164 // If we have let the service slide into the background 13165 // state, still have some text describing what it is doing 13166 // even though the service no longer has an impact. 13167 if (adj > ProcessList.SERVICE_ADJ) { 13168 app.adjType = "started-bg-services"; 13169 } 13170 } 13171 // Don't kill this process because it is doing work; it 13172 // has said it is doing work. 13173 app.keeping = true; 13174 } 13175 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13176 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13177 Iterator<ArrayList<ConnectionRecord>> kt 13178 = s.connections.values().iterator(); 13179 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13180 ArrayList<ConnectionRecord> clist = kt.next(); 13181 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 13182 // XXX should compute this based on the max of 13183 // all connected clients. 13184 ConnectionRecord cr = clist.get(i); 13185 if (cr.binding.client == app) { 13186 // Binding to ourself is not interesting. 13187 continue; 13188 } 13189 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 13190 ProcessRecord client = cr.binding.client; 13191 int clientAdj = adj; 13192 int myHiddenAdj = hiddenAdj; 13193 if (myHiddenAdj > client.hiddenAdj) { 13194 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13195 myHiddenAdj = client.hiddenAdj; 13196 } else { 13197 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13198 } 13199 } 13200 int myClientHiddenAdj = clientHiddenAdj; 13201 if (myClientHiddenAdj > client.clientHiddenAdj) { 13202 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 13203 myClientHiddenAdj = client.clientHiddenAdj; 13204 } else { 13205 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 13206 } 13207 } 13208 int myEmptyAdj = emptyAdj; 13209 if (myEmptyAdj > client.emptyAdj) { 13210 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 13211 myEmptyAdj = client.emptyAdj; 13212 } else { 13213 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 13214 } 13215 } 13216 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13217 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13218 String adjType = null; 13219 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 13220 // Not doing bind OOM management, so treat 13221 // this guy more like a started service. 13222 if (app.hasShownUi && app != mHomeProcess) { 13223 // If this process has shown some UI, let it immediately 13224 // go to the LRU list because it may be pretty heavy with 13225 // UI stuff. We'll tag it with a label just to help 13226 // debug and understand what is going on. 13227 if (adj > clientAdj) { 13228 adjType = "bound-bg-ui-services"; 13229 } 13230 app.hidden = false; 13231 clientAdj = adj; 13232 } else { 13233 if (now >= (s.lastActivity 13234 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 13235 // This service has not seen activity within 13236 // recent memory, so allow it to drop to the 13237 // LRU list if there is no other reason to keep 13238 // it around. We'll also tag it with a label just 13239 // to help debug and undertand what is going on. 13240 if (adj > clientAdj) { 13241 adjType = "bound-bg-services"; 13242 } 13243 clientAdj = adj; 13244 } 13245 } 13246 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13247 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 13248 // If this connection is keeping the service 13249 // created, then we want to try to better follow 13250 // its memory management semantics for activities. 13251 // That is, if it is sitting in the background 13252 // LRU list as a hidden process (with activities), 13253 // we don't want the service it is connected to 13254 // to go into the empty LRU and quickly get killed, 13255 // because I'll we'll do is just end up restarting 13256 // the service. 13257 app.hasClientActivities |= client.hasActivities; 13258 } 13259 } 13260 if (adj > clientAdj) { 13261 // If this process has recently shown UI, and 13262 // the process that is binding to it is less 13263 // important than being visible, then we don't 13264 // care about the binding as much as we care 13265 // about letting this process get into the LRU 13266 // list to be killed and restarted if needed for 13267 // memory. 13268 if (app.hasShownUi && app != mHomeProcess 13269 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13270 adjType = "bound-bg-ui-services"; 13271 } else { 13272 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 13273 |Context.BIND_IMPORTANT)) != 0) { 13274 adj = clientAdj; 13275 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 13276 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 13277 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13278 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13279 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 13280 adj = clientAdj; 13281 } else { 13282 app.pendingUiClean = true; 13283 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13284 adj = ProcessList.VISIBLE_APP_ADJ; 13285 } 13286 } 13287 if (!client.hidden) { 13288 app.hidden = false; 13289 } 13290 if (client.keeping) { 13291 app.keeping = true; 13292 } 13293 adjType = "service"; 13294 } 13295 } 13296 if (adjType != null) { 13297 app.adjType = adjType; 13298 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13299 .REASON_SERVICE_IN_USE; 13300 app.adjSource = cr.binding.client; 13301 app.adjSourceOom = clientAdj; 13302 app.adjTarget = s.name; 13303 } 13304 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13305 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13306 schedGroup = Process.THREAD_GROUP_DEFAULT; 13307 } 13308 } 13309 } 13310 final ActivityRecord a = cr.activity; 13311 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 13312 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 13313 (a.visible || a.state == ActivityState.RESUMED 13314 || a.state == ActivityState.PAUSING)) { 13315 adj = ProcessList.FOREGROUND_APP_ADJ; 13316 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13317 schedGroup = Process.THREAD_GROUP_DEFAULT; 13318 } 13319 app.hidden = false; 13320 app.adjType = "service"; 13321 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13322 .REASON_SERVICE_IN_USE; 13323 app.adjSource = a; 13324 app.adjSourceOom = adj; 13325 app.adjTarget = s.name; 13326 } 13327 } 13328 } 13329 } 13330 } 13331 } 13332 13333 // Finally, if this process has active services running in it, we 13334 // would like to avoid killing it unless it would prevent the current 13335 // application from running. By default we put the process in 13336 // with the rest of the background processes; as we scan through 13337 // its services we may bump it up from there. 13338 if (adj > hiddenAdj) { 13339 adj = hiddenAdj; 13340 app.hidden = false; 13341 app.adjType = "bg-services"; 13342 } 13343 } 13344 13345 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13346 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13347 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13348 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13349 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13350 ContentProviderRecord cpr = jt.next(); 13351 for (int i = cpr.connections.size()-1; 13352 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13353 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 13354 i--) { 13355 ContentProviderConnection conn = cpr.connections.get(i); 13356 ProcessRecord client = conn.client; 13357 if (client == app) { 13358 // Being our own client is not interesting. 13359 continue; 13360 } 13361 int myHiddenAdj = hiddenAdj; 13362 if (myHiddenAdj > client.hiddenAdj) { 13363 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13364 myHiddenAdj = client.hiddenAdj; 13365 } else { 13366 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13367 } 13368 } 13369 int myClientHiddenAdj = clientHiddenAdj; 13370 if (myClientHiddenAdj > client.clientHiddenAdj) { 13371 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 13372 myClientHiddenAdj = client.clientHiddenAdj; 13373 } else { 13374 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13375 } 13376 } 13377 int myEmptyAdj = emptyAdj; 13378 if (myEmptyAdj > client.emptyAdj) { 13379 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 13380 myEmptyAdj = client.emptyAdj; 13381 } else { 13382 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 13383 } 13384 } 13385 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13386 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13387 if (adj > clientAdj) { 13388 if (app.hasShownUi && app != mHomeProcess 13389 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13390 app.adjType = "bg-ui-provider"; 13391 } else { 13392 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13393 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13394 app.adjType = "provider"; 13395 } 13396 if (!client.hidden) { 13397 app.hidden = false; 13398 } 13399 if (client.keeping) { 13400 app.keeping = true; 13401 } 13402 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13403 .REASON_PROVIDER_IN_USE; 13404 app.adjSource = client; 13405 app.adjSourceOom = clientAdj; 13406 app.adjTarget = cpr.name; 13407 } 13408 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13409 schedGroup = Process.THREAD_GROUP_DEFAULT; 13410 } 13411 } 13412 // If the provider has external (non-framework) process 13413 // dependencies, ensure that its adjustment is at least 13414 // FOREGROUND_APP_ADJ. 13415 if (cpr.hasExternalProcessHandles()) { 13416 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13417 adj = ProcessList.FOREGROUND_APP_ADJ; 13418 schedGroup = Process.THREAD_GROUP_DEFAULT; 13419 app.hidden = false; 13420 app.keeping = true; 13421 app.adjType = "provider"; 13422 app.adjTarget = cpr.name; 13423 } 13424 } 13425 } 13426 } 13427 13428 if (adj == ProcessList.SERVICE_ADJ) { 13429 if (doingAll) { 13430 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13431 mNewNumServiceProcs++; 13432 } 13433 if (app.serviceb) { 13434 adj = ProcessList.SERVICE_B_ADJ; 13435 } 13436 } else { 13437 app.serviceb = false; 13438 } 13439 13440 app.nonStoppingAdj = adj; 13441 13442 if (hasStoppingActivities) { 13443 // Only upgrade adjustment. 13444 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13445 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13446 app.adjType = "stopping"; 13447 } 13448 } 13449 13450 app.curRawAdj = adj; 13451 13452 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13453 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13454 if (adj > app.maxAdj) { 13455 adj = app.maxAdj; 13456 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13457 schedGroup = Process.THREAD_GROUP_DEFAULT; 13458 } 13459 } 13460 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13461 app.keeping = true; 13462 } 13463 13464 if (app.hasAboveClient) { 13465 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13466 // then we need to drop its adjustment to be lower than the service's 13467 // in order to honor the request. We want to drop it by one adjustment 13468 // level... but there is special meaning applied to various levels so 13469 // we will skip some of them. 13470 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13471 // System process will not get dropped, ever 13472 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13473 adj = ProcessList.VISIBLE_APP_ADJ; 13474 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13475 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13476 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13477 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13478 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13479 adj++; 13480 } 13481 } 13482 13483 int importance = app.memImportance; 13484 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13485 app.curAdj = adj; 13486 app.curSchedGroup = schedGroup; 13487 if (!interesting) { 13488 // For this reporting, if there is not something explicitly 13489 // interesting in this process then we will push it to the 13490 // background importance. 13491 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13492 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13493 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13494 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13495 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13496 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13497 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13498 } else if (adj >= ProcessList.SERVICE_ADJ) { 13499 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13500 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13501 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13502 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13503 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13504 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13505 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13506 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13507 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13508 } else { 13509 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13510 } 13511 } 13512 13513 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13514 if (foregroundActivities != app.foregroundActivities) { 13515 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13516 } 13517 if (changes != 0) { 13518 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13519 app.memImportance = importance; 13520 app.foregroundActivities = foregroundActivities; 13521 int i = mPendingProcessChanges.size()-1; 13522 ProcessChangeItem item = null; 13523 while (i >= 0) { 13524 item = mPendingProcessChanges.get(i); 13525 if (item.pid == app.pid) { 13526 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13527 break; 13528 } 13529 i--; 13530 } 13531 if (i < 0) { 13532 // No existing item in pending changes; need a new one. 13533 final int NA = mAvailProcessChanges.size(); 13534 if (NA > 0) { 13535 item = mAvailProcessChanges.remove(NA-1); 13536 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13537 } else { 13538 item = new ProcessChangeItem(); 13539 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13540 } 13541 item.changes = 0; 13542 item.pid = app.pid; 13543 item.uid = app.info.uid; 13544 if (mPendingProcessChanges.size() == 0) { 13545 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13546 "*** Enqueueing dispatch processes changed!"); 13547 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13548 } 13549 mPendingProcessChanges.add(item); 13550 } 13551 item.changes |= changes; 13552 item.importance = importance; 13553 item.foregroundActivities = foregroundActivities; 13554 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13555 + Integer.toHexString(System.identityHashCode(item)) 13556 + " " + app.toShortString() + ": changes=" + item.changes 13557 + " importance=" + item.importance 13558 + " foreground=" + item.foregroundActivities 13559 + " type=" + app.adjType + " source=" + app.adjSource 13560 + " target=" + app.adjTarget); 13561 } 13562 13563 return app.curRawAdj; 13564 } 13565 13566 /** 13567 * Ask a given process to GC right now. 13568 */ 13569 final void performAppGcLocked(ProcessRecord app) { 13570 try { 13571 app.lastRequestedGc = SystemClock.uptimeMillis(); 13572 if (app.thread != null) { 13573 if (app.reportLowMemory) { 13574 app.reportLowMemory = false; 13575 app.thread.scheduleLowMemory(); 13576 } else { 13577 app.thread.processInBackground(); 13578 } 13579 } 13580 } catch (Exception e) { 13581 // whatever. 13582 } 13583 } 13584 13585 /** 13586 * Returns true if things are idle enough to perform GCs. 13587 */ 13588 private final boolean canGcNowLocked() { 13589 boolean processingBroadcasts = false; 13590 for (BroadcastQueue q : mBroadcastQueues) { 13591 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13592 processingBroadcasts = true; 13593 } 13594 } 13595 return !processingBroadcasts 13596 && (mSleeping || (mMainStack.mResumedActivity != null && 13597 mMainStack.mResumedActivity.idle)); 13598 } 13599 13600 /** 13601 * Perform GCs on all processes that are waiting for it, but only 13602 * if things are idle. 13603 */ 13604 final void performAppGcsLocked() { 13605 final int N = mProcessesToGc.size(); 13606 if (N <= 0) { 13607 return; 13608 } 13609 if (canGcNowLocked()) { 13610 while (mProcessesToGc.size() > 0) { 13611 ProcessRecord proc = mProcessesToGc.remove(0); 13612 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13613 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13614 <= SystemClock.uptimeMillis()) { 13615 // To avoid spamming the system, we will GC processes one 13616 // at a time, waiting a few seconds between each. 13617 performAppGcLocked(proc); 13618 scheduleAppGcsLocked(); 13619 return; 13620 } else { 13621 // It hasn't been long enough since we last GCed this 13622 // process... put it in the list to wait for its time. 13623 addProcessToGcListLocked(proc); 13624 break; 13625 } 13626 } 13627 } 13628 13629 scheduleAppGcsLocked(); 13630 } 13631 } 13632 13633 /** 13634 * If all looks good, perform GCs on all processes waiting for them. 13635 */ 13636 final void performAppGcsIfAppropriateLocked() { 13637 if (canGcNowLocked()) { 13638 performAppGcsLocked(); 13639 return; 13640 } 13641 // Still not idle, wait some more. 13642 scheduleAppGcsLocked(); 13643 } 13644 13645 /** 13646 * Schedule the execution of all pending app GCs. 13647 */ 13648 final void scheduleAppGcsLocked() { 13649 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13650 13651 if (mProcessesToGc.size() > 0) { 13652 // Schedule a GC for the time to the next process. 13653 ProcessRecord proc = mProcessesToGc.get(0); 13654 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13655 13656 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13657 long now = SystemClock.uptimeMillis(); 13658 if (when < (now+GC_TIMEOUT)) { 13659 when = now + GC_TIMEOUT; 13660 } 13661 mHandler.sendMessageAtTime(msg, when); 13662 } 13663 } 13664 13665 /** 13666 * Add a process to the array of processes waiting to be GCed. Keeps the 13667 * list in sorted order by the last GC time. The process can't already be 13668 * on the list. 13669 */ 13670 final void addProcessToGcListLocked(ProcessRecord proc) { 13671 boolean added = false; 13672 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13673 if (mProcessesToGc.get(i).lastRequestedGc < 13674 proc.lastRequestedGc) { 13675 added = true; 13676 mProcessesToGc.add(i+1, proc); 13677 break; 13678 } 13679 } 13680 if (!added) { 13681 mProcessesToGc.add(0, proc); 13682 } 13683 } 13684 13685 /** 13686 * Set up to ask a process to GC itself. This will either do it 13687 * immediately, or put it on the list of processes to gc the next 13688 * time things are idle. 13689 */ 13690 final void scheduleAppGcLocked(ProcessRecord app) { 13691 long now = SystemClock.uptimeMillis(); 13692 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13693 return; 13694 } 13695 if (!mProcessesToGc.contains(app)) { 13696 addProcessToGcListLocked(app); 13697 scheduleAppGcsLocked(); 13698 } 13699 } 13700 13701 final void checkExcessivePowerUsageLocked(boolean doKills) { 13702 updateCpuStatsNow(); 13703 13704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13705 boolean doWakeKills = doKills; 13706 boolean doCpuKills = doKills; 13707 if (mLastPowerCheckRealtime == 0) { 13708 doWakeKills = false; 13709 } 13710 if (mLastPowerCheckUptime == 0) { 13711 doCpuKills = false; 13712 } 13713 if (stats.isScreenOn()) { 13714 doWakeKills = false; 13715 } 13716 final long curRealtime = SystemClock.elapsedRealtime(); 13717 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13718 final long curUptime = SystemClock.uptimeMillis(); 13719 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13720 mLastPowerCheckRealtime = curRealtime; 13721 mLastPowerCheckUptime = curUptime; 13722 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13723 doWakeKills = false; 13724 } 13725 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13726 doCpuKills = false; 13727 } 13728 int i = mLruProcesses.size(); 13729 while (i > 0) { 13730 i--; 13731 ProcessRecord app = mLruProcesses.get(i); 13732 if (!app.keeping) { 13733 long wtime; 13734 synchronized (stats) { 13735 wtime = stats.getProcessWakeTime(app.info.uid, 13736 app.pid, curRealtime); 13737 } 13738 long wtimeUsed = wtime - app.lastWakeTime; 13739 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13740 if (DEBUG_POWER) { 13741 StringBuilder sb = new StringBuilder(128); 13742 sb.append("Wake for "); 13743 app.toShortString(sb); 13744 sb.append(": over "); 13745 TimeUtils.formatDuration(realtimeSince, sb); 13746 sb.append(" used "); 13747 TimeUtils.formatDuration(wtimeUsed, sb); 13748 sb.append(" ("); 13749 sb.append((wtimeUsed*100)/realtimeSince); 13750 sb.append("%)"); 13751 Slog.i(TAG, sb.toString()); 13752 sb.setLength(0); 13753 sb.append("CPU for "); 13754 app.toShortString(sb); 13755 sb.append(": over "); 13756 TimeUtils.formatDuration(uptimeSince, sb); 13757 sb.append(" used "); 13758 TimeUtils.formatDuration(cputimeUsed, sb); 13759 sb.append(" ("); 13760 sb.append((cputimeUsed*100)/uptimeSince); 13761 sb.append("%)"); 13762 Slog.i(TAG, sb.toString()); 13763 } 13764 // If a process has held a wake lock for more 13765 // than 50% of the time during this period, 13766 // that sounds bad. Kill! 13767 if (doWakeKills && realtimeSince > 0 13768 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13769 synchronized (stats) { 13770 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13771 realtimeSince, wtimeUsed); 13772 } 13773 Slog.w(TAG, "Excessive wake lock in " + app.processName 13774 + " (pid " + app.pid + "): held " + wtimeUsed 13775 + " during " + realtimeSince); 13776 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13777 app.processName, app.setAdj, "excessive wake lock"); 13778 Process.killProcessQuiet(app.pid); 13779 } else if (doCpuKills && uptimeSince > 0 13780 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13781 synchronized (stats) { 13782 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13783 uptimeSince, cputimeUsed); 13784 } 13785 Slog.w(TAG, "Excessive CPU in " + app.processName 13786 + " (pid " + app.pid + "): used " + cputimeUsed 13787 + " during " + uptimeSince); 13788 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13789 app.processName, app.setAdj, "excessive cpu"); 13790 Process.killProcessQuiet(app.pid); 13791 } else { 13792 app.lastWakeTime = wtime; 13793 app.lastCpuTime = app.curCpuTime; 13794 } 13795 } 13796 } 13797 } 13798 13799 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13800 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13801 app.hiddenAdj = hiddenAdj; 13802 app.clientHiddenAdj = clientHiddenAdj; 13803 app.emptyAdj = emptyAdj; 13804 13805 if (app.thread == null) { 13806 return false; 13807 } 13808 13809 final boolean wasKeeping = app.keeping; 13810 13811 boolean success = true; 13812 13813 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13814 13815 if (app.curRawAdj != app.setRawAdj) { 13816 if (wasKeeping && !app.keeping) { 13817 // This app is no longer something we want to keep. Note 13818 // its current wake lock time to later know to kill it if 13819 // it is not behaving well. 13820 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13821 synchronized (stats) { 13822 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13823 app.pid, SystemClock.elapsedRealtime()); 13824 } 13825 app.lastCpuTime = app.curCpuTime; 13826 } 13827 13828 app.setRawAdj = app.curRawAdj; 13829 } 13830 13831 if (app.curAdj != app.setAdj) { 13832 if (Process.setOomAdj(app.pid, app.curAdj)) { 13833 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13834 TAG, "Set " + app.pid + " " + app.processName + 13835 " adj " + app.curAdj + ": " + app.adjType); 13836 app.setAdj = app.curAdj; 13837 } else { 13838 success = false; 13839 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13840 } 13841 } 13842 if (app.setSchedGroup != app.curSchedGroup) { 13843 app.setSchedGroup = app.curSchedGroup; 13844 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13845 "Setting process group of " + app.processName 13846 + " to " + app.curSchedGroup); 13847 if (app.waitingToKill != null && 13848 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13849 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13850 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13851 app.processName, app.setAdj, app.waitingToKill); 13852 app.killedBackground = true; 13853 Process.killProcessQuiet(app.pid); 13854 success = false; 13855 } else { 13856 if (true) { 13857 long oldId = Binder.clearCallingIdentity(); 13858 try { 13859 Process.setProcessGroup(app.pid, app.curSchedGroup); 13860 } catch (Exception e) { 13861 Slog.w(TAG, "Failed setting process group of " + app.pid 13862 + " to " + app.curSchedGroup); 13863 e.printStackTrace(); 13864 } finally { 13865 Binder.restoreCallingIdentity(oldId); 13866 } 13867 } else { 13868 if (app.thread != null) { 13869 try { 13870 app.thread.setSchedulingGroup(app.curSchedGroup); 13871 } catch (RemoteException e) { 13872 } 13873 } 13874 } 13875 } 13876 } 13877 return success; 13878 } 13879 13880 private final ActivityRecord resumedAppLocked() { 13881 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13882 if (resumedActivity == null || resumedActivity.app == null) { 13883 resumedActivity = mMainStack.mPausingActivity; 13884 if (resumedActivity == null || resumedActivity.app == null) { 13885 resumedActivity = mMainStack.topRunningActivityLocked(null); 13886 } 13887 } 13888 return resumedActivity; 13889 } 13890 13891 final boolean updateOomAdjLocked(ProcessRecord app) { 13892 final ActivityRecord TOP_ACT = resumedAppLocked(); 13893 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13894 int curAdj = app.curAdj; 13895 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13896 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13897 13898 mAdjSeq++; 13899 13900 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13901 app.emptyAdj, TOP_APP, false); 13902 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13903 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13904 if (nowHidden != wasHidden) { 13905 // Changed to/from hidden state, so apps after it in the LRU 13906 // list may also be changed. 13907 updateOomAdjLocked(); 13908 } 13909 return success; 13910 } 13911 13912 final void updateOomAdjLocked() { 13913 final ActivityRecord TOP_ACT = resumedAppLocked(); 13914 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13915 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13916 13917 if (false) { 13918 RuntimeException e = new RuntimeException(); 13919 e.fillInStackTrace(); 13920 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13921 } 13922 13923 mAdjSeq++; 13924 mNewNumServiceProcs = 0; 13925 13926 final int emptyProcessLimit; 13927 final int hiddenProcessLimit; 13928 if (mProcessLimit <= 0) { 13929 emptyProcessLimit = hiddenProcessLimit = 0; 13930 } else if (mProcessLimit == 1) { 13931 emptyProcessLimit = 1; 13932 hiddenProcessLimit = 0; 13933 } else { 13934 emptyProcessLimit = (mProcessLimit*2)/3; 13935 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13936 } 13937 13938 // Let's determine how many processes we have running vs. 13939 // how many slots we have for background processes; we may want 13940 // to put multiple processes in a slot of there are enough of 13941 // them. 13942 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13943 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13944 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13945 if (numEmptyProcs > hiddenProcessLimit) { 13946 // If there are more empty processes than our limit on hidden 13947 // processes, then use the hidden process limit for the factor. 13948 // This ensures that the really old empty processes get pushed 13949 // down to the bottom, so if we are running low on memory we will 13950 // have a better chance at keeping around more hidden processes 13951 // instead of a gazillion empty processes. 13952 numEmptyProcs = hiddenProcessLimit; 13953 } 13954 int emptyFactor = numEmptyProcs/numSlots; 13955 if (emptyFactor < 1) emptyFactor = 1; 13956 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13957 if (hiddenFactor < 1) hiddenFactor = 1; 13958 int stepHidden = 0; 13959 int stepEmpty = 0; 13960 int numHidden = 0; 13961 int numEmpty = 0; 13962 int numTrimming = 0; 13963 13964 mNumNonHiddenProcs = 0; 13965 mNumHiddenProcs = 0; 13966 13967 // First update the OOM adjustment for each of the 13968 // application processes based on their current state. 13969 int i = mLruProcesses.size(); 13970 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13971 int nextHiddenAdj = curHiddenAdj+1; 13972 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13973 int nextEmptyAdj = curEmptyAdj+2; 13974 int curClientHiddenAdj = curEmptyAdj; 13975 while (i > 0) { 13976 i--; 13977 ProcessRecord app = mLruProcesses.get(i); 13978 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13979 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13980 if (!app.killedBackground) { 13981 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13982 // This process was assigned as a hidden process... step the 13983 // hidden level. 13984 mNumHiddenProcs++; 13985 if (curHiddenAdj != nextHiddenAdj) { 13986 stepHidden++; 13987 if (stepHidden >= hiddenFactor) { 13988 stepHidden = 0; 13989 curHiddenAdj = nextHiddenAdj; 13990 nextHiddenAdj += 2; 13991 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13992 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13993 } 13994 if (curClientHiddenAdj <= curHiddenAdj) { 13995 curClientHiddenAdj = curHiddenAdj + 1; 13996 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13997 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13998 } 13999 } 14000 } 14001 } 14002 numHidden++; 14003 if (numHidden > hiddenProcessLimit) { 14004 Slog.i(TAG, "No longer want " + app.processName 14005 + " (pid " + app.pid + "): hidden #" + numHidden); 14006 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 14007 app.processName, app.setAdj, "too many background"); 14008 app.killedBackground = true; 14009 Process.killProcessQuiet(app.pid); 14010 } 14011 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 14012 // This process has a client that has activities. We will have 14013 // given it the current hidden adj; here we will just leave it 14014 // without stepping the hidden adj. 14015 curClientHiddenAdj++; 14016 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 14017 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 14018 } 14019 } else { 14020 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 14021 // This process was assigned as an empty process... step the 14022 // empty level. 14023 if (curEmptyAdj != nextEmptyAdj) { 14024 stepEmpty++; 14025 if (stepEmpty >= emptyFactor) { 14026 stepEmpty = 0; 14027 curEmptyAdj = nextEmptyAdj; 14028 nextEmptyAdj += 2; 14029 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 14030 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 14031 } 14032 } 14033 } 14034 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14035 mNumNonHiddenProcs++; 14036 } 14037 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14038 && !app.hasClientActivities) { 14039 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 14040 && app.lastActivityTime < oldTime) { 14041 Slog.i(TAG, "No longer want " + app.processName 14042 + " (pid " + app.pid + "): empty for " 14043 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 14044 / 1000) + "s"); 14045 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 14046 app.processName, app.setAdj, "old background process"); 14047 app.killedBackground = true; 14048 Process.killProcessQuiet(app.pid); 14049 } else { 14050 numEmpty++; 14051 if (numEmpty > emptyProcessLimit) { 14052 Slog.i(TAG, "No longer want " + app.processName 14053 + " (pid " + app.pid + "): empty #" + numEmpty); 14054 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 14055 app.processName, app.setAdj, "too many background"); 14056 app.killedBackground = true; 14057 Process.killProcessQuiet(app.pid); 14058 } 14059 } 14060 } 14061 } 14062 if (app.isolated && app.services.size() <= 0) { 14063 // If this is an isolated process, and there are no 14064 // services running in it, then the process is no longer 14065 // needed. We agressively kill these because we can by 14066 // definition not re-use the same process again, and it is 14067 // good to avoid having whatever code was running in them 14068 // left sitting around after no longer needed. 14069 Slog.i(TAG, "Isolated process " + app.processName 14070 + " (pid " + app.pid + ") no longer needed"); 14071 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 14072 app.processName, app.setAdj, "isolated not needed"); 14073 app.killedBackground = true; 14074 Process.killProcessQuiet(app.pid); 14075 } 14076 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14077 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14078 && !app.killedBackground) { 14079 numTrimming++; 14080 } 14081 } 14082 } 14083 14084 mNumServiceProcs = mNewNumServiceProcs; 14085 14086 // Now determine the memory trimming level of background processes. 14087 // Unfortunately we need to start at the back of the list to do this 14088 // properly. We only do this if the number of background apps we 14089 // are managing to keep around is less than half the maximum we desire; 14090 // if we are keeping a good number around, we'll let them use whatever 14091 // memory they want. 14092 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 14093 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 14094 final int numHiddenAndEmpty = numHidden + numEmpty; 14095 final int N = mLruProcesses.size(); 14096 int factor = numTrimming/3; 14097 int minFactor = 2; 14098 if (mHomeProcess != null) minFactor++; 14099 if (mPreviousProcess != null) minFactor++; 14100 if (factor < minFactor) factor = minFactor; 14101 int step = 0; 14102 int fgTrimLevel; 14103 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 14104 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 14105 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 14106 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 14107 } else { 14108 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 14109 } 14110 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14111 for (i=0; i<N; i++) { 14112 ProcessRecord app = mLruProcesses.get(i); 14113 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14114 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14115 && !app.killedBackground) { 14116 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14117 try { 14118 app.thread.scheduleTrimMemory(curLevel); 14119 } catch (RemoteException e) { 14120 } 14121 if (false) { 14122 // For now we won't do this; our memory trimming seems 14123 // to be good enough at this point that destroying 14124 // activities causes more harm than good. 14125 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14126 && app != mHomeProcess && app != mPreviousProcess) { 14127 // Need to do this on its own message because the stack may not 14128 // be in a consistent state at this point. 14129 // For these apps we will also finish their activities 14130 // to help them free memory. 14131 mMainStack.scheduleDestroyActivities(app, false, "trim"); 14132 } 14133 } 14134 } 14135 app.trimMemoryLevel = curLevel; 14136 step++; 14137 if (step >= factor) { 14138 step = 0; 14139 switch (curLevel) { 14140 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14141 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14142 break; 14143 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14144 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14145 break; 14146 } 14147 } 14148 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14149 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14150 && app.thread != null) { 14151 try { 14152 app.thread.scheduleTrimMemory( 14153 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14154 } catch (RemoteException e) { 14155 } 14156 } 14157 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14158 } else { 14159 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14160 && app.pendingUiClean) { 14161 // If this application is now in the background and it 14162 // had done UI, then give it the special trim level to 14163 // have it free UI resources. 14164 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14165 if (app.trimMemoryLevel < level && app.thread != null) { 14166 try { 14167 app.thread.scheduleTrimMemory(level); 14168 } catch (RemoteException e) { 14169 } 14170 } 14171 app.pendingUiClean = false; 14172 } 14173 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 14174 try { 14175 app.thread.scheduleTrimMemory(fgTrimLevel); 14176 } catch (RemoteException e) { 14177 } 14178 } 14179 app.trimMemoryLevel = fgTrimLevel; 14180 } 14181 } 14182 } else { 14183 final int N = mLruProcesses.size(); 14184 for (i=0; i<N; i++) { 14185 ProcessRecord app = mLruProcesses.get(i); 14186 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14187 && app.pendingUiClean) { 14188 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14189 && app.thread != null) { 14190 try { 14191 app.thread.scheduleTrimMemory( 14192 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14193 } catch (RemoteException e) { 14194 } 14195 } 14196 app.pendingUiClean = false; 14197 } 14198 app.trimMemoryLevel = 0; 14199 } 14200 } 14201 14202 if (mAlwaysFinishActivities) { 14203 // Need to do this on its own message because the stack may not 14204 // be in a consistent state at this point. 14205 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 14206 } 14207 } 14208 14209 final void trimApplications() { 14210 synchronized (this) { 14211 int i; 14212 14213 // First remove any unused application processes whose package 14214 // has been removed. 14215 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14216 final ProcessRecord app = mRemovedProcesses.get(i); 14217 if (app.activities.size() == 0 14218 && app.curReceiver == null && app.services.size() == 0) { 14219 Slog.i( 14220 TAG, "Exiting empty application process " 14221 + app.processName + " (" 14222 + (app.thread != null ? app.thread.asBinder() : null) 14223 + ")\n"); 14224 if (app.pid > 0 && app.pid != MY_PID) { 14225 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 14226 app.processName, app.setAdj, "empty"); 14227 Process.killProcessQuiet(app.pid); 14228 } else { 14229 try { 14230 app.thread.scheduleExit(); 14231 } catch (Exception e) { 14232 // Ignore exceptions. 14233 } 14234 } 14235 cleanUpApplicationRecordLocked(app, false, true, -1); 14236 mRemovedProcesses.remove(i); 14237 14238 if (app.persistent) { 14239 if (app.persistent) { 14240 addAppLocked(app.info, false); 14241 } 14242 } 14243 } 14244 } 14245 14246 // Now update the oom adj for all processes. 14247 updateOomAdjLocked(); 14248 } 14249 } 14250 14251 /** This method sends the specified signal to each of the persistent apps */ 14252 public void signalPersistentProcesses(int sig) throws RemoteException { 14253 if (sig != Process.SIGNAL_USR1) { 14254 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14255 } 14256 14257 synchronized (this) { 14258 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14259 != PackageManager.PERMISSION_GRANTED) { 14260 throw new SecurityException("Requires permission " 14261 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14262 } 14263 14264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14265 ProcessRecord r = mLruProcesses.get(i); 14266 if (r.thread != null && r.persistent) { 14267 Process.sendSignal(r.pid, sig); 14268 } 14269 } 14270 } 14271 } 14272 14273 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14274 if (proc == null || proc == mProfileProc) { 14275 proc = mProfileProc; 14276 path = mProfileFile; 14277 profileType = mProfileType; 14278 clearProfilerLocked(); 14279 } 14280 if (proc == null) { 14281 return; 14282 } 14283 try { 14284 proc.thread.profilerControl(false, path, null, profileType); 14285 } catch (RemoteException e) { 14286 throw new IllegalStateException("Process disappeared"); 14287 } 14288 } 14289 14290 private void clearProfilerLocked() { 14291 if (mProfileFd != null) { 14292 try { 14293 mProfileFd.close(); 14294 } catch (IOException e) { 14295 } 14296 } 14297 mProfileApp = null; 14298 mProfileProc = null; 14299 mProfileFile = null; 14300 mProfileType = 0; 14301 mAutoStopProfiler = false; 14302 } 14303 14304 public boolean profileControl(String process, int userId, boolean start, 14305 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14306 14307 try { 14308 synchronized (this) { 14309 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14310 // its own permission. 14311 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14312 != PackageManager.PERMISSION_GRANTED) { 14313 throw new SecurityException("Requires permission " 14314 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14315 } 14316 14317 if (start && fd == null) { 14318 throw new IllegalArgumentException("null fd"); 14319 } 14320 14321 ProcessRecord proc = null; 14322 if (process != null) { 14323 proc = findProcessLocked(process, userId, "profileControl"); 14324 } 14325 14326 if (start && (proc == null || proc.thread == null)) { 14327 throw new IllegalArgumentException("Unknown process: " + process); 14328 } 14329 14330 if (start) { 14331 stopProfilerLocked(null, null, 0); 14332 setProfileApp(proc.info, proc.processName, path, fd, false); 14333 mProfileProc = proc; 14334 mProfileType = profileType; 14335 try { 14336 fd = fd.dup(); 14337 } catch (IOException e) { 14338 fd = null; 14339 } 14340 proc.thread.profilerControl(start, path, fd, profileType); 14341 fd = null; 14342 mProfileFd = null; 14343 } else { 14344 stopProfilerLocked(proc, path, profileType); 14345 if (fd != null) { 14346 try { 14347 fd.close(); 14348 } catch (IOException e) { 14349 } 14350 } 14351 } 14352 14353 return true; 14354 } 14355 } catch (RemoteException e) { 14356 throw new IllegalStateException("Process disappeared"); 14357 } finally { 14358 if (fd != null) { 14359 try { 14360 fd.close(); 14361 } catch (IOException e) { 14362 } 14363 } 14364 } 14365 } 14366 14367 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 14368 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14369 userId, true, true, callName, null); 14370 ProcessRecord proc = null; 14371 try { 14372 int pid = Integer.parseInt(process); 14373 synchronized (mPidsSelfLocked) { 14374 proc = mPidsSelfLocked.get(pid); 14375 } 14376 } catch (NumberFormatException e) { 14377 } 14378 14379 if (proc == null) { 14380 HashMap<String, SparseArray<ProcessRecord>> all 14381 = mProcessNames.getMap(); 14382 SparseArray<ProcessRecord> procs = all.get(process); 14383 if (procs != null && procs.size() > 0) { 14384 proc = procs.valueAt(0); 14385 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14386 for (int i=1; i<procs.size(); i++) { 14387 ProcessRecord thisProc = procs.valueAt(i); 14388 if (thisProc.userId == userId) { 14389 proc = thisProc; 14390 break; 14391 } 14392 } 14393 } 14394 } 14395 } 14396 14397 return proc; 14398 } 14399 14400 public boolean dumpHeap(String process, int userId, boolean managed, 14401 String path, ParcelFileDescriptor fd) throws RemoteException { 14402 14403 try { 14404 synchronized (this) { 14405 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14406 // its own permission (same as profileControl). 14407 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14408 != PackageManager.PERMISSION_GRANTED) { 14409 throw new SecurityException("Requires permission " 14410 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14411 } 14412 14413 if (fd == null) { 14414 throw new IllegalArgumentException("null fd"); 14415 } 14416 14417 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14418 if (proc == null || proc.thread == null) { 14419 throw new IllegalArgumentException("Unknown process: " + process); 14420 } 14421 14422 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14423 if (!isDebuggable) { 14424 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14425 throw new SecurityException("Process not debuggable: " + proc); 14426 } 14427 } 14428 14429 proc.thread.dumpHeap(managed, path, fd); 14430 fd = null; 14431 return true; 14432 } 14433 } catch (RemoteException e) { 14434 throw new IllegalStateException("Process disappeared"); 14435 } finally { 14436 if (fd != null) { 14437 try { 14438 fd.close(); 14439 } catch (IOException e) { 14440 } 14441 } 14442 } 14443 } 14444 14445 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14446 public void monitor() { 14447 synchronized (this) { } 14448 } 14449 14450 void onCoreSettingsChange(Bundle settings) { 14451 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14452 ProcessRecord processRecord = mLruProcesses.get(i); 14453 try { 14454 if (processRecord.thread != null) { 14455 processRecord.thread.setCoreSettings(settings); 14456 } 14457 } catch (RemoteException re) { 14458 /* ignore */ 14459 } 14460 } 14461 } 14462 14463 // Multi-user methods 14464 14465 @Override 14466 public boolean switchUser(final int userId) { 14467 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14468 != PackageManager.PERMISSION_GRANTED) { 14469 String msg = "Permission Denial: switchUser() from pid=" 14470 + Binder.getCallingPid() 14471 + ", uid=" + Binder.getCallingUid() 14472 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14473 Slog.w(TAG, msg); 14474 throw new SecurityException(msg); 14475 } 14476 14477 final long ident = Binder.clearCallingIdentity(); 14478 try { 14479 synchronized (this) { 14480 final int oldUserId = mCurrentUserId; 14481 if (oldUserId == userId) { 14482 return true; 14483 } 14484 14485 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14486 if (userInfo == null) { 14487 Slog.w(TAG, "No user info for user #" + userId); 14488 return false; 14489 } 14490 14491 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14492 R.anim.screen_user_enter); 14493 14494 boolean needStart = false; 14495 14496 // If the user we are switching to is not currently started, then 14497 // we need to start it now. 14498 if (mStartedUsers.get(userId) == null) { 14499 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14500 updateStartedUserArrayLocked(); 14501 needStart = true; 14502 } 14503 14504 mCurrentUserId = userId; 14505 mCurrentUserArray = new int[] { userId }; 14506 final Integer userIdInt = Integer.valueOf(userId); 14507 mUserLru.remove(userIdInt); 14508 mUserLru.add(userIdInt); 14509 14510 mWindowManager.setCurrentUser(userId); 14511 14512 // Once the internal notion of the active user has switched, we lock the device 14513 // with the option to show the user switcher on the keyguard. 14514 mWindowManager.lockNow(null); 14515 14516 final UserStartedState uss = mStartedUsers.get(userId); 14517 14518 // Make sure user is in the started state. If it is currently 14519 // stopping, we need to knock that off. 14520 if (uss.mState == UserStartedState.STATE_STOPPING) { 14521 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 14522 // so we can just fairly silently bring the user back from 14523 // the almost-dead. 14524 uss.mState = UserStartedState.STATE_RUNNING; 14525 updateStartedUserArrayLocked(); 14526 needStart = true; 14527 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 14528 // This means ACTION_SHUTDOWN has been sent, so we will 14529 // need to treat this as a new boot of the user. 14530 uss.mState = UserStartedState.STATE_BOOTING; 14531 updateStartedUserArrayLocked(); 14532 needStart = true; 14533 } 14534 14535 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14536 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14537 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14538 oldUserId, userId, uss)); 14539 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14540 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14541 if (needStart) { 14542 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14543 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14544 | Intent.FLAG_RECEIVER_FOREGROUND); 14545 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14546 broadcastIntentLocked(null, null, intent, 14547 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14548 false, false, MY_PID, Process.SYSTEM_UID, userId); 14549 } 14550 14551 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14552 if (userId != 0) { 14553 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14554 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14555 broadcastIntentLocked(null, null, intent, null, 14556 new IIntentReceiver.Stub() { 14557 public void performReceive(Intent intent, int resultCode, 14558 String data, Bundle extras, boolean ordered, 14559 boolean sticky, int sendingUser) { 14560 userInitialized(uss, userId); 14561 } 14562 }, 0, null, null, null, AppOpsManager.OP_NONE, 14563 true, false, MY_PID, Process.SYSTEM_UID, 14564 userId); 14565 uss.initializing = true; 14566 } else { 14567 getUserManagerLocked().makeInitialized(userInfo.id); 14568 } 14569 } 14570 14571 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14572 if (!haveActivities) { 14573 startHomeActivityLocked(userId); 14574 } 14575 14576 EventLogTags.writeAmSwitchUser(userId); 14577 getUserManagerLocked().userForeground(userId); 14578 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14579 if (needStart) { 14580 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 14581 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14582 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14583 broadcastIntentLocked(null, null, intent, 14584 null, new IIntentReceiver.Stub() { 14585 @Override 14586 public void performReceive(Intent intent, int resultCode, String data, 14587 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14588 throws RemoteException { 14589 } 14590 }, 0, null, null, 14591 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 14592 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14593 } 14594 } 14595 } finally { 14596 Binder.restoreCallingIdentity(ident); 14597 } 14598 14599 return true; 14600 } 14601 14602 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14603 long ident = Binder.clearCallingIdentity(); 14604 try { 14605 Intent intent; 14606 if (oldUserId >= 0) { 14607 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14608 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14609 | Intent.FLAG_RECEIVER_FOREGROUND); 14610 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14611 broadcastIntentLocked(null, null, intent, 14612 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14613 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14614 } 14615 if (newUserId >= 0) { 14616 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14617 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14618 | Intent.FLAG_RECEIVER_FOREGROUND); 14619 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14620 broadcastIntentLocked(null, null, intent, 14621 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14622 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14623 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14624 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14625 | Intent.FLAG_RECEIVER_FOREGROUND); 14626 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14627 broadcastIntentLocked(null, null, intent, 14628 null, null, 0, null, null, 14629 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 14630 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14631 } 14632 } finally { 14633 Binder.restoreCallingIdentity(ident); 14634 } 14635 } 14636 14637 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14638 final int newUserId) { 14639 final int N = mUserSwitchObservers.beginBroadcast(); 14640 if (N > 0) { 14641 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14642 int mCount = 0; 14643 @Override 14644 public void sendResult(Bundle data) throws RemoteException { 14645 synchronized (ActivityManagerService.this) { 14646 if (mCurUserSwitchCallback == this) { 14647 mCount++; 14648 if (mCount == N) { 14649 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14650 } 14651 } 14652 } 14653 } 14654 }; 14655 synchronized (this) { 14656 uss.switching = true; 14657 mCurUserSwitchCallback = callback; 14658 } 14659 for (int i=0; i<N; i++) { 14660 try { 14661 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14662 newUserId, callback); 14663 } catch (RemoteException e) { 14664 } 14665 } 14666 } else { 14667 synchronized (this) { 14668 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14669 } 14670 } 14671 mUserSwitchObservers.finishBroadcast(); 14672 } 14673 14674 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14675 synchronized (this) { 14676 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14677 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14678 } 14679 } 14680 14681 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14682 mCurUserSwitchCallback = null; 14683 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14684 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14685 oldUserId, newUserId, uss)); 14686 } 14687 14688 void userInitialized(UserStartedState uss, int newUserId) { 14689 completeSwitchAndInitalize(uss, newUserId, true, false); 14690 } 14691 14692 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14693 completeSwitchAndInitalize(uss, newUserId, false, true); 14694 } 14695 14696 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 14697 boolean clearInitializing, boolean clearSwitching) { 14698 boolean unfrozen = false; 14699 synchronized (this) { 14700 if (clearInitializing) { 14701 uss.initializing = false; 14702 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14703 } 14704 if (clearSwitching) { 14705 uss.switching = false; 14706 } 14707 if (!uss.switching && !uss.initializing) { 14708 mWindowManager.stopFreezingScreen(); 14709 unfrozen = true; 14710 } 14711 } 14712 if (unfrozen) { 14713 final int N = mUserSwitchObservers.beginBroadcast(); 14714 for (int i=0; i<N; i++) { 14715 try { 14716 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14717 } catch (RemoteException e) { 14718 } 14719 } 14720 mUserSwitchObservers.finishBroadcast(); 14721 } 14722 } 14723 14724 void finishUserSwitch(UserStartedState uss) { 14725 synchronized (this) { 14726 if (uss.mState == UserStartedState.STATE_BOOTING 14727 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14728 uss.mState = UserStartedState.STATE_RUNNING; 14729 final int userId = uss.mHandle.getIdentifier(); 14730 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14731 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14732 broadcastIntentLocked(null, null, intent, 14733 null, null, 0, null, null, 14734 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 14735 false, false, MY_PID, Process.SYSTEM_UID, userId); 14736 } 14737 int num = mUserLru.size(); 14738 int i = 0; 14739 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14740 Integer oldUserId = mUserLru.get(i); 14741 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14742 if (oldUss == null) { 14743 // Shouldn't happen, but be sane if it does. 14744 mUserLru.remove(i); 14745 num--; 14746 continue; 14747 } 14748 if (oldUss.mState == UserStartedState.STATE_STOPPING 14749 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 14750 // This user is already stopping, doesn't count. 14751 num--; 14752 i++; 14753 continue; 14754 } 14755 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14756 // Owner and current can't be stopped, but count as running. 14757 i++; 14758 continue; 14759 } 14760 // This is a user to be stopped. 14761 stopUserLocked(oldUserId, null); 14762 num--; 14763 i++; 14764 } 14765 } 14766 } 14767 14768 @Override 14769 public int stopUser(final int userId, final IStopUserCallback callback) { 14770 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14771 != PackageManager.PERMISSION_GRANTED) { 14772 String msg = "Permission Denial: switchUser() from pid=" 14773 + Binder.getCallingPid() 14774 + ", uid=" + Binder.getCallingUid() 14775 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14776 Slog.w(TAG, msg); 14777 throw new SecurityException(msg); 14778 } 14779 if (userId <= 0) { 14780 throw new IllegalArgumentException("Can't stop primary user " + userId); 14781 } 14782 synchronized (this) { 14783 return stopUserLocked(userId, callback); 14784 } 14785 } 14786 14787 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14788 if (mCurrentUserId == userId) { 14789 return ActivityManager.USER_OP_IS_CURRENT; 14790 } 14791 14792 final UserStartedState uss = mStartedUsers.get(userId); 14793 if (uss == null) { 14794 // User is not started, nothing to do... but we do need to 14795 // callback if requested. 14796 if (callback != null) { 14797 mHandler.post(new Runnable() { 14798 @Override 14799 public void run() { 14800 try { 14801 callback.userStopped(userId); 14802 } catch (RemoteException e) { 14803 } 14804 } 14805 }); 14806 } 14807 return ActivityManager.USER_OP_SUCCESS; 14808 } 14809 14810 if (callback != null) { 14811 uss.mStopCallbacks.add(callback); 14812 } 14813 14814 if (uss.mState != UserStartedState.STATE_STOPPING 14815 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14816 uss.mState = UserStartedState.STATE_STOPPING; 14817 updateStartedUserArrayLocked(); 14818 14819 long ident = Binder.clearCallingIdentity(); 14820 try { 14821 // We are going to broadcast ACTION_USER_STOPPING and then 14822 // once that is done send a final ACTION_SHUTDOWN and then 14823 // stop the user. 14824 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 14825 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14826 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14827 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 14828 // This is the result receiver for the final shutdown broadcast. 14829 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 14830 @Override 14831 public void performReceive(Intent intent, int resultCode, String data, 14832 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14833 finishUserStop(uss); 14834 } 14835 }; 14836 // This is the result receiver for the initial stopping broadcast. 14837 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 14838 @Override 14839 public void performReceive(Intent intent, int resultCode, String data, 14840 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14841 // On to the next. 14842 synchronized (ActivityManagerService.this) { 14843 if (uss.mState != UserStartedState.STATE_STOPPING) { 14844 // Whoops, we are being started back up. Abort, abort! 14845 return; 14846 } 14847 uss.mState = UserStartedState.STATE_SHUTDOWN; 14848 } 14849 broadcastIntentLocked(null, null, shutdownIntent, 14850 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 14851 true, false, MY_PID, Process.SYSTEM_UID, userId); 14852 } 14853 }; 14854 // Kick things off. 14855 broadcastIntentLocked(null, null, stoppingIntent, 14856 null, stoppingReceiver, 0, null, null, 14857 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 14858 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14859 } finally { 14860 Binder.restoreCallingIdentity(ident); 14861 } 14862 } 14863 14864 return ActivityManager.USER_OP_SUCCESS; 14865 } 14866 14867 void finishUserStop(UserStartedState uss) { 14868 final int userId = uss.mHandle.getIdentifier(); 14869 boolean stopped; 14870 ArrayList<IStopUserCallback> callbacks; 14871 synchronized (this) { 14872 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14873 if (mStartedUsers.get(userId) != uss) { 14874 stopped = false; 14875 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 14876 stopped = false; 14877 } else { 14878 stopped = true; 14879 // User can no longer run. 14880 mStartedUsers.remove(userId); 14881 mUserLru.remove(Integer.valueOf(userId)); 14882 updateStartedUserArrayLocked(); 14883 14884 // Clean up all state and processes associated with the user. 14885 // Kill all the processes for the user. 14886 forceStopUserLocked(userId); 14887 } 14888 } 14889 14890 for (int i=0; i<callbacks.size(); i++) { 14891 try { 14892 if (stopped) callbacks.get(i).userStopped(userId); 14893 else callbacks.get(i).userStopAborted(userId); 14894 } catch (RemoteException e) { 14895 } 14896 } 14897 } 14898 14899 @Override 14900 public UserInfo getCurrentUser() { 14901 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14902 != PackageManager.PERMISSION_GRANTED) && ( 14903 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14904 != PackageManager.PERMISSION_GRANTED)) { 14905 String msg = "Permission Denial: getCurrentUser() from pid=" 14906 + Binder.getCallingPid() 14907 + ", uid=" + Binder.getCallingUid() 14908 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14909 Slog.w(TAG, msg); 14910 throw new SecurityException(msg); 14911 } 14912 synchronized (this) { 14913 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14914 } 14915 } 14916 14917 int getCurrentUserIdLocked() { 14918 return mCurrentUserId; 14919 } 14920 14921 @Override 14922 public boolean isUserRunning(int userId, boolean orStopped) { 14923 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14924 != PackageManager.PERMISSION_GRANTED) { 14925 String msg = "Permission Denial: isUserRunning() from pid=" 14926 + Binder.getCallingPid() 14927 + ", uid=" + Binder.getCallingUid() 14928 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14929 Slog.w(TAG, msg); 14930 throw new SecurityException(msg); 14931 } 14932 synchronized (this) { 14933 return isUserRunningLocked(userId, orStopped); 14934 } 14935 } 14936 14937 boolean isUserRunningLocked(int userId, boolean orStopped) { 14938 UserStartedState state = mStartedUsers.get(userId); 14939 if (state == null) { 14940 return false; 14941 } 14942 if (orStopped) { 14943 return true; 14944 } 14945 return state.mState != UserStartedState.STATE_STOPPING 14946 && state.mState != UserStartedState.STATE_SHUTDOWN; 14947 } 14948 14949 @Override 14950 public int[] getRunningUserIds() { 14951 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14952 != PackageManager.PERMISSION_GRANTED) { 14953 String msg = "Permission Denial: isUserRunning() from pid=" 14954 + Binder.getCallingPid() 14955 + ", uid=" + Binder.getCallingUid() 14956 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14957 Slog.w(TAG, msg); 14958 throw new SecurityException(msg); 14959 } 14960 synchronized (this) { 14961 return mStartedUserArray; 14962 } 14963 } 14964 14965 private void updateStartedUserArrayLocked() { 14966 int num = 0; 14967 for (int i=0; i<mStartedUsers.size(); i++) { 14968 UserStartedState uss = mStartedUsers.valueAt(i); 14969 // This list does not include stopping users. 14970 if (uss.mState != UserStartedState.STATE_STOPPING 14971 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14972 num++; 14973 } 14974 } 14975 mStartedUserArray = new int[num]; 14976 num = 0; 14977 for (int i=0; i<mStartedUsers.size(); i++) { 14978 UserStartedState uss = mStartedUsers.valueAt(i); 14979 if (uss.mState != UserStartedState.STATE_STOPPING 14980 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14981 mStartedUserArray[num] = mStartedUsers.keyAt(i); 14982 num++; 14983 } 14984 } 14985 } 14986 14987 @Override 14988 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14989 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14990 != PackageManager.PERMISSION_GRANTED) { 14991 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14992 + Binder.getCallingPid() 14993 + ", uid=" + Binder.getCallingUid() 14994 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14995 Slog.w(TAG, msg); 14996 throw new SecurityException(msg); 14997 } 14998 14999 mUserSwitchObservers.register(observer); 15000 } 15001 15002 @Override 15003 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 15004 mUserSwitchObservers.unregister(observer); 15005 } 15006 15007 private boolean userExists(int userId) { 15008 if (userId == 0) { 15009 return true; 15010 } 15011 UserManagerService ums = getUserManagerLocked(); 15012 return ums != null ? (ums.getUserInfo(userId) != null) : false; 15013 } 15014 15015 int[] getUsersLocked() { 15016 UserManagerService ums = getUserManagerLocked(); 15017 return ums != null ? ums.getUserIds() : new int[] { 0 }; 15018 } 15019 15020 UserManagerService getUserManagerLocked() { 15021 if (mUserManager == null) { 15022 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 15023 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 15024 } 15025 return mUserManager; 15026 } 15027 15028 private void checkValidCaller(int uid, int userId) { 15029 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 15030 15031 throw new SecurityException("Caller uid=" + uid 15032 + " is not privileged to communicate with user=" + userId); 15033 } 15034 15035 private int applyUserId(int uid, int userId) { 15036 return UserHandle.getUid(userId, uid); 15037 } 15038 15039 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 15040 if (info == null) return null; 15041 ApplicationInfo newInfo = new ApplicationInfo(info); 15042 newInfo.uid = applyUserId(info.uid, userId); 15043 newInfo.dataDir = USER_DATA_DIR + userId + "/" 15044 + info.packageName; 15045 return newInfo; 15046 } 15047 15048 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 15049 if (aInfo == null 15050 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 15051 return aInfo; 15052 } 15053 15054 ActivityInfo info = new ActivityInfo(aInfo); 15055 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 15056 return info; 15057 } 15058 } 15059