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 com.android.internal.R; 22 import com.android.internal.os.BatteryStatsImpl; 23 import com.android.internal.os.ProcessStats; 24 import com.android.server.AttributeCache; 25 import com.android.server.IntentResolver; 26 import com.android.server.ProcessMap; 27 import com.android.server.SystemServer; 28 import com.android.server.Watchdog; 29 import com.android.server.am.ActivityStack.ActivityState; 30 import com.android.server.pm.UserManagerService; 31 import com.android.server.wm.WindowManagerService; 32 33 import dalvik.system.Zygote; 34 35 import android.app.Activity; 36 import android.app.ActivityManager; 37 import android.app.ActivityManagerNative; 38 import android.app.ActivityOptions; 39 import android.app.ActivityThread; 40 import android.app.AlertDialog; 41 import android.app.AppGlobals; 42 import android.app.ApplicationErrorReport; 43 import android.app.Dialog; 44 import android.app.IActivityController; 45 import android.app.IApplicationThread; 46 import android.app.IInstrumentationWatcher; 47 import android.app.INotificationManager; 48 import android.app.IProcessObserver; 49 import android.app.IServiceConnection; 50 import android.app.IStopUserCallback; 51 import android.app.IThumbnailReceiver; 52 import android.app.IUserSwitchObserver; 53 import android.app.Instrumentation; 54 import android.app.Notification; 55 import android.app.NotificationManager; 56 import android.app.PendingIntent; 57 import android.app.backup.IBackupManager; 58 import android.content.ActivityNotFoundException; 59 import android.content.BroadcastReceiver; 60 import android.content.ClipData; 61 import android.content.ComponentCallbacks2; 62 import android.content.ComponentName; 63 import android.content.ContentProvider; 64 import android.content.ContentResolver; 65 import android.content.Context; 66 import android.content.DialogInterface; 67 import android.content.IContentProvider; 68 import android.content.IIntentReceiver; 69 import android.content.IIntentSender; 70 import android.content.Intent; 71 import android.content.IntentFilter; 72 import android.content.IntentSender; 73 import android.content.pm.ActivityInfo; 74 import android.content.pm.ApplicationInfo; 75 import android.content.pm.ConfigurationInfo; 76 import android.content.pm.IPackageDataObserver; 77 import android.content.pm.IPackageManager; 78 import android.content.pm.InstrumentationInfo; 79 import android.content.pm.PackageInfo; 80 import android.content.pm.PackageManager; 81 import android.content.pm.UserInfo; 82 import android.content.pm.PackageManager.NameNotFoundException; 83 import android.content.pm.PathPermission; 84 import android.content.pm.ProviderInfo; 85 import android.content.pm.ResolveInfo; 86 import android.content.pm.ServiceInfo; 87 import android.content.res.CompatibilityInfo; 88 import android.content.res.Configuration; 89 import android.graphics.Bitmap; 90 import android.net.Proxy; 91 import android.net.ProxyProperties; 92 import android.net.Uri; 93 import android.os.Binder; 94 import android.os.Build; 95 import android.os.Bundle; 96 import android.os.Debug; 97 import android.os.DropBoxManager; 98 import android.os.Environment; 99 import android.os.FileObserver; 100 import android.os.FileUtils; 101 import android.os.Handler; 102 import android.os.IBinder; 103 import android.os.IPermissionController; 104 import android.os.IRemoteCallback; 105 import android.os.IUserManager; 106 import android.os.Looper; 107 import android.os.Message; 108 import android.os.Parcel; 109 import android.os.ParcelFileDescriptor; 110 import android.os.Process; 111 import android.os.RemoteCallbackList; 112 import android.os.RemoteException; 113 import android.os.SELinux; 114 import android.os.ServiceManager; 115 import android.os.StrictMode; 116 import android.os.SystemClock; 117 import android.os.SystemProperties; 118 import android.os.UserHandle; 119 import android.provider.Settings; 120 import android.text.format.Time; 121 import android.util.EventLog; 122 import android.util.Log; 123 import android.util.Pair; 124 import android.util.PrintWriterPrinter; 125 import android.util.Slog; 126 import android.util.SparseArray; 127 import android.util.TimeUtils; 128 import android.view.Gravity; 129 import android.view.LayoutInflater; 130 import android.view.View; 131 import android.view.WindowManager; 132 import android.view.WindowManagerPolicy; 133 134 import java.io.BufferedInputStream; 135 import java.io.BufferedOutputStream; 136 import java.io.BufferedReader; 137 import java.io.DataInputStream; 138 import java.io.DataOutputStream; 139 import java.io.File; 140 import java.io.FileDescriptor; 141 import java.io.FileInputStream; 142 import java.io.FileNotFoundException; 143 import java.io.FileOutputStream; 144 import java.io.IOException; 145 import java.io.InputStreamReader; 146 import java.io.PrintWriter; 147 import java.io.StringWriter; 148 import java.lang.ref.WeakReference; 149 import java.util.ArrayList; 150 import java.util.Arrays; 151 import java.util.Collections; 152 import java.util.Comparator; 153 import java.util.HashMap; 154 import java.util.HashSet; 155 import java.util.Iterator; 156 import java.util.List; 157 import java.util.Locale; 158 import java.util.Map; 159 import java.util.Set; 160 import java.util.concurrent.atomic.AtomicBoolean; 161 import java.util.concurrent.atomic.AtomicLong; 162 163 public final class ActivityManagerService extends ActivityManagerNative 164 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 165 private static final String USER_DATA_DIR = "/data/user/"; 166 static final String TAG = "ActivityManager"; 167 static final String TAG_MU = "ActivityManagerServiceMU"; 168 static final boolean DEBUG = false; 169 static final boolean localLOGV = DEBUG; 170 static final boolean DEBUG_SWITCH = localLOGV || false; 171 static final boolean DEBUG_TASKS = localLOGV || false; 172 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 173 static final boolean DEBUG_PAUSE = localLOGV || false; 174 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 175 static final boolean DEBUG_TRANSITION = localLOGV || false; 176 static final boolean DEBUG_BROADCAST = localLOGV || false; 177 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_SERVICE = localLOGV || false; 180 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 181 static final boolean DEBUG_VISBILITY = localLOGV || false; 182 static final boolean DEBUG_PROCESSES = localLOGV || false; 183 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 184 static final boolean DEBUG_CLEANUP = localLOGV || false; 185 static final boolean DEBUG_PROVIDER = localLOGV || false; 186 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 187 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 188 static final boolean DEBUG_RESULTS = localLOGV || false; 189 static final boolean DEBUG_BACKUP = localLOGV || false; 190 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 191 static final boolean DEBUG_POWER = localLOGV || false; 192 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 193 static final boolean DEBUG_MU = localLOGV || false; 194 static final boolean VALIDATE_TOKENS = false; 195 static final boolean SHOW_ACTIVITY_START_TIME = true; 196 197 // Control over CPU and battery monitoring. 198 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 199 static final boolean MONITOR_CPU_USAGE = true; 200 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 201 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 202 static final boolean MONITOR_THREAD_CPU_USAGE = false; 203 204 // The flags that are set for all calls we make to the package manager. 205 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 206 207 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 208 209 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 210 211 // Maximum number of recent tasks that we can remember. 212 static final int MAX_RECENT_TASKS = 20; 213 214 // Amount of time after a call to stopAppSwitches() during which we will 215 // prevent further untrusted switches from happening. 216 static final long APP_SWITCH_DELAY_TIME = 5*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real. 220 static final int PROC_START_TIMEOUT = 10*1000; 221 222 // How long we wait for a launched process to attach to the activity manager 223 // before we decide it's never going to come up for real, when the process was 224 // started with a wrapper for instrumentation (such as Valgrind) because it 225 // could take much longer than usual. 226 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 227 228 // How long to wait after going idle before forcing apps to GC. 229 static final int GC_TIMEOUT = 5*1000; 230 231 // The minimum amount of time between successive GC requests for a process. 232 static final int GC_MIN_INTERVAL = 60*1000; 233 234 // The rate at which we check for apps using excessive power -- 15 mins. 235 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on wake locks to start killing things. 239 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // The minimum sample duration we will allow before deciding we have 242 // enough data on CPU usage to start killing things. 243 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 244 245 // How long we allow a receiver to run before giving up on it. 246 static final int BROADCAST_FG_TIMEOUT = 10*1000; 247 static final int BROADCAST_BG_TIMEOUT = 60*1000; 248 249 // How long we wait until we timeout on key dispatching. 250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 251 252 // How long we wait until we timeout on key dispatching during instrumentation. 253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 254 255 // Amount of time we wait for observers to handle a user switch before 256 // giving up on them and unfreezing the screen. 257 static final int USER_SWITCH_TIMEOUT = 2*1000; 258 259 // Maximum number of users we allow to be running at a time. 260 static final int MAX_RUNNING_USERS = 3; 261 262 static final int MY_PID = Process.myPid(); 263 264 static final String[] EMPTY_STRING_ARRAY = new String[0]; 265 266 public ActivityStack mMainStack; 267 268 private final boolean mHeadless; 269 270 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 271 // default actuion automatically. Important for devices without direct input 272 // devices. 273 private boolean mShowDialogs = true; 274 275 /** 276 * Description of a request to start a new activity, which has been held 277 * due to app switches being disabled. 278 */ 279 static class PendingActivityLaunch { 280 ActivityRecord r; 281 ActivityRecord sourceRecord; 282 int startFlags; 283 } 284 285 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 286 = new ArrayList<PendingActivityLaunch>(); 287 288 289 BroadcastQueue mFgBroadcastQueue; 290 BroadcastQueue mBgBroadcastQueue; 291 // Convenient for easy iteration over the queues. Foreground is first 292 // so that dispatch of foreground broadcasts gets precedence. 293 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 294 broadcastQueueForIntent(Intent intent)295 BroadcastQueue broadcastQueueForIntent(Intent intent) { 296 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 297 if (DEBUG_BACKGROUND_BROADCAST) { 298 Slog.i(TAG, "Broadcast intent " + intent + " on " 299 + (isFg ? "foreground" : "background") 300 + " queue"); 301 } 302 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 303 } 304 broadcastRecordForReceiverLocked(IBinder receiver)305 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 306 for (BroadcastQueue queue : mBroadcastQueues) { 307 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 308 if (r != null) { 309 return r; 310 } 311 } 312 return null; 313 } 314 315 /** 316 * Activity we have told the window manager to have key focus. 317 */ 318 ActivityRecord mFocusedActivity = null; 319 /** 320 * List of intents that were used to start the most recent tasks. 321 */ 322 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 323 324 /** 325 * Process management. 326 */ 327 final ProcessList mProcessList = new ProcessList(); 328 329 /** 330 * All of the applications we currently have running organized by name. 331 * The keys are strings of the application package name (as 332 * returned by the package manager), and the keys are ApplicationRecord 333 * objects. 334 */ 335 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 336 337 /** 338 * The currently running isolated processes. 339 */ 340 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 341 342 /** 343 * Counter for assigning isolated process uids, to avoid frequently reusing the 344 * same ones. 345 */ 346 int mNextIsolatedProcessUid = 0; 347 348 /** 349 * The currently running heavy-weight process, if any. 350 */ 351 ProcessRecord mHeavyWeightProcess = null; 352 353 /** 354 * The last time that various processes have crashed. 355 */ 356 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 357 358 /** 359 * Set of applications that we consider to be bad, and will reject 360 * incoming broadcasts from (which the user has no control over). 361 * Processes are added to this set when they have crashed twice within 362 * a minimum amount of time; they are removed from it when they are 363 * later restarted (hopefully due to some user action). The value is the 364 * time it was added to the list. 365 */ 366 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 367 368 /** 369 * All of the processes we currently have running organized by pid. 370 * The keys are the pid running the application. 371 * 372 * <p>NOTE: This object is protected by its own lock, NOT the global 373 * activity manager lock! 374 */ 375 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 376 377 /** 378 * All of the processes that have been forced to be foreground. The key 379 * is the pid of the caller who requested it (we hold a death 380 * link on it). 381 */ 382 abstract class ForegroundToken implements IBinder.DeathRecipient { 383 int pid; 384 IBinder token; 385 } 386 final SparseArray<ForegroundToken> mForegroundProcesses 387 = new SparseArray<ForegroundToken>(); 388 389 /** 390 * List of records for processes that someone had tried to start before the 391 * system was ready. We don't start them at that point, but ensure they 392 * are started by the time booting is complete. 393 */ 394 final ArrayList<ProcessRecord> mProcessesOnHold 395 = new ArrayList<ProcessRecord>(); 396 397 /** 398 * List of persistent applications that are in the process 399 * of being started. 400 */ 401 final ArrayList<ProcessRecord> mPersistentStartingProcesses 402 = new ArrayList<ProcessRecord>(); 403 404 /** 405 * Processes that are being forcibly torn down. 406 */ 407 final ArrayList<ProcessRecord> mRemovedProcesses 408 = new ArrayList<ProcessRecord>(); 409 410 /** 411 * List of running applications, sorted by recent usage. 412 * The first entry in the list is the least recently used. 413 * It contains ApplicationRecord objects. This list does NOT include 414 * any persistent application records (since we never want to exit them). 415 */ 416 final ArrayList<ProcessRecord> mLruProcesses 417 = new ArrayList<ProcessRecord>(); 418 419 /** 420 * List of processes that should gc as soon as things are idle. 421 */ 422 final ArrayList<ProcessRecord> mProcessesToGc 423 = new ArrayList<ProcessRecord>(); 424 425 /** 426 * This is the process holding what we currently consider to be 427 * the "home" activity. 428 */ 429 ProcessRecord mHomeProcess; 430 431 /** 432 * This is the process holding the activity the user last visited that 433 * is in a different process from the one they are currently in. 434 */ 435 ProcessRecord mPreviousProcess; 436 437 /** 438 * The time at which the previous process was last visible. 439 */ 440 long mPreviousProcessVisibleTime; 441 442 /** 443 * Which uses have been started, so are allowed to run code. 444 */ 445 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 446 447 /** 448 * LRU list of history of current users. Most recently current is at the end. 449 */ 450 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 451 452 /** 453 * Constant array of the users that are currently started. 454 */ 455 int[] mStartedUserArray = new int[] { 0 }; 456 457 /** 458 * Registered observers of the user switching mechanics. 459 */ 460 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 461 = new RemoteCallbackList<IUserSwitchObserver>(); 462 463 /** 464 * Currently active user switch. 465 */ 466 Object mCurUserSwitchCallback; 467 468 /** 469 * Packages that the user has asked to have run in screen size 470 * compatibility mode instead of filling the screen. 471 */ 472 final CompatModePackages mCompatModePackages; 473 474 /** 475 * Set of PendingResultRecord objects that are currently active. 476 */ 477 final HashSet mPendingResultRecords = new HashSet(); 478 479 /** 480 * Set of IntentSenderRecord objects that are currently active. 481 */ 482 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 483 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 484 485 /** 486 * Fingerprints (hashCode()) of stack traces that we've 487 * already logged DropBox entries for. Guarded by itself. If 488 * something (rogue user app) forces this over 489 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 490 */ 491 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 492 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 493 494 /** 495 * Strict Mode background batched logging state. 496 * 497 * The string buffer is guarded by itself, and its lock is also 498 * used to determine if another batched write is already 499 * in-flight. 500 */ 501 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 502 503 /** 504 * Keeps track of all IIntentReceivers that have been registered for 505 * broadcasts. Hash keys are the receiver IBinder, hash value is 506 * a ReceiverList. 507 */ 508 final HashMap mRegisteredReceivers = new HashMap(); 509 510 /** 511 * Resolver for broadcast intents to registered receivers. 512 * Holds BroadcastFilter (subclass of IntentFilter). 513 */ 514 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 515 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 516 @Override 517 protected boolean allowFilterResult( 518 BroadcastFilter filter, List<BroadcastFilter> dest) { 519 IBinder target = filter.receiverList.receiver.asBinder(); 520 for (int i=dest.size()-1; i>=0; i--) { 521 if (dest.get(i).receiverList.receiver.asBinder() == target) { 522 return false; 523 } 524 } 525 return true; 526 } 527 528 @Override 529 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 530 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 531 || userId == filter.owningUserId) { 532 return super.newResult(filter, match, userId); 533 } 534 return null; 535 } 536 537 @Override 538 protected BroadcastFilter[] newArray(int size) { 539 return new BroadcastFilter[size]; 540 } 541 542 @Override 543 protected String packageForFilter(BroadcastFilter filter) { 544 return filter.packageName; 545 } 546 }; 547 548 /** 549 * State of all active sticky broadcasts per user. Keys are the action of the 550 * sticky Intent, values are an ArrayList of all broadcasted intents with 551 * that action (which should usually be one). The SparseArray is keyed 552 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 553 * for stickies that are sent to all users. 554 */ 555 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 556 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 557 558 final ActiveServices mServices; 559 560 /** 561 * Backup/restore process management 562 */ 563 String mBackupAppName = null; 564 BackupRecord mBackupTarget = null; 565 566 /** 567 * List of PendingThumbnailsRecord objects of clients who are still 568 * waiting to receive all of the thumbnails for a task. 569 */ 570 final ArrayList mPendingThumbnails = new ArrayList(); 571 572 /** 573 * List of HistoryRecord objects that have been finished and must 574 * still report back to a pending thumbnail receiver. 575 */ 576 final ArrayList mCancelledThumbnails = new ArrayList(); 577 578 final ProviderMap mProviderMap; 579 580 /** 581 * List of content providers who have clients waiting for them. The 582 * application is currently being launched and the provider will be 583 * removed from this list once it is published. 584 */ 585 final ArrayList<ContentProviderRecord> mLaunchingProviders 586 = new ArrayList<ContentProviderRecord>(); 587 588 /** 589 * Global set of specific Uri permissions that have been granted. 590 */ 591 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 592 = new SparseArray<HashMap<Uri, UriPermission>>(); 593 594 CoreSettingsObserver mCoreSettingsObserver; 595 596 /** 597 * Thread-local storage used to carry caller permissions over through 598 * indirect content-provider access. 599 * @see #ActivityManagerService.openContentUri() 600 */ 601 private class Identity { 602 public int pid; 603 public int uid; 604 Identity(int _pid, int _uid)605 Identity(int _pid, int _uid) { 606 pid = _pid; 607 uid = _uid; 608 } 609 } 610 611 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 612 613 /** 614 * All information we have collected about the runtime performance of 615 * any user id that can impact battery performance. 616 */ 617 final BatteryStatsService mBatteryStatsService; 618 619 /** 620 * information about component usage 621 */ 622 final UsageStatsService mUsageStatsService; 623 624 /** 625 * Current configuration information. HistoryRecord objects are given 626 * a reference to this object to indicate which configuration they are 627 * currently running in, so this object must be kept immutable. 628 */ 629 Configuration mConfiguration = new Configuration(); 630 631 /** 632 * Current sequencing integer of the configuration, for skipping old 633 * configurations. 634 */ 635 int mConfigurationSeq = 0; 636 637 /** 638 * Hardware-reported OpenGLES version. 639 */ 640 final int GL_ES_VERSION; 641 642 /** 643 * List of initialization arguments to pass to all processes when binding applications to them. 644 * For example, references to the commonly used services. 645 */ 646 HashMap<String, IBinder> mAppBindArgs; 647 648 /** 649 * Temporary to avoid allocations. Protected by main lock. 650 */ 651 final StringBuilder mStringBuilder = new StringBuilder(256); 652 653 /** 654 * Used to control how we initialize the service. 655 */ 656 boolean mStartRunning = false; 657 ComponentName mTopComponent; 658 String mTopAction; 659 String mTopData; 660 boolean mProcessesReady = false; 661 boolean mSystemReady = false; 662 boolean mBooting = false; 663 boolean mWaitingUpdate = false; 664 boolean mDidUpdate = false; 665 boolean mOnBattery = false; 666 boolean mLaunchWarningShown = false; 667 668 Context mContext; 669 670 int mFactoryTest; 671 672 boolean mCheckedForSetup; 673 674 /** 675 * The time at which we will allow normal application switches again, 676 * after a call to {@link #stopAppSwitches()}. 677 */ 678 long mAppSwitchesAllowedTime; 679 680 /** 681 * This is set to true after the first switch after mAppSwitchesAllowedTime 682 * is set; any switches after that will clear the time. 683 */ 684 boolean mDidAppSwitch; 685 686 /** 687 * Last time (in realtime) at which we checked for power usage. 688 */ 689 long mLastPowerCheckRealtime; 690 691 /** 692 * Last time (in uptime) at which we checked for power usage. 693 */ 694 long mLastPowerCheckUptime; 695 696 /** 697 * Set while we are wanting to sleep, to prevent any 698 * activities from being started/resumed. 699 */ 700 boolean mSleeping = false; 701 702 /** 703 * State of external calls telling us if the device is asleep. 704 */ 705 boolean mWentToSleep = false; 706 707 /** 708 * State of external call telling us if the lock screen is shown. 709 */ 710 boolean mLockScreenShown = false; 711 712 /** 713 * Set if we are shutting down the system, similar to sleeping. 714 */ 715 boolean mShuttingDown = false; 716 717 /** 718 * Task identifier that activities are currently being started 719 * in. Incremented each time a new task is created. 720 * todo: Replace this with a TokenSpace class that generates non-repeating 721 * integers that won't wrap. 722 */ 723 int mCurTask = 1; 724 725 /** 726 * Current sequence id for oom_adj computation traversal. 727 */ 728 int mAdjSeq = 0; 729 730 /** 731 * Current sequence id for process LRU updating. 732 */ 733 int mLruSeq = 0; 734 735 /** 736 * Keep track of the non-hidden/empty process we last found, to help 737 * determine how to distribute hidden/empty processes next time. 738 */ 739 int mNumNonHiddenProcs = 0; 740 741 /** 742 * Keep track of the number of hidden procs, to balance oom adj 743 * distribution between those and empty procs. 744 */ 745 int mNumHiddenProcs = 0; 746 747 /** 748 * Keep track of the number of service processes we last found, to 749 * determine on the next iteration which should be B services. 750 */ 751 int mNumServiceProcs = 0; 752 int mNewNumServiceProcs = 0; 753 754 /** 755 * System monitoring: number of processes that died since the last 756 * N procs were started. 757 */ 758 int[] mProcDeaths = new int[20]; 759 760 /** 761 * This is set if we had to do a delayed dexopt of an app before launching 762 * it, to increasing the ANR timeouts in that case. 763 */ 764 boolean mDidDexOpt; 765 766 String mDebugApp = null; 767 boolean mWaitForDebugger = false; 768 boolean mDebugTransient = false; 769 String mOrigDebugApp = null; 770 boolean mOrigWaitForDebugger = false; 771 boolean mAlwaysFinishActivities = false; 772 IActivityController mController = null; 773 String mProfileApp = null; 774 ProcessRecord mProfileProc = null; 775 String mProfileFile; 776 ParcelFileDescriptor mProfileFd; 777 int mProfileType = 0; 778 boolean mAutoStopProfiler = false; 779 String mOpenGlTraceApp = null; 780 781 static class ProcessChangeItem { 782 static final int CHANGE_ACTIVITIES = 1<<0; 783 static final int CHANGE_IMPORTANCE= 1<<1; 784 int changes; 785 int uid; 786 int pid; 787 int importance; 788 boolean foregroundActivities; 789 } 790 791 final RemoteCallbackList<IProcessObserver> mProcessObservers 792 = new RemoteCallbackList<IProcessObserver>(); 793 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 794 795 final ArrayList<ProcessChangeItem> mPendingProcessChanges 796 = new ArrayList<ProcessChangeItem>(); 797 final ArrayList<ProcessChangeItem> mAvailProcessChanges 798 = new ArrayList<ProcessChangeItem>(); 799 800 /** 801 * Callback of last caller to {@link #requestPss}. 802 */ 803 Runnable mRequestPssCallback; 804 805 /** 806 * Remaining processes for which we are waiting results from the last 807 * call to {@link #requestPss}. 808 */ 809 final ArrayList<ProcessRecord> mRequestPssList 810 = new ArrayList<ProcessRecord>(); 811 812 /** 813 * Runtime statistics collection thread. This object's lock is used to 814 * protect all related state. 815 */ 816 final Thread mProcessStatsThread; 817 818 /** 819 * Used to collect process stats when showing not responding dialog. 820 * Protected by mProcessStatsThread. 821 */ 822 final ProcessStats mProcessStats = new ProcessStats( 823 MONITOR_THREAD_CPU_USAGE); 824 final AtomicLong mLastCpuTime = new AtomicLong(0); 825 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 826 827 long mLastWriteTime = 0; 828 829 /** 830 * Set to true after the system has finished booting. 831 */ 832 boolean mBooted = false; 833 834 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 835 int mProcessLimitOverride = -1; 836 837 WindowManagerService mWindowManager; 838 839 static ActivityManagerService mSelf; 840 static ActivityThread mSystemThread; 841 842 private int mCurrentUserId = 0; 843 private int[] mCurrentUserArray = new int[] { 0 }; 844 private UserManagerService mUserManager; 845 846 private final class AppDeathRecipient implements IBinder.DeathRecipient { 847 final ProcessRecord mApp; 848 final int mPid; 849 final IApplicationThread mAppThread; 850 AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)851 AppDeathRecipient(ProcessRecord app, int pid, 852 IApplicationThread thread) { 853 if (localLOGV) Slog.v( 854 TAG, "New death recipient " + this 855 + " for thread " + thread.asBinder()); 856 mApp = app; 857 mPid = pid; 858 mAppThread = thread; 859 } 860 binderDied()861 public void binderDied() { 862 if (localLOGV) Slog.v( 863 TAG, "Death received in " + this 864 + " for thread " + mAppThread.asBinder()); 865 synchronized(ActivityManagerService.this) { 866 appDiedLocked(mApp, mPid, mAppThread); 867 } 868 } 869 } 870 871 static final int SHOW_ERROR_MSG = 1; 872 static final int SHOW_NOT_RESPONDING_MSG = 2; 873 static final int SHOW_FACTORY_ERROR_MSG = 3; 874 static final int UPDATE_CONFIGURATION_MSG = 4; 875 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 876 static final int WAIT_FOR_DEBUGGER_MSG = 6; 877 static final int SERVICE_TIMEOUT_MSG = 12; 878 static final int UPDATE_TIME_ZONE = 13; 879 static final int SHOW_UID_ERROR_MSG = 14; 880 static final int IM_FEELING_LUCKY_MSG = 15; 881 static final int PROC_START_TIMEOUT_MSG = 20; 882 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 883 static final int KILL_APPLICATION_MSG = 22; 884 static final int FINALIZE_PENDING_INTENT_MSG = 23; 885 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 886 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 887 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 888 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 889 static final int CLEAR_DNS_CACHE = 28; 890 static final int UPDATE_HTTP_PROXY = 29; 891 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 892 static final int DISPATCH_PROCESSES_CHANGED = 31; 893 static final int DISPATCH_PROCESS_DIED = 32; 894 static final int REPORT_MEM_USAGE = 33; 895 static final int REPORT_USER_SWITCH_MSG = 34; 896 static final int CONTINUE_USER_SWITCH_MSG = 35; 897 static final int USER_SWITCH_TIMEOUT_MSG = 36; 898 899 static final int FIRST_ACTIVITY_STACK_MSG = 100; 900 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 901 static final int FIRST_COMPAT_MODE_MSG = 300; 902 903 AlertDialog mUidAlert; 904 CompatModeDialog mCompatModeDialog; 905 long mLastMemUsageReportTime = 0; 906 907 final Handler mHandler = new Handler() { 908 //public Handler() { 909 // if (localLOGV) Slog.v(TAG, "Handler started!"); 910 //} 911 912 public void handleMessage(Message msg) { 913 switch (msg.what) { 914 case SHOW_ERROR_MSG: { 915 HashMap data = (HashMap) msg.obj; 916 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 917 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 918 synchronized (ActivityManagerService.this) { 919 ProcessRecord proc = (ProcessRecord)data.get("app"); 920 AppErrorResult res = (AppErrorResult) data.get("result"); 921 if (proc != null && proc.crashDialog != null) { 922 Slog.e(TAG, "App already has crash dialog: " + proc); 923 if (res != null) { 924 res.set(0); 925 } 926 return; 927 } 928 if (!showBackground && UserHandle.getAppId(proc.uid) 929 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 930 && proc.pid != MY_PID) { 931 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 932 if (res != null) { 933 res.set(0); 934 } 935 return; 936 } 937 if (mShowDialogs && !mSleeping && !mShuttingDown) { 938 Dialog d = new AppErrorDialog(mContext, 939 ActivityManagerService.this, res, proc); 940 d.show(); 941 proc.crashDialog = d; 942 } else { 943 // The device is asleep, so just pretend that the user 944 // saw a crash dialog and hit "force quit". 945 if (res != null) { 946 res.set(0); 947 } 948 } 949 } 950 951 ensureBootCompleted(); 952 } break; 953 case SHOW_NOT_RESPONDING_MSG: { 954 synchronized (ActivityManagerService.this) { 955 HashMap data = (HashMap) msg.obj; 956 ProcessRecord proc = (ProcessRecord)data.get("app"); 957 if (proc != null && proc.anrDialog != null) { 958 Slog.e(TAG, "App already has anr dialog: " + proc); 959 return; 960 } 961 962 Intent intent = new Intent("android.intent.action.ANR"); 963 if (!mProcessesReady) { 964 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 965 | Intent.FLAG_RECEIVER_FOREGROUND); 966 } 967 broadcastIntentLocked(null, null, intent, 968 null, null, 0, null, null, null, 969 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 970 971 if (mShowDialogs) { 972 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 973 mContext, proc, (ActivityRecord)data.get("activity"), 974 msg.arg1 != 0); 975 d.show(); 976 proc.anrDialog = d; 977 } else { 978 // Just kill the app if there is no dialog to be shown. 979 killAppAtUsersRequest(proc, null); 980 } 981 } 982 983 ensureBootCompleted(); 984 } break; 985 case SHOW_STRICT_MODE_VIOLATION_MSG: { 986 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 987 synchronized (ActivityManagerService.this) { 988 ProcessRecord proc = (ProcessRecord) data.get("app"); 989 if (proc == null) { 990 Slog.e(TAG, "App not found when showing strict mode dialog."); 991 break; 992 } 993 if (proc.crashDialog != null) { 994 Slog.e(TAG, "App already has strict mode dialog: " + proc); 995 return; 996 } 997 AppErrorResult res = (AppErrorResult) data.get("result"); 998 if (mShowDialogs && !mSleeping && !mShuttingDown) { 999 Dialog d = new StrictModeViolationDialog(mContext, 1000 ActivityManagerService.this, res, proc); 1001 d.show(); 1002 proc.crashDialog = d; 1003 } else { 1004 // The device is asleep, so just pretend that the user 1005 // saw a crash dialog and hit "force quit". 1006 res.set(0); 1007 } 1008 } 1009 ensureBootCompleted(); 1010 } break; 1011 case SHOW_FACTORY_ERROR_MSG: { 1012 Dialog d = new FactoryErrorDialog( 1013 mContext, msg.getData().getCharSequence("msg")); 1014 d.show(); 1015 ensureBootCompleted(); 1016 } break; 1017 case UPDATE_CONFIGURATION_MSG: { 1018 final ContentResolver resolver = mContext.getContentResolver(); 1019 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1020 } break; 1021 case GC_BACKGROUND_PROCESSES_MSG: { 1022 synchronized (ActivityManagerService.this) { 1023 performAppGcsIfAppropriateLocked(); 1024 } 1025 } break; 1026 case WAIT_FOR_DEBUGGER_MSG: { 1027 synchronized (ActivityManagerService.this) { 1028 ProcessRecord app = (ProcessRecord)msg.obj; 1029 if (msg.arg1 != 0) { 1030 if (!app.waitedForDebugger) { 1031 Dialog d = new AppWaitingForDebuggerDialog( 1032 ActivityManagerService.this, 1033 mContext, app); 1034 app.waitDialog = d; 1035 app.waitedForDebugger = true; 1036 d.show(); 1037 } 1038 } else { 1039 if (app.waitDialog != null) { 1040 app.waitDialog.dismiss(); 1041 app.waitDialog = null; 1042 } 1043 } 1044 } 1045 } break; 1046 case SERVICE_TIMEOUT_MSG: { 1047 if (mDidDexOpt) { 1048 mDidDexOpt = false; 1049 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1050 nmsg.obj = msg.obj; 1051 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1052 return; 1053 } 1054 mServices.serviceTimeout((ProcessRecord)msg.obj); 1055 } break; 1056 case UPDATE_TIME_ZONE: { 1057 synchronized (ActivityManagerService.this) { 1058 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1059 ProcessRecord r = mLruProcesses.get(i); 1060 if (r.thread != null) { 1061 try { 1062 r.thread.updateTimeZone(); 1063 } catch (RemoteException ex) { 1064 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1065 } 1066 } 1067 } 1068 } 1069 } break; 1070 case CLEAR_DNS_CACHE: { 1071 synchronized (ActivityManagerService.this) { 1072 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1073 ProcessRecord r = mLruProcesses.get(i); 1074 if (r.thread != null) { 1075 try { 1076 r.thread.clearDnsCache(); 1077 } catch (RemoteException ex) { 1078 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1079 } 1080 } 1081 } 1082 } 1083 } break; 1084 case UPDATE_HTTP_PROXY: { 1085 ProxyProperties proxy = (ProxyProperties)msg.obj; 1086 String host = ""; 1087 String port = ""; 1088 String exclList = ""; 1089 if (proxy != null) { 1090 host = proxy.getHost(); 1091 port = Integer.toString(proxy.getPort()); 1092 exclList = proxy.getExclusionList(); 1093 } 1094 synchronized (ActivityManagerService.this) { 1095 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1096 ProcessRecord r = mLruProcesses.get(i); 1097 if (r.thread != null) { 1098 try { 1099 r.thread.setHttpProxy(host, port, exclList); 1100 } catch (RemoteException ex) { 1101 Slog.w(TAG, "Failed to update http proxy for: " + 1102 r.info.processName); 1103 } 1104 } 1105 } 1106 } 1107 } break; 1108 case SHOW_UID_ERROR_MSG: { 1109 String title = "System UIDs Inconsistent"; 1110 String text = "UIDs on the system are inconsistent, you need to wipe your" 1111 + " data partition or your device will be unstable."; 1112 Log.e(TAG, title + ": " + text); 1113 if (mShowDialogs) { 1114 // XXX This is a temporary dialog, no need to localize. 1115 AlertDialog d = new BaseErrorDialog(mContext); 1116 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1117 d.setCancelable(false); 1118 d.setTitle(title); 1119 d.setMessage(text); 1120 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1121 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1122 mUidAlert = d; 1123 d.show(); 1124 } 1125 } break; 1126 case IM_FEELING_LUCKY_MSG: { 1127 if (mUidAlert != null) { 1128 mUidAlert.dismiss(); 1129 mUidAlert = null; 1130 } 1131 } break; 1132 case PROC_START_TIMEOUT_MSG: { 1133 if (mDidDexOpt) { 1134 mDidDexOpt = false; 1135 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1136 nmsg.obj = msg.obj; 1137 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1138 return; 1139 } 1140 ProcessRecord app = (ProcessRecord)msg.obj; 1141 synchronized (ActivityManagerService.this) { 1142 processStartTimedOutLocked(app); 1143 } 1144 } break; 1145 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 doPendingActivityLaunchesLocked(true); 1148 } 1149 } break; 1150 case KILL_APPLICATION_MSG: { 1151 synchronized (ActivityManagerService.this) { 1152 int appid = msg.arg1; 1153 boolean restart = (msg.arg2 == 1); 1154 String pkg = (String) msg.obj; 1155 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1156 UserHandle.USER_ALL); 1157 } 1158 } break; 1159 case FINALIZE_PENDING_INTENT_MSG: { 1160 ((PendingIntentRecord)msg.obj).completeFinalize(); 1161 } break; 1162 case POST_HEAVY_NOTIFICATION_MSG: { 1163 INotificationManager inm = NotificationManager.getService(); 1164 if (inm == null) { 1165 return; 1166 } 1167 1168 ActivityRecord root = (ActivityRecord)msg.obj; 1169 ProcessRecord process = root.app; 1170 if (process == null) { 1171 return; 1172 } 1173 1174 try { 1175 Context context = mContext.createPackageContext(process.info.packageName, 0); 1176 String text = mContext.getString(R.string.heavy_weight_notification, 1177 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1178 Notification notification = new Notification(); 1179 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1180 notification.when = 0; 1181 notification.flags = Notification.FLAG_ONGOING_EVENT; 1182 notification.tickerText = text; 1183 notification.defaults = 0; // please be quiet 1184 notification.sound = null; 1185 notification.vibrate = null; 1186 notification.setLatestEventInfo(context, text, 1187 mContext.getText(R.string.heavy_weight_notification_detail), 1188 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1189 PendingIntent.FLAG_CANCEL_CURRENT, null, 1190 new UserHandle(root.userId))); 1191 1192 try { 1193 int[] outId = new int[1]; 1194 inm.enqueueNotificationWithTag("android", null, 1195 R.string.heavy_weight_notification, 1196 notification, outId, root.userId); 1197 } catch (RuntimeException e) { 1198 Slog.w(ActivityManagerService.TAG, 1199 "Error showing notification for heavy-weight app", e); 1200 } catch (RemoteException e) { 1201 } 1202 } catch (NameNotFoundException e) { 1203 Slog.w(TAG, "Unable to create context for heavy notification", e); 1204 } 1205 } break; 1206 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1207 INotificationManager inm = NotificationManager.getService(); 1208 if (inm == null) { 1209 return; 1210 } 1211 try { 1212 inm.cancelNotificationWithTag("android", null, 1213 R.string.heavy_weight_notification, msg.arg1); 1214 } catch (RuntimeException e) { 1215 Slog.w(ActivityManagerService.TAG, 1216 "Error canceling notification for service", e); 1217 } catch (RemoteException e) { 1218 } 1219 } break; 1220 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1221 synchronized (ActivityManagerService.this) { 1222 checkExcessivePowerUsageLocked(true); 1223 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1224 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1225 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1226 } 1227 } break; 1228 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1229 synchronized (ActivityManagerService.this) { 1230 ActivityRecord ar = (ActivityRecord)msg.obj; 1231 if (mCompatModeDialog != null) { 1232 if (mCompatModeDialog.mAppInfo.packageName.equals( 1233 ar.info.applicationInfo.packageName)) { 1234 return; 1235 } 1236 mCompatModeDialog.dismiss(); 1237 mCompatModeDialog = null; 1238 } 1239 if (ar != null && false) { 1240 if (mCompatModePackages.getPackageAskCompatModeLocked( 1241 ar.packageName)) { 1242 int mode = mCompatModePackages.computeCompatModeLocked( 1243 ar.info.applicationInfo); 1244 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1245 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1246 mCompatModeDialog = new CompatModeDialog( 1247 ActivityManagerService.this, mContext, 1248 ar.info.applicationInfo); 1249 mCompatModeDialog.show(); 1250 } 1251 } 1252 } 1253 } 1254 break; 1255 } 1256 case DISPATCH_PROCESSES_CHANGED: { 1257 dispatchProcessesChanged(); 1258 break; 1259 } 1260 case DISPATCH_PROCESS_DIED: { 1261 final int pid = msg.arg1; 1262 final int uid = msg.arg2; 1263 dispatchProcessDied(pid, uid); 1264 break; 1265 } 1266 case REPORT_MEM_USAGE: { 1267 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1268 if (!isDebuggable) { 1269 return; 1270 } 1271 synchronized (ActivityManagerService.this) { 1272 long now = SystemClock.uptimeMillis(); 1273 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1274 // Don't report more than every 5 minutes to somewhat 1275 // avoid spamming. 1276 return; 1277 } 1278 mLastMemUsageReportTime = now; 1279 } 1280 Thread thread = new Thread() { 1281 @Override public void run() { 1282 StringBuilder dropBuilder = new StringBuilder(1024); 1283 StringBuilder logBuilder = new StringBuilder(1024); 1284 StringWriter oomSw = new StringWriter(); 1285 PrintWriter oomPw = new PrintWriter(oomSw); 1286 StringWriter catSw = new StringWriter(); 1287 PrintWriter catPw = new PrintWriter(catSw); 1288 String[] emptyArgs = new String[] { }; 1289 StringBuilder tag = new StringBuilder(128); 1290 StringBuilder stack = new StringBuilder(128); 1291 tag.append("Low on memory -- "); 1292 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1293 tag, stack); 1294 dropBuilder.append(stack); 1295 dropBuilder.append('\n'); 1296 dropBuilder.append('\n'); 1297 String oomString = oomSw.toString(); 1298 dropBuilder.append(oomString); 1299 dropBuilder.append('\n'); 1300 logBuilder.append(oomString); 1301 try { 1302 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1303 "procrank", }); 1304 final InputStreamReader converter = new InputStreamReader( 1305 proc.getInputStream()); 1306 BufferedReader in = new BufferedReader(converter); 1307 String line; 1308 while (true) { 1309 line = in.readLine(); 1310 if (line == null) { 1311 break; 1312 } 1313 if (line.length() > 0) { 1314 logBuilder.append(line); 1315 logBuilder.append('\n'); 1316 } 1317 dropBuilder.append(line); 1318 dropBuilder.append('\n'); 1319 } 1320 converter.close(); 1321 } catch (IOException e) { 1322 } 1323 synchronized (ActivityManagerService.this) { 1324 catPw.println(); 1325 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1326 catPw.println(); 1327 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1328 false, false, null); 1329 catPw.println(); 1330 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1331 } 1332 dropBuilder.append(catSw.toString()); 1333 addErrorToDropBox("lowmem", null, "system_server", null, 1334 null, tag.toString(), dropBuilder.toString(), null, null); 1335 Slog.i(TAG, logBuilder.toString()); 1336 synchronized (ActivityManagerService.this) { 1337 long now = SystemClock.uptimeMillis(); 1338 if (mLastMemUsageReportTime < now) { 1339 mLastMemUsageReportTime = now; 1340 } 1341 } 1342 } 1343 }; 1344 thread.start(); 1345 break; 1346 } 1347 case REPORT_USER_SWITCH_MSG: { 1348 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1349 break; 1350 } 1351 case CONTINUE_USER_SWITCH_MSG: { 1352 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1353 break; 1354 } 1355 case USER_SWITCH_TIMEOUT_MSG: { 1356 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1357 break; 1358 } 1359 } 1360 } 1361 }; 1362 setSystemProcess()1363 public static void setSystemProcess() { 1364 try { 1365 ActivityManagerService m = mSelf; 1366 1367 ServiceManager.addService("activity", m, true); 1368 ServiceManager.addService("meminfo", new MemBinder(m)); 1369 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1370 ServiceManager.addService("dbinfo", new DbBinder(m)); 1371 if (MONITOR_CPU_USAGE) { 1372 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1373 } 1374 ServiceManager.addService("permission", new PermissionController(m)); 1375 1376 ApplicationInfo info = 1377 mSelf.mContext.getPackageManager().getApplicationInfo( 1378 "android", STOCK_PM_FLAGS); 1379 mSystemThread.installSystemApplicationInfo(info); 1380 1381 synchronized (mSelf) { 1382 ProcessRecord app = mSelf.newProcessRecordLocked( 1383 mSystemThread.getApplicationThread(), info, 1384 info.processName, false); 1385 app.persistent = true; 1386 app.pid = MY_PID; 1387 app.maxAdj = ProcessList.SYSTEM_ADJ; 1388 mSelf.mProcessNames.put(app.processName, app.uid, app); 1389 synchronized (mSelf.mPidsSelfLocked) { 1390 mSelf.mPidsSelfLocked.put(app.pid, app); 1391 } 1392 mSelf.updateLruProcessLocked(app, true); 1393 } 1394 } catch (PackageManager.NameNotFoundException e) { 1395 throw new RuntimeException( 1396 "Unable to find android system package", e); 1397 } 1398 } 1399 setWindowManager(WindowManagerService wm)1400 public void setWindowManager(WindowManagerService wm) { 1401 mWindowManager = wm; 1402 } 1403 main(int factoryTest)1404 public static final Context main(int factoryTest) { 1405 AThread thr = new AThread(); 1406 thr.start(); 1407 1408 synchronized (thr) { 1409 while (thr.mService == null) { 1410 try { 1411 thr.wait(); 1412 } catch (InterruptedException e) { 1413 } 1414 } 1415 } 1416 1417 ActivityManagerService m = thr.mService; 1418 mSelf = m; 1419 ActivityThread at = ActivityThread.systemMain(); 1420 mSystemThread = at; 1421 Context context = at.getSystemContext(); 1422 context.setTheme(android.R.style.Theme_Holo); 1423 m.mContext = context; 1424 m.mFactoryTest = factoryTest; 1425 m.mMainStack = new ActivityStack(m, context, true); 1426 1427 m.mBatteryStatsService.publish(context); 1428 m.mUsageStatsService.publish(context); 1429 1430 synchronized (thr) { 1431 thr.mReady = true; 1432 thr.notifyAll(); 1433 } 1434 1435 m.startRunning(null, null, null, null); 1436 1437 return context; 1438 } 1439 self()1440 public static ActivityManagerService self() { 1441 return mSelf; 1442 } 1443 1444 static class AThread extends Thread { 1445 ActivityManagerService mService; 1446 boolean mReady = false; 1447 AThread()1448 public AThread() { 1449 super("ActivityManager"); 1450 } 1451 run()1452 public void run() { 1453 Looper.prepare(); 1454 1455 android.os.Process.setThreadPriority( 1456 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1457 android.os.Process.setCanSelfBackground(false); 1458 1459 ActivityManagerService m = new ActivityManagerService(); 1460 1461 synchronized (this) { 1462 mService = m; 1463 notifyAll(); 1464 } 1465 1466 synchronized (this) { 1467 while (!mReady) { 1468 try { 1469 wait(); 1470 } catch (InterruptedException e) { 1471 } 1472 } 1473 } 1474 1475 // For debug builds, log event loop stalls to dropbox for analysis. 1476 if (StrictMode.conditionallyEnableDebugLogging()) { 1477 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1478 } 1479 1480 Looper.loop(); 1481 } 1482 } 1483 1484 static class MemBinder extends Binder { 1485 ActivityManagerService mActivityManagerService; MemBinder(ActivityManagerService activityManagerService)1486 MemBinder(ActivityManagerService activityManagerService) { 1487 mActivityManagerService = activityManagerService; 1488 } 1489 1490 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1491 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1492 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1493 != PackageManager.PERMISSION_GRANTED) { 1494 pw.println("Permission Denial: can't dump meminfo from from pid=" 1495 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1496 + " without permission " + android.Manifest.permission.DUMP); 1497 return; 1498 } 1499 1500 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1501 false, null, null, null); 1502 } 1503 } 1504 1505 static class GraphicsBinder extends Binder { 1506 ActivityManagerService mActivityManagerService; GraphicsBinder(ActivityManagerService activityManagerService)1507 GraphicsBinder(ActivityManagerService activityManagerService) { 1508 mActivityManagerService = activityManagerService; 1509 } 1510 1511 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1512 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1513 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1514 != PackageManager.PERMISSION_GRANTED) { 1515 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1516 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1517 + " without permission " + android.Manifest.permission.DUMP); 1518 return; 1519 } 1520 1521 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1522 } 1523 } 1524 1525 static class DbBinder extends Binder { 1526 ActivityManagerService mActivityManagerService; DbBinder(ActivityManagerService activityManagerService)1527 DbBinder(ActivityManagerService activityManagerService) { 1528 mActivityManagerService = activityManagerService; 1529 } 1530 1531 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1532 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1533 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1534 != PackageManager.PERMISSION_GRANTED) { 1535 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1536 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1537 + " without permission " + android.Manifest.permission.DUMP); 1538 return; 1539 } 1540 1541 mActivityManagerService.dumpDbInfo(fd, pw, args); 1542 } 1543 } 1544 1545 static class CpuBinder extends Binder { 1546 ActivityManagerService mActivityManagerService; CpuBinder(ActivityManagerService activityManagerService)1547 CpuBinder(ActivityManagerService activityManagerService) { 1548 mActivityManagerService = activityManagerService; 1549 } 1550 1551 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1552 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1553 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1554 != PackageManager.PERMISSION_GRANTED) { 1555 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1556 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1557 + " without permission " + android.Manifest.permission.DUMP); 1558 return; 1559 } 1560 1561 synchronized (mActivityManagerService.mProcessStatsThread) { 1562 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1563 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1564 SystemClock.uptimeMillis())); 1565 } 1566 } 1567 } 1568 ActivityManagerService()1569 private ActivityManagerService() { 1570 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1571 1572 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1573 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1574 mBroadcastQueues[0] = mFgBroadcastQueue; 1575 mBroadcastQueues[1] = mBgBroadcastQueue; 1576 1577 mServices = new ActiveServices(this); 1578 mProviderMap = new ProviderMap(this); 1579 1580 File dataDir = Environment.getDataDirectory(); 1581 File systemDir = new File(dataDir, "system"); 1582 systemDir.mkdirs(); 1583 mBatteryStatsService = new BatteryStatsService(new File( 1584 systemDir, "batterystats.bin").toString()); 1585 mBatteryStatsService.getActiveStatistics().readLocked(); 1586 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1587 mOnBattery = DEBUG_POWER ? true 1588 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1589 mBatteryStatsService.getActiveStatistics().setCallback(this); 1590 1591 mUsageStatsService = new UsageStatsService(new File( 1592 systemDir, "usagestats").toString()); 1593 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1594 1595 // User 0 is the first and only user that runs at boot. 1596 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1597 mUserLru.add(Integer.valueOf(0)); 1598 updateStartedUserArrayLocked(); 1599 1600 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1601 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1602 1603 mConfiguration.setToDefaults(); 1604 mConfiguration.setLocale(Locale.getDefault()); 1605 1606 mConfigurationSeq = mConfiguration.seq = 1; 1607 mProcessStats.init(); 1608 1609 mCompatModePackages = new CompatModePackages(this, systemDir); 1610 1611 // Add ourself to the Watchdog monitors. 1612 Watchdog.getInstance().addMonitor(this); 1613 1614 mProcessStatsThread = new Thread("ProcessStats") { 1615 public void run() { 1616 while (true) { 1617 try { 1618 try { 1619 synchronized(this) { 1620 final long now = SystemClock.uptimeMillis(); 1621 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1622 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1623 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1624 // + ", write delay=" + nextWriteDelay); 1625 if (nextWriteDelay < nextCpuDelay) { 1626 nextCpuDelay = nextWriteDelay; 1627 } 1628 if (nextCpuDelay > 0) { 1629 mProcessStatsMutexFree.set(true); 1630 this.wait(nextCpuDelay); 1631 } 1632 } 1633 } catch (InterruptedException e) { 1634 } 1635 updateCpuStatsNow(); 1636 } catch (Exception e) { 1637 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1638 } 1639 } 1640 } 1641 }; 1642 mProcessStatsThread.start(); 1643 } 1644 1645 @Override onTransact(int code, Parcel data, Parcel reply, int flags)1646 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1647 throws RemoteException { 1648 if (code == SYSPROPS_TRANSACTION) { 1649 // We need to tell all apps about the system property change. 1650 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1651 synchronized(this) { 1652 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1653 final int NA = apps.size(); 1654 for (int ia=0; ia<NA; ia++) { 1655 ProcessRecord app = apps.valueAt(ia); 1656 if (app.thread != null) { 1657 procs.add(app.thread.asBinder()); 1658 } 1659 } 1660 } 1661 } 1662 1663 int N = procs.size(); 1664 for (int i=0; i<N; i++) { 1665 Parcel data2 = Parcel.obtain(); 1666 try { 1667 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1668 } catch (RemoteException e) { 1669 } 1670 data2.recycle(); 1671 } 1672 } 1673 try { 1674 return super.onTransact(code, data, reply, flags); 1675 } catch (RuntimeException e) { 1676 // The activity manager only throws security exceptions, so let's 1677 // log all others. 1678 if (!(e instanceof SecurityException)) { 1679 Slog.e(TAG, "Activity Manager Crash", e); 1680 } 1681 throw e; 1682 } 1683 } 1684 updateCpuStats()1685 void updateCpuStats() { 1686 final long now = SystemClock.uptimeMillis(); 1687 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1688 return; 1689 } 1690 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1691 synchronized (mProcessStatsThread) { 1692 mProcessStatsThread.notify(); 1693 } 1694 } 1695 } 1696 updateCpuStatsNow()1697 void updateCpuStatsNow() { 1698 synchronized (mProcessStatsThread) { 1699 mProcessStatsMutexFree.set(false); 1700 final long now = SystemClock.uptimeMillis(); 1701 boolean haveNewCpuStats = false; 1702 1703 if (MONITOR_CPU_USAGE && 1704 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1705 mLastCpuTime.set(now); 1706 haveNewCpuStats = true; 1707 mProcessStats.update(); 1708 //Slog.i(TAG, mProcessStats.printCurrentState()); 1709 //Slog.i(TAG, "Total CPU usage: " 1710 // + mProcessStats.getTotalCpuPercent() + "%"); 1711 1712 // Slog the cpu usage if the property is set. 1713 if ("true".equals(SystemProperties.get("events.cpu"))) { 1714 int user = mProcessStats.getLastUserTime(); 1715 int system = mProcessStats.getLastSystemTime(); 1716 int iowait = mProcessStats.getLastIoWaitTime(); 1717 int irq = mProcessStats.getLastIrqTime(); 1718 int softIrq = mProcessStats.getLastSoftIrqTime(); 1719 int idle = mProcessStats.getLastIdleTime(); 1720 1721 int total = user + system + iowait + irq + softIrq + idle; 1722 if (total == 0) total = 1; 1723 1724 EventLog.writeEvent(EventLogTags.CPU, 1725 ((user+system+iowait+irq+softIrq) * 100) / total, 1726 (user * 100) / total, 1727 (system * 100) / total, 1728 (iowait * 100) / total, 1729 (irq * 100) / total, 1730 (softIrq * 100) / total); 1731 } 1732 } 1733 1734 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1735 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1736 synchronized(bstats) { 1737 synchronized(mPidsSelfLocked) { 1738 if (haveNewCpuStats) { 1739 if (mOnBattery) { 1740 int perc = bstats.startAddingCpuLocked(); 1741 int totalUTime = 0; 1742 int totalSTime = 0; 1743 final int N = mProcessStats.countStats(); 1744 for (int i=0; i<N; i++) { 1745 ProcessStats.Stats st = mProcessStats.getStats(i); 1746 if (!st.working) { 1747 continue; 1748 } 1749 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1750 int otherUTime = (st.rel_utime*perc)/100; 1751 int otherSTime = (st.rel_stime*perc)/100; 1752 totalUTime += otherUTime; 1753 totalSTime += otherSTime; 1754 if (pr != null) { 1755 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1756 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1757 st.rel_stime-otherSTime); 1758 ps.addSpeedStepTimes(cpuSpeedTimes); 1759 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1760 } else { 1761 BatteryStatsImpl.Uid.Proc ps = 1762 bstats.getProcessStatsLocked(st.name, st.pid); 1763 if (ps != null) { 1764 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1765 st.rel_stime-otherSTime); 1766 ps.addSpeedStepTimes(cpuSpeedTimes); 1767 } 1768 } 1769 } 1770 bstats.finishAddingCpuLocked(perc, totalUTime, 1771 totalSTime, cpuSpeedTimes); 1772 } 1773 } 1774 } 1775 1776 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1777 mLastWriteTime = now; 1778 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1779 } 1780 } 1781 } 1782 } 1783 1784 @Override batteryNeedsCpuUpdate()1785 public void batteryNeedsCpuUpdate() { 1786 updateCpuStatsNow(); 1787 } 1788 1789 @Override batteryPowerChanged(boolean onBattery)1790 public void batteryPowerChanged(boolean onBattery) { 1791 // When plugging in, update the CPU stats first before changing 1792 // the plug state. 1793 updateCpuStatsNow(); 1794 synchronized (this) { 1795 synchronized(mPidsSelfLocked) { 1796 mOnBattery = DEBUG_POWER ? true : onBattery; 1797 } 1798 } 1799 } 1800 1801 /** 1802 * Initialize the application bind args. These are passed to each 1803 * process when the bindApplication() IPC is sent to the process. They're 1804 * lazily setup to make sure the services are running when they're asked for. 1805 */ getCommonServicesLocked()1806 private HashMap<String, IBinder> getCommonServicesLocked() { 1807 if (mAppBindArgs == null) { 1808 mAppBindArgs = new HashMap<String, IBinder>(); 1809 1810 // Setup the application init args 1811 mAppBindArgs.put("package", ServiceManager.getService("package")); 1812 mAppBindArgs.put("window", ServiceManager.getService("window")); 1813 mAppBindArgs.put(Context.ALARM_SERVICE, 1814 ServiceManager.getService(Context.ALARM_SERVICE)); 1815 } 1816 return mAppBindArgs; 1817 } 1818 setFocusedActivityLocked(ActivityRecord r)1819 final void setFocusedActivityLocked(ActivityRecord r) { 1820 if (mFocusedActivity != r) { 1821 mFocusedActivity = r; 1822 if (r != null) { 1823 mWindowManager.setFocusedApp(r.appToken, true); 1824 } 1825 } 1826 } 1827 updateLruProcessInternalLocked(ProcessRecord app, int bestPos)1828 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1829 // put it on the LRU to keep track of when it should be exited. 1830 int lrui = mLruProcesses.indexOf(app); 1831 if (lrui >= 0) mLruProcesses.remove(lrui); 1832 1833 int i = mLruProcesses.size()-1; 1834 int skipTop = 0; 1835 1836 app.lruSeq = mLruSeq; 1837 1838 // compute the new weight for this process. 1839 app.lastActivityTime = SystemClock.uptimeMillis(); 1840 if (app.activities.size() > 0) { 1841 // If this process has activities, we more strongly want to keep 1842 // it around. 1843 app.lruWeight = app.lastActivityTime; 1844 } else if (app.pubProviders.size() > 0) { 1845 // If this process contains content providers, we want to keep 1846 // it a little more strongly. 1847 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1848 // Also don't let it kick out the first few "real" hidden processes. 1849 skipTop = ProcessList.MIN_HIDDEN_APPS; 1850 } else { 1851 // If this process doesn't have activities, we less strongly 1852 // want to keep it around, and generally want to avoid getting 1853 // in front of any very recently used activities. 1854 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1855 // Also don't let it kick out the first few "real" hidden processes. 1856 skipTop = ProcessList.MIN_HIDDEN_APPS; 1857 } 1858 1859 while (i >= 0) { 1860 ProcessRecord p = mLruProcesses.get(i); 1861 // If this app shouldn't be in front of the first N background 1862 // apps, then skip over that many that are currently hidden. 1863 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1864 skipTop--; 1865 } 1866 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1867 mLruProcesses.add(i+1, app); 1868 break; 1869 } 1870 i--; 1871 } 1872 if (i < 0) { 1873 mLruProcesses.add(0, app); 1874 } 1875 1876 // If the app is currently using a content provider or service, 1877 // bump those processes as well. 1878 if (app.connections.size() > 0) { 1879 for (ConnectionRecord cr : app.connections) { 1880 if (cr.binding != null && cr.binding.service != null 1881 && cr.binding.service.app != null 1882 && cr.binding.service.app.lruSeq != mLruSeq) { 1883 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1884 } 1885 } 1886 } 1887 for (int j=app.conProviders.size()-1; j>=0; j--) { 1888 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1889 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1890 updateLruProcessInternalLocked(cpr.proc, i+1); 1891 } 1892 } 1893 } 1894 updateLruProcessLocked(ProcessRecord app, boolean oomAdj)1895 final void updateLruProcessLocked(ProcessRecord app, 1896 boolean oomAdj) { 1897 mLruSeq++; 1898 updateLruProcessInternalLocked(app, 0); 1899 1900 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1901 if (oomAdj) { 1902 updateOomAdjLocked(); 1903 } 1904 } 1905 getProcessRecordLocked( String processName, int uid)1906 final ProcessRecord getProcessRecordLocked( 1907 String processName, int uid) { 1908 if (uid == Process.SYSTEM_UID) { 1909 // The system gets to run in any process. If there are multiple 1910 // processes with the same uid, just pick the first (this 1911 // should never happen). 1912 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1913 processName); 1914 if (procs == null) return null; 1915 final int N = procs.size(); 1916 for (int i = 0; i < N; i++) { 1917 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1918 } 1919 } 1920 ProcessRecord proc = mProcessNames.get(processName, uid); 1921 return proc; 1922 } 1923 ensurePackageDexOpt(String packageName)1924 void ensurePackageDexOpt(String packageName) { 1925 IPackageManager pm = AppGlobals.getPackageManager(); 1926 try { 1927 if (pm.performDexOpt(packageName)) { 1928 mDidDexOpt = true; 1929 } 1930 } catch (RemoteException e) { 1931 } 1932 } 1933 isNextTransitionForward()1934 boolean isNextTransitionForward() { 1935 int transit = mWindowManager.getPendingAppTransition(); 1936 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1937 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1938 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1939 } 1940 startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated)1941 final ProcessRecord startProcessLocked(String processName, 1942 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1943 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1944 boolean isolated) { 1945 ProcessRecord app; 1946 if (!isolated) { 1947 app = getProcessRecordLocked(processName, info.uid); 1948 } else { 1949 // If this is an isolated process, it can't re-use an existing process. 1950 app = null; 1951 } 1952 // We don't have to do anything more if: 1953 // (1) There is an existing application record; and 1954 // (2) The caller doesn't think it is dead, OR there is no thread 1955 // object attached to it so we know it couldn't have crashed; and 1956 // (3) There is a pid assigned to it, so it is either starting or 1957 // already running. 1958 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1959 + " app=" + app + " knownToBeDead=" + knownToBeDead 1960 + " thread=" + (app != null ? app.thread : null) 1961 + " pid=" + (app != null ? app.pid : -1)); 1962 if (app != null && app.pid > 0) { 1963 if (!knownToBeDead || app.thread == null) { 1964 // We already have the app running, or are waiting for it to 1965 // come up (we have a pid but not yet its thread), so keep it. 1966 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1967 // If this is a new package in the process, add the package to the list 1968 app.addPackage(info.packageName); 1969 return app; 1970 } else { 1971 // An application record is attached to a previous process, 1972 // clean it up now. 1973 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 1974 handleAppDiedLocked(app, true, true); 1975 } 1976 } 1977 1978 String hostingNameStr = hostingName != null 1979 ? hostingName.flattenToShortString() : null; 1980 1981 if (!isolated) { 1982 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1983 // If we are in the background, then check to see if this process 1984 // is bad. If so, we will just silently fail. 1985 if (mBadProcesses.get(info.processName, info.uid) != null) { 1986 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1987 + "/" + info.processName); 1988 return null; 1989 } 1990 } else { 1991 // When the user is explicitly starting a process, then clear its 1992 // crash count so that we won't make it bad until they see at 1993 // least one crash dialog again, and make the process good again 1994 // if it had been bad. 1995 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1996 + "/" + info.processName); 1997 mProcessCrashTimes.remove(info.processName, info.uid); 1998 if (mBadProcesses.get(info.processName, info.uid) != null) { 1999 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2000 UserHandle.getUserId(info.uid), info.uid, 2001 info.processName); 2002 mBadProcesses.remove(info.processName, info.uid); 2003 if (app != null) { 2004 app.bad = false; 2005 } 2006 } 2007 } 2008 } 2009 2010 if (app == null) { 2011 app = newProcessRecordLocked(null, info, processName, isolated); 2012 if (app == null) { 2013 Slog.w(TAG, "Failed making new process record for " 2014 + processName + "/" + info.uid + " isolated=" + isolated); 2015 return null; 2016 } 2017 mProcessNames.put(processName, app.uid, app); 2018 if (isolated) { 2019 mIsolatedProcesses.put(app.uid, app); 2020 } 2021 } else { 2022 // If this is a new package in the process, add the package to the list 2023 app.addPackage(info.packageName); 2024 } 2025 2026 // If the system is not ready yet, then hold off on starting this 2027 // process until it is. 2028 if (!mProcessesReady 2029 && !isAllowedWhileBooting(info) 2030 && !allowWhileBooting) { 2031 if (!mProcessesOnHold.contains(app)) { 2032 mProcessesOnHold.add(app); 2033 } 2034 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2035 return app; 2036 } 2037 2038 startProcessLocked(app, hostingType, hostingNameStr); 2039 return (app.pid != 0) ? app : null; 2040 } 2041 isAllowedWhileBooting(ApplicationInfo ai)2042 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2043 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2044 } 2045 startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)2046 private final void startProcessLocked(ProcessRecord app, 2047 String hostingType, String hostingNameStr) { 2048 if (app.pid > 0 && app.pid != MY_PID) { 2049 synchronized (mPidsSelfLocked) { 2050 mPidsSelfLocked.remove(app.pid); 2051 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2052 } 2053 app.setPid(0); 2054 } 2055 2056 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2057 "startProcessLocked removing on hold: " + app); 2058 mProcessesOnHold.remove(app); 2059 2060 updateCpuStats(); 2061 2062 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2063 mProcDeaths[0] = 0; 2064 2065 try { 2066 int uid = app.uid; 2067 2068 int[] gids = null; 2069 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2070 if (!app.isolated) { 2071 int[] permGids = null; 2072 try { 2073 final PackageManager pm = mContext.getPackageManager(); 2074 permGids = pm.getPackageGids(app.info.packageName); 2075 2076 if (Environment.isExternalStorageEmulated()) { 2077 if (pm.checkPermission( 2078 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2079 app.info.packageName) == PERMISSION_GRANTED) { 2080 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2081 } else { 2082 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2083 } 2084 } 2085 } catch (PackageManager.NameNotFoundException e) { 2086 Slog.w(TAG, "Unable to retrieve gids", e); 2087 } 2088 2089 /* 2090 * Add shared application GID so applications can share some 2091 * resources like shared libraries 2092 */ 2093 if (permGids == null) { 2094 gids = new int[1]; 2095 } else { 2096 gids = new int[permGids.length + 1]; 2097 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2098 } 2099 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2100 } 2101 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2102 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2103 && mTopComponent != null 2104 && app.processName.equals(mTopComponent.getPackageName())) { 2105 uid = 0; 2106 } 2107 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2108 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2109 uid = 0; 2110 } 2111 } 2112 int debugFlags = 0; 2113 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2114 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2115 // Also turn on CheckJNI for debuggable apps. It's quite 2116 // awkward to turn on otherwise. 2117 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2118 } 2119 // Run the app in safe mode if its manifest requests so or the 2120 // system is booted in safe mode. 2121 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2122 Zygote.systemInSafeMode == true) { 2123 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2124 } 2125 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2126 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2127 } 2128 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2129 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2130 } 2131 if ("1".equals(SystemProperties.get("debug.assert"))) { 2132 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2133 } 2134 2135 // Start the process. It will either succeed and return a result containing 2136 // the PID of the new process, or else throw a RuntimeException. 2137 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2138 app.processName, uid, uid, gids, debugFlags, mountExternal, 2139 app.info.targetSdkVersion, null, null); 2140 2141 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2142 synchronized (bs) { 2143 if (bs.isOnBattery()) { 2144 app.batteryStats.incStartsLocked(); 2145 } 2146 } 2147 2148 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2149 UserHandle.getUserId(uid), startResult.pid, uid, 2150 app.processName, hostingType, 2151 hostingNameStr != null ? hostingNameStr : ""); 2152 2153 if (app.persistent) { 2154 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2155 } 2156 2157 StringBuilder buf = mStringBuilder; 2158 buf.setLength(0); 2159 buf.append("Start proc "); 2160 buf.append(app.processName); 2161 buf.append(" for "); 2162 buf.append(hostingType); 2163 if (hostingNameStr != null) { 2164 buf.append(" "); 2165 buf.append(hostingNameStr); 2166 } 2167 buf.append(": pid="); 2168 buf.append(startResult.pid); 2169 buf.append(" uid="); 2170 buf.append(uid); 2171 buf.append(" gids={"); 2172 if (gids != null) { 2173 for (int gi=0; gi<gids.length; gi++) { 2174 if (gi != 0) buf.append(", "); 2175 buf.append(gids[gi]); 2176 2177 } 2178 } 2179 buf.append("}"); 2180 Slog.i(TAG, buf.toString()); 2181 app.setPid(startResult.pid); 2182 app.usingWrapper = startResult.usingWrapper; 2183 app.removed = false; 2184 synchronized (mPidsSelfLocked) { 2185 this.mPidsSelfLocked.put(startResult.pid, app); 2186 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2187 msg.obj = app; 2188 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2189 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2190 } 2191 } catch (RuntimeException e) { 2192 // XXX do better error recovery. 2193 app.setPid(0); 2194 Slog.e(TAG, "Failure starting process " + app.processName, e); 2195 } 2196 } 2197 updateUsageStats(ActivityRecord resumedComponent, boolean resumed)2198 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2199 if (resumed) { 2200 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2201 } else { 2202 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2203 } 2204 } 2205 startHomeActivityLocked(int userId)2206 boolean startHomeActivityLocked(int userId) { 2207 if (mHeadless) { 2208 // Added because none of the other calls to ensureBootCompleted seem to fire 2209 // when running headless. 2210 ensureBootCompleted(); 2211 return false; 2212 } 2213 2214 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2215 && mTopAction == null) { 2216 // We are running in factory test mode, but unable to find 2217 // the factory test app, so just sit around displaying the 2218 // error message and don't try to start anything. 2219 return false; 2220 } 2221 Intent intent = new Intent( 2222 mTopAction, 2223 mTopData != null ? Uri.parse(mTopData) : null); 2224 intent.setComponent(mTopComponent); 2225 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2226 intent.addCategory(Intent.CATEGORY_HOME); 2227 } 2228 ActivityInfo aInfo = 2229 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2230 if (aInfo != null) { 2231 intent.setComponent(new ComponentName( 2232 aInfo.applicationInfo.packageName, aInfo.name)); 2233 // Don't do this if the home app is currently being 2234 // instrumented. 2235 aInfo = new ActivityInfo(aInfo); 2236 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2237 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2238 aInfo.applicationInfo.uid); 2239 if (app == null || app.instrumentationClass == null) { 2240 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2241 mMainStack.startActivityLocked(null, intent, null, aInfo, 2242 null, null, 0, 0, 0, 0, null, false, null); 2243 } 2244 } 2245 2246 return true; 2247 } 2248 resolveActivityInfo(Intent intent, int flags, int userId)2249 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2250 ActivityInfo ai = null; 2251 ComponentName comp = intent.getComponent(); 2252 try { 2253 if (comp != null) { 2254 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2255 } else { 2256 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2257 intent, 2258 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2259 flags, userId); 2260 2261 if (info != null) { 2262 ai = info.activityInfo; 2263 } 2264 } 2265 } catch (RemoteException e) { 2266 // ignore 2267 } 2268 2269 return ai; 2270 } 2271 2272 /** 2273 * Starts the "new version setup screen" if appropriate. 2274 */ startSetupActivityLocked()2275 void startSetupActivityLocked() { 2276 // Only do this once per boot. 2277 if (mCheckedForSetup) { 2278 return; 2279 } 2280 2281 // We will show this screen if the current one is a different 2282 // version than the last one shown, and we are not running in 2283 // low-level factory test mode. 2284 final ContentResolver resolver = mContext.getContentResolver(); 2285 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2286 Settings.Global.getInt(resolver, 2287 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2288 mCheckedForSetup = true; 2289 2290 // See if we should be showing the platform update setup UI. 2291 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2292 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2293 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2294 2295 // We don't allow third party apps to replace this. 2296 ResolveInfo ri = null; 2297 for (int i=0; ris != null && i<ris.size(); i++) { 2298 if ((ris.get(i).activityInfo.applicationInfo.flags 2299 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2300 ri = ris.get(i); 2301 break; 2302 } 2303 } 2304 2305 if (ri != null) { 2306 String vers = ri.activityInfo.metaData != null 2307 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2308 : null; 2309 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2310 vers = ri.activityInfo.applicationInfo.metaData.getString( 2311 Intent.METADATA_SETUP_VERSION); 2312 } 2313 String lastVers = Settings.Secure.getString( 2314 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2315 if (vers != null && !vers.equals(lastVers)) { 2316 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2317 intent.setComponent(new ComponentName( 2318 ri.activityInfo.packageName, ri.activityInfo.name)); 2319 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2320 null, null, 0, 0, 0, 0, null, false, null); 2321 } 2322 } 2323 } 2324 } 2325 compatibilityInfoForPackageLocked(ApplicationInfo ai)2326 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2327 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2328 } 2329 enforceNotIsolatedCaller(String caller)2330 void enforceNotIsolatedCaller(String caller) { 2331 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2332 throw new SecurityException("Isolated process not allowed to call " + caller); 2333 } 2334 } 2335 getFrontActivityScreenCompatMode()2336 public int getFrontActivityScreenCompatMode() { 2337 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2338 synchronized (this) { 2339 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2340 } 2341 } 2342 setFrontActivityScreenCompatMode(int mode)2343 public void setFrontActivityScreenCompatMode(int mode) { 2344 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2345 "setFrontActivityScreenCompatMode"); 2346 synchronized (this) { 2347 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2348 } 2349 } 2350 getPackageScreenCompatMode(String packageName)2351 public int getPackageScreenCompatMode(String packageName) { 2352 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2353 synchronized (this) { 2354 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2355 } 2356 } 2357 setPackageScreenCompatMode(String packageName, int mode)2358 public void setPackageScreenCompatMode(String packageName, int mode) { 2359 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2360 "setPackageScreenCompatMode"); 2361 synchronized (this) { 2362 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2363 } 2364 } 2365 getPackageAskScreenCompat(String packageName)2366 public boolean getPackageAskScreenCompat(String packageName) { 2367 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2368 synchronized (this) { 2369 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2370 } 2371 } 2372 setPackageAskScreenCompat(String packageName, boolean ask)2373 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2374 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2375 "setPackageAskScreenCompat"); 2376 synchronized (this) { 2377 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2378 } 2379 } 2380 reportResumedActivityLocked(ActivityRecord r)2381 void reportResumedActivityLocked(ActivityRecord r) { 2382 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2383 updateUsageStats(r, true); 2384 } 2385 dispatchProcessesChanged()2386 private void dispatchProcessesChanged() { 2387 int N; 2388 synchronized (this) { 2389 N = mPendingProcessChanges.size(); 2390 if (mActiveProcessChanges.length < N) { 2391 mActiveProcessChanges = new ProcessChangeItem[N]; 2392 } 2393 mPendingProcessChanges.toArray(mActiveProcessChanges); 2394 mAvailProcessChanges.addAll(mPendingProcessChanges); 2395 mPendingProcessChanges.clear(); 2396 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2397 } 2398 int i = mProcessObservers.beginBroadcast(); 2399 while (i > 0) { 2400 i--; 2401 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2402 if (observer != null) { 2403 try { 2404 for (int j=0; j<N; j++) { 2405 ProcessChangeItem item = mActiveProcessChanges[j]; 2406 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2407 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2408 + item.pid + " uid=" + item.uid + ": " 2409 + item.foregroundActivities); 2410 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2411 item.foregroundActivities); 2412 } 2413 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2414 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2415 + item.pid + " uid=" + item.uid + ": " + item.importance); 2416 observer.onImportanceChanged(item.pid, item.uid, 2417 item.importance); 2418 } 2419 } 2420 } catch (RemoteException e) { 2421 } 2422 } 2423 } 2424 mProcessObservers.finishBroadcast(); 2425 } 2426 dispatchProcessDied(int pid, int uid)2427 private void dispatchProcessDied(int pid, int uid) { 2428 int i = mProcessObservers.beginBroadcast(); 2429 while (i > 0) { 2430 i--; 2431 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2432 if (observer != null) { 2433 try { 2434 observer.onProcessDied(pid, uid); 2435 } catch (RemoteException e) { 2436 } 2437 } 2438 } 2439 mProcessObservers.finishBroadcast(); 2440 } 2441 doPendingActivityLaunchesLocked(boolean doResume)2442 final void doPendingActivityLaunchesLocked(boolean doResume) { 2443 final int N = mPendingActivityLaunches.size(); 2444 if (N <= 0) { 2445 return; 2446 } 2447 for (int i=0; i<N; i++) { 2448 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2449 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2450 pal.startFlags, doResume && i == (N-1), null); 2451 } 2452 mPendingActivityLaunches.clear(); 2453 } 2454 startActivity(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options)2455 public final int startActivity(IApplicationThread caller, 2456 Intent intent, String resolvedType, IBinder resultTo, 2457 String resultWho, int requestCode, int startFlags, 2458 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2459 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2460 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2461 } 2462 startActivityAsUser(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2463 public final int startActivityAsUser(IApplicationThread caller, 2464 Intent intent, String resolvedType, IBinder resultTo, 2465 String resultWho, int requestCode, int startFlags, 2466 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2467 enforceNotIsolatedCaller("startActivity"); 2468 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2469 false, true, "startActivity", null); 2470 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2471 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2472 null, null, options, userId); 2473 } 2474 startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2475 public final WaitResult startActivityAndWait(IApplicationThread caller, 2476 Intent intent, String resolvedType, IBinder resultTo, 2477 String resultWho, int requestCode, int startFlags, String profileFile, 2478 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2479 enforceNotIsolatedCaller("startActivityAndWait"); 2480 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2481 false, true, "startActivityAndWait", null); 2482 WaitResult res = new WaitResult(); 2483 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2484 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2485 res, null, options, UserHandle.getCallingUserId()); 2486 return res; 2487 } 2488 startActivityWithConfig(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle options, int userId)2489 public final int startActivityWithConfig(IApplicationThread caller, 2490 Intent intent, String resolvedType, IBinder resultTo, 2491 String resultWho, int requestCode, int startFlags, Configuration config, 2492 Bundle options, int userId) { 2493 enforceNotIsolatedCaller("startActivityWithConfig"); 2494 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2495 false, true, "startActivityWithConfig", null); 2496 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2497 resultTo, resultWho, requestCode, startFlags, 2498 null, null, null, config, options, userId); 2499 return ret; 2500 } 2501 startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)2502 public int startActivityIntentSender(IApplicationThread caller, 2503 IntentSender intent, Intent fillInIntent, String resolvedType, 2504 IBinder resultTo, String resultWho, int requestCode, 2505 int flagsMask, int flagsValues, Bundle options) { 2506 enforceNotIsolatedCaller("startActivityIntentSender"); 2507 // Refuse possible leaked file descriptors 2508 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2509 throw new IllegalArgumentException("File descriptors passed in Intent"); 2510 } 2511 2512 IIntentSender sender = intent.getTarget(); 2513 if (!(sender instanceof PendingIntentRecord)) { 2514 throw new IllegalArgumentException("Bad PendingIntent object"); 2515 } 2516 2517 PendingIntentRecord pir = (PendingIntentRecord)sender; 2518 2519 synchronized (this) { 2520 // If this is coming from the currently resumed activity, it is 2521 // effectively saying that app switches are allowed at this point. 2522 if (mMainStack.mResumedActivity != null 2523 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2524 Binder.getCallingUid()) { 2525 mAppSwitchesAllowedTime = 0; 2526 } 2527 } 2528 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2529 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2530 return ret; 2531 } 2532 startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options)2533 public boolean startNextMatchingActivity(IBinder callingActivity, 2534 Intent intent, Bundle options) { 2535 // Refuse possible leaked file descriptors 2536 if (intent != null && intent.hasFileDescriptors() == true) { 2537 throw new IllegalArgumentException("File descriptors passed in Intent"); 2538 } 2539 2540 synchronized (this) { 2541 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2542 if (r == null) { 2543 ActivityOptions.abort(options); 2544 return false; 2545 } 2546 if (r.app == null || r.app.thread == null) { 2547 // The caller is not running... d'oh! 2548 ActivityOptions.abort(options); 2549 return false; 2550 } 2551 intent = new Intent(intent); 2552 // The caller is not allowed to change the data. 2553 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2554 // And we are resetting to find the next component... 2555 intent.setComponent(null); 2556 2557 ActivityInfo aInfo = null; 2558 try { 2559 List<ResolveInfo> resolves = 2560 AppGlobals.getPackageManager().queryIntentActivities( 2561 intent, r.resolvedType, 2562 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2563 UserHandle.getCallingUserId()); 2564 2565 // Look for the original activity in the list... 2566 final int N = resolves != null ? resolves.size() : 0; 2567 for (int i=0; i<N; i++) { 2568 ResolveInfo rInfo = resolves.get(i); 2569 if (rInfo.activityInfo.packageName.equals(r.packageName) 2570 && rInfo.activityInfo.name.equals(r.info.name)) { 2571 // We found the current one... the next matching is 2572 // after it. 2573 i++; 2574 if (i<N) { 2575 aInfo = resolves.get(i).activityInfo; 2576 } 2577 break; 2578 } 2579 } 2580 } catch (RemoteException e) { 2581 } 2582 2583 if (aInfo == null) { 2584 // Nobody who is next! 2585 ActivityOptions.abort(options); 2586 return false; 2587 } 2588 2589 intent.setComponent(new ComponentName( 2590 aInfo.applicationInfo.packageName, aInfo.name)); 2591 intent.setFlags(intent.getFlags()&~( 2592 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2593 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2594 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2595 Intent.FLAG_ACTIVITY_NEW_TASK)); 2596 2597 // Okay now we need to start the new activity, replacing the 2598 // currently running activity. This is a little tricky because 2599 // we want to start the new one as if the current one is finished, 2600 // but not finish the current one first so that there is no flicker. 2601 // And thus... 2602 final boolean wasFinishing = r.finishing; 2603 r.finishing = true; 2604 2605 // Propagate reply information over to the new activity. 2606 final ActivityRecord resultTo = r.resultTo; 2607 final String resultWho = r.resultWho; 2608 final int requestCode = r.requestCode; 2609 r.resultTo = null; 2610 if (resultTo != null) { 2611 resultTo.removeResultsLocked(r, resultWho, requestCode); 2612 } 2613 2614 final long origId = Binder.clearCallingIdentity(); 2615 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2616 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2617 resultWho, requestCode, -1, r.launchedFromUid, 0, 2618 options, false, null); 2619 Binder.restoreCallingIdentity(origId); 2620 2621 r.finishing = wasFinishing; 2622 if (res != ActivityManager.START_SUCCESS) { 2623 return false; 2624 } 2625 return true; 2626 } 2627 } 2628 startActivityInPackage(int uid, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle options, int userId)2629 final int startActivityInPackage(int uid, 2630 Intent intent, String resolvedType, IBinder resultTo, 2631 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2632 2633 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2634 false, true, "startActivityInPackage", null); 2635 2636 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2637 resultTo, resultWho, requestCode, startFlags, 2638 null, null, null, null, options, userId); 2639 return ret; 2640 } 2641 startActivities(IApplicationThread caller, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2642 public final int startActivities(IApplicationThread caller, 2643 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2644 int userId) { 2645 enforceNotIsolatedCaller("startActivities"); 2646 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2647 false, true, "startActivity", null); 2648 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2649 options, userId); 2650 return ret; 2651 } 2652 startActivitiesInPackage(int uid, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2653 final int startActivitiesInPackage(int uid, 2654 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2655 Bundle options, int userId) { 2656 2657 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2658 false, true, "startActivityInPackage", null); 2659 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2660 options, userId); 2661 return ret; 2662 } 2663 addRecentTaskLocked(TaskRecord task)2664 final void addRecentTaskLocked(TaskRecord task) { 2665 int N = mRecentTasks.size(); 2666 // Quick case: check if the top-most recent task is the same. 2667 if (N > 0 && mRecentTasks.get(0) == task) { 2668 return; 2669 } 2670 // Remove any existing entries that are the same kind of task. 2671 for (int i=0; i<N; i++) { 2672 TaskRecord tr = mRecentTasks.get(i); 2673 if (task.userId == tr.userId 2674 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2675 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2676 mRecentTasks.remove(i); 2677 i--; 2678 N--; 2679 if (task.intent == null) { 2680 // If the new recent task we are adding is not fully 2681 // specified, then replace it with the existing recent task. 2682 task = tr; 2683 } 2684 } 2685 } 2686 if (N >= MAX_RECENT_TASKS) { 2687 mRecentTasks.remove(N-1); 2688 } 2689 mRecentTasks.add(0, task); 2690 } 2691 setRequestedOrientation(IBinder token, int requestedOrientation)2692 public void setRequestedOrientation(IBinder token, 2693 int requestedOrientation) { 2694 synchronized (this) { 2695 ActivityRecord r = mMainStack.isInStackLocked(token); 2696 if (r == null) { 2697 return; 2698 } 2699 final long origId = Binder.clearCallingIdentity(); 2700 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2701 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2702 mConfiguration, 2703 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2704 if (config != null) { 2705 r.frozenBeforeDestroy = true; 2706 if (!updateConfigurationLocked(config, r, false, false)) { 2707 mMainStack.resumeTopActivityLocked(null); 2708 } 2709 } 2710 Binder.restoreCallingIdentity(origId); 2711 } 2712 } 2713 getRequestedOrientation(IBinder token)2714 public int getRequestedOrientation(IBinder token) { 2715 synchronized (this) { 2716 ActivityRecord r = mMainStack.isInStackLocked(token); 2717 if (r == null) { 2718 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2719 } 2720 return mWindowManager.getAppOrientation(r.appToken); 2721 } 2722 } 2723 2724 /** 2725 * This is the internal entry point for handling Activity.finish(). 2726 * 2727 * @param token The Binder token referencing the Activity we want to finish. 2728 * @param resultCode Result code, if any, from this Activity. 2729 * @param resultData Result data (Intent), if any, from this Activity. 2730 * 2731 * @return Returns true if the activity successfully finished, or false if it is still running. 2732 */ finishActivity(IBinder token, int resultCode, Intent resultData)2733 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2734 // Refuse possible leaked file descriptors 2735 if (resultData != null && resultData.hasFileDescriptors() == true) { 2736 throw new IllegalArgumentException("File descriptors passed in Intent"); 2737 } 2738 2739 synchronized(this) { 2740 if (mController != null) { 2741 // Find the first activity that is not finishing. 2742 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2743 if (next != null) { 2744 // ask watcher if this is allowed 2745 boolean resumeOK = true; 2746 try { 2747 resumeOK = mController.activityResuming(next.packageName); 2748 } catch (RemoteException e) { 2749 mController = null; 2750 } 2751 2752 if (!resumeOK) { 2753 return false; 2754 } 2755 } 2756 } 2757 final long origId = Binder.clearCallingIdentity(); 2758 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2759 resultData, "app-request", true); 2760 Binder.restoreCallingIdentity(origId); 2761 return res; 2762 } 2763 } 2764 finishHeavyWeightApp()2765 public final void finishHeavyWeightApp() { 2766 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2767 != PackageManager.PERMISSION_GRANTED) { 2768 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2769 + Binder.getCallingPid() 2770 + ", uid=" + Binder.getCallingUid() 2771 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2772 Slog.w(TAG, msg); 2773 throw new SecurityException(msg); 2774 } 2775 2776 synchronized(this) { 2777 if (mHeavyWeightProcess == null) { 2778 return; 2779 } 2780 2781 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2782 mHeavyWeightProcess.activities); 2783 for (int i=0; i<activities.size(); i++) { 2784 ActivityRecord r = activities.get(i); 2785 if (!r.finishing) { 2786 int index = mMainStack.indexOfTokenLocked(r.appToken); 2787 if (index >= 0) { 2788 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2789 null, "finish-heavy", true); 2790 } 2791 } 2792 } 2793 2794 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2795 mHeavyWeightProcess.userId, 0)); 2796 mHeavyWeightProcess = null; 2797 } 2798 } 2799 crashApplication(int uid, int initialPid, String packageName, String message)2800 public void crashApplication(int uid, int initialPid, String packageName, 2801 String message) { 2802 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2803 != PackageManager.PERMISSION_GRANTED) { 2804 String msg = "Permission Denial: crashApplication() from pid=" 2805 + Binder.getCallingPid() 2806 + ", uid=" + Binder.getCallingUid() 2807 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2808 Slog.w(TAG, msg); 2809 throw new SecurityException(msg); 2810 } 2811 2812 synchronized(this) { 2813 ProcessRecord proc = null; 2814 2815 // Figure out which process to kill. We don't trust that initialPid 2816 // still has any relation to current pids, so must scan through the 2817 // list. 2818 synchronized (mPidsSelfLocked) { 2819 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2820 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2821 if (p.uid != uid) { 2822 continue; 2823 } 2824 if (p.pid == initialPid) { 2825 proc = p; 2826 break; 2827 } 2828 for (String str : p.pkgList) { 2829 if (str.equals(packageName)) { 2830 proc = p; 2831 } 2832 } 2833 } 2834 } 2835 2836 if (proc == null) { 2837 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2838 + " initialPid=" + initialPid 2839 + " packageName=" + packageName); 2840 return; 2841 } 2842 2843 if (proc.thread != null) { 2844 if (proc.pid == Process.myPid()) { 2845 Log.w(TAG, "crashApplication: trying to crash self!"); 2846 return; 2847 } 2848 long ident = Binder.clearCallingIdentity(); 2849 try { 2850 proc.thread.scheduleCrash(message); 2851 } catch (RemoteException e) { 2852 } 2853 Binder.restoreCallingIdentity(ident); 2854 } 2855 } 2856 } 2857 finishSubActivity(IBinder token, String resultWho, int requestCode)2858 public final void finishSubActivity(IBinder token, String resultWho, 2859 int requestCode) { 2860 synchronized(this) { 2861 final long origId = Binder.clearCallingIdentity(); 2862 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2863 Binder.restoreCallingIdentity(origId); 2864 } 2865 } 2866 finishActivityAffinity(IBinder token)2867 public boolean finishActivityAffinity(IBinder token) { 2868 synchronized(this) { 2869 final long origId = Binder.clearCallingIdentity(); 2870 boolean res = mMainStack.finishActivityAffinityLocked(token); 2871 Binder.restoreCallingIdentity(origId); 2872 return res; 2873 } 2874 } 2875 willActivityBeVisible(IBinder token)2876 public boolean willActivityBeVisible(IBinder token) { 2877 synchronized(this) { 2878 int i; 2879 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2880 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2881 if (r.appToken == token) { 2882 return true; 2883 } 2884 if (r.fullscreen && !r.finishing) { 2885 return false; 2886 } 2887 } 2888 return true; 2889 } 2890 } 2891 overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)2892 public void overridePendingTransition(IBinder token, String packageName, 2893 int enterAnim, int exitAnim) { 2894 synchronized(this) { 2895 ActivityRecord self = mMainStack.isInStackLocked(token); 2896 if (self == null) { 2897 return; 2898 } 2899 2900 final long origId = Binder.clearCallingIdentity(); 2901 2902 if (self.state == ActivityState.RESUMED 2903 || self.state == ActivityState.PAUSING) { 2904 mWindowManager.overridePendingAppTransition(packageName, 2905 enterAnim, exitAnim, null); 2906 } 2907 2908 Binder.restoreCallingIdentity(origId); 2909 } 2910 } 2911 2912 /** 2913 * Main function for removing an existing process from the activity manager 2914 * as a result of that process going away. Clears out all connections 2915 * to the process. 2916 */ handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart)2917 private final void handleAppDiedLocked(ProcessRecord app, 2918 boolean restarting, boolean allowRestart) { 2919 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2920 if (!restarting) { 2921 mLruProcesses.remove(app); 2922 } 2923 2924 if (mProfileProc == app) { 2925 clearProfilerLocked(); 2926 } 2927 2928 // Just in case... 2929 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2930 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 2931 "App died while pausing: " + mMainStack.mPausingActivity); 2932 mMainStack.mPausingActivity = null; 2933 } 2934 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2935 mMainStack.mLastPausedActivity = null; 2936 } 2937 2938 // Remove this application's activities from active lists. 2939 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 2940 2941 app.activities.clear(); 2942 2943 if (app.instrumentationClass != null) { 2944 Slog.w(TAG, "Crash of app " + app.processName 2945 + " running instrumentation " + app.instrumentationClass); 2946 Bundle info = new Bundle(); 2947 info.putString("shortMsg", "Process crashed."); 2948 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2949 } 2950 2951 if (!restarting) { 2952 if (!mMainStack.resumeTopActivityLocked(null)) { 2953 // If there was nothing to resume, and we are not already 2954 // restarting this process, but there is a visible activity that 2955 // is hosted by the process... then make sure all visible 2956 // activities are running, taking care of restarting this 2957 // process. 2958 if (hasVisibleActivities) { 2959 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2960 } 2961 } 2962 } 2963 } 2964 getLRURecordIndexForAppLocked(IApplicationThread thread)2965 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2966 IBinder threadBinder = thread.asBinder(); 2967 // Find the application record. 2968 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2969 ProcessRecord rec = mLruProcesses.get(i); 2970 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2971 return i; 2972 } 2973 } 2974 return -1; 2975 } 2976 getRecordForAppLocked( IApplicationThread thread)2977 final ProcessRecord getRecordForAppLocked( 2978 IApplicationThread thread) { 2979 if (thread == null) { 2980 return null; 2981 } 2982 2983 int appIndex = getLRURecordIndexForAppLocked(thread); 2984 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2985 } 2986 appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)2987 final void appDiedLocked(ProcessRecord app, int pid, 2988 IApplicationThread thread) { 2989 2990 mProcDeaths[0]++; 2991 2992 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2993 synchronized (stats) { 2994 stats.noteProcessDiedLocked(app.info.uid, pid); 2995 } 2996 2997 // Clean up already done if the process has been re-started. 2998 if (app.pid == pid && app.thread != null && 2999 app.thread.asBinder() == thread.asBinder()) { 3000 if (!app.killedBackground) { 3001 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3002 + ") has died."); 3003 } 3004 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3005 if (DEBUG_CLEANUP) Slog.v( 3006 TAG, "Dying app: " + app + ", pid: " + pid 3007 + ", thread: " + thread.asBinder()); 3008 boolean doLowMem = app.instrumentationClass == null; 3009 handleAppDiedLocked(app, false, true); 3010 3011 if (doLowMem) { 3012 // If there are no longer any background processes running, 3013 // and the app that died was not running instrumentation, 3014 // then tell everyone we are now low on memory. 3015 boolean haveBg = false; 3016 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3017 ProcessRecord rec = mLruProcesses.get(i); 3018 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3019 haveBg = true; 3020 break; 3021 } 3022 } 3023 3024 if (!haveBg) { 3025 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3026 long now = SystemClock.uptimeMillis(); 3027 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3028 ProcessRecord rec = mLruProcesses.get(i); 3029 if (rec != app && rec.thread != null && 3030 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3031 // The low memory report is overriding any current 3032 // state for a GC request. Make sure to do 3033 // heavy/important/visible/foreground processes first. 3034 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3035 rec.lastRequestedGc = 0; 3036 } else { 3037 rec.lastRequestedGc = rec.lastLowMemory; 3038 } 3039 rec.reportLowMemory = true; 3040 rec.lastLowMemory = now; 3041 mProcessesToGc.remove(rec); 3042 addProcessToGcListLocked(rec); 3043 } 3044 } 3045 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3046 scheduleAppGcsLocked(); 3047 } 3048 } 3049 } else if (app.pid != pid) { 3050 // A new process has already been started. 3051 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3052 + ") has died and restarted (pid " + app.pid + ")."); 3053 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3054 } else if (DEBUG_PROCESSES) { 3055 Slog.d(TAG, "Received spurious death notification for thread " 3056 + thread.asBinder()); 3057 } 3058 } 3059 3060 /** 3061 * If a stack trace dump file is configured, dump process stack traces. 3062 * @param clearTraces causes the dump file to be erased prior to the new 3063 * traces being written, if true; when false, the new traces will be 3064 * appended to any existing file content. 3065 * @param firstPids of dalvik VM processes to dump stack traces for first 3066 * @param lastPids of dalvik VM processes to dump stack traces for last 3067 * @param nativeProcs optional list of native process names to dump stack crawls 3068 * @return file containing stack traces, or null if no dump file is configured 3069 */ dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3070 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3071 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3072 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3073 if (tracesPath == null || tracesPath.length() == 0) { 3074 return null; 3075 } 3076 3077 File tracesFile = new File(tracesPath); 3078 try { 3079 File tracesDir = tracesFile.getParentFile(); 3080 if (!tracesDir.exists()) { 3081 tracesFile.mkdirs(); 3082 if (!SELinux.restorecon(tracesDir)) { 3083 return null; 3084 } 3085 } 3086 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3087 3088 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3089 tracesFile.createNewFile(); 3090 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3091 } catch (IOException e) { 3092 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3093 return null; 3094 } 3095 3096 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3097 return tracesFile; 3098 } 3099 dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3100 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3101 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3102 // Use a FileObserver to detect when traces finish writing. 3103 // The order of traces is considered important to maintain for legibility. 3104 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3105 public synchronized void onEvent(int event, String path) { notify(); } 3106 }; 3107 3108 try { 3109 observer.startWatching(); 3110 3111 // First collect all of the stacks of the most important pids. 3112 if (firstPids != null) { 3113 try { 3114 int num = firstPids.size(); 3115 for (int i = 0; i < num; i++) { 3116 synchronized (observer) { 3117 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3118 observer.wait(200); // Wait for write-close, give up after 200msec 3119 } 3120 } 3121 } catch (InterruptedException e) { 3122 Log.wtf(TAG, e); 3123 } 3124 } 3125 3126 // Next measure CPU usage. 3127 if (processStats != null) { 3128 processStats.init(); 3129 System.gc(); 3130 processStats.update(); 3131 try { 3132 synchronized (processStats) { 3133 processStats.wait(500); // measure over 1/2 second. 3134 } 3135 } catch (InterruptedException e) { 3136 } 3137 processStats.update(); 3138 3139 // We'll take the stack crawls of just the top apps using CPU. 3140 final int N = processStats.countWorkingStats(); 3141 int numProcs = 0; 3142 for (int i=0; i<N && numProcs<5; i++) { 3143 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3144 if (lastPids.indexOfKey(stats.pid) >= 0) { 3145 numProcs++; 3146 try { 3147 synchronized (observer) { 3148 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3149 observer.wait(200); // Wait for write-close, give up after 200msec 3150 } 3151 } catch (InterruptedException e) { 3152 Log.wtf(TAG, e); 3153 } 3154 3155 } 3156 } 3157 } 3158 3159 } finally { 3160 observer.stopWatching(); 3161 } 3162 3163 if (nativeProcs != null) { 3164 int[] pids = Process.getPidsForCommands(nativeProcs); 3165 if (pids != null) { 3166 for (int pid : pids) { 3167 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3168 } 3169 } 3170 } 3171 } 3172 logAppTooSlow(ProcessRecord app, long startTime, String msg)3173 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3174 if (true || IS_USER_BUILD) { 3175 return; 3176 } 3177 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3178 if (tracesPath == null || tracesPath.length() == 0) { 3179 return; 3180 } 3181 3182 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3183 StrictMode.allowThreadDiskWrites(); 3184 try { 3185 final File tracesFile = new File(tracesPath); 3186 final File tracesDir = tracesFile.getParentFile(); 3187 final File tracesTmp = new File(tracesDir, "__tmp__"); 3188 try { 3189 if (!tracesDir.exists()) { 3190 tracesFile.mkdirs(); 3191 if (!SELinux.restorecon(tracesDir.getPath())) { 3192 return; 3193 } 3194 } 3195 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3196 3197 if (tracesFile.exists()) { 3198 tracesTmp.delete(); 3199 tracesFile.renameTo(tracesTmp); 3200 } 3201 StringBuilder sb = new StringBuilder(); 3202 Time tobj = new Time(); 3203 tobj.set(System.currentTimeMillis()); 3204 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3205 sb.append(": "); 3206 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3207 sb.append(" since "); 3208 sb.append(msg); 3209 FileOutputStream fos = new FileOutputStream(tracesFile); 3210 fos.write(sb.toString().getBytes()); 3211 if (app == null) { 3212 fos.write("\n*** No application process!".getBytes()); 3213 } 3214 fos.close(); 3215 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3216 } catch (IOException e) { 3217 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3218 return; 3219 } 3220 3221 if (app != null) { 3222 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3223 firstPids.add(app.pid); 3224 dumpStackTraces(tracesPath, firstPids, null, null, null); 3225 } 3226 3227 File lastTracesFile = null; 3228 File curTracesFile = null; 3229 for (int i=9; i>=0; i--) { 3230 String name = String.format("slow%02d.txt", i); 3231 curTracesFile = new File(tracesDir, name); 3232 if (curTracesFile.exists()) { 3233 if (lastTracesFile != null) { 3234 curTracesFile.renameTo(lastTracesFile); 3235 } else { 3236 curTracesFile.delete(); 3237 } 3238 } 3239 lastTracesFile = curTracesFile; 3240 } 3241 tracesFile.renameTo(curTracesFile); 3242 if (tracesTmp.exists()) { 3243 tracesTmp.renameTo(tracesFile); 3244 } 3245 } finally { 3246 StrictMode.setThreadPolicy(oldPolicy); 3247 } 3248 } 3249 appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation)3250 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3251 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3252 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3253 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3254 3255 if (mController != null) { 3256 try { 3257 // 0 == continue, -1 = kill process immediately 3258 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3259 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3260 } catch (RemoteException e) { 3261 mController = null; 3262 } 3263 } 3264 3265 long anrTime = SystemClock.uptimeMillis(); 3266 if (MONITOR_CPU_USAGE) { 3267 updateCpuStatsNow(); 3268 } 3269 3270 synchronized (this) { 3271 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3272 if (mShuttingDown) { 3273 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3274 return; 3275 } else if (app.notResponding) { 3276 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3277 return; 3278 } else if (app.crashing) { 3279 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3280 return; 3281 } 3282 3283 // In case we come through here for the same app before completing 3284 // this one, mark as anring now so we will bail out. 3285 app.notResponding = true; 3286 3287 // Log the ANR to the event log. 3288 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3289 app.processName, app.info.flags, annotation); 3290 3291 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3292 firstPids.add(app.pid); 3293 3294 int parentPid = app.pid; 3295 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3296 if (parentPid != app.pid) firstPids.add(parentPid); 3297 3298 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3299 3300 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3301 ProcessRecord r = mLruProcesses.get(i); 3302 if (r != null && r.thread != null) { 3303 int pid = r.pid; 3304 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3305 if (r.persistent) { 3306 firstPids.add(pid); 3307 } else { 3308 lastPids.put(pid, Boolean.TRUE); 3309 } 3310 } 3311 } 3312 } 3313 } 3314 3315 // Log the ANR to the main log. 3316 StringBuilder info = new StringBuilder(); 3317 info.setLength(0); 3318 info.append("ANR in ").append(app.processName); 3319 if (activity != null && activity.shortComponentName != null) { 3320 info.append(" (").append(activity.shortComponentName).append(")"); 3321 } 3322 info.append("\n"); 3323 if (annotation != null) { 3324 info.append("Reason: ").append(annotation).append("\n"); 3325 } 3326 if (parent != null && parent != activity) { 3327 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3328 } 3329 3330 final ProcessStats processStats = new ProcessStats(true); 3331 3332 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3333 3334 String cpuInfo = null; 3335 if (MONITOR_CPU_USAGE) { 3336 updateCpuStatsNow(); 3337 synchronized (mProcessStatsThread) { 3338 cpuInfo = mProcessStats.printCurrentState(anrTime); 3339 } 3340 info.append(processStats.printCurrentLoad()); 3341 info.append(cpuInfo); 3342 } 3343 3344 info.append(processStats.printCurrentState(anrTime)); 3345 3346 Slog.e(TAG, info.toString()); 3347 if (tracesFile == null) { 3348 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3349 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3350 } 3351 3352 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3353 cpuInfo, tracesFile, null); 3354 3355 if (mController != null) { 3356 try { 3357 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3358 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3359 if (res != 0) { 3360 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3361 return; 3362 } 3363 } catch (RemoteException e) { 3364 mController = null; 3365 } 3366 } 3367 3368 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3369 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3370 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3371 3372 synchronized (this) { 3373 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3374 Slog.w(TAG, "Killing " + app + ": background ANR"); 3375 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3376 app.processName, app.setAdj, "background ANR"); 3377 Process.killProcessQuiet(app.pid); 3378 return; 3379 } 3380 3381 // Set the app's notResponding state, and look up the errorReportReceiver 3382 makeAppNotRespondingLocked(app, 3383 activity != null ? activity.shortComponentName : null, 3384 annotation != null ? "ANR " + annotation : "ANR", 3385 info.toString()); 3386 3387 // Bring up the infamous App Not Responding dialog 3388 Message msg = Message.obtain(); 3389 HashMap map = new HashMap(); 3390 msg.what = SHOW_NOT_RESPONDING_MSG; 3391 msg.obj = map; 3392 msg.arg1 = aboveSystem ? 1 : 0; 3393 map.put("app", app); 3394 if (activity != null) { 3395 map.put("activity", activity); 3396 } 3397 3398 mHandler.sendMessage(msg); 3399 } 3400 } 3401 showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next)3402 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3403 if (!mLaunchWarningShown) { 3404 mLaunchWarningShown = true; 3405 mHandler.post(new Runnable() { 3406 @Override 3407 public void run() { 3408 synchronized (ActivityManagerService.this) { 3409 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3410 d.show(); 3411 mHandler.postDelayed(new Runnable() { 3412 @Override 3413 public void run() { 3414 synchronized (ActivityManagerService.this) { 3415 d.dismiss(); 3416 mLaunchWarningShown = false; 3417 } 3418 } 3419 }, 4000); 3420 } 3421 } 3422 }); 3423 } 3424 } 3425 clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId)3426 public boolean clearApplicationUserData(final String packageName, 3427 final IPackageDataObserver observer, int userId) { 3428 enforceNotIsolatedCaller("clearApplicationUserData"); 3429 int uid = Binder.getCallingUid(); 3430 int pid = Binder.getCallingPid(); 3431 userId = handleIncomingUser(pid, uid, 3432 userId, false, true, "clearApplicationUserData", null); 3433 long callingId = Binder.clearCallingIdentity(); 3434 try { 3435 IPackageManager pm = AppGlobals.getPackageManager(); 3436 int pkgUid = -1; 3437 synchronized(this) { 3438 try { 3439 pkgUid = pm.getPackageUid(packageName, userId); 3440 } catch (RemoteException e) { 3441 } 3442 if (pkgUid == -1) { 3443 Slog.w(TAG, "Invalid packageName:" + packageName); 3444 return false; 3445 } 3446 if (uid == pkgUid || checkComponentPermission( 3447 android.Manifest.permission.CLEAR_APP_USER_DATA, 3448 pid, uid, -1, true) 3449 == PackageManager.PERMISSION_GRANTED) { 3450 forceStopPackageLocked(packageName, pkgUid); 3451 } else { 3452 throw new SecurityException(pid+" does not have permission:"+ 3453 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3454 "for process:"+packageName); 3455 } 3456 } 3457 3458 try { 3459 //clear application user data 3460 pm.clearApplicationUserData(packageName, observer, userId); 3461 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3462 Uri.fromParts("package", packageName, null)); 3463 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3464 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3465 null, null, 0, null, null, null, false, false, userId); 3466 } catch (RemoteException e) { 3467 } 3468 } finally { 3469 Binder.restoreCallingIdentity(callingId); 3470 } 3471 return true; 3472 } 3473 killBackgroundProcesses(final String packageName, int userId)3474 public void killBackgroundProcesses(final String packageName, int userId) { 3475 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3476 != PackageManager.PERMISSION_GRANTED && 3477 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3478 != PackageManager.PERMISSION_GRANTED) { 3479 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3480 + Binder.getCallingPid() 3481 + ", uid=" + Binder.getCallingUid() 3482 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3483 Slog.w(TAG, msg); 3484 throw new SecurityException(msg); 3485 } 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3488 userId, true, true, "killBackgroundProcesses", null); 3489 long callingId = Binder.clearCallingIdentity(); 3490 try { 3491 IPackageManager pm = AppGlobals.getPackageManager(); 3492 synchronized(this) { 3493 int appId = -1; 3494 try { 3495 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3496 } catch (RemoteException e) { 3497 } 3498 if (appId == -1) { 3499 Slog.w(TAG, "Invalid packageName: " + packageName); 3500 return; 3501 } 3502 killPackageProcessesLocked(packageName, appId, userId, 3503 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3504 } 3505 } finally { 3506 Binder.restoreCallingIdentity(callingId); 3507 } 3508 } 3509 killAllBackgroundProcesses()3510 public void killAllBackgroundProcesses() { 3511 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3512 != PackageManager.PERMISSION_GRANTED) { 3513 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3514 + Binder.getCallingPid() 3515 + ", uid=" + Binder.getCallingUid() 3516 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3517 Slog.w(TAG, msg); 3518 throw new SecurityException(msg); 3519 } 3520 3521 long callingId = Binder.clearCallingIdentity(); 3522 try { 3523 synchronized(this) { 3524 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3525 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3526 final int NA = apps.size(); 3527 for (int ia=0; ia<NA; ia++) { 3528 ProcessRecord app = apps.valueAt(ia); 3529 if (app.persistent) { 3530 // we don't kill persistent processes 3531 continue; 3532 } 3533 if (app.removed) { 3534 procs.add(app); 3535 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3536 app.removed = true; 3537 procs.add(app); 3538 } 3539 } 3540 } 3541 3542 int N = procs.size(); 3543 for (int i=0; i<N; i++) { 3544 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3545 } 3546 } 3547 } finally { 3548 Binder.restoreCallingIdentity(callingId); 3549 } 3550 } 3551 forceStopPackage(final String packageName, int userId)3552 public void forceStopPackage(final String packageName, int userId) { 3553 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3554 != PackageManager.PERMISSION_GRANTED) { 3555 String msg = "Permission Denial: forceStopPackage() from pid=" 3556 + Binder.getCallingPid() 3557 + ", uid=" + Binder.getCallingUid() 3558 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3559 Slog.w(TAG, msg); 3560 throw new SecurityException(msg); 3561 } 3562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3563 userId, true, true, "forceStopPackage", null); 3564 long callingId = Binder.clearCallingIdentity(); 3565 try { 3566 IPackageManager pm = AppGlobals.getPackageManager(); 3567 synchronized(this) { 3568 int[] users = userId == UserHandle.USER_ALL 3569 ? getUsersLocked() : new int[] { userId }; 3570 for (int user : users) { 3571 int pkgUid = -1; 3572 try { 3573 pkgUid = pm.getPackageUid(packageName, user); 3574 } catch (RemoteException e) { 3575 } 3576 if (pkgUid == -1) { 3577 Slog.w(TAG, "Invalid packageName: " + packageName); 3578 continue; 3579 } 3580 try { 3581 pm.setPackageStoppedState(packageName, true, user); 3582 } catch (RemoteException e) { 3583 } catch (IllegalArgumentException e) { 3584 Slog.w(TAG, "Failed trying to unstop package " 3585 + packageName + ": " + e); 3586 } 3587 if (isUserRunningLocked(user, false)) { 3588 forceStopPackageLocked(packageName, pkgUid); 3589 } 3590 } 3591 } 3592 } finally { 3593 Binder.restoreCallingIdentity(callingId); 3594 } 3595 } 3596 3597 /* 3598 * The pkg name and app id have to be specified. 3599 */ killApplicationWithAppId(String pkg, int appid)3600 public void killApplicationWithAppId(String pkg, int appid) { 3601 if (pkg == null) { 3602 return; 3603 } 3604 // Make sure the uid is valid. 3605 if (appid < 0) { 3606 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3607 return; 3608 } 3609 int callerUid = Binder.getCallingUid(); 3610 // Only the system server can kill an application 3611 if (callerUid == Process.SYSTEM_UID) { 3612 // Post an aysnc message to kill the application 3613 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3614 msg.arg1 = appid; 3615 msg.arg2 = 0; 3616 msg.obj = pkg; 3617 mHandler.sendMessage(msg); 3618 } else { 3619 throw new SecurityException(callerUid + " cannot kill pkg: " + 3620 pkg); 3621 } 3622 } 3623 closeSystemDialogs(String reason)3624 public void closeSystemDialogs(String reason) { 3625 enforceNotIsolatedCaller("closeSystemDialogs"); 3626 3627 final int pid = Binder.getCallingPid(); 3628 final int uid = Binder.getCallingUid(); 3629 final long origId = Binder.clearCallingIdentity(); 3630 try { 3631 synchronized (this) { 3632 // Only allow this from foreground processes, so that background 3633 // applications can't abuse it to prevent system UI from being shown. 3634 if (uid >= Process.FIRST_APPLICATION_UID) { 3635 ProcessRecord proc; 3636 synchronized (mPidsSelfLocked) { 3637 proc = mPidsSelfLocked.get(pid); 3638 } 3639 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3640 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3641 + " from background process " + proc); 3642 return; 3643 } 3644 } 3645 closeSystemDialogsLocked(reason); 3646 } 3647 } finally { 3648 Binder.restoreCallingIdentity(origId); 3649 } 3650 } 3651 closeSystemDialogsLocked(String reason)3652 void closeSystemDialogsLocked(String reason) { 3653 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3655 | Intent.FLAG_RECEIVER_FOREGROUND); 3656 if (reason != null) { 3657 intent.putExtra("reason", reason); 3658 } 3659 mWindowManager.closeSystemDialogs(reason); 3660 3661 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3662 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3663 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3664 r.stack.finishActivityLocked(r, i, 3665 Activity.RESULT_CANCELED, null, "close-sys", true); 3666 } 3667 } 3668 3669 broadcastIntentLocked(null, null, intent, null, 3670 null, 0, null, null, null, false, false, -1, 3671 Process.SYSTEM_UID, UserHandle.USER_ALL); 3672 } 3673 getProcessMemoryInfo(int[] pids)3674 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3675 throws RemoteException { 3676 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3677 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3678 for (int i=pids.length-1; i>=0; i--) { 3679 infos[i] = new Debug.MemoryInfo(); 3680 Debug.getMemoryInfo(pids[i], infos[i]); 3681 } 3682 return infos; 3683 } 3684 getProcessPss(int[] pids)3685 public long[] getProcessPss(int[] pids) throws RemoteException { 3686 enforceNotIsolatedCaller("getProcessPss"); 3687 long[] pss = new long[pids.length]; 3688 for (int i=pids.length-1; i>=0; i--) { 3689 pss[i] = Debug.getPss(pids[i]); 3690 } 3691 return pss; 3692 } 3693 killApplicationProcess(String processName, int uid)3694 public void killApplicationProcess(String processName, int uid) { 3695 if (processName == null) { 3696 return; 3697 } 3698 3699 int callerUid = Binder.getCallingUid(); 3700 // Only the system server can kill an application 3701 if (callerUid == Process.SYSTEM_UID) { 3702 synchronized (this) { 3703 ProcessRecord app = getProcessRecordLocked(processName, uid); 3704 if (app != null && app.thread != null) { 3705 try { 3706 app.thread.scheduleSuicide(); 3707 } catch (RemoteException e) { 3708 // If the other end already died, then our work here is done. 3709 } 3710 } else { 3711 Slog.w(TAG, "Process/uid not found attempting kill of " 3712 + processName + " / " + uid); 3713 } 3714 } 3715 } else { 3716 throw new SecurityException(callerUid + " cannot kill app process: " + 3717 processName); 3718 } 3719 } 3720 forceStopPackageLocked(final String packageName, int uid)3721 private void forceStopPackageLocked(final String packageName, int uid) { 3722 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3723 false, true, false, UserHandle.getUserId(uid)); 3724 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3725 Uri.fromParts("package", packageName, null)); 3726 if (!mProcessesReady) { 3727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3728 | Intent.FLAG_RECEIVER_FOREGROUND); 3729 } 3730 intent.putExtra(Intent.EXTRA_UID, uid); 3731 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3732 broadcastIntentLocked(null, null, intent, 3733 null, null, 0, null, null, null, 3734 false, false, 3735 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3736 } 3737 forceStopUserLocked(int userId)3738 private void forceStopUserLocked(int userId) { 3739 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3740 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3741 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3742 | Intent.FLAG_RECEIVER_FOREGROUND); 3743 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3744 broadcastIntentLocked(null, null, intent, 3745 null, null, 0, null, null, null, 3746 false, false, 3747 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3748 } 3749 killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, String reason)3750 private final boolean killPackageProcessesLocked(String packageName, int appId, 3751 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3752 boolean doit, boolean evenPersistent, String reason) { 3753 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3754 3755 // Remove all processes this package may have touched: all with the 3756 // same UID (except for the system or root user), and all whose name 3757 // matches the package name. 3758 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3759 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3760 final int NA = apps.size(); 3761 for (int ia=0; ia<NA; ia++) { 3762 ProcessRecord app = apps.valueAt(ia); 3763 if (app.persistent && !evenPersistent) { 3764 // we don't kill persistent processes 3765 continue; 3766 } 3767 if (app.removed) { 3768 if (doit) { 3769 procs.add(app); 3770 } 3771 continue; 3772 } 3773 3774 // Skip process if it doesn't meet our oom adj requirement. 3775 if (app.setAdj < minOomAdj) { 3776 continue; 3777 } 3778 3779 // If no package is specified, we call all processes under the 3780 // give user id. 3781 if (packageName == null) { 3782 if (app.userId != userId) { 3783 continue; 3784 } 3785 // Package has been specified, we want to hit all processes 3786 // that match it. We need to qualify this by the processes 3787 // that are running under the specified app and user ID. 3788 } else { 3789 if (UserHandle.getAppId(app.uid) != appId) { 3790 continue; 3791 } 3792 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3793 continue; 3794 } 3795 if (!app.pkgList.contains(packageName)) { 3796 continue; 3797 } 3798 } 3799 3800 // Process has passed all conditions, kill it! 3801 if (!doit) { 3802 return true; 3803 } 3804 app.removed = true; 3805 procs.add(app); 3806 } 3807 } 3808 3809 int N = procs.size(); 3810 for (int i=0; i<N; i++) { 3811 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3812 } 3813 return N > 0; 3814 } 3815 forceStopPackageLocked(String name, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, int userId)3816 private final boolean forceStopPackageLocked(String name, int appId, 3817 boolean callerWillRestart, boolean purgeCache, boolean doit, 3818 boolean evenPersistent, int userId) { 3819 int i; 3820 int N; 3821 3822 if (userId == UserHandle.USER_ALL && name == null) { 3823 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3824 } 3825 3826 if (appId < 0 && name != null) { 3827 try { 3828 appId = UserHandle.getAppId( 3829 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3830 } catch (RemoteException e) { 3831 } 3832 } 3833 3834 if (doit) { 3835 if (name != null) { 3836 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3837 + " user=" + userId); 3838 } else { 3839 Slog.i(TAG, "Force stopping user " + userId); 3840 } 3841 3842 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3843 while (badApps.hasNext()) { 3844 SparseArray<Long> ba = badApps.next(); 3845 for (i=ba.size()-1; i>=0; i--) { 3846 boolean remove = false; 3847 final int entUid = ba.keyAt(i); 3848 if (name != null) { 3849 if (userId == UserHandle.USER_ALL) { 3850 if (UserHandle.getAppId(entUid) == appId) { 3851 remove = true; 3852 } 3853 } else { 3854 if (entUid == UserHandle.getUid(userId, appId)) { 3855 remove = true; 3856 } 3857 } 3858 } else if (UserHandle.getUserId(entUid) == userId) { 3859 remove = true; 3860 } 3861 if (remove) { 3862 ba.removeAt(i); 3863 } 3864 } 3865 if (ba.size() == 0) { 3866 badApps.remove(); 3867 } 3868 } 3869 } 3870 3871 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3872 -100, callerWillRestart, true, doit, evenPersistent, 3873 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3874 3875 TaskRecord lastTask = null; 3876 for (i=0; i<mMainStack.mHistory.size(); i++) { 3877 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3878 final boolean samePackage = r.packageName.equals(name) 3879 || (name == null && r.userId == userId); 3880 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3881 && (samePackage || r.task == lastTask) 3882 && (r.app == null || evenPersistent || !r.app.persistent)) { 3883 if (!doit) { 3884 if (r.finishing) { 3885 // If this activity is just finishing, then it is not 3886 // interesting as far as something to stop. 3887 continue; 3888 } 3889 return true; 3890 } 3891 didSomething = true; 3892 Slog.i(TAG, " Force finishing activity " + r); 3893 if (samePackage) { 3894 if (r.app != null) { 3895 r.app.removed = true; 3896 } 3897 r.app = null; 3898 } 3899 lastTask = r.task; 3900 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3901 null, "force-stop", true)) { 3902 i--; 3903 } 3904 } 3905 } 3906 3907 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3908 if (!doit) { 3909 return true; 3910 } 3911 didSomething = true; 3912 } 3913 3914 if (name == null) { 3915 // Remove all sticky broadcasts from this user. 3916 mStickyBroadcasts.remove(userId); 3917 } 3918 3919 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3920 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3921 userId, providers)) { 3922 if (!doit) { 3923 return true; 3924 } 3925 didSomething = true; 3926 } 3927 N = providers.size(); 3928 for (i=0; i<N; i++) { 3929 removeDyingProviderLocked(null, providers.get(i), true); 3930 } 3931 3932 if (name == null) { 3933 // Remove pending intents. For now we only do this when force 3934 // stopping users, because we have some problems when doing this 3935 // for packages -- app widgets are not currently cleaned up for 3936 // such packages, so they can be left with bad pending intents. 3937 if (mIntentSenderRecords.size() > 0) { 3938 Iterator<WeakReference<PendingIntentRecord>> it 3939 = mIntentSenderRecords.values().iterator(); 3940 while (it.hasNext()) { 3941 WeakReference<PendingIntentRecord> wpir = it.next(); 3942 if (wpir == null) { 3943 it.remove(); 3944 continue; 3945 } 3946 PendingIntentRecord pir = wpir.get(); 3947 if (pir == null) { 3948 it.remove(); 3949 continue; 3950 } 3951 if (name == null) { 3952 // Stopping user, remove all objects for the user. 3953 if (pir.key.userId != userId) { 3954 // Not the same user, skip it. 3955 continue; 3956 } 3957 } else { 3958 if (UserHandle.getAppId(pir.uid) != appId) { 3959 // Different app id, skip it. 3960 continue; 3961 } 3962 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3963 // Different user, skip it. 3964 continue; 3965 } 3966 if (!pir.key.packageName.equals(name)) { 3967 // Different package, skip it. 3968 continue; 3969 } 3970 } 3971 if (!doit) { 3972 return true; 3973 } 3974 didSomething = true; 3975 it.remove(); 3976 pir.canceled = true; 3977 if (pir.key.activity != null) { 3978 pir.key.activity.pendingResults.remove(pir.ref); 3979 } 3980 } 3981 } 3982 } 3983 3984 if (doit) { 3985 if (purgeCache && name != null) { 3986 AttributeCache ac = AttributeCache.instance(); 3987 if (ac != null) { 3988 ac.removePackage(name); 3989 } 3990 } 3991 if (mBooted) { 3992 mMainStack.resumeTopActivityLocked(null); 3993 mMainStack.scheduleIdleLocked(); 3994 } 3995 } 3996 3997 return didSomething; 3998 } 3999 removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)4000 private final boolean removeProcessLocked(ProcessRecord app, 4001 boolean callerWillRestart, boolean allowRestart, String reason) { 4002 final String name = app.processName; 4003 final int uid = app.uid; 4004 if (DEBUG_PROCESSES) Slog.d( 4005 TAG, "Force removing proc " + app.toShortString() + " (" + name 4006 + "/" + uid + ")"); 4007 4008 mProcessNames.remove(name, uid); 4009 mIsolatedProcesses.remove(app.uid); 4010 if (mHeavyWeightProcess == app) { 4011 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4012 mHeavyWeightProcess.userId, 0)); 4013 mHeavyWeightProcess = null; 4014 } 4015 boolean needRestart = false; 4016 if (app.pid > 0 && app.pid != MY_PID) { 4017 int pid = app.pid; 4018 synchronized (mPidsSelfLocked) { 4019 mPidsSelfLocked.remove(pid); 4020 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4021 } 4022 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4023 handleAppDiedLocked(app, true, allowRestart); 4024 mLruProcesses.remove(app); 4025 Process.killProcessQuiet(pid); 4026 4027 if (app.persistent && !app.isolated) { 4028 if (!callerWillRestart) { 4029 addAppLocked(app.info, false); 4030 } else { 4031 needRestart = true; 4032 } 4033 } 4034 } else { 4035 mRemovedProcesses.add(app); 4036 } 4037 4038 return needRestart; 4039 } 4040 processStartTimedOutLocked(ProcessRecord app)4041 private final void processStartTimedOutLocked(ProcessRecord app) { 4042 final int pid = app.pid; 4043 boolean gone = false; 4044 synchronized (mPidsSelfLocked) { 4045 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4046 if (knownApp != null && knownApp.thread == null) { 4047 mPidsSelfLocked.remove(pid); 4048 gone = true; 4049 } 4050 } 4051 4052 if (gone) { 4053 Slog.w(TAG, "Process " + app + " failed to attach"); 4054 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4055 pid, app.uid, app.processName); 4056 mProcessNames.remove(app.processName, app.uid); 4057 mIsolatedProcesses.remove(app.uid); 4058 if (mHeavyWeightProcess == app) { 4059 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4060 mHeavyWeightProcess.userId, 0)); 4061 mHeavyWeightProcess = null; 4062 } 4063 // Take care of any launching providers waiting for this process. 4064 checkAppInLaunchingProvidersLocked(app, true); 4065 // Take care of any services that are waiting for the process. 4066 mServices.processStartTimedOutLocked(app); 4067 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4068 app.processName, app.setAdj, "start timeout"); 4069 Process.killProcessQuiet(pid); 4070 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4071 Slog.w(TAG, "Unattached app died before backup, skipping"); 4072 try { 4073 IBackupManager bm = IBackupManager.Stub.asInterface( 4074 ServiceManager.getService(Context.BACKUP_SERVICE)); 4075 bm.agentDisconnected(app.info.packageName); 4076 } catch (RemoteException e) { 4077 // Can't happen; the backup manager is local 4078 } 4079 } 4080 if (isPendingBroadcastProcessLocked(pid)) { 4081 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4082 skipPendingBroadcastLocked(pid); 4083 } 4084 } else { 4085 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4086 } 4087 } 4088 attachApplicationLocked(IApplicationThread thread, int pid)4089 private final boolean attachApplicationLocked(IApplicationThread thread, 4090 int pid) { 4091 4092 // Find the application record that is being attached... either via 4093 // the pid if we are running in multiple processes, or just pull the 4094 // next app record if we are emulating process with anonymous threads. 4095 ProcessRecord app; 4096 if (pid != MY_PID && pid >= 0) { 4097 synchronized (mPidsSelfLocked) { 4098 app = mPidsSelfLocked.get(pid); 4099 } 4100 } else { 4101 app = null; 4102 } 4103 4104 if (app == null) { 4105 Slog.w(TAG, "No pending application record for pid " + pid 4106 + " (IApplicationThread " + thread + "); dropping process"); 4107 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4108 if (pid > 0 && pid != MY_PID) { 4109 Process.killProcessQuiet(pid); 4110 } else { 4111 try { 4112 thread.scheduleExit(); 4113 } catch (Exception e) { 4114 // Ignore exceptions. 4115 } 4116 } 4117 return false; 4118 } 4119 4120 // If this application record is still attached to a previous 4121 // process, clean it up now. 4122 if (app.thread != null) { 4123 handleAppDiedLocked(app, true, true); 4124 } 4125 4126 // Tell the process all about itself. 4127 4128 if (localLOGV) Slog.v( 4129 TAG, "Binding process pid " + pid + " to record " + app); 4130 4131 String processName = app.processName; 4132 try { 4133 AppDeathRecipient adr = new AppDeathRecipient( 4134 app, pid, thread); 4135 thread.asBinder().linkToDeath(adr, 0); 4136 app.deathRecipient = adr; 4137 } catch (RemoteException e) { 4138 app.resetPackageList(); 4139 startProcessLocked(app, "link fail", processName); 4140 return false; 4141 } 4142 4143 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4144 4145 app.thread = thread; 4146 app.curAdj = app.setAdj = -100; 4147 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4148 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4149 app.forcingToForeground = null; 4150 app.foregroundServices = false; 4151 app.hasShownUi = false; 4152 app.debugging = false; 4153 4154 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4155 4156 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4157 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4158 4159 if (!normalMode) { 4160 Slog.i(TAG, "Launching preboot mode app: " + app); 4161 } 4162 4163 if (localLOGV) Slog.v( 4164 TAG, "New app record " + app 4165 + " thread=" + thread.asBinder() + " pid=" + pid); 4166 try { 4167 int testMode = IApplicationThread.DEBUG_OFF; 4168 if (mDebugApp != null && mDebugApp.equals(processName)) { 4169 testMode = mWaitForDebugger 4170 ? IApplicationThread.DEBUG_WAIT 4171 : IApplicationThread.DEBUG_ON; 4172 app.debugging = true; 4173 if (mDebugTransient) { 4174 mDebugApp = mOrigDebugApp; 4175 mWaitForDebugger = mOrigWaitForDebugger; 4176 } 4177 } 4178 String profileFile = app.instrumentationProfileFile; 4179 ParcelFileDescriptor profileFd = null; 4180 boolean profileAutoStop = false; 4181 if (mProfileApp != null && mProfileApp.equals(processName)) { 4182 mProfileProc = app; 4183 profileFile = mProfileFile; 4184 profileFd = mProfileFd; 4185 profileAutoStop = mAutoStopProfiler; 4186 } 4187 boolean enableOpenGlTrace = false; 4188 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4189 enableOpenGlTrace = true; 4190 mOpenGlTraceApp = null; 4191 } 4192 4193 // If the app is being launched for restore or full backup, set it up specially 4194 boolean isRestrictedBackupMode = false; 4195 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4196 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4197 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4198 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4199 } 4200 4201 ensurePackageDexOpt(app.instrumentationInfo != null 4202 ? app.instrumentationInfo.packageName 4203 : app.info.packageName); 4204 if (app.instrumentationClass != null) { 4205 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4206 } 4207 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4208 + processName + " with config " + mConfiguration); 4209 ApplicationInfo appInfo = app.instrumentationInfo != null 4210 ? app.instrumentationInfo : app.info; 4211 app.compat = compatibilityInfoForPackageLocked(appInfo); 4212 if (profileFd != null) { 4213 profileFd = profileFd.dup(); 4214 } 4215 thread.bindApplication(processName, appInfo, providers, 4216 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4217 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4218 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4219 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4220 mCoreSettingsObserver.getCoreSettingsLocked()); 4221 updateLruProcessLocked(app, false); 4222 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4223 } catch (Exception e) { 4224 // todo: Yikes! What should we do? For now we will try to 4225 // start another process, but that could easily get us in 4226 // an infinite loop of restarting processes... 4227 Slog.w(TAG, "Exception thrown during bind!", e); 4228 4229 app.resetPackageList(); 4230 app.unlinkDeathRecipient(); 4231 startProcessLocked(app, "bind fail", processName); 4232 return false; 4233 } 4234 4235 // Remove this record from the list of starting applications. 4236 mPersistentStartingProcesses.remove(app); 4237 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4238 "Attach application locked removing on hold: " + app); 4239 mProcessesOnHold.remove(app); 4240 4241 boolean badApp = false; 4242 boolean didSomething = false; 4243 4244 // See if the top visible activity is waiting to run in this process... 4245 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4246 if (hr != null && normalMode) { 4247 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4248 && processName.equals(hr.processName)) { 4249 try { 4250 if (mHeadless) { 4251 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4252 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4253 didSomething = true; 4254 } 4255 } catch (Exception e) { 4256 Slog.w(TAG, "Exception in new application when starting activity " 4257 + hr.intent.getComponent().flattenToShortString(), e); 4258 badApp = true; 4259 } 4260 } else { 4261 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4262 } 4263 } 4264 4265 // Find any services that should be running in this process... 4266 if (!badApp) { 4267 try { 4268 didSomething |= mServices.attachApplicationLocked(app, processName); 4269 } catch (Exception e) { 4270 badApp = true; 4271 } 4272 } 4273 4274 // Check if a next-broadcast receiver is in this process... 4275 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4276 try { 4277 didSomething = sendPendingBroadcastsLocked(app); 4278 } catch (Exception e) { 4279 // If the app died trying to launch the receiver we declare it 'bad' 4280 badApp = true; 4281 } 4282 } 4283 4284 // Check whether the next backup agent is in this process... 4285 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4286 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4287 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4288 try { 4289 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4290 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4291 mBackupTarget.backupMode); 4292 } catch (Exception e) { 4293 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4294 e.printStackTrace(); 4295 } 4296 } 4297 4298 if (badApp) { 4299 // todo: Also need to kill application to deal with all 4300 // kinds of exceptions. 4301 handleAppDiedLocked(app, false, true); 4302 return false; 4303 } 4304 4305 if (!didSomething) { 4306 updateOomAdjLocked(); 4307 } 4308 4309 return true; 4310 } 4311 attachApplication(IApplicationThread thread)4312 public final void attachApplication(IApplicationThread thread) { 4313 synchronized (this) { 4314 int callingPid = Binder.getCallingPid(); 4315 final long origId = Binder.clearCallingIdentity(); 4316 attachApplicationLocked(thread, callingPid); 4317 Binder.restoreCallingIdentity(origId); 4318 } 4319 } 4320 activityIdle(IBinder token, Configuration config, boolean stopProfiling)4321 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4322 final long origId = Binder.clearCallingIdentity(); 4323 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4324 if (stopProfiling) { 4325 synchronized (this) { 4326 if (mProfileProc == r.app) { 4327 if (mProfileFd != null) { 4328 try { 4329 mProfileFd.close(); 4330 } catch (IOException e) { 4331 } 4332 clearProfilerLocked(); 4333 } 4334 } 4335 } 4336 } 4337 Binder.restoreCallingIdentity(origId); 4338 } 4339 enableScreenAfterBoot()4340 void enableScreenAfterBoot() { 4341 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4342 SystemClock.uptimeMillis()); 4343 mWindowManager.enableScreenAfterBoot(); 4344 4345 synchronized (this) { 4346 updateEventDispatchingLocked(); 4347 } 4348 } 4349 showBootMessage(final CharSequence msg, final boolean always)4350 public void showBootMessage(final CharSequence msg, final boolean always) { 4351 enforceNotIsolatedCaller("showBootMessage"); 4352 mWindowManager.showBootMessage(msg, always); 4353 } 4354 dismissKeyguardOnNextActivity()4355 public void dismissKeyguardOnNextActivity() { 4356 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4357 final long token = Binder.clearCallingIdentity(); 4358 try { 4359 synchronized (this) { 4360 if (mLockScreenShown) { 4361 mLockScreenShown = false; 4362 comeOutOfSleepIfNeededLocked(); 4363 } 4364 mMainStack.dismissKeyguardOnNextActivityLocked(); 4365 } 4366 } finally { 4367 Binder.restoreCallingIdentity(token); 4368 } 4369 } 4370 finishBooting()4371 final void finishBooting() { 4372 IntentFilter pkgFilter = new IntentFilter(); 4373 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4374 pkgFilter.addDataScheme("package"); 4375 mContext.registerReceiver(new BroadcastReceiver() { 4376 @Override 4377 public void onReceive(Context context, Intent intent) { 4378 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4379 if (pkgs != null) { 4380 for (String pkg : pkgs) { 4381 synchronized (ActivityManagerService.this) { 4382 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4383 setResultCode(Activity.RESULT_OK); 4384 return; 4385 } 4386 } 4387 } 4388 } 4389 } 4390 }, pkgFilter); 4391 4392 synchronized (this) { 4393 // Ensure that any processes we had put on hold are now started 4394 // up. 4395 final int NP = mProcessesOnHold.size(); 4396 if (NP > 0) { 4397 ArrayList<ProcessRecord> procs = 4398 new ArrayList<ProcessRecord>(mProcessesOnHold); 4399 for (int ip=0; ip<NP; ip++) { 4400 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4401 + procs.get(ip)); 4402 startProcessLocked(procs.get(ip), "on-hold", null); 4403 } 4404 } 4405 4406 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4407 // Start looking for apps that are abusing wake locks. 4408 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4409 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4410 // Tell anyone interested that we are done booting! 4411 SystemProperties.set("sys.boot_completed", "1"); 4412 SystemProperties.set("dev.bootcomplete", "1"); 4413 for (int i=0; i<mStartedUsers.size(); i++) { 4414 UserStartedState uss = mStartedUsers.valueAt(i); 4415 if (uss.mState == UserStartedState.STATE_BOOTING) { 4416 uss.mState = UserStartedState.STATE_RUNNING; 4417 final int userId = mStartedUsers.keyAt(i); 4418 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4419 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4420 broadcastIntentLocked(null, null, intent, 4421 null, null, 0, null, null, 4422 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4423 false, false, MY_PID, Process.SYSTEM_UID, userId); 4424 } 4425 } 4426 } 4427 } 4428 } 4429 ensureBootCompleted()4430 final void ensureBootCompleted() { 4431 boolean booting; 4432 boolean enableScreen; 4433 synchronized (this) { 4434 booting = mBooting; 4435 mBooting = false; 4436 enableScreen = !mBooted; 4437 mBooted = true; 4438 } 4439 4440 if (booting) { 4441 finishBooting(); 4442 } 4443 4444 if (enableScreen) { 4445 enableScreenAfterBoot(); 4446 } 4447 } 4448 activityResumed(IBinder token)4449 public final void activityResumed(IBinder token) { 4450 final long origId = Binder.clearCallingIdentity(); 4451 mMainStack.activityResumed(token); 4452 Binder.restoreCallingIdentity(origId); 4453 } 4454 activityPaused(IBinder token)4455 public final void activityPaused(IBinder token) { 4456 final long origId = Binder.clearCallingIdentity(); 4457 mMainStack.activityPaused(token, false); 4458 Binder.restoreCallingIdentity(origId); 4459 } 4460 activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, CharSequence description)4461 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4462 CharSequence description) { 4463 if (localLOGV) Slog.v( 4464 TAG, "Activity stopped: token=" + token); 4465 4466 // Refuse possible leaked file descriptors 4467 if (icicle != null && icicle.hasFileDescriptors()) { 4468 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4469 } 4470 4471 ActivityRecord r = null; 4472 4473 final long origId = Binder.clearCallingIdentity(); 4474 4475 synchronized (this) { 4476 r = mMainStack.isInStackLocked(token); 4477 if (r != null) { 4478 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4479 } 4480 } 4481 4482 if (r != null) { 4483 sendPendingThumbnail(r, null, null, null, false); 4484 } 4485 4486 trimApplications(); 4487 4488 Binder.restoreCallingIdentity(origId); 4489 } 4490 activityDestroyed(IBinder token)4491 public final void activityDestroyed(IBinder token) { 4492 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4493 mMainStack.activityDestroyed(token); 4494 } 4495 getCallingPackage(IBinder token)4496 public String getCallingPackage(IBinder token) { 4497 synchronized (this) { 4498 ActivityRecord r = getCallingRecordLocked(token); 4499 return r != null && r.app != null ? r.info.packageName : null; 4500 } 4501 } 4502 getCallingActivity(IBinder token)4503 public ComponentName getCallingActivity(IBinder token) { 4504 synchronized (this) { 4505 ActivityRecord r = getCallingRecordLocked(token); 4506 return r != null ? r.intent.getComponent() : null; 4507 } 4508 } 4509 getCallingRecordLocked(IBinder token)4510 private ActivityRecord getCallingRecordLocked(IBinder token) { 4511 ActivityRecord r = mMainStack.isInStackLocked(token); 4512 if (r == null) { 4513 return null; 4514 } 4515 return r.resultTo; 4516 } 4517 getActivityClassForToken(IBinder token)4518 public ComponentName getActivityClassForToken(IBinder token) { 4519 synchronized(this) { 4520 ActivityRecord r = mMainStack.isInStackLocked(token); 4521 if (r == null) { 4522 return null; 4523 } 4524 return r.intent.getComponent(); 4525 } 4526 } 4527 getPackageForToken(IBinder token)4528 public String getPackageForToken(IBinder token) { 4529 synchronized(this) { 4530 ActivityRecord r = mMainStack.isInStackLocked(token); 4531 if (r == null) { 4532 return null; 4533 } 4534 return r.packageName; 4535 } 4536 } 4537 getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options, int userId)4538 public IIntentSender getIntentSender(int type, 4539 String packageName, IBinder token, String resultWho, 4540 int requestCode, Intent[] intents, String[] resolvedTypes, 4541 int flags, Bundle options, int userId) { 4542 enforceNotIsolatedCaller("getIntentSender"); 4543 // Refuse possible leaked file descriptors 4544 if (intents != null) { 4545 if (intents.length < 1) { 4546 throw new IllegalArgumentException("Intents array length must be >= 1"); 4547 } 4548 for (int i=0; i<intents.length; i++) { 4549 Intent intent = intents[i]; 4550 if (intent != null) { 4551 if (intent.hasFileDescriptors()) { 4552 throw new IllegalArgumentException("File descriptors passed in Intent"); 4553 } 4554 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4555 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4556 throw new IllegalArgumentException( 4557 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4558 } 4559 intents[i] = new Intent(intent); 4560 } 4561 } 4562 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4563 throw new IllegalArgumentException( 4564 "Intent array length does not match resolvedTypes length"); 4565 } 4566 } 4567 if (options != null) { 4568 if (options.hasFileDescriptors()) { 4569 throw new IllegalArgumentException("File descriptors passed in options"); 4570 } 4571 } 4572 4573 synchronized(this) { 4574 int callingUid = Binder.getCallingUid(); 4575 int origUserId = userId; 4576 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4577 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 4578 "getIntentSender", null); 4579 if (origUserId == UserHandle.USER_CURRENT) { 4580 // We don't want to evaluate this until the pending intent is 4581 // actually executed. However, we do want to always do the 4582 // security checking for it above. 4583 userId = UserHandle.USER_CURRENT; 4584 } 4585 try { 4586 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4587 int uid = AppGlobals.getPackageManager() 4588 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4589 if (!UserHandle.isSameApp(callingUid, uid)) { 4590 String msg = "Permission Denial: getIntentSender() from pid=" 4591 + Binder.getCallingPid() 4592 + ", uid=" + Binder.getCallingUid() 4593 + ", (need uid=" + uid + ")" 4594 + " is not allowed to send as package " + packageName; 4595 Slog.w(TAG, msg); 4596 throw new SecurityException(msg); 4597 } 4598 } 4599 4600 return getIntentSenderLocked(type, packageName, callingUid, userId, 4601 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4602 4603 } catch (RemoteException e) { 4604 throw new SecurityException(e); 4605 } 4606 } 4607 } 4608 getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options)4609 IIntentSender getIntentSenderLocked(int type, String packageName, 4610 int callingUid, int userId, IBinder token, String resultWho, 4611 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4612 Bundle options) { 4613 if (DEBUG_MU) 4614 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4615 ActivityRecord activity = null; 4616 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4617 activity = mMainStack.isInStackLocked(token); 4618 if (activity == null) { 4619 return null; 4620 } 4621 if (activity.finishing) { 4622 return null; 4623 } 4624 } 4625 4626 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4627 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4628 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4629 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4630 |PendingIntent.FLAG_UPDATE_CURRENT); 4631 4632 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4633 type, packageName, activity, resultWho, 4634 requestCode, intents, resolvedTypes, flags, options, userId); 4635 WeakReference<PendingIntentRecord> ref; 4636 ref = mIntentSenderRecords.get(key); 4637 PendingIntentRecord rec = ref != null ? ref.get() : null; 4638 if (rec != null) { 4639 if (!cancelCurrent) { 4640 if (updateCurrent) { 4641 if (rec.key.requestIntent != null) { 4642 rec.key.requestIntent.replaceExtras(intents != null ? 4643 intents[intents.length - 1] : null); 4644 } 4645 if (intents != null) { 4646 intents[intents.length-1] = rec.key.requestIntent; 4647 rec.key.allIntents = intents; 4648 rec.key.allResolvedTypes = resolvedTypes; 4649 } else { 4650 rec.key.allIntents = null; 4651 rec.key.allResolvedTypes = null; 4652 } 4653 } 4654 return rec; 4655 } 4656 rec.canceled = true; 4657 mIntentSenderRecords.remove(key); 4658 } 4659 if (noCreate) { 4660 return rec; 4661 } 4662 rec = new PendingIntentRecord(this, key, callingUid); 4663 mIntentSenderRecords.put(key, rec.ref); 4664 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4665 if (activity.pendingResults == null) { 4666 activity.pendingResults 4667 = new HashSet<WeakReference<PendingIntentRecord>>(); 4668 } 4669 activity.pendingResults.add(rec.ref); 4670 } 4671 return rec; 4672 } 4673 cancelIntentSender(IIntentSender sender)4674 public void cancelIntentSender(IIntentSender sender) { 4675 if (!(sender instanceof PendingIntentRecord)) { 4676 return; 4677 } 4678 synchronized(this) { 4679 PendingIntentRecord rec = (PendingIntentRecord)sender; 4680 try { 4681 int uid = AppGlobals.getPackageManager() 4682 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4683 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4684 String msg = "Permission Denial: cancelIntentSender() from pid=" 4685 + Binder.getCallingPid() 4686 + ", uid=" + Binder.getCallingUid() 4687 + " is not allowed to cancel packges " 4688 + rec.key.packageName; 4689 Slog.w(TAG, msg); 4690 throw new SecurityException(msg); 4691 } 4692 } catch (RemoteException e) { 4693 throw new SecurityException(e); 4694 } 4695 cancelIntentSenderLocked(rec, true); 4696 } 4697 } 4698 cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)4699 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4700 rec.canceled = true; 4701 mIntentSenderRecords.remove(rec.key); 4702 if (cleanActivity && rec.key.activity != null) { 4703 rec.key.activity.pendingResults.remove(rec.ref); 4704 } 4705 } 4706 getPackageForIntentSender(IIntentSender pendingResult)4707 public String getPackageForIntentSender(IIntentSender pendingResult) { 4708 if (!(pendingResult instanceof PendingIntentRecord)) { 4709 return null; 4710 } 4711 try { 4712 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4713 return res.key.packageName; 4714 } catch (ClassCastException e) { 4715 } 4716 return null; 4717 } 4718 getUidForIntentSender(IIntentSender sender)4719 public int getUidForIntentSender(IIntentSender sender) { 4720 if (sender instanceof PendingIntentRecord) { 4721 try { 4722 PendingIntentRecord res = (PendingIntentRecord)sender; 4723 return res.uid; 4724 } catch (ClassCastException e) { 4725 } 4726 } 4727 return -1; 4728 } 4729 isIntentSenderTargetedToPackage(IIntentSender pendingResult)4730 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4731 if (!(pendingResult instanceof PendingIntentRecord)) { 4732 return false; 4733 } 4734 try { 4735 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4736 if (res.key.allIntents == null) { 4737 return false; 4738 } 4739 for (int i=0; i<res.key.allIntents.length; i++) { 4740 Intent intent = res.key.allIntents[i]; 4741 if (intent.getPackage() != null && intent.getComponent() != null) { 4742 return false; 4743 } 4744 } 4745 return true; 4746 } catch (ClassCastException e) { 4747 } 4748 return false; 4749 } 4750 isIntentSenderAnActivity(IIntentSender pendingResult)4751 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4752 if (!(pendingResult instanceof PendingIntentRecord)) { 4753 return false; 4754 } 4755 try { 4756 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4757 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4758 return true; 4759 } 4760 return false; 4761 } catch (ClassCastException e) { 4762 } 4763 return false; 4764 } 4765 getIntentForIntentSender(IIntentSender pendingResult)4766 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 4767 if (!(pendingResult instanceof PendingIntentRecord)) { 4768 return null; 4769 } 4770 try { 4771 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4772 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 4773 } catch (ClassCastException e) { 4774 } 4775 return null; 4776 } 4777 setProcessLimit(int max)4778 public void setProcessLimit(int max) { 4779 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4780 "setProcessLimit()"); 4781 synchronized (this) { 4782 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4783 mProcessLimitOverride = max; 4784 } 4785 trimApplications(); 4786 } 4787 4788 public int getProcessLimit() { 4789 synchronized (this) { 4790 return mProcessLimitOverride; 4791 } 4792 } 4793 4794 void foregroundTokenDied(ForegroundToken token) { 4795 synchronized (ActivityManagerService.this) { 4796 synchronized (mPidsSelfLocked) { 4797 ForegroundToken cur 4798 = mForegroundProcesses.get(token.pid); 4799 if (cur != token) { 4800 return; 4801 } 4802 mForegroundProcesses.remove(token.pid); 4803 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4804 if (pr == null) { 4805 return; 4806 } 4807 pr.forcingToForeground = null; 4808 pr.foregroundServices = false; 4809 } 4810 updateOomAdjLocked(); 4811 } 4812 } 4813 4814 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4815 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4816 "setProcessForeground()"); 4817 synchronized(this) { 4818 boolean changed = false; 4819 4820 synchronized (mPidsSelfLocked) { 4821 ProcessRecord pr = mPidsSelfLocked.get(pid); 4822 if (pr == null && isForeground) { 4823 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4824 return; 4825 } 4826 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4827 if (oldToken != null) { 4828 oldToken.token.unlinkToDeath(oldToken, 0); 4829 mForegroundProcesses.remove(pid); 4830 if (pr != null) { 4831 pr.forcingToForeground = null; 4832 } 4833 changed = true; 4834 } 4835 if (isForeground && token != null) { 4836 ForegroundToken newToken = new ForegroundToken() { 4837 public void binderDied() { 4838 foregroundTokenDied(this); 4839 } 4840 }; 4841 newToken.pid = pid; 4842 newToken.token = token; 4843 try { 4844 token.linkToDeath(newToken, 0); 4845 mForegroundProcesses.put(pid, newToken); 4846 pr.forcingToForeground = token; 4847 changed = true; 4848 } catch (RemoteException e) { 4849 // If the process died while doing this, we will later 4850 // do the cleanup with the process death link. 4851 } 4852 } 4853 } 4854 4855 if (changed) { 4856 updateOomAdjLocked(); 4857 } 4858 } 4859 } 4860 4861 // ========================================================= 4862 // PERMISSIONS 4863 // ========================================================= 4864 4865 static class PermissionController extends IPermissionController.Stub { 4866 ActivityManagerService mActivityManagerService; 4867 PermissionController(ActivityManagerService activityManagerService) { 4868 mActivityManagerService = activityManagerService; 4869 } 4870 4871 public boolean checkPermission(String permission, int pid, int uid) { 4872 return mActivityManagerService.checkPermission(permission, pid, 4873 uid) == PackageManager.PERMISSION_GRANTED; 4874 } 4875 } 4876 4877 /** 4878 * This can be called with or without the global lock held. 4879 */ 4880 int checkComponentPermission(String permission, int pid, int uid, 4881 int owningUid, boolean exported) { 4882 // We might be performing an operation on behalf of an indirect binder 4883 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4884 // client identity accordingly before proceeding. 4885 Identity tlsIdentity = sCallerIdentity.get(); 4886 if (tlsIdentity != null) { 4887 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4888 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4889 uid = tlsIdentity.uid; 4890 pid = tlsIdentity.pid; 4891 } 4892 4893 if (pid == MY_PID) { 4894 return PackageManager.PERMISSION_GRANTED; 4895 } 4896 4897 return ActivityManager.checkComponentPermission(permission, uid, 4898 owningUid, exported); 4899 } 4900 4901 /** 4902 * As the only public entry point for permissions checking, this method 4903 * can enforce the semantic that requesting a check on a null global 4904 * permission is automatically denied. (Internally a null permission 4905 * string is used when calling {@link #checkComponentPermission} in cases 4906 * when only uid-based security is needed.) 4907 * 4908 * This can be called with or without the global lock held. 4909 */ 4910 public int checkPermission(String permission, int pid, int uid) { 4911 if (permission == null) { 4912 return PackageManager.PERMISSION_DENIED; 4913 } 4914 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4915 } 4916 4917 /** 4918 * Binder IPC calls go through the public entry point. 4919 * This can be called with or without the global lock held. 4920 */ 4921 int checkCallingPermission(String permission) { 4922 return checkPermission(permission, 4923 Binder.getCallingPid(), 4924 UserHandle.getAppId(Binder.getCallingUid())); 4925 } 4926 4927 /** 4928 * This can be called with or without the global lock held. 4929 */ 4930 void enforceCallingPermission(String permission, String func) { 4931 if (checkCallingPermission(permission) 4932 == PackageManager.PERMISSION_GRANTED) { 4933 return; 4934 } 4935 4936 String msg = "Permission Denial: " + func + " from pid=" 4937 + Binder.getCallingPid() 4938 + ", uid=" + Binder.getCallingUid() 4939 + " requires " + permission; 4940 Slog.w(TAG, msg); 4941 throw new SecurityException(msg); 4942 } 4943 4944 /** 4945 * Determine if UID is holding permissions required to access {@link Uri} in 4946 * the given {@link ProviderInfo}. Final permission checking is always done 4947 * in {@link ContentProvider}. 4948 */ 4949 private final boolean checkHoldingPermissionsLocked( 4950 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4951 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4952 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4953 4954 if (pi.applicationInfo.uid == uid) { 4955 return true; 4956 } else if (!pi.exported) { 4957 return false; 4958 } 4959 4960 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4961 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4962 try { 4963 // check if target holds top-level <provider> permissions 4964 if (!readMet && pi.readPermission != null 4965 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4966 readMet = true; 4967 } 4968 if (!writeMet && pi.writePermission != null 4969 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4970 writeMet = true; 4971 } 4972 4973 // track if unprotected read/write is allowed; any denied 4974 // <path-permission> below removes this ability 4975 boolean allowDefaultRead = pi.readPermission == null; 4976 boolean allowDefaultWrite = pi.writePermission == null; 4977 4978 // check if target holds any <path-permission> that match uri 4979 final PathPermission[] pps = pi.pathPermissions; 4980 if (pps != null) { 4981 final String path = uri.getPath(); 4982 int i = pps.length; 4983 while (i > 0 && (!readMet || !writeMet)) { 4984 i--; 4985 PathPermission pp = pps[i]; 4986 if (pp.match(path)) { 4987 if (!readMet) { 4988 final String pprperm = pp.getReadPermission(); 4989 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4990 + pprperm + " for " + pp.getPath() 4991 + ": match=" + pp.match(path) 4992 + " check=" + pm.checkUidPermission(pprperm, uid)); 4993 if (pprperm != null) { 4994 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4995 readMet = true; 4996 } else { 4997 allowDefaultRead = false; 4998 } 4999 } 5000 } 5001 if (!writeMet) { 5002 final String ppwperm = pp.getWritePermission(); 5003 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5004 + ppwperm + " for " + pp.getPath() 5005 + ": match=" + pp.match(path) 5006 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5007 if (ppwperm != null) { 5008 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5009 writeMet = true; 5010 } else { 5011 allowDefaultWrite = false; 5012 } 5013 } 5014 } 5015 } 5016 } 5017 } 5018 5019 // grant unprotected <provider> read/write, if not blocked by 5020 // <path-permission> above 5021 if (allowDefaultRead) readMet = true; 5022 if (allowDefaultWrite) writeMet = true; 5023 5024 } catch (RemoteException e) { 5025 return false; 5026 } 5027 5028 return readMet && writeMet; 5029 } 5030 checkUriPermissionLocked(Uri uri, int uid, int modeFlags)5031 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5032 int modeFlags) { 5033 // Root gets to do everything. 5034 if (uid == 0) { 5035 return true; 5036 } 5037 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5038 if (perms == null) return false; 5039 UriPermission perm = perms.get(uri); 5040 if (perm == null) return false; 5041 return (modeFlags&perm.modeFlags) == modeFlags; 5042 } 5043 checkUriPermission(Uri uri, int pid, int uid, int modeFlags)5044 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5045 enforceNotIsolatedCaller("checkUriPermission"); 5046 5047 // Another redirected-binder-call permissions check as in 5048 // {@link checkComponentPermission}. 5049 Identity tlsIdentity = sCallerIdentity.get(); 5050 if (tlsIdentity != null) { 5051 uid = tlsIdentity.uid; 5052 pid = tlsIdentity.pid; 5053 } 5054 5055 // Our own process gets to do everything. 5056 if (pid == MY_PID) { 5057 return PackageManager.PERMISSION_GRANTED; 5058 } 5059 synchronized(this) { 5060 return checkUriPermissionLocked(uri, uid, modeFlags) 5061 ? PackageManager.PERMISSION_GRANTED 5062 : PackageManager.PERMISSION_DENIED; 5063 } 5064 } 5065 5066 /** 5067 * Check if the targetPkg can be granted permission to access uri by 5068 * the callingUid using the given modeFlags. Throws a security exception 5069 * if callingUid is not allowed to do this. Returns the uid of the target 5070 * if the URI permission grant should be performed; returns -1 if it is not 5071 * needed (for example targetPkg already has permission to access the URI). 5072 * If you already know the uid of the target, you can supply it in 5073 * lastTargetUid else set that to -1. 5074 */ checkGrantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, int lastTargetUid)5075 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5076 Uri uri, int modeFlags, int lastTargetUid) { 5077 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5078 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5079 if (modeFlags == 0) { 5080 return -1; 5081 } 5082 5083 if (targetPkg != null) { 5084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5085 "Checking grant " + targetPkg + " permission to " + uri); 5086 } 5087 5088 final IPackageManager pm = AppGlobals.getPackageManager(); 5089 5090 // If this is not a content: uri, we can't do anything with it. 5091 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5092 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5093 "Can't grant URI permission for non-content URI: " + uri); 5094 return -1; 5095 } 5096 5097 String name = uri.getAuthority(); 5098 ProviderInfo pi = null; 5099 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5100 UserHandle.getUserId(callingUid)); 5101 if (cpr != null) { 5102 pi = cpr.info; 5103 } else { 5104 try { 5105 pi = pm.resolveContentProvider(name, 5106 PackageManager.GET_URI_PERMISSION_PATTERNS, 5107 UserHandle.getUserId(callingUid)); 5108 } catch (RemoteException ex) { 5109 } 5110 } 5111 if (pi == null) { 5112 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5113 return -1; 5114 } 5115 5116 int targetUid = lastTargetUid; 5117 if (targetUid < 0 && targetPkg != null) { 5118 try { 5119 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5120 if (targetUid < 0) { 5121 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5122 "Can't grant URI permission no uid for: " + targetPkg); 5123 return -1; 5124 } 5125 } catch (RemoteException ex) { 5126 return -1; 5127 } 5128 } 5129 5130 if (targetUid >= 0) { 5131 // First... does the target actually need this permission? 5132 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5133 // No need to grant the target this permission. 5134 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5135 "Target " + targetPkg + " already has full permission to " + uri); 5136 return -1; 5137 } 5138 } else { 5139 // First... there is no target package, so can anyone access it? 5140 boolean allowed = pi.exported; 5141 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5142 if (pi.readPermission != null) { 5143 allowed = false; 5144 } 5145 } 5146 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5147 if (pi.writePermission != null) { 5148 allowed = false; 5149 } 5150 } 5151 if (allowed) { 5152 return -1; 5153 } 5154 } 5155 5156 // Second... is the provider allowing granting of URI permissions? 5157 if (!pi.grantUriPermissions) { 5158 throw new SecurityException("Provider " + pi.packageName 5159 + "/" + pi.name 5160 + " does not allow granting of Uri permissions (uri " 5161 + uri + ")"); 5162 } 5163 if (pi.uriPermissionPatterns != null) { 5164 final int N = pi.uriPermissionPatterns.length; 5165 boolean allowed = false; 5166 for (int i=0; i<N; i++) { 5167 if (pi.uriPermissionPatterns[i] != null 5168 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5169 allowed = true; 5170 break; 5171 } 5172 } 5173 if (!allowed) { 5174 throw new SecurityException("Provider " + pi.packageName 5175 + "/" + pi.name 5176 + " does not allow granting of permission to path of Uri " 5177 + uri); 5178 } 5179 } 5180 5181 // Third... does the caller itself have permission to access 5182 // this uri? 5183 if (callingUid != Process.myUid()) { 5184 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5185 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5186 throw new SecurityException("Uid " + callingUid 5187 + " does not have permission to uri " + uri); 5188 } 5189 } 5190 } 5191 5192 return targetUid; 5193 } 5194 checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags)5195 public int checkGrantUriPermission(int callingUid, String targetPkg, 5196 Uri uri, int modeFlags) { 5197 enforceNotIsolatedCaller("checkGrantUriPermission"); 5198 synchronized(this) { 5199 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5200 } 5201 } 5202 grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5203 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5204 Uri uri, int modeFlags, UriPermissionOwner owner) { 5205 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5206 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5207 if (modeFlags == 0) { 5208 return; 5209 } 5210 5211 // So here we are: the caller has the assumed permission 5212 // to the uri, and the target doesn't. Let's now give this to 5213 // the target. 5214 5215 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5216 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5217 5218 HashMap<Uri, UriPermission> targetUris 5219 = mGrantedUriPermissions.get(targetUid); 5220 if (targetUris == null) { 5221 targetUris = new HashMap<Uri, UriPermission>(); 5222 mGrantedUriPermissions.put(targetUid, targetUris); 5223 } 5224 5225 UriPermission perm = targetUris.get(uri); 5226 if (perm == null) { 5227 perm = new UriPermission(targetUid, uri); 5228 targetUris.put(uri, perm); 5229 } 5230 5231 perm.modeFlags |= modeFlags; 5232 if (owner == null) { 5233 perm.globalModeFlags |= modeFlags; 5234 } else { 5235 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5236 perm.readOwners.add(owner); 5237 owner.addReadPermission(perm); 5238 } 5239 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5240 perm.writeOwners.add(owner); 5241 owner.addWritePermission(perm); 5242 } 5243 } 5244 } 5245 grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5246 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5247 int modeFlags, UriPermissionOwner owner) { 5248 if (targetPkg == null) { 5249 throw new NullPointerException("targetPkg"); 5250 } 5251 5252 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5253 if (targetUid < 0) { 5254 return; 5255 } 5256 5257 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5258 } 5259 5260 static class NeededUriGrants extends ArrayList<Uri> { 5261 final String targetPkg; 5262 final int targetUid; 5263 final int flags; 5264 NeededUriGrants(String _targetPkg, int _targetUid, int _flags)5265 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5266 targetPkg = _targetPkg; 5267 targetUid = _targetUid; 5268 flags = _flags; 5269 } 5270 } 5271 5272 /** 5273 * Like checkGrantUriPermissionLocked, but takes an Intent. 5274 */ checkGrantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed)5275 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5276 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5277 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5278 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5279 + " clip=" + (intent != null ? intent.getClipData() : null) 5280 + " from " + intent + "; flags=0x" 5281 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5282 5283 if (targetPkg == null) { 5284 throw new NullPointerException("targetPkg"); 5285 } 5286 5287 if (intent == null) { 5288 return null; 5289 } 5290 Uri data = intent.getData(); 5291 ClipData clip = intent.getClipData(); 5292 if (data == null && clip == null) { 5293 return null; 5294 } 5295 if (data != null) { 5296 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5297 mode, needed != null ? needed.targetUid : -1); 5298 if (target > 0) { 5299 if (needed == null) { 5300 needed = new NeededUriGrants(targetPkg, target, mode); 5301 } 5302 needed.add(data); 5303 } 5304 } 5305 if (clip != null) { 5306 for (int i=0; i<clip.getItemCount(); i++) { 5307 Uri uri = clip.getItemAt(i).getUri(); 5308 if (uri != null) { 5309 int target = -1; 5310 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5311 mode, needed != null ? needed.targetUid : -1); 5312 if (target > 0) { 5313 if (needed == null) { 5314 needed = new NeededUriGrants(targetPkg, target, mode); 5315 } 5316 needed.add(uri); 5317 } 5318 } else { 5319 Intent clipIntent = clip.getItemAt(i).getIntent(); 5320 if (clipIntent != null) { 5321 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5322 callingUid, targetPkg, clipIntent, mode, needed); 5323 if (newNeeded != null) { 5324 needed = newNeeded; 5325 } 5326 } 5327 } 5328 } 5329 } 5330 5331 return needed; 5332 } 5333 5334 /** 5335 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5336 */ grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, UriPermissionOwner owner)5337 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5338 UriPermissionOwner owner) { 5339 if (needed != null) { 5340 for (int i=0; i<needed.size(); i++) { 5341 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5342 needed.get(i), needed.flags, owner); 5343 } 5344 } 5345 } 5346 grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, UriPermissionOwner owner)5347 void grantUriPermissionFromIntentLocked(int callingUid, 5348 String targetPkg, Intent intent, UriPermissionOwner owner) { 5349 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5350 intent, intent != null ? intent.getFlags() : 0, null); 5351 if (needed == null) { 5352 return; 5353 } 5354 5355 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5356 } 5357 grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int modeFlags)5358 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5359 Uri uri, int modeFlags) { 5360 enforceNotIsolatedCaller("grantUriPermission"); 5361 synchronized(this) { 5362 final ProcessRecord r = getRecordForAppLocked(caller); 5363 if (r == null) { 5364 throw new SecurityException("Unable to find app for caller " 5365 + caller 5366 + " when granting permission to uri " + uri); 5367 } 5368 if (targetPkg == null) { 5369 throw new IllegalArgumentException("null target"); 5370 } 5371 if (uri == null) { 5372 throw new IllegalArgumentException("null uri"); 5373 } 5374 5375 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5376 null); 5377 } 5378 } 5379 removeUriPermissionIfNeededLocked(UriPermission perm)5380 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5381 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5382 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5383 HashMap<Uri, UriPermission> perms 5384 = mGrantedUriPermissions.get(perm.uid); 5385 if (perms != null) { 5386 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5387 "Removing " + perm.uid + " permission to " + perm.uri); 5388 perms.remove(perm.uri); 5389 if (perms.size() == 0) { 5390 mGrantedUriPermissions.remove(perm.uid); 5391 } 5392 } 5393 } 5394 } 5395 revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags)5396 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5397 int modeFlags) { 5398 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5399 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5400 if (modeFlags == 0) { 5401 return; 5402 } 5403 5404 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5405 "Revoking all granted permissions to " + uri); 5406 5407 final IPackageManager pm = AppGlobals.getPackageManager(); 5408 5409 final String authority = uri.getAuthority(); 5410 ProviderInfo pi = null; 5411 int userId = UserHandle.getUserId(callingUid); 5412 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5413 if (cpr != null) { 5414 pi = cpr.info; 5415 } else { 5416 try { 5417 pi = pm.resolveContentProvider(authority, 5418 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5419 } catch (RemoteException ex) { 5420 } 5421 } 5422 if (pi == null) { 5423 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5424 return; 5425 } 5426 5427 // Does the caller have this permission on the URI? 5428 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5429 // Right now, if you are not the original owner of the permission, 5430 // you are not allowed to revoke it. 5431 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5432 throw new SecurityException("Uid " + callingUid 5433 + " does not have permission to uri " + uri); 5434 //} 5435 } 5436 5437 // Go through all of the permissions and remove any that match. 5438 final List<String> SEGMENTS = uri.getPathSegments(); 5439 if (SEGMENTS != null) { 5440 final int NS = SEGMENTS.size(); 5441 int N = mGrantedUriPermissions.size(); 5442 for (int i=0; i<N; i++) { 5443 HashMap<Uri, UriPermission> perms 5444 = mGrantedUriPermissions.valueAt(i); 5445 Iterator<UriPermission> it = perms.values().iterator(); 5446 toploop: 5447 while (it.hasNext()) { 5448 UriPermission perm = it.next(); 5449 Uri targetUri = perm.uri; 5450 if (!authority.equals(targetUri.getAuthority())) { 5451 continue; 5452 } 5453 List<String> targetSegments = targetUri.getPathSegments(); 5454 if (targetSegments == null) { 5455 continue; 5456 } 5457 if (targetSegments.size() < NS) { 5458 continue; 5459 } 5460 for (int j=0; j<NS; j++) { 5461 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5462 continue toploop; 5463 } 5464 } 5465 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5466 "Revoking " + perm.uid + " permission to " + perm.uri); 5467 perm.clearModes(modeFlags); 5468 if (perm.modeFlags == 0) { 5469 it.remove(); 5470 } 5471 } 5472 if (perms.size() == 0) { 5473 mGrantedUriPermissions.remove( 5474 mGrantedUriPermissions.keyAt(i)); 5475 N--; 5476 i--; 5477 } 5478 } 5479 } 5480 } 5481 revokeUriPermission(IApplicationThread caller, Uri uri, int modeFlags)5482 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5483 int modeFlags) { 5484 enforceNotIsolatedCaller("revokeUriPermission"); 5485 synchronized(this) { 5486 final ProcessRecord r = getRecordForAppLocked(caller); 5487 if (r == null) { 5488 throw new SecurityException("Unable to find app for caller " 5489 + caller 5490 + " when revoking permission to uri " + uri); 5491 } 5492 if (uri == null) { 5493 Slog.w(TAG, "revokeUriPermission: null uri"); 5494 return; 5495 } 5496 5497 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5498 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5499 if (modeFlags == 0) { 5500 return; 5501 } 5502 5503 final IPackageManager pm = AppGlobals.getPackageManager(); 5504 5505 final String authority = uri.getAuthority(); 5506 ProviderInfo pi = null; 5507 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5508 if (cpr != null) { 5509 pi = cpr.info; 5510 } else { 5511 try { 5512 pi = pm.resolveContentProvider(authority, 5513 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5514 } catch (RemoteException ex) { 5515 } 5516 } 5517 if (pi == null) { 5518 Slog.w(TAG, "No content provider found for permission revoke: " 5519 + uri.toSafeString()); 5520 return; 5521 } 5522 5523 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5524 } 5525 } 5526 5527 @Override newUriPermissionOwner(String name)5528 public IBinder newUriPermissionOwner(String name) { 5529 enforceNotIsolatedCaller("newUriPermissionOwner"); 5530 synchronized(this) { 5531 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5532 return owner.getExternalTokenLocked(); 5533 } 5534 } 5535 5536 @Override grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, int modeFlags)5537 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5538 Uri uri, int modeFlags) { 5539 synchronized(this) { 5540 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5541 if (owner == null) { 5542 throw new IllegalArgumentException("Unknown owner: " + token); 5543 } 5544 if (fromUid != Binder.getCallingUid()) { 5545 if (Binder.getCallingUid() != Process.myUid()) { 5546 // Only system code can grant URI permissions on behalf 5547 // of other users. 5548 throw new SecurityException("nice try"); 5549 } 5550 } 5551 if (targetPkg == null) { 5552 throw new IllegalArgumentException("null target"); 5553 } 5554 if (uri == null) { 5555 throw new IllegalArgumentException("null uri"); 5556 } 5557 5558 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5559 } 5560 } 5561 5562 @Override revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode)5563 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5564 synchronized(this) { 5565 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5566 if (owner == null) { 5567 throw new IllegalArgumentException("Unknown owner: " + token); 5568 } 5569 5570 if (uri == null) { 5571 owner.removeUriPermissionsLocked(mode); 5572 } else { 5573 owner.removeUriPermissionLocked(uri, mode); 5574 } 5575 } 5576 } 5577 showWaitingForDebugger(IApplicationThread who, boolean waiting)5578 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5579 synchronized (this) { 5580 ProcessRecord app = 5581 who != null ? getRecordForAppLocked(who) : null; 5582 if (app == null) return; 5583 5584 Message msg = Message.obtain(); 5585 msg.what = WAIT_FOR_DEBUGGER_MSG; 5586 msg.obj = app; 5587 msg.arg1 = waiting ? 1 : 0; 5588 mHandler.sendMessage(msg); 5589 } 5590 } 5591 getMemoryInfo(ActivityManager.MemoryInfo outInfo)5592 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5593 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5594 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5595 outInfo.availMem = Process.getFreeMemory(); 5596 outInfo.totalMem = Process.getTotalMemory(); 5597 outInfo.threshold = homeAppMem; 5598 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5599 outInfo.hiddenAppThreshold = hiddenAppMem; 5600 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5601 ProcessList.SERVICE_ADJ); 5602 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5603 ProcessList.VISIBLE_APP_ADJ); 5604 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5605 ProcessList.FOREGROUND_APP_ADJ); 5606 } 5607 5608 // ========================================================= 5609 // TASK MANAGEMENT 5610 // ========================================================= 5611 5612 public List getTasks(int maxNum, int flags, 5613 IThumbnailReceiver receiver) { 5614 ArrayList list = new ArrayList(); 5615 5616 PendingThumbnailsRecord pending = null; 5617 IApplicationThread topThumbnail = null; 5618 ActivityRecord topRecord = null; 5619 5620 synchronized(this) { 5621 if (localLOGV) Slog.v( 5622 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5623 + ", receiver=" + receiver); 5624 5625 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5626 != PackageManager.PERMISSION_GRANTED) { 5627 if (receiver != null) { 5628 // If the caller wants to wait for pending thumbnails, 5629 // it ain't gonna get them. 5630 try { 5631 receiver.finished(); 5632 } catch (RemoteException ex) { 5633 } 5634 } 5635 String msg = "Permission Denial: getTasks() from pid=" 5636 + Binder.getCallingPid() 5637 + ", uid=" + Binder.getCallingUid() 5638 + " requires " + android.Manifest.permission.GET_TASKS; 5639 Slog.w(TAG, msg); 5640 throw new SecurityException(msg); 5641 } 5642 5643 int pos = mMainStack.mHistory.size()-1; 5644 ActivityRecord next = 5645 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5646 ActivityRecord top = null; 5647 TaskRecord curTask = null; 5648 int numActivities = 0; 5649 int numRunning = 0; 5650 while (pos >= 0 && maxNum > 0) { 5651 final ActivityRecord r = next; 5652 pos--; 5653 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5654 5655 // Initialize state for next task if needed. 5656 if (top == null || 5657 (top.state == ActivityState.INITIALIZING 5658 && top.task == r.task)) { 5659 top = r; 5660 curTask = r.task; 5661 numActivities = numRunning = 0; 5662 } 5663 5664 // Add 'r' into the current task. 5665 numActivities++; 5666 if (r.app != null && r.app.thread != null) { 5667 numRunning++; 5668 } 5669 5670 if (localLOGV) Slog.v( 5671 TAG, r.intent.getComponent().flattenToShortString() 5672 + ": task=" + r.task); 5673 5674 // If the next one is a different task, generate a new 5675 // TaskInfo entry for what we have. 5676 if (next == null || next.task != curTask) { 5677 ActivityManager.RunningTaskInfo ci 5678 = new ActivityManager.RunningTaskInfo(); 5679 ci.id = curTask.taskId; 5680 ci.baseActivity = r.intent.getComponent(); 5681 ci.topActivity = top.intent.getComponent(); 5682 if (top.thumbHolder != null) { 5683 ci.description = top.thumbHolder.lastDescription; 5684 } 5685 ci.numActivities = numActivities; 5686 ci.numRunning = numRunning; 5687 //System.out.println( 5688 // "#" + maxNum + ": " + " descr=" + ci.description); 5689 if (ci.thumbnail == null && receiver != null) { 5690 if (localLOGV) Slog.v( 5691 TAG, "State=" + top.state + "Idle=" + top.idle 5692 + " app=" + top.app 5693 + " thr=" + (top.app != null ? top.app.thread : null)); 5694 if (top.state == ActivityState.RESUMED 5695 || top.state == ActivityState.PAUSING) { 5696 if (top.idle && top.app != null 5697 && top.app.thread != null) { 5698 topRecord = top; 5699 topThumbnail = top.app.thread; 5700 } else { 5701 top.thumbnailNeeded = true; 5702 } 5703 } 5704 if (pending == null) { 5705 pending = new PendingThumbnailsRecord(receiver); 5706 } 5707 pending.pendingRecords.add(top); 5708 } 5709 list.add(ci); 5710 maxNum--; 5711 top = null; 5712 } 5713 } 5714 5715 if (pending != null) { 5716 mPendingThumbnails.add(pending); 5717 } 5718 } 5719 Slog.v(TAG, "We have pending thumbnails: " + pending)5720 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5721 5722 if (topThumbnail != null) { Slog.v(TAG, "Requesting top thumbnail")5723 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5724 try { 5725 topThumbnail.requestThumbnail(topRecord.appToken); 5726 } catch (Exception e) { 5727 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5728 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5729 } 5730 } 5731 5732 if (pending == null && receiver != null) { 5733 // In this case all thumbnails were available and the client 5734 // is being asked to be told when the remaining ones come in... 5735 // which is unusually, since the top-most currently running 5736 // activity should never have a canned thumbnail! Oh well. 5737 try { receiver.finished()5738 receiver.finished(); 5739 } catch (RemoteException ex) { 5740 } 5741 } 5742 5743 return list; 5744 } 5745 getRecentTasks(int maxNum, int flags, int userId)5746 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5747 int flags, int userId) { 5748 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5749 false, true, "getRecentTasks", null); 5750 5751 synchronized (this) { 5752 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5753 "getRecentTasks()"); 5754 final boolean detailed = checkCallingPermission( 5755 android.Manifest.permission.GET_DETAILED_TASKS) 5756 == PackageManager.PERMISSION_GRANTED; 5757 5758 IPackageManager pm = AppGlobals.getPackageManager(); 5759 5760 final int N = mRecentTasks.size(); 5761 ArrayList<ActivityManager.RecentTaskInfo> res 5762 = new ArrayList<ActivityManager.RecentTaskInfo>( 5763 maxNum < N ? maxNum : N); 5764 for (int i=0; i<N && maxNum > 0; i++) { 5765 TaskRecord tr = mRecentTasks.get(i); 5766 // Only add calling user's recent tasks 5767 if (tr.userId != userId) continue; 5768 // Return the entry if desired by the caller. We always return 5769 // the first entry, because callers always expect this to be the 5770 // foreground app. We may filter others if the caller has 5771 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5772 // we should exclude the entry. 5773 5774 if (i == 0 5775 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5776 || (tr.intent == null) 5777 || ((tr.intent.getFlags() 5778 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5779 ActivityManager.RecentTaskInfo rti 5780 = new ActivityManager.RecentTaskInfo(); 5781 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5782 rti.persistentId = tr.taskId; 5783 rti.baseIntent = new Intent( 5784 tr.intent != null ? tr.intent : tr.affinityIntent); 5785 if (!detailed) { 5786 rti.baseIntent.replaceExtras((Bundle)null); 5787 } 5788 rti.origActivity = tr.origActivity; 5789 rti.description = tr.lastDescription; 5790 5791 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5792 // Check whether this activity is currently available. 5793 try { 5794 if (rti.origActivity != null) { 5795 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5796 == null) { 5797 continue; 5798 } 5799 } else if (rti.baseIntent != null) { 5800 if (pm.queryIntentActivities(rti.baseIntent, 5801 null, 0, userId) == null) { 5802 continue; 5803 } 5804 } 5805 } catch (RemoteException e) { 5806 // Will never happen. 5807 } 5808 } 5809 5810 res.add(rti); 5811 maxNum--; 5812 } 5813 } 5814 return res; 5815 } 5816 } 5817 taskForIdLocked(int id)5818 private TaskRecord taskForIdLocked(int id) { 5819 final int N = mRecentTasks.size(); 5820 for (int i=0; i<N; i++) { 5821 TaskRecord tr = mRecentTasks.get(i); 5822 if (tr.taskId == id) { 5823 return tr; 5824 } 5825 } 5826 return null; 5827 } 5828 getTaskThumbnails(int id)5829 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5830 synchronized (this) { 5831 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5832 "getTaskThumbnails()"); 5833 TaskRecord tr = taskForIdLocked(id); 5834 if (tr != null) { 5835 return mMainStack.getTaskThumbnailsLocked(tr); 5836 } 5837 } 5838 return null; 5839 } 5840 getTaskTopThumbnail(int id)5841 public Bitmap getTaskTopThumbnail(int id) { 5842 synchronized (this) { 5843 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5844 "getTaskTopThumbnail()"); 5845 TaskRecord tr = taskForIdLocked(id); 5846 if (tr != null) { 5847 return mMainStack.getTaskTopThumbnailLocked(tr); 5848 } 5849 } 5850 return null; 5851 } 5852 removeSubTask(int taskId, int subTaskIndex)5853 public boolean removeSubTask(int taskId, int subTaskIndex) { 5854 synchronized (this) { 5855 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5856 "removeSubTask()"); 5857 long ident = Binder.clearCallingIdentity(); 5858 try { 5859 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5860 true) != null; 5861 } finally { 5862 Binder.restoreCallingIdentity(ident); 5863 } 5864 } 5865 } 5866 cleanUpRemovedTaskLocked(TaskRecord tr, int flags)5867 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5868 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5869 Intent baseIntent = new Intent( 5870 tr.intent != null ? tr.intent : tr.affinityIntent); 5871 ComponentName component = baseIntent.getComponent(); 5872 if (component == null) { 5873 Slog.w(TAG, "Now component for base intent of task: " + tr); 5874 return; 5875 } 5876 5877 // Find any running services associated with this app. 5878 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5879 5880 if (killProcesses) { 5881 // Find any running processes associated with this app. 5882 final String pkg = component.getPackageName(); 5883 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5884 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5885 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5886 for (int i=0; i<uids.size(); i++) { 5887 ProcessRecord proc = uids.valueAt(i); 5888 if (proc.userId != tr.userId) { 5889 continue; 5890 } 5891 if (!proc.pkgList.contains(pkg)) { 5892 continue; 5893 } 5894 procs.add(proc); 5895 } 5896 } 5897 5898 // Kill the running processes. 5899 for (int i=0; i<procs.size(); i++) { 5900 ProcessRecord pr = procs.get(i); 5901 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5902 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5903 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 5904 pr.processName, pr.setAdj, "remove task"); 5905 pr.killedBackground = true; 5906 Process.killProcessQuiet(pr.pid); 5907 } else { 5908 pr.waitingToKill = "remove task"; 5909 } 5910 } 5911 } 5912 } 5913 removeTask(int taskId, int flags)5914 public boolean removeTask(int taskId, int flags) { 5915 synchronized (this) { 5916 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5917 "removeTask()"); 5918 long ident = Binder.clearCallingIdentity(); 5919 try { 5920 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5921 false); 5922 if (r != null) { 5923 mRecentTasks.remove(r.task); 5924 cleanUpRemovedTaskLocked(r.task, flags); 5925 return true; 5926 } else { 5927 TaskRecord tr = null; 5928 int i=0; 5929 while (i < mRecentTasks.size()) { 5930 TaskRecord t = mRecentTasks.get(i); 5931 if (t.taskId == taskId) { 5932 tr = t; 5933 break; 5934 } 5935 i++; 5936 } 5937 if (tr != null) { 5938 if (tr.numActivities <= 0) { 5939 // Caller is just removing a recent task that is 5940 // not actively running. That is easy! 5941 mRecentTasks.remove(i); 5942 cleanUpRemovedTaskLocked(tr, flags); 5943 return true; 5944 } else { 5945 Slog.w(TAG, "removeTask: task " + taskId 5946 + " does not have activities to remove, " 5947 + " but numActivities=" + tr.numActivities 5948 + ": " + tr); 5949 } 5950 } 5951 } 5952 } finally { 5953 Binder.restoreCallingIdentity(ident); 5954 } 5955 } 5956 return false; 5957 } 5958 findAffinityTaskTopLocked(int startIndex, String affinity)5959 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5960 int j; 5961 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5962 TaskRecord jt = startTask; 5963 5964 // First look backwards 5965 for (j=startIndex-1; j>=0; j--) { 5966 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5967 if (r.task != jt) { 5968 jt = r.task; 5969 if (affinity.equals(jt.affinity)) { 5970 return j; 5971 } 5972 } 5973 } 5974 5975 // Now look forwards 5976 final int N = mMainStack.mHistory.size(); 5977 jt = startTask; 5978 for (j=startIndex+1; j<N; j++) { 5979 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5980 if (r.task != jt) { 5981 if (affinity.equals(jt.affinity)) { 5982 return j; 5983 } 5984 jt = r.task; 5985 } 5986 } 5987 5988 // Might it be at the top? 5989 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5990 return N-1; 5991 } 5992 5993 return -1; 5994 } 5995 5996 /** 5997 * TODO: Add mController hook 5998 */ moveTaskToFront(int task, int flags, Bundle options)5999 public void moveTaskToFront(int task, int flags, Bundle options) { 6000 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6001 "moveTaskToFront()"); 6002 6003 synchronized(this) { 6004 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6005 Binder.getCallingUid(), "Task to front")) { 6006 ActivityOptions.abort(options); 6007 return; 6008 } 6009 final long origId = Binder.clearCallingIdentity(); 6010 try { 6011 TaskRecord tr = taskForIdLocked(task); 6012 if (tr != null) { 6013 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6014 mMainStack.mUserLeaving = true; 6015 } 6016 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6017 // Caller wants the home activity moved with it. To accomplish this, 6018 // we'll just move the home task to the top first. 6019 mMainStack.moveHomeToFrontLocked(); 6020 } 6021 mMainStack.moveTaskToFrontLocked(tr, null, options); 6022 return; 6023 } 6024 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6025 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6026 if (hr.task.taskId == task) { 6027 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6028 mMainStack.mUserLeaving = true; 6029 } 6030 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6031 // Caller wants the home activity moved with it. To accomplish this, 6032 // we'll just move the home task to the top first. 6033 mMainStack.moveHomeToFrontLocked(); 6034 } 6035 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6036 return; 6037 } 6038 } 6039 } finally { 6040 Binder.restoreCallingIdentity(origId); 6041 } 6042 ActivityOptions.abort(options); 6043 } 6044 } 6045 moveTaskToBack(int task)6046 public void moveTaskToBack(int task) { 6047 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6048 "moveTaskToBack()"); 6049 6050 synchronized(this) { 6051 if (mMainStack.mResumedActivity != null 6052 && mMainStack.mResumedActivity.task.taskId == task) { 6053 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6054 Binder.getCallingUid(), "Task to back")) { 6055 return; 6056 } 6057 } 6058 final long origId = Binder.clearCallingIdentity(); 6059 mMainStack.moveTaskToBackLocked(task, null); 6060 Binder.restoreCallingIdentity(origId); 6061 } 6062 } 6063 6064 /** 6065 * Moves an activity, and all of the other activities within the same task, to the bottom 6066 * of the history stack. The activity's order within the task is unchanged. 6067 * 6068 * @param token A reference to the activity we wish to move 6069 * @param nonRoot If false then this only works if the activity is the root 6070 * of a task; if true it will work for any activity in a task. 6071 * @return Returns true if the move completed, false if not. 6072 */ moveActivityTaskToBack(IBinder token, boolean nonRoot)6073 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6074 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6075 synchronized(this) { 6076 final long origId = Binder.clearCallingIdentity(); 6077 int taskId = getTaskForActivityLocked(token, !nonRoot); 6078 if (taskId >= 0) { 6079 return mMainStack.moveTaskToBackLocked(taskId, null); 6080 } 6081 Binder.restoreCallingIdentity(origId); 6082 } 6083 return false; 6084 } 6085 moveTaskBackwards(int task)6086 public void moveTaskBackwards(int task) { 6087 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6088 "moveTaskBackwards()"); 6089 6090 synchronized(this) { 6091 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6092 Binder.getCallingUid(), "Task backwards")) { 6093 return; 6094 } 6095 final long origId = Binder.clearCallingIdentity(); 6096 moveTaskBackwardsLocked(task); 6097 Binder.restoreCallingIdentity(origId); 6098 } 6099 } 6100 moveTaskBackwardsLocked(int task)6101 private final void moveTaskBackwardsLocked(int task) { 6102 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6103 } 6104 getTaskForActivity(IBinder token, boolean onlyRoot)6105 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6106 synchronized(this) { 6107 return getTaskForActivityLocked(token, onlyRoot); 6108 } 6109 } 6110 getTaskForActivityLocked(IBinder token, boolean onlyRoot)6111 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6112 final int N = mMainStack.mHistory.size(); 6113 TaskRecord lastTask = null; 6114 for (int i=0; i<N; i++) { 6115 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6116 if (r.appToken == token) { 6117 if (!onlyRoot || lastTask != r.task) { 6118 return r.task.taskId; 6119 } 6120 return -1; 6121 } 6122 lastTask = r.task; 6123 } 6124 6125 return -1; 6126 } 6127 6128 // ========================================================= 6129 // THUMBNAILS 6130 // ========================================================= 6131 reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description)6132 public void reportThumbnail(IBinder token, 6133 Bitmap thumbnail, CharSequence description) { 6134 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6135 final long origId = Binder.clearCallingIdentity(); 6136 sendPendingThumbnail(null, token, thumbnail, description, true); 6137 Binder.restoreCallingIdentity(origId); 6138 } 6139 sendPendingThumbnail(ActivityRecord r, IBinder token, Bitmap thumbnail, CharSequence description, boolean always)6140 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6141 Bitmap thumbnail, CharSequence description, boolean always) { 6142 TaskRecord task = null; 6143 ArrayList receivers = null; 6144 6145 //System.out.println("Send pending thumbnail: " + r); 6146 6147 synchronized(this) { 6148 if (r == null) { 6149 r = mMainStack.isInStackLocked(token); 6150 if (r == null) { 6151 return; 6152 } 6153 } 6154 if (thumbnail == null && r.thumbHolder != null) { 6155 thumbnail = r.thumbHolder.lastThumbnail; 6156 description = r.thumbHolder.lastDescription; 6157 } 6158 if (thumbnail == null && !always) { 6159 // If there is no thumbnail, and this entry is not actually 6160 // going away, then abort for now and pick up the next 6161 // thumbnail we get. 6162 return; 6163 } 6164 task = r.task; 6165 6166 int N = mPendingThumbnails.size(); 6167 int i=0; 6168 while (i<N) { 6169 PendingThumbnailsRecord pr = 6170 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6171 //System.out.println("Looking in " + pr.pendingRecords); 6172 if (pr.pendingRecords.remove(r)) { 6173 if (receivers == null) { 6174 receivers = new ArrayList(); 6175 } 6176 receivers.add(pr); 6177 if (pr.pendingRecords.size() == 0) { 6178 pr.finished = true; 6179 mPendingThumbnails.remove(i); 6180 N--; 6181 continue; 6182 } 6183 } 6184 i++; 6185 } 6186 } 6187 6188 if (receivers != null) { 6189 final int N = receivers.size(); 6190 for (int i=0; i<N; i++) { 6191 try { 6192 PendingThumbnailsRecord pr = 6193 (PendingThumbnailsRecord)receivers.get(i); 6194 pr.receiver.newThumbnail( 6195 task != null ? task.taskId : -1, thumbnail, description); 6196 if (pr.finished) { 6197 pr.receiver.finished(); 6198 } 6199 } catch (Exception e) { 6200 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6201 } 6202 } 6203 } 6204 } 6205 6206 // ========================================================= 6207 // CONTENT PROVIDERS 6208 // ========================================================= 6209 generateApplicationProvidersLocked(ProcessRecord app)6210 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6211 List<ProviderInfo> providers = null; 6212 try { 6213 providers = AppGlobals.getPackageManager(). 6214 queryContentProviders(app.processName, app.uid, 6215 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6216 } catch (RemoteException ex) { 6217 } 6218 if (DEBUG_MU) 6219 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6220 int userId = app.userId; 6221 if (providers != null) { 6222 int N = providers.size(); 6223 for (int i=0; i<N; i++) { 6224 ProviderInfo cpi = 6225 (ProviderInfo)providers.get(i); 6226 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6227 cpi.name, cpi.flags); 6228 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6229 // This is a singleton provider, but a user besides the 6230 // default user is asking to initialize a process it runs 6231 // in... well, no, it doesn't actually run in this process, 6232 // it runs in the process of the default user. Get rid of it. 6233 providers.remove(i); 6234 N--; 6235 continue; 6236 } 6237 6238 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6239 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6240 if (cpr == null) { 6241 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6242 mProviderMap.putProviderByClass(comp, cpr); 6243 } 6244 if (DEBUG_MU) 6245 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6246 app.pubProviders.put(cpi.name, cpr); 6247 app.addPackage(cpi.applicationInfo.packageName); 6248 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6249 } 6250 } 6251 return providers; 6252 } 6253 6254 /** 6255 * Check if {@link ProcessRecord} has a possible chance at accessing the 6256 * given {@link ProviderInfo}. Final permission checking is always done 6257 * in {@link ContentProvider}. 6258 */ checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r)6259 private final String checkContentProviderPermissionLocked( 6260 ProviderInfo cpi, ProcessRecord r) { 6261 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6262 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6263 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6264 cpi.applicationInfo.uid, cpi.exported) 6265 == PackageManager.PERMISSION_GRANTED) { 6266 return null; 6267 } 6268 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6269 cpi.applicationInfo.uid, cpi.exported) 6270 == PackageManager.PERMISSION_GRANTED) { 6271 return null; 6272 } 6273 6274 PathPermission[] pps = cpi.pathPermissions; 6275 if (pps != null) { 6276 int i = pps.length; 6277 while (i > 0) { 6278 i--; 6279 PathPermission pp = pps[i]; 6280 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6281 cpi.applicationInfo.uid, cpi.exported) 6282 == PackageManager.PERMISSION_GRANTED) { 6283 return null; 6284 } 6285 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6286 cpi.applicationInfo.uid, cpi.exported) 6287 == PackageManager.PERMISSION_GRANTED) { 6288 return null; 6289 } 6290 } 6291 } 6292 6293 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6294 if (perms != null) { 6295 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6296 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6297 return null; 6298 } 6299 } 6300 } 6301 6302 String msg; 6303 if (!cpi.exported) { 6304 msg = "Permission Denial: opening provider " + cpi.name 6305 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6306 + ", uid=" + callingUid + ") that is not exported from uid " 6307 + cpi.applicationInfo.uid; 6308 } else { 6309 msg = "Permission Denial: opening provider " + cpi.name 6310 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6311 + ", uid=" + callingUid + ") requires " 6312 + cpi.readPermission + " or " + cpi.writePermission; 6313 } 6314 Slog.w(TAG, msg); 6315 return msg; 6316 } 6317 incProviderCountLocked(ProcessRecord r, final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6318 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6319 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6320 if (r != null) { 6321 for (int i=0; i<r.conProviders.size(); i++) { 6322 ContentProviderConnection conn = r.conProviders.get(i); 6323 if (conn.provider == cpr) { 6324 if (DEBUG_PROVIDER) Slog.v(TAG, 6325 "Adding provider requested by " 6326 + r.processName + " from process " 6327 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6328 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6329 if (stable) { 6330 conn.stableCount++; 6331 conn.numStableIncs++; 6332 } else { 6333 conn.unstableCount++; 6334 conn.numUnstableIncs++; 6335 } 6336 return conn; 6337 } 6338 } 6339 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6340 if (stable) { 6341 conn.stableCount = 1; 6342 conn.numStableIncs = 1; 6343 } else { 6344 conn.unstableCount = 1; 6345 conn.numUnstableIncs = 1; 6346 } 6347 cpr.connections.add(conn); 6348 r.conProviders.add(conn); 6349 return conn; 6350 } 6351 cpr.addExternalProcessHandleLocked(externalProcessToken); 6352 return null; 6353 } 6354 decProviderCountLocked(ContentProviderConnection conn, ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6355 boolean decProviderCountLocked(ContentProviderConnection conn, 6356 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6357 if (conn != null) { 6358 cpr = conn.provider; 6359 if (DEBUG_PROVIDER) Slog.v(TAG, 6360 "Removing provider requested by " 6361 + conn.client.processName + " from process " 6362 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6363 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6364 if (stable) { 6365 conn.stableCount--; 6366 } else { 6367 conn.unstableCount--; 6368 } 6369 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6370 cpr.connections.remove(conn); 6371 conn.client.conProviders.remove(conn); 6372 return true; 6373 } 6374 return false; 6375 } 6376 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6377 return false; 6378 } 6379 getContentProviderImpl(IApplicationThread caller, String name, IBinder token, boolean stable, int userId)6380 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6381 String name, IBinder token, boolean stable, int userId) { 6382 ContentProviderRecord cpr; 6383 ContentProviderConnection conn = null; 6384 ProviderInfo cpi = null; 6385 6386 synchronized(this) { 6387 ProcessRecord r = null; 6388 if (caller != null) { 6389 r = getRecordForAppLocked(caller); 6390 if (r == null) { 6391 throw new SecurityException( 6392 "Unable to find app for caller " + caller 6393 + " (pid=" + Binder.getCallingPid() 6394 + ") when getting content provider " + name); 6395 } 6396 } 6397 6398 // First check if this content provider has been published... 6399 cpr = mProviderMap.getProviderByName(name, userId); 6400 boolean providerRunning = cpr != null; 6401 if (providerRunning) { 6402 cpi = cpr.info; 6403 String msg; 6404 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6405 throw new SecurityException(msg); 6406 } 6407 6408 if (r != null && cpr.canRunHere(r)) { 6409 // This provider has been published or is in the process 6410 // of being published... but it is also allowed to run 6411 // in the caller's process, so don't make a connection 6412 // and just let the caller instantiate its own instance. 6413 ContentProviderHolder holder = cpr.newHolder(null); 6414 // don't give caller the provider object, it needs 6415 // to make its own. 6416 holder.provider = null; 6417 return holder; 6418 } 6419 6420 final long origId = Binder.clearCallingIdentity(); 6421 6422 // In this case the provider instance already exists, so we can 6423 // return it right away. 6424 conn = incProviderCountLocked(r, cpr, token, stable); 6425 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6426 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6427 // If this is a perceptible app accessing the provider, 6428 // make sure to count it as being accessed and thus 6429 // back up on the LRU list. This is good because 6430 // content providers are often expensive to start. 6431 updateLruProcessLocked(cpr.proc, false); 6432 } 6433 } 6434 6435 if (cpr.proc != null) { 6436 if (false) { 6437 if (cpr.name.flattenToShortString().equals( 6438 "com.android.providers.calendar/.CalendarProvider2")) { 6439 Slog.v(TAG, "****************** KILLING " 6440 + cpr.name.flattenToShortString()); 6441 Process.killProcess(cpr.proc.pid); 6442 } 6443 } 6444 boolean success = updateOomAdjLocked(cpr.proc); 6445 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6446 // NOTE: there is still a race here where a signal could be 6447 // pending on the process even though we managed to update its 6448 // adj level. Not sure what to do about this, but at least 6449 // the race is now smaller. 6450 if (!success) { 6451 // Uh oh... it looks like the provider's process 6452 // has been killed on us. We need to wait for a new 6453 // process to be started, and make sure its death 6454 // doesn't kill our process. 6455 Slog.i(TAG, 6456 "Existing provider " + cpr.name.flattenToShortString() 6457 + " is crashing; detaching " + r); 6458 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6459 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6460 if (!lastRef) { 6461 // This wasn't the last ref our process had on 6462 // the provider... we have now been killed, bail. 6463 return null; 6464 } 6465 providerRunning = false; 6466 conn = null; 6467 } 6468 } 6469 6470 Binder.restoreCallingIdentity(origId); 6471 } 6472 6473 boolean singleton; 6474 if (!providerRunning) { 6475 try { 6476 cpi = AppGlobals.getPackageManager(). 6477 resolveContentProvider(name, 6478 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6479 } catch (RemoteException ex) { 6480 } 6481 if (cpi == null) { 6482 return null; 6483 } 6484 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6485 cpi.name, cpi.flags); 6486 if (singleton) { 6487 userId = 0; 6488 } 6489 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6490 6491 String msg; 6492 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6493 throw new SecurityException(msg); 6494 } 6495 6496 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6497 && !cpi.processName.equals("system")) { 6498 // If this content provider does not run in the system 6499 // process, and the system is not yet ready to run other 6500 // processes, then fail fast instead of hanging. 6501 throw new IllegalArgumentException( 6502 "Attempt to launch content provider before system ready"); 6503 } 6504 6505 // Make sure that the user who owns this provider is started. If not, 6506 // we don't want to allow it to run. 6507 if (mStartedUsers.get(userId) == null) { 6508 Slog.w(TAG, "Unable to launch app " 6509 + cpi.applicationInfo.packageName + "/" 6510 + cpi.applicationInfo.uid + " for provider " 6511 + name + ": user " + userId + " is stopped"); 6512 return null; 6513 } 6514 6515 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6516 cpr = mProviderMap.getProviderByClass(comp, userId); 6517 final boolean firstClass = cpr == null; 6518 if (firstClass) { 6519 try { 6520 ApplicationInfo ai = 6521 AppGlobals.getPackageManager(). 6522 getApplicationInfo( 6523 cpi.applicationInfo.packageName, 6524 STOCK_PM_FLAGS, userId); 6525 if (ai == null) { 6526 Slog.w(TAG, "No package info for content provider " 6527 + cpi.name); 6528 return null; 6529 } 6530 ai = getAppInfoForUser(ai, userId); 6531 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6532 } catch (RemoteException ex) { 6533 // pm is in same process, this will never happen. 6534 } 6535 } 6536 6537 if (r != null && cpr.canRunHere(r)) { 6538 // If this is a multiprocess provider, then just return its 6539 // info and allow the caller to instantiate it. Only do 6540 // this if the provider is the same user as the caller's 6541 // process, or can run as root (so can be in any process). 6542 return cpr.newHolder(null); 6543 } 6544 6545 if (DEBUG_PROVIDER) { 6546 RuntimeException e = new RuntimeException("here"); 6547 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6548 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6549 } 6550 6551 // This is single process, and our app is now connecting to it. 6552 // See if we are already in the process of launching this 6553 // provider. 6554 final int N = mLaunchingProviders.size(); 6555 int i; 6556 for (i=0; i<N; i++) { 6557 if (mLaunchingProviders.get(i) == cpr) { 6558 break; 6559 } 6560 } 6561 6562 // If the provider is not already being launched, then get it 6563 // started. 6564 if (i >= N) { 6565 final long origId = Binder.clearCallingIdentity(); 6566 6567 try { 6568 // Content provider is now in use, its package can't be stopped. 6569 try { 6570 AppGlobals.getPackageManager().setPackageStoppedState( 6571 cpr.appInfo.packageName, false, userId); 6572 } catch (RemoteException e) { 6573 } catch (IllegalArgumentException e) { 6574 Slog.w(TAG, "Failed trying to unstop package " 6575 + cpr.appInfo.packageName + ": " + e); 6576 } 6577 6578 ProcessRecord proc = startProcessLocked(cpi.processName, 6579 cpr.appInfo, false, 0, "content provider", 6580 new ComponentName(cpi.applicationInfo.packageName, 6581 cpi.name), false, false); 6582 if (proc == null) { 6583 Slog.w(TAG, "Unable to launch app " 6584 + cpi.applicationInfo.packageName + "/" 6585 + cpi.applicationInfo.uid + " for provider " 6586 + name + ": process is bad"); 6587 return null; 6588 } 6589 cpr.launchingApp = proc; 6590 mLaunchingProviders.add(cpr); 6591 } finally { 6592 Binder.restoreCallingIdentity(origId); 6593 } 6594 } 6595 6596 // Make sure the provider is published (the same provider class 6597 // may be published under multiple names). 6598 if (firstClass) { 6599 mProviderMap.putProviderByClass(comp, cpr); 6600 } 6601 6602 mProviderMap.putProviderByName(name, cpr); 6603 conn = incProviderCountLocked(r, cpr, token, stable); 6604 if (conn != null) { 6605 conn.waiting = true; 6606 } 6607 } 6608 } 6609 6610 // Wait for the provider to be published... 6611 synchronized (cpr) { 6612 while (cpr.provider == null) { 6613 if (cpr.launchingApp == null) { 6614 Slog.w(TAG, "Unable to launch app " 6615 + cpi.applicationInfo.packageName + "/" 6616 + cpi.applicationInfo.uid + " for provider " 6617 + name + ": launching app became null"); 6618 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6619 UserHandle.getUserId(cpi.applicationInfo.uid), 6620 cpi.applicationInfo.packageName, 6621 cpi.applicationInfo.uid, name); 6622 return null; 6623 } 6624 try { 6625 if (DEBUG_MU) { 6626 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6627 + cpr.launchingApp); 6628 } 6629 if (conn != null) { 6630 conn.waiting = true; 6631 } 6632 cpr.wait(); 6633 } catch (InterruptedException ex) { 6634 } finally { 6635 if (conn != null) { 6636 conn.waiting = false; 6637 } 6638 } 6639 } 6640 } 6641 return cpr != null ? cpr.newHolder(conn) : null; 6642 } 6643 getContentProvider( IApplicationThread caller, String name, int userId, boolean stable)6644 public final ContentProviderHolder getContentProvider( 6645 IApplicationThread caller, String name, int userId, boolean stable) { 6646 enforceNotIsolatedCaller("getContentProvider"); 6647 if (caller == null) { 6648 String msg = "null IApplicationThread when getting content provider " 6649 + name; 6650 Slog.w(TAG, msg); 6651 throw new SecurityException(msg); 6652 } 6653 6654 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6655 false, true, "getContentProvider", null); 6656 return getContentProviderImpl(caller, name, null, stable, userId); 6657 } 6658 getContentProviderExternal( String name, int userId, IBinder token)6659 public ContentProviderHolder getContentProviderExternal( 6660 String name, int userId, IBinder token) { 6661 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6662 "Do not have permission in call getContentProviderExternal()"); 6663 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6664 false, true, "getContentProvider", null); 6665 return getContentProviderExternalUnchecked(name, token, userId); 6666 } 6667 getContentProviderExternalUnchecked(String name, IBinder token, int userId)6668 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6669 IBinder token, int userId) { 6670 return getContentProviderImpl(null, name, token, true, userId); 6671 } 6672 6673 /** 6674 * Drop a content provider from a ProcessRecord's bookkeeping 6675 * @param cpr 6676 */ removeContentProvider(IBinder connection, boolean stable)6677 public void removeContentProvider(IBinder connection, boolean stable) { 6678 enforceNotIsolatedCaller("removeContentProvider"); 6679 synchronized (this) { 6680 ContentProviderConnection conn; 6681 try { 6682 conn = (ContentProviderConnection)connection; 6683 } catch (ClassCastException e) { 6684 String msg ="removeContentProvider: " + connection 6685 + " not a ContentProviderConnection"; 6686 Slog.w(TAG, msg); 6687 throw new IllegalArgumentException(msg); 6688 } 6689 if (conn == null) { 6690 throw new NullPointerException("connection is null"); 6691 } 6692 if (decProviderCountLocked(conn, null, null, stable)) { 6693 updateOomAdjLocked(); 6694 } 6695 } 6696 } 6697 removeContentProviderExternal(String name, IBinder token)6698 public void removeContentProviderExternal(String name, IBinder token) { 6699 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6700 "Do not have permission in call removeContentProviderExternal()"); 6701 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6702 } 6703 removeContentProviderExternalUnchecked(String name, IBinder token, int userId)6704 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6705 synchronized (this) { 6706 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6707 if(cpr == null) { 6708 //remove from mProvidersByClass 6709 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6710 return; 6711 } 6712 6713 //update content provider record entry info 6714 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6715 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6716 if (localCpr.hasExternalProcessHandles()) { 6717 if (localCpr.removeExternalProcessHandleLocked(token)) { 6718 updateOomAdjLocked(); 6719 } else { 6720 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6721 + " with no external reference for token: " 6722 + token + "."); 6723 } 6724 } else { 6725 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6726 + " with no external references."); 6727 } 6728 } 6729 } 6730 publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)6731 public final void publishContentProviders(IApplicationThread caller, 6732 List<ContentProviderHolder> providers) { 6733 if (providers == null) { 6734 return; 6735 } 6736 6737 enforceNotIsolatedCaller("publishContentProviders"); 6738 synchronized (this) { 6739 final ProcessRecord r = getRecordForAppLocked(caller); 6740 if (DEBUG_MU) 6741 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6742 if (r == null) { 6743 throw new SecurityException( 6744 "Unable to find app for caller " + caller 6745 + " (pid=" + Binder.getCallingPid() 6746 + ") when publishing content providers"); 6747 } 6748 6749 final long origId = Binder.clearCallingIdentity(); 6750 6751 final int N = providers.size(); 6752 for (int i=0; i<N; i++) { 6753 ContentProviderHolder src = providers.get(i); 6754 if (src == null || src.info == null || src.provider == null) { 6755 continue; 6756 } 6757 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6758 if (DEBUG_MU) 6759 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6760 if (dst != null) { 6761 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6762 mProviderMap.putProviderByClass(comp, dst); 6763 String names[] = dst.info.authority.split(";"); 6764 for (int j = 0; j < names.length; j++) { 6765 mProviderMap.putProviderByName(names[j], dst); 6766 } 6767 6768 int NL = mLaunchingProviders.size(); 6769 int j; 6770 for (j=0; j<NL; j++) { 6771 if (mLaunchingProviders.get(j) == dst) { 6772 mLaunchingProviders.remove(j); 6773 j--; 6774 NL--; 6775 } 6776 } 6777 synchronized (dst) { 6778 dst.provider = src.provider; 6779 dst.proc = r; 6780 dst.notifyAll(); 6781 } 6782 updateOomAdjLocked(r); 6783 } 6784 } 6785 6786 Binder.restoreCallingIdentity(origId); 6787 } 6788 } 6789 refContentProvider(IBinder connection, int stable, int unstable)6790 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6791 ContentProviderConnection conn; 6792 try { 6793 conn = (ContentProviderConnection)connection; 6794 } catch (ClassCastException e) { 6795 String msg ="refContentProvider: " + connection 6796 + " not a ContentProviderConnection"; 6797 Slog.w(TAG, msg); 6798 throw new IllegalArgumentException(msg); 6799 } 6800 if (conn == null) { 6801 throw new NullPointerException("connection is null"); 6802 } 6803 6804 synchronized (this) { 6805 if (stable > 0) { 6806 conn.numStableIncs += stable; 6807 } 6808 stable = conn.stableCount + stable; 6809 if (stable < 0) { 6810 throw new IllegalStateException("stableCount < 0: " + stable); 6811 } 6812 6813 if (unstable > 0) { 6814 conn.numUnstableIncs += unstable; 6815 } 6816 unstable = conn.unstableCount + unstable; 6817 if (unstable < 0) { 6818 throw new IllegalStateException("unstableCount < 0: " + unstable); 6819 } 6820 6821 if ((stable+unstable) <= 0) { 6822 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6823 + stable + " unstable=" + unstable); 6824 } 6825 conn.stableCount = stable; 6826 conn.unstableCount = unstable; 6827 return !conn.dead; 6828 } 6829 } 6830 unstableProviderDied(IBinder connection)6831 public void unstableProviderDied(IBinder connection) { 6832 ContentProviderConnection conn; 6833 try { 6834 conn = (ContentProviderConnection)connection; 6835 } catch (ClassCastException e) { 6836 String msg ="refContentProvider: " + connection 6837 + " not a ContentProviderConnection"; 6838 Slog.w(TAG, msg); 6839 throw new IllegalArgumentException(msg); 6840 } 6841 if (conn == null) { 6842 throw new NullPointerException("connection is null"); 6843 } 6844 6845 // Safely retrieve the content provider associated with the connection. 6846 IContentProvider provider; 6847 synchronized (this) { 6848 provider = conn.provider.provider; 6849 } 6850 6851 if (provider == null) { 6852 // Um, yeah, we're way ahead of you. 6853 return; 6854 } 6855 6856 // Make sure the caller is being honest with us. 6857 if (provider.asBinder().pingBinder()) { 6858 // Er, no, still looks good to us. 6859 synchronized (this) { 6860 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6861 + " says " + conn + " died, but we don't agree"); 6862 return; 6863 } 6864 } 6865 6866 // Well look at that! It's dead! 6867 synchronized (this) { 6868 if (conn.provider.provider != provider) { 6869 // But something changed... good enough. 6870 return; 6871 } 6872 6873 ProcessRecord proc = conn.provider.proc; 6874 if (proc == null || proc.thread == null) { 6875 // Seems like the process is already cleaned up. 6876 return; 6877 } 6878 6879 // As far as we're concerned, this is just like receiving a 6880 // death notification... just a bit prematurely. 6881 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6882 + ") early provider death"); 6883 final long ident = Binder.clearCallingIdentity(); 6884 try { 6885 appDiedLocked(proc, proc.pid, proc.thread); 6886 } finally { 6887 Binder.restoreCallingIdentity(ident); 6888 } 6889 } 6890 } 6891 installSystemProviders()6892 public static final void installSystemProviders() { 6893 List<ProviderInfo> providers; 6894 synchronized (mSelf) { 6895 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6896 providers = mSelf.generateApplicationProvidersLocked(app); 6897 if (providers != null) { 6898 for (int i=providers.size()-1; i>=0; i--) { 6899 ProviderInfo pi = (ProviderInfo)providers.get(i); 6900 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6901 Slog.w(TAG, "Not installing system proc provider " + pi.name 6902 + ": not system .apk"); 6903 providers.remove(i); 6904 } 6905 } 6906 } 6907 } 6908 if (providers != null) { 6909 mSystemThread.installSystemProviders(providers); 6910 } 6911 6912 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6913 6914 mSelf.mUsageStatsService.monitorPackages(); 6915 } 6916 6917 /** 6918 * Allows app to retrieve the MIME type of a URI without having permission 6919 * to access its content provider. 6920 * 6921 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6922 * 6923 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6924 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6925 */ getProviderMimeType(Uri uri, int userId)6926 public String getProviderMimeType(Uri uri, int userId) { 6927 enforceNotIsolatedCaller("getProviderMimeType"); 6928 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6929 userId, false, true, "getProviderMimeType", null); 6930 final String name = uri.getAuthority(); 6931 final long ident = Binder.clearCallingIdentity(); 6932 ContentProviderHolder holder = null; 6933 6934 try { 6935 holder = getContentProviderExternalUnchecked(name, null, userId); 6936 if (holder != null) { 6937 return holder.provider.getType(uri); 6938 } 6939 } catch (RemoteException e) { 6940 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6941 return null; 6942 } finally { 6943 if (holder != null) { 6944 removeContentProviderExternalUnchecked(name, null, userId); 6945 } 6946 Binder.restoreCallingIdentity(ident); 6947 } 6948 6949 return null; 6950 } 6951 6952 // ========================================================= 6953 // GLOBAL MANAGEMENT 6954 // ========================================================= 6955 newProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess, boolean isolated)6956 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6957 ApplicationInfo info, String customProcess, boolean isolated) { 6958 String proc = customProcess != null ? customProcess : info.processName; 6959 BatteryStatsImpl.Uid.Proc ps = null; 6960 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6961 int uid = info.uid; 6962 if (isolated) { 6963 int userId = UserHandle.getUserId(uid); 6964 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6965 uid = 0; 6966 while (true) { 6967 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6968 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6969 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6970 } 6971 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6972 mNextIsolatedProcessUid++; 6973 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6974 // No process for this uid, use it. 6975 break; 6976 } 6977 stepsLeft--; 6978 if (stepsLeft <= 0) { 6979 return null; 6980 } 6981 } 6982 } 6983 synchronized (stats) { 6984 ps = stats.getProcessStatsLocked(info.uid, proc); 6985 } 6986 return new ProcessRecord(ps, thread, info, proc, uid); 6987 } 6988 addAppLocked(ApplicationInfo info, boolean isolated)6989 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6990 ProcessRecord app; 6991 if (!isolated) { 6992 app = getProcessRecordLocked(info.processName, info.uid); 6993 } else { 6994 app = null; 6995 } 6996 6997 if (app == null) { 6998 app = newProcessRecordLocked(null, info, null, isolated); 6999 mProcessNames.put(info.processName, app.uid, app); 7000 if (isolated) { 7001 mIsolatedProcesses.put(app.uid, app); 7002 } 7003 updateLruProcessLocked(app, true); 7004 } 7005 7006 // This package really, really can not be stopped. 7007 try { 7008 AppGlobals.getPackageManager().setPackageStoppedState( 7009 info.packageName, false, UserHandle.getUserId(app.uid)); 7010 } catch (RemoteException e) { 7011 } catch (IllegalArgumentException e) { 7012 Slog.w(TAG, "Failed trying to unstop package " 7013 + info.packageName + ": " + e); 7014 } 7015 7016 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7017 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7018 app.persistent = true; 7019 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7020 } 7021 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7022 mPersistentStartingProcesses.add(app); 7023 startProcessLocked(app, "added application", app.processName); 7024 } 7025 7026 return app; 7027 } 7028 unhandledBack()7029 public void unhandledBack() { 7030 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7031 "unhandledBack()"); 7032 7033 synchronized(this) { 7034 int count = mMainStack.mHistory.size(); 7035 if (DEBUG_SWITCH) Slog.d( 7036 TAG, "Performing unhandledBack(): stack size = " + count); 7037 if (count > 1) { 7038 final long origId = Binder.clearCallingIdentity(); 7039 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7040 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7041 Binder.restoreCallingIdentity(origId); 7042 } 7043 } 7044 } 7045 openContentUri(Uri uri)7046 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7047 enforceNotIsolatedCaller("openContentUri"); 7048 final int userId = UserHandle.getCallingUserId(); 7049 String name = uri.getAuthority(); 7050 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7051 ParcelFileDescriptor pfd = null; 7052 if (cph != null) { 7053 // We record the binder invoker's uid in thread-local storage before 7054 // going to the content provider to open the file. Later, in the code 7055 // that handles all permissions checks, we look for this uid and use 7056 // that rather than the Activity Manager's own uid. The effect is that 7057 // we do the check against the caller's permissions even though it looks 7058 // to the content provider like the Activity Manager itself is making 7059 // the request. 7060 sCallerIdentity.set(new Identity( 7061 Binder.getCallingPid(), Binder.getCallingUid())); 7062 try { 7063 pfd = cph.provider.openFile(uri, "r"); 7064 } catch (FileNotFoundException e) { 7065 // do nothing; pfd will be returned null 7066 } finally { 7067 // Ensure that whatever happens, we clean up the identity state 7068 sCallerIdentity.remove(); 7069 } 7070 7071 // We've got the fd now, so we're done with the provider. 7072 removeContentProviderExternalUnchecked(name, null, userId); 7073 } else { 7074 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7075 } 7076 return pfd; 7077 } 7078 7079 // Actually is sleeping or shutting down or whatever else in the future 7080 // is an inactive state. isSleeping()7081 public boolean isSleeping() { 7082 return mSleeping || mShuttingDown; 7083 } 7084 goingToSleep()7085 public void goingToSleep() { 7086 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7087 != PackageManager.PERMISSION_GRANTED) { 7088 throw new SecurityException("Requires permission " 7089 + android.Manifest.permission.DEVICE_POWER); 7090 } 7091 7092 synchronized(this) { 7093 mWentToSleep = true; 7094 updateEventDispatchingLocked(); 7095 7096 if (!mSleeping) { 7097 mSleeping = true; 7098 mMainStack.stopIfSleepingLocked(); 7099 7100 // Initialize the wake times of all processes. 7101 checkExcessivePowerUsageLocked(false); 7102 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7103 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7104 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7105 } 7106 } 7107 } 7108 shutdown(int timeout)7109 public boolean shutdown(int timeout) { 7110 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7111 != PackageManager.PERMISSION_GRANTED) { 7112 throw new SecurityException("Requires permission " 7113 + android.Manifest.permission.SHUTDOWN); 7114 } 7115 7116 boolean timedout = false; 7117 7118 synchronized(this) { 7119 mShuttingDown = true; 7120 updateEventDispatchingLocked(); 7121 7122 if (mMainStack.mResumedActivity != null) { 7123 mMainStack.stopIfSleepingLocked(); 7124 final long endTime = System.currentTimeMillis() + timeout; 7125 while (mMainStack.mResumedActivity != null 7126 || mMainStack.mPausingActivity != null) { 7127 long delay = endTime - System.currentTimeMillis(); 7128 if (delay <= 0) { 7129 Slog.w(TAG, "Activity manager shutdown timed out"); 7130 timedout = true; 7131 break; 7132 } 7133 try { 7134 this.wait(); 7135 } catch (InterruptedException e) { 7136 } 7137 } 7138 } 7139 } 7140 7141 mUsageStatsService.shutdown(); 7142 mBatteryStatsService.shutdown(); 7143 7144 return timedout; 7145 } 7146 activitySlept(IBinder token)7147 public final void activitySlept(IBinder token) { 7148 if (localLOGV) Slog.v( 7149 TAG, "Activity slept: token=" + token); 7150 7151 ActivityRecord r = null; 7152 7153 final long origId = Binder.clearCallingIdentity(); 7154 7155 synchronized (this) { 7156 r = mMainStack.isInStackLocked(token); 7157 if (r != null) { 7158 mMainStack.activitySleptLocked(r); 7159 } 7160 } 7161 7162 Binder.restoreCallingIdentity(origId); 7163 } 7164 comeOutOfSleepIfNeededLocked()7165 private void comeOutOfSleepIfNeededLocked() { 7166 if (!mWentToSleep && !mLockScreenShown) { 7167 if (mSleeping) { 7168 mSleeping = false; 7169 mMainStack.awakeFromSleepingLocked(); 7170 mMainStack.resumeTopActivityLocked(null); 7171 } 7172 } 7173 } 7174 wakingUp()7175 public void wakingUp() { 7176 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7177 != PackageManager.PERMISSION_GRANTED) { 7178 throw new SecurityException("Requires permission " 7179 + android.Manifest.permission.DEVICE_POWER); 7180 } 7181 7182 synchronized(this) { 7183 mWentToSleep = false; 7184 updateEventDispatchingLocked(); 7185 comeOutOfSleepIfNeededLocked(); 7186 } 7187 } 7188 updateEventDispatchingLocked()7189 private void updateEventDispatchingLocked() { 7190 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7191 } 7192 setLockScreenShown(boolean shown)7193 public void setLockScreenShown(boolean shown) { 7194 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7195 != PackageManager.PERMISSION_GRANTED) { 7196 throw new SecurityException("Requires permission " 7197 + android.Manifest.permission.DEVICE_POWER); 7198 } 7199 7200 synchronized(this) { 7201 mLockScreenShown = shown; 7202 comeOutOfSleepIfNeededLocked(); 7203 } 7204 } 7205 stopAppSwitches()7206 public void stopAppSwitches() { 7207 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7208 != PackageManager.PERMISSION_GRANTED) { 7209 throw new SecurityException("Requires permission " 7210 + android.Manifest.permission.STOP_APP_SWITCHES); 7211 } 7212 7213 synchronized(this) { 7214 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7215 + APP_SWITCH_DELAY_TIME; 7216 mDidAppSwitch = false; 7217 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7218 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7219 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7220 } 7221 } 7222 resumeAppSwitches()7223 public void resumeAppSwitches() { 7224 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7225 != PackageManager.PERMISSION_GRANTED) { 7226 throw new SecurityException("Requires permission " 7227 + android.Manifest.permission.STOP_APP_SWITCHES); 7228 } 7229 7230 synchronized(this) { 7231 // Note that we don't execute any pending app switches... we will 7232 // let those wait until either the timeout, or the next start 7233 // activity request. 7234 mAppSwitchesAllowedTime = 0; 7235 } 7236 } 7237 checkAppSwitchAllowedLocked(int callingPid, int callingUid, String name)7238 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7239 String name) { 7240 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7241 return true; 7242 } 7243 7244 final int perm = checkComponentPermission( 7245 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7246 callingUid, -1, true); 7247 if (perm == PackageManager.PERMISSION_GRANTED) { 7248 return true; 7249 } 7250 7251 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7252 return false; 7253 } 7254 setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)7255 public void setDebugApp(String packageName, boolean waitForDebugger, 7256 boolean persistent) { 7257 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7258 "setDebugApp()"); 7259 7260 // Note that this is not really thread safe if there are multiple 7261 // callers into it at the same time, but that's not a situation we 7262 // care about. 7263 if (persistent) { 7264 final ContentResolver resolver = mContext.getContentResolver(); 7265 Settings.Global.putString( 7266 resolver, Settings.Global.DEBUG_APP, 7267 packageName); 7268 Settings.Global.putInt( 7269 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 7270 waitForDebugger ? 1 : 0); 7271 } 7272 7273 synchronized (this) { 7274 if (!persistent) { 7275 mOrigDebugApp = mDebugApp; 7276 mOrigWaitForDebugger = mWaitForDebugger; 7277 } 7278 mDebugApp = packageName; 7279 mWaitForDebugger = waitForDebugger; 7280 mDebugTransient = !persistent; 7281 if (packageName != null) { 7282 final long origId = Binder.clearCallingIdentity(); 7283 forceStopPackageLocked(packageName, -1, false, false, true, true, 7284 UserHandle.USER_ALL); 7285 Binder.restoreCallingIdentity(origId); 7286 } 7287 } 7288 } 7289 setOpenGlTraceApp(ApplicationInfo app, String processName)7290 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7291 synchronized (this) { 7292 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7293 if (!isDebuggable) { 7294 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7295 throw new SecurityException("Process not debuggable: " + app.packageName); 7296 } 7297 } 7298 7299 mOpenGlTraceApp = processName; 7300 } 7301 } 7302 setProfileApp(ApplicationInfo app, String processName, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler)7303 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7304 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7305 synchronized (this) { 7306 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7307 if (!isDebuggable) { 7308 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7309 throw new SecurityException("Process not debuggable: " + app.packageName); 7310 } 7311 } 7312 mProfileApp = processName; 7313 mProfileFile = profileFile; 7314 if (mProfileFd != null) { 7315 try { 7316 mProfileFd.close(); 7317 } catch (IOException e) { 7318 } 7319 mProfileFd = null; 7320 } 7321 mProfileFd = profileFd; 7322 mProfileType = 0; 7323 mAutoStopProfiler = autoStopProfiler; 7324 } 7325 } 7326 setAlwaysFinish(boolean enabled)7327 public void setAlwaysFinish(boolean enabled) { 7328 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7329 "setAlwaysFinish()"); 7330 7331 Settings.Global.putInt( 7332 mContext.getContentResolver(), 7333 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7334 7335 synchronized (this) { 7336 mAlwaysFinishActivities = enabled; 7337 } 7338 } 7339 setActivityController(IActivityController controller)7340 public void setActivityController(IActivityController controller) { 7341 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7342 "setActivityController()"); 7343 synchronized (this) { 7344 mController = controller; 7345 } 7346 } 7347 isUserAMonkey()7348 public boolean isUserAMonkey() { 7349 // For now the fact that there is a controller implies 7350 // we have a monkey. 7351 synchronized (this) { 7352 return mController != null; 7353 } 7354 } 7355 requestBugReport()7356 public void requestBugReport() { 7357 // No permission check because this can't do anything harmful -- 7358 // it will just eventually cause the user to be presented with 7359 // a UI to select where the bug report goes. 7360 SystemProperties.set("ctl.start", "bugreport"); 7361 } 7362 inputDispatchingTimedOut(int pid, boolean aboveSystem)7363 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) { 7364 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7365 != PackageManager.PERMISSION_GRANTED) { 7366 throw new SecurityException("Requires permission " 7367 + android.Manifest.permission.FILTER_EVENTS); 7368 } 7369 7370 ProcessRecord proc; 7371 7372 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut(). 7373 synchronized (this) { 7374 synchronized (mPidsSelfLocked) { 7375 proc = mPidsSelfLocked.get(pid); 7376 } 7377 if (proc != null) { 7378 if (proc.debugging) { 7379 return -1; 7380 } 7381 7382 if (mDidDexOpt) { 7383 // Give more time since we were dexopting. 7384 mDidDexOpt = false; 7385 return -1; 7386 } 7387 7388 if (proc.instrumentationClass != null) { 7389 Bundle info = new Bundle(); 7390 info.putString("shortMsg", "keyDispatchingTimedOut"); 7391 info.putString("longMsg", "Timed out while dispatching key event"); 7392 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 7393 proc = null; 7394 } 7395 } 7396 } 7397 7398 if (proc != null) { 7399 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut"); 7400 if (proc.instrumentationClass != null || proc.usingWrapper) { 7401 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 7402 } 7403 } 7404 7405 return KEY_DISPATCHING_TIMEOUT; 7406 } 7407 registerProcessObserver(IProcessObserver observer)7408 public void registerProcessObserver(IProcessObserver observer) { 7409 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7410 "registerProcessObserver()"); 7411 synchronized (this) { 7412 mProcessObservers.register(observer); 7413 } 7414 } 7415 unregisterProcessObserver(IProcessObserver observer)7416 public void unregisterProcessObserver(IProcessObserver observer) { 7417 synchronized (this) { 7418 mProcessObservers.unregister(observer); 7419 } 7420 } 7421 setImmersive(IBinder token, boolean immersive)7422 public void setImmersive(IBinder token, boolean immersive) { 7423 synchronized(this) { 7424 ActivityRecord r = mMainStack.isInStackLocked(token); 7425 if (r == null) { 7426 throw new IllegalArgumentException(); 7427 } 7428 r.immersive = immersive; 7429 } 7430 } 7431 isImmersive(IBinder token)7432 public boolean isImmersive(IBinder token) { 7433 synchronized (this) { 7434 ActivityRecord r = mMainStack.isInStackLocked(token); 7435 if (r == null) { 7436 throw new IllegalArgumentException(); 7437 } 7438 return r.immersive; 7439 } 7440 } 7441 isTopActivityImmersive()7442 public boolean isTopActivityImmersive() { 7443 enforceNotIsolatedCaller("startActivity"); 7444 synchronized (this) { 7445 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7446 return (r != null) ? r.immersive : false; 7447 } 7448 } 7449 enterSafeMode()7450 public final void enterSafeMode() { 7451 synchronized(this) { 7452 // It only makes sense to do this before the system is ready 7453 // and started launching other packages. 7454 if (!mSystemReady) { 7455 try { 7456 AppGlobals.getPackageManager().enterSafeMode(); 7457 } catch (RemoteException e) { 7458 } 7459 } 7460 } 7461 } 7462 showSafeModeOverlay()7463 public final void showSafeModeOverlay() { 7464 View v = LayoutInflater.from(mContext).inflate( 7465 com.android.internal.R.layout.safe_mode, null); 7466 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7467 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7468 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7469 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7470 lp.gravity = Gravity.BOTTOM | Gravity.START; 7471 lp.format = v.getBackground().getOpacity(); 7472 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7473 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7474 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 7475 ((WindowManager)mContext.getSystemService( 7476 Context.WINDOW_SERVICE)).addView(v, lp); 7477 } 7478 noteWakeupAlarm(IIntentSender sender)7479 public void noteWakeupAlarm(IIntentSender sender) { 7480 if (!(sender instanceof PendingIntentRecord)) { 7481 return; 7482 } 7483 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7484 synchronized (stats) { 7485 if (mBatteryStatsService.isOnBattery()) { 7486 mBatteryStatsService.enforceCallingPermission(); 7487 PendingIntentRecord rec = (PendingIntentRecord)sender; 7488 int MY_UID = Binder.getCallingUid(); 7489 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7490 BatteryStatsImpl.Uid.Pkg pkg = 7491 stats.getPackageStatsLocked(uid, rec.key.packageName); 7492 pkg.incWakeupsLocked(); 7493 } 7494 } 7495 } 7496 killPids(int[] pids, String pReason, boolean secure)7497 public boolean killPids(int[] pids, String pReason, boolean secure) { 7498 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7499 throw new SecurityException("killPids only available to the system"); 7500 } 7501 String reason = (pReason == null) ? "Unknown" : pReason; 7502 // XXX Note: don't acquire main activity lock here, because the window 7503 // manager calls in with its locks held. 7504 7505 boolean killed = false; 7506 synchronized (mPidsSelfLocked) { 7507 int[] types = new int[pids.length]; 7508 int worstType = 0; 7509 for (int i=0; i<pids.length; i++) { 7510 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7511 if (proc != null) { 7512 int type = proc.setAdj; 7513 types[i] = type; 7514 if (type > worstType) { 7515 worstType = type; 7516 } 7517 } 7518 } 7519 7520 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7521 // then constrain it so we will kill all hidden procs. 7522 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7523 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7524 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7525 } 7526 7527 // If this is not a secure call, don't let it kill processes that 7528 // are important. 7529 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7530 worstType = ProcessList.SERVICE_ADJ; 7531 } 7532 7533 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7534 for (int i=0; i<pids.length; i++) { 7535 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7536 if (proc == null) { 7537 continue; 7538 } 7539 int adj = proc.setAdj; 7540 if (adj >= worstType && !proc.killedBackground) { 7541 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7542 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7543 proc.processName, adj, reason); 7544 killed = true; 7545 proc.killedBackground = true; 7546 Process.killProcessQuiet(pids[i]); 7547 } 7548 } 7549 } 7550 return killed; 7551 } 7552 7553 @Override killProcessesBelowForeground(String reason)7554 public boolean killProcessesBelowForeground(String reason) { 7555 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7556 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7557 } 7558 7559 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7560 } 7561 killProcessesBelowAdj(int belowAdj, String reason)7562 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7563 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7564 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7565 } 7566 7567 boolean killed = false; 7568 synchronized (mPidsSelfLocked) { 7569 final int size = mPidsSelfLocked.size(); 7570 for (int i = 0; i < size; i++) { 7571 final int pid = mPidsSelfLocked.keyAt(i); 7572 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7573 if (proc == null) continue; 7574 7575 final int adj = proc.setAdj; 7576 if (adj > belowAdj && !proc.killedBackground) { 7577 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7578 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7579 proc.pid, proc.processName, adj, reason); 7580 killed = true; 7581 proc.killedBackground = true; 7582 Process.killProcessQuiet(pid); 7583 } 7584 } 7585 } 7586 return killed; 7587 } 7588 startRunning(String pkg, String cls, String action, String data)7589 public final void startRunning(String pkg, String cls, String action, 7590 String data) { 7591 synchronized(this) { 7592 if (mStartRunning) { 7593 return; 7594 } 7595 mStartRunning = true; 7596 mTopComponent = pkg != null && cls != null 7597 ? new ComponentName(pkg, cls) : null; 7598 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7599 mTopData = data; 7600 if (!mSystemReady) { 7601 return; 7602 } 7603 } 7604 7605 systemReady(null); 7606 } 7607 retrieveSettings()7608 private void retrieveSettings() { 7609 final ContentResolver resolver = mContext.getContentResolver(); 7610 String debugApp = Settings.Global.getString( 7611 resolver, Settings.Global.DEBUG_APP); 7612 boolean waitForDebugger = Settings.Global.getInt( 7613 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 7614 boolean alwaysFinishActivities = Settings.Global.getInt( 7615 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7616 7617 Configuration configuration = new Configuration(); 7618 Settings.System.getConfiguration(resolver, configuration); 7619 7620 synchronized (this) { 7621 mDebugApp = mOrigDebugApp = debugApp; 7622 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7623 mAlwaysFinishActivities = alwaysFinishActivities; 7624 // This happens before any activities are started, so we can 7625 // change mConfiguration in-place. 7626 updateConfigurationLocked(configuration, null, false, true); 7627 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7628 } 7629 } 7630 testIsSystemReady()7631 public boolean testIsSystemReady() { 7632 // no need to synchronize(this) just to read & return the value 7633 return mSystemReady; 7634 } 7635 getCalledPreBootReceiversFile()7636 private static File getCalledPreBootReceiversFile() { 7637 File dataDir = Environment.getDataDirectory(); 7638 File systemDir = new File(dataDir, "system"); 7639 File fname = new File(systemDir, "called_pre_boots.dat"); 7640 return fname; 7641 } 7642 7643 static final int LAST_DONE_VERSION = 10000; 7644 readLastDonePreBootReceivers()7645 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7646 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7647 File file = getCalledPreBootReceiversFile(); 7648 FileInputStream fis = null; 7649 try { 7650 fis = new FileInputStream(file); 7651 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7652 int fvers = dis.readInt(); 7653 if (fvers == LAST_DONE_VERSION) { 7654 String vers = dis.readUTF(); 7655 String codename = dis.readUTF(); 7656 String build = dis.readUTF(); 7657 if (android.os.Build.VERSION.RELEASE.equals(vers) 7658 && android.os.Build.VERSION.CODENAME.equals(codename) 7659 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7660 int num = dis.readInt(); 7661 while (num > 0) { 7662 num--; 7663 String pkg = dis.readUTF(); 7664 String cls = dis.readUTF(); 7665 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7666 } 7667 } 7668 } 7669 } catch (FileNotFoundException e) { 7670 } catch (IOException e) { 7671 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7672 } finally { 7673 if (fis != null) { 7674 try { 7675 fis.close(); 7676 } catch (IOException e) { 7677 } 7678 } 7679 } 7680 return lastDoneReceivers; 7681 } 7682 writeLastDonePreBootReceivers(ArrayList<ComponentName> list)7683 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7684 File file = getCalledPreBootReceiversFile(); 7685 FileOutputStream fos = null; 7686 DataOutputStream dos = null; 7687 try { 7688 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7689 fos = new FileOutputStream(file); 7690 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7691 dos.writeInt(LAST_DONE_VERSION); 7692 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7693 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7694 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7695 dos.writeInt(list.size()); 7696 for (int i=0; i<list.size(); i++) { 7697 dos.writeUTF(list.get(i).getPackageName()); 7698 dos.writeUTF(list.get(i).getClassName()); 7699 } 7700 } catch (IOException e) { 7701 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7702 file.delete(); 7703 } finally { 7704 FileUtils.sync(fos); 7705 if (dos != null) { 7706 try { 7707 dos.close(); 7708 } catch (IOException e) { 7709 // TODO Auto-generated catch block 7710 e.printStackTrace(); 7711 } 7712 } 7713 } 7714 } 7715 systemReady(final Runnable goingCallback)7716 public void systemReady(final Runnable goingCallback) { 7717 synchronized(this) { 7718 if (mSystemReady) { 7719 if (goingCallback != null) goingCallback.run(); 7720 return; 7721 } 7722 7723 // Check to see if there are any update receivers to run. 7724 if (!mDidUpdate) { 7725 if (mWaitingUpdate) { 7726 return; 7727 } 7728 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7729 List<ResolveInfo> ris = null; 7730 try { 7731 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7732 intent, null, 0, 0); 7733 } catch (RemoteException e) { 7734 } 7735 if (ris != null) { 7736 for (int i=ris.size()-1; i>=0; i--) { 7737 if ((ris.get(i).activityInfo.applicationInfo.flags 7738 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7739 ris.remove(i); 7740 } 7741 } 7742 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7743 7744 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7745 7746 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7747 for (int i=0; i<ris.size(); i++) { 7748 ActivityInfo ai = ris.get(i).activityInfo; 7749 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7750 if (lastDoneReceivers.contains(comp)) { 7751 ris.remove(i); 7752 i--; 7753 } 7754 } 7755 7756 final int[] users = getUsersLocked(); 7757 for (int i=0; i<ris.size(); i++) { 7758 ActivityInfo ai = ris.get(i).activityInfo; 7759 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7760 doneReceivers.add(comp); 7761 intent.setComponent(comp); 7762 for (int j=0; j<users.length; j++) { 7763 IIntentReceiver finisher = null; 7764 if (i == ris.size()-1 && j == users.length-1) { 7765 finisher = new IIntentReceiver.Stub() { 7766 public void performReceive(Intent intent, int resultCode, 7767 String data, Bundle extras, boolean ordered, 7768 boolean sticky, int sendingUser) { 7769 // The raw IIntentReceiver interface is called 7770 // with the AM lock held, so redispatch to 7771 // execute our code without the lock. 7772 mHandler.post(new Runnable() { 7773 public void run() { 7774 synchronized (ActivityManagerService.this) { 7775 mDidUpdate = true; 7776 } 7777 writeLastDonePreBootReceivers(doneReceivers); 7778 showBootMessage(mContext.getText( 7779 R.string.android_upgrading_complete), 7780 false); 7781 systemReady(goingCallback); 7782 } 7783 }); 7784 } 7785 }; 7786 } 7787 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7788 + " for user " + users[j]); 7789 broadcastIntentLocked(null, null, intent, null, finisher, 7790 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7791 users[j]); 7792 if (finisher != null) { 7793 mWaitingUpdate = true; 7794 } 7795 } 7796 } 7797 } 7798 if (mWaitingUpdate) { 7799 return; 7800 } 7801 mDidUpdate = true; 7802 } 7803 7804 mSystemReady = true; 7805 if (!mStartRunning) { 7806 return; 7807 } 7808 } 7809 7810 ArrayList<ProcessRecord> procsToKill = null; 7811 synchronized(mPidsSelfLocked) { 7812 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7813 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7814 if (!isAllowedWhileBooting(proc.info)){ 7815 if (procsToKill == null) { 7816 procsToKill = new ArrayList<ProcessRecord>(); 7817 } 7818 procsToKill.add(proc); 7819 } 7820 } 7821 } 7822 7823 synchronized(this) { 7824 if (procsToKill != null) { 7825 for (int i=procsToKill.size()-1; i>=0; i--) { 7826 ProcessRecord proc = procsToKill.get(i); 7827 Slog.i(TAG, "Removing system update proc: " + proc); 7828 removeProcessLocked(proc, true, false, "system update done"); 7829 } 7830 } 7831 7832 // Now that we have cleaned up any update processes, we 7833 // are ready to start launching real processes and know that 7834 // we won't trample on them any more. 7835 mProcessesReady = true; 7836 } 7837 7838 Slog.i(TAG, "System now ready"); 7839 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7840 SystemClock.uptimeMillis()); 7841 7842 synchronized(this) { 7843 // Make sure we have no pre-ready processes sitting around. 7844 7845 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7846 ResolveInfo ri = mContext.getPackageManager() 7847 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7848 STOCK_PM_FLAGS); 7849 CharSequence errorMsg = null; 7850 if (ri != null) { 7851 ActivityInfo ai = ri.activityInfo; 7852 ApplicationInfo app = ai.applicationInfo; 7853 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7854 mTopAction = Intent.ACTION_FACTORY_TEST; 7855 mTopData = null; 7856 mTopComponent = new ComponentName(app.packageName, 7857 ai.name); 7858 } else { 7859 errorMsg = mContext.getResources().getText( 7860 com.android.internal.R.string.factorytest_not_system); 7861 } 7862 } else { 7863 errorMsg = mContext.getResources().getText( 7864 com.android.internal.R.string.factorytest_no_action); 7865 } 7866 if (errorMsg != null) { 7867 mTopAction = null; 7868 mTopData = null; 7869 mTopComponent = null; 7870 Message msg = Message.obtain(); 7871 msg.what = SHOW_FACTORY_ERROR_MSG; 7872 msg.getData().putCharSequence("msg", errorMsg); 7873 mHandler.sendMessage(msg); 7874 } 7875 } 7876 } 7877 7878 retrieveSettings(); 7879 7880 if (goingCallback != null) goingCallback.run(); 7881 7882 synchronized (this) { 7883 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7884 try { 7885 List apps = AppGlobals.getPackageManager(). 7886 getPersistentApplications(STOCK_PM_FLAGS); 7887 if (apps != null) { 7888 int N = apps.size(); 7889 int i; 7890 for (i=0; i<N; i++) { 7891 ApplicationInfo info 7892 = (ApplicationInfo)apps.get(i); 7893 if (info != null && 7894 !info.packageName.equals("android")) { 7895 addAppLocked(info, false); 7896 } 7897 } 7898 } 7899 } catch (RemoteException ex) { 7900 // pm is in same process, this will never happen. 7901 } 7902 } 7903 7904 // Start up initial activity. 7905 mBooting = true; 7906 7907 try { 7908 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7909 Message msg = Message.obtain(); 7910 msg.what = SHOW_UID_ERROR_MSG; 7911 mHandler.sendMessage(msg); 7912 } 7913 } catch (RemoteException e) { 7914 } 7915 7916 long ident = Binder.clearCallingIdentity(); 7917 try { 7918 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7919 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 7920 | Intent.FLAG_RECEIVER_FOREGROUND); 7921 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7922 broadcastIntentLocked(null, null, intent, 7923 null, null, 0, null, null, null, 7924 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7925 intent = new Intent(Intent.ACTION_USER_STARTING); 7926 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7927 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7928 broadcastIntentLocked(null, null, intent, 7929 null, new IIntentReceiver.Stub() { 7930 @Override 7931 public void performReceive(Intent intent, int resultCode, String data, 7932 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 7933 throws RemoteException { 7934 } 7935 }, 0, null, null, 7936 android.Manifest.permission.INTERACT_ACROSS_USERS, 7937 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 7938 } finally { 7939 Binder.restoreCallingIdentity(ident); 7940 } 7941 mMainStack.resumeTopActivityLocked(null); 7942 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7943 } 7944 } 7945 makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace)7946 private boolean makeAppCrashingLocked(ProcessRecord app, 7947 String shortMsg, String longMsg, String stackTrace) { 7948 app.crashing = true; 7949 app.crashingReport = generateProcessError(app, 7950 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7951 startAppProblemLocked(app); 7952 app.stopFreezingAllLocked(); 7953 return handleAppCrashLocked(app); 7954 } 7955 makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg)7956 private void makeAppNotRespondingLocked(ProcessRecord app, 7957 String activity, String shortMsg, String longMsg) { 7958 app.notResponding = true; 7959 app.notRespondingReport = generateProcessError(app, 7960 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7961 activity, shortMsg, longMsg, null); 7962 startAppProblemLocked(app); 7963 app.stopFreezingAllLocked(); 7964 } 7965 7966 /** 7967 * Generate a process error record, suitable for attachment to a ProcessRecord. 7968 * 7969 * @param app The ProcessRecord in which the error occurred. 7970 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7971 * ActivityManager.AppErrorStateInfo 7972 * @param activity The activity associated with the crash, if known. 7973 * @param shortMsg Short message describing the crash. 7974 * @param longMsg Long message describing the crash. 7975 * @param stackTrace Full crash stack trace, may be null. 7976 * 7977 * @return Returns a fully-formed AppErrorStateInfo record. 7978 */ generateProcessError(ProcessRecord app, int condition, String activity, String shortMsg, String longMsg, String stackTrace)7979 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7980 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7981 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7982 7983 report.condition = condition; 7984 report.processName = app.processName; 7985 report.pid = app.pid; 7986 report.uid = app.info.uid; 7987 report.tag = activity; 7988 report.shortMsg = shortMsg; 7989 report.longMsg = longMsg; 7990 report.stackTrace = stackTrace; 7991 7992 return report; 7993 } 7994 killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog)7995 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7996 synchronized (this) { 7997 app.crashing = false; 7998 app.crashingReport = null; 7999 app.notResponding = false; 8000 app.notRespondingReport = null; 8001 if (app.anrDialog == fromDialog) { 8002 app.anrDialog = null; 8003 } 8004 if (app.waitDialog == fromDialog) { 8005 app.waitDialog = null; 8006 } 8007 if (app.pid > 0 && app.pid != MY_PID) { 8008 handleAppCrashLocked(app); 8009 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 8010 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 8011 app.processName, app.setAdj, "user's request after error"); 8012 Process.killProcessQuiet(app.pid); 8013 } 8014 } 8015 } 8016 handleAppCrashLocked(ProcessRecord app)8017 private boolean handleAppCrashLocked(ProcessRecord app) { 8018 if (mHeadless) { 8019 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 8020 return false; 8021 } 8022 long now = SystemClock.uptimeMillis(); 8023 8024 Long crashTime; 8025 if (!app.isolated) { 8026 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 8027 } else { 8028 crashTime = null; 8029 } 8030 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 8031 // This process loses! 8032 Slog.w(TAG, "Process " + app.info.processName 8033 + " has crashed too many times: killing!"); 8034 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8035 app.userId, app.info.processName, app.uid); 8036 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8037 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8038 if (r.app == app) { 8039 Slog.w(TAG, " Force finishing activity " 8040 + r.intent.getComponent().flattenToShortString()); 8041 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8042 null, "crashed", false); 8043 } 8044 } 8045 if (!app.persistent) { 8046 // We don't want to start this process again until the user 8047 // explicitly does so... but for persistent process, we really 8048 // need to keep it running. If a persistent process is actually 8049 // repeatedly crashing, then badness for everyone. 8050 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 8051 app.info.processName); 8052 if (!app.isolated) { 8053 // XXX We don't have a way to mark isolated processes 8054 // as bad, since they don't have a peristent identity. 8055 mBadProcesses.put(app.info.processName, app.uid, now); 8056 mProcessCrashTimes.remove(app.info.processName, app.uid); 8057 } 8058 app.bad = true; 8059 app.removed = true; 8060 // Don't let services in this process be restarted and potentially 8061 // annoy the user repeatedly. Unless it is persistent, since those 8062 // processes run critical code. 8063 removeProcessLocked(app, false, false, "crash"); 8064 mMainStack.resumeTopActivityLocked(null); 8065 return false; 8066 } 8067 mMainStack.resumeTopActivityLocked(null); 8068 } else { 8069 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8070 if (r != null && r.app == app) { 8071 // If the top running activity is from this crashing 8072 // process, then terminate it to avoid getting in a loop. 8073 Slog.w(TAG, " Force finishing activity " 8074 + r.intent.getComponent().flattenToShortString()); 8075 int index = mMainStack.indexOfActivityLocked(r); 8076 r.stack.finishActivityLocked(r, index, 8077 Activity.RESULT_CANCELED, null, "crashed", false); 8078 // Also terminate any activities below it that aren't yet 8079 // stopped, to avoid a situation where one will get 8080 // re-start our crashing activity once it gets resumed again. 8081 index--; 8082 if (index >= 0) { 8083 r = (ActivityRecord)mMainStack.mHistory.get(index); 8084 if (r.state == ActivityState.RESUMED 8085 || r.state == ActivityState.PAUSING 8086 || r.state == ActivityState.PAUSED) { 8087 if (!r.isHomeActivity || mHomeProcess != r.app) { 8088 Slog.w(TAG, " Force finishing activity " 8089 + r.intent.getComponent().flattenToShortString()); 8090 r.stack.finishActivityLocked(r, index, 8091 Activity.RESULT_CANCELED, null, "crashed", false); 8092 } 8093 } 8094 } 8095 } 8096 } 8097 8098 // Bump up the crash count of any services currently running in the proc. 8099 if (app.services.size() != 0) { 8100 // Any services running in the application need to be placed 8101 // back in the pending list. 8102 Iterator<ServiceRecord> it = app.services.iterator(); 8103 while (it.hasNext()) { 8104 ServiceRecord sr = it.next(); 8105 sr.crashCount++; 8106 } 8107 } 8108 8109 // If the crashing process is what we consider to be the "home process" and it has been 8110 // replaced by a third-party app, clear the package preferred activities from packages 8111 // with a home activity running in the process to prevent a repeatedly crashing app 8112 // from blocking the user to manually clear the list. 8113 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8114 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8115 Iterator it = mHomeProcess.activities.iterator(); 8116 while (it.hasNext()) { 8117 ActivityRecord r = (ActivityRecord)it.next(); 8118 if (r.isHomeActivity) { 8119 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8120 try { 8121 ActivityThread.getPackageManager() 8122 .clearPackagePreferredActivities(r.packageName); 8123 } catch (RemoteException c) { 8124 // pm is in same process, this will never happen. 8125 } 8126 } 8127 } 8128 } 8129 8130 if (!app.isolated) { 8131 // XXX Can't keep track of crash times for isolated processes, 8132 // because they don't have a perisistent identity. 8133 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8134 } 8135 8136 return true; 8137 } 8138 startAppProblemLocked(ProcessRecord app)8139 void startAppProblemLocked(ProcessRecord app) { 8140 if (app.userId == mCurrentUserId) { 8141 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8142 mContext, app.info.packageName, app.info.flags); 8143 } else { 8144 // If this app is not running under the current user, then we 8145 // can't give it a report button because that would require 8146 // launching the report UI under a different user. 8147 app.errorReportReceiver = null; 8148 } 8149 skipCurrentReceiverLocked(app); 8150 } 8151 skipCurrentReceiverLocked(ProcessRecord app)8152 void skipCurrentReceiverLocked(ProcessRecord app) { 8153 for (BroadcastQueue queue : mBroadcastQueues) { 8154 queue.skipCurrentReceiverLocked(app); 8155 } 8156 } 8157 8158 /** 8159 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8160 * The application process will exit immediately after this call returns. 8161 * @param app object of the crashing app, null for the system server 8162 * @param crashInfo describing the exception 8163 */ handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo)8164 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8165 ProcessRecord r = findAppProcess(app, "Crash"); 8166 final String processName = app == null ? "system_server" 8167 : (r == null ? "unknown" : r.processName); 8168 8169 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8170 UserHandle.getUserId(Binder.getCallingUid()), processName, 8171 r == null ? -1 : r.info.flags, 8172 crashInfo.exceptionClassName, 8173 crashInfo.exceptionMessage, 8174 crashInfo.throwFileName, 8175 crashInfo.throwLineNumber); 8176 8177 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8178 8179 crashApplication(r, crashInfo); 8180 } 8181 handleApplicationStrictModeViolation( IBinder app, int violationMask, StrictMode.ViolationInfo info)8182 public void handleApplicationStrictModeViolation( 8183 IBinder app, 8184 int violationMask, 8185 StrictMode.ViolationInfo info) { 8186 ProcessRecord r = findAppProcess(app, "StrictMode"); 8187 if (r == null) { 8188 return; 8189 } 8190 8191 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8192 Integer stackFingerprint = info.hashCode(); 8193 boolean logIt = true; 8194 synchronized (mAlreadyLoggedViolatedStacks) { 8195 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8196 logIt = false; 8197 // TODO: sub-sample into EventLog for these, with 8198 // the info.durationMillis? Then we'd get 8199 // the relative pain numbers, without logging all 8200 // the stack traces repeatedly. We'd want to do 8201 // likewise in the client code, which also does 8202 // dup suppression, before the Binder call. 8203 } else { 8204 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8205 mAlreadyLoggedViolatedStacks.clear(); 8206 } 8207 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8208 } 8209 } 8210 if (logIt) { 8211 logStrictModeViolationToDropBox(r, info); 8212 } 8213 } 8214 8215 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8216 AppErrorResult result = new AppErrorResult(); 8217 synchronized (this) { 8218 final long origId = Binder.clearCallingIdentity(); 8219 8220 Message msg = Message.obtain(); 8221 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8222 HashMap<String, Object> data = new HashMap<String, Object>(); 8223 data.put("result", result); 8224 data.put("app", r); 8225 data.put("violationMask", violationMask); 8226 data.put("info", info); 8227 msg.obj = data; 8228 mHandler.sendMessage(msg); 8229 8230 Binder.restoreCallingIdentity(origId); 8231 } 8232 int res = result.get(); 8233 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8234 } 8235 } 8236 8237 // Depending on the policy in effect, there could be a bunch of 8238 // these in quick succession so we try to batch these together to 8239 // minimize disk writes, number of dropbox entries, and maximize 8240 // compression, by having more fewer, larger records. logStrictModeViolationToDropBox( ProcessRecord process, StrictMode.ViolationInfo info)8241 private void logStrictModeViolationToDropBox( 8242 ProcessRecord process, 8243 StrictMode.ViolationInfo info) { 8244 if (info == null) { 8245 return; 8246 } 8247 final boolean isSystemApp = process == null || 8248 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8249 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8250 final String processName = process == null ? "unknown" : process.processName; 8251 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8252 final DropBoxManager dbox = (DropBoxManager) 8253 mContext.getSystemService(Context.DROPBOX_SERVICE); 8254 8255 // Exit early if the dropbox isn't configured to accept this report type. 8256 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8257 8258 boolean bufferWasEmpty; 8259 boolean needsFlush; 8260 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8261 synchronized (sb) { 8262 bufferWasEmpty = sb.length() == 0; 8263 appendDropBoxProcessHeaders(process, processName, sb); 8264 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8265 sb.append("System-App: ").append(isSystemApp).append("\n"); 8266 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8267 if (info.violationNumThisLoop != 0) { 8268 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8269 } 8270 if (info.numAnimationsRunning != 0) { 8271 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8272 } 8273 if (info.broadcastIntentAction != null) { 8274 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8275 } 8276 if (info.durationMillis != -1) { 8277 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8278 } 8279 if (info.numInstances != -1) { 8280 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8281 } 8282 if (info.tags != null) { 8283 for (String tag : info.tags) { 8284 sb.append("Span-Tag: ").append(tag).append("\n"); 8285 } 8286 } 8287 sb.append("\n"); 8288 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8289 sb.append(info.crashInfo.stackTrace); 8290 } 8291 sb.append("\n"); 8292 8293 // Only buffer up to ~64k. Various logging bits truncate 8294 // things at 128k. 8295 needsFlush = (sb.length() > 64 * 1024); 8296 } 8297 8298 // Flush immediately if the buffer's grown too large, or this 8299 // is a non-system app. Non-system apps are isolated with a 8300 // different tag & policy and not batched. 8301 // 8302 // Batching is useful during internal testing with 8303 // StrictMode settings turned up high. Without batching, 8304 // thousands of separate files could be created on boot. 8305 if (!isSystemApp || needsFlush) { 8306 new Thread("Error dump: " + dropboxTag) { 8307 @Override 8308 public void run() { 8309 String report; 8310 synchronized (sb) { 8311 report = sb.toString(); 8312 sb.delete(0, sb.length()); 8313 sb.trimToSize(); 8314 } 8315 if (report.length() != 0) { 8316 dbox.addText(dropboxTag, report); 8317 } 8318 } 8319 }.start(); 8320 return; 8321 } 8322 8323 // System app batching: 8324 if (!bufferWasEmpty) { 8325 // An existing dropbox-writing thread is outstanding, so 8326 // we don't need to start it up. The existing thread will 8327 // catch the buffer appends we just did. 8328 return; 8329 } 8330 8331 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8332 // (After this point, we shouldn't access AMS internal data structures.) 8333 new Thread("Error dump: " + dropboxTag) { 8334 @Override 8335 public void run() { 8336 // 5 second sleep to let stacks arrive and be batched together 8337 try { 8338 Thread.sleep(5000); // 5 seconds 8339 } catch (InterruptedException e) {} 8340 8341 String errorReport; 8342 synchronized (mStrictModeBuffer) { 8343 errorReport = mStrictModeBuffer.toString(); 8344 if (errorReport.length() == 0) { 8345 return; 8346 } 8347 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8348 mStrictModeBuffer.trimToSize(); 8349 } 8350 dbox.addText(dropboxTag, errorReport); 8351 } 8352 }.start(); 8353 } 8354 8355 /** 8356 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8357 * @param app object of the crashing app, null for the system server 8358 * @param tag reported by the caller 8359 * @param crashInfo describing the context of the error 8360 * @return true if the process should exit immediately (WTF is fatal) 8361 */ handleApplicationWtf(IBinder app, String tag, ApplicationErrorReport.CrashInfo crashInfo)8362 public boolean handleApplicationWtf(IBinder app, String tag, 8363 ApplicationErrorReport.CrashInfo crashInfo) { 8364 ProcessRecord r = findAppProcess(app, "WTF"); 8365 final String processName = app == null ? "system_server" 8366 : (r == null ? "unknown" : r.processName); 8367 8368 EventLog.writeEvent(EventLogTags.AM_WTF, 8369 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8370 processName, 8371 r == null ? -1 : r.info.flags, 8372 tag, crashInfo.exceptionMessage); 8373 8374 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8375 8376 if (r != null && r.pid != Process.myPid() && 8377 Settings.Global.getInt(mContext.getContentResolver(), 8378 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8379 crashApplication(r, crashInfo); 8380 return true; 8381 } else { 8382 return false; 8383 } 8384 } 8385 8386 /** 8387 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8388 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8389 */ findAppProcess(IBinder app, String reason)8390 private ProcessRecord findAppProcess(IBinder app, String reason) { 8391 if (app == null) { 8392 return null; 8393 } 8394 8395 synchronized (this) { 8396 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8397 final int NA = apps.size(); 8398 for (int ia=0; ia<NA; ia++) { 8399 ProcessRecord p = apps.valueAt(ia); 8400 if (p.thread != null && p.thread.asBinder() == app) { 8401 return p; 8402 } 8403 } 8404 } 8405 8406 Slog.w(TAG, "Can't find mystery application for " + reason 8407 + " from pid=" + Binder.getCallingPid() 8408 + " uid=" + Binder.getCallingUid() + ": " + app); 8409 return null; 8410 } 8411 } 8412 8413 /** 8414 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8415 * to append various headers to the dropbox log text. 8416 */ appendDropBoxProcessHeaders(ProcessRecord process, String processName, StringBuilder sb)8417 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8418 StringBuilder sb) { 8419 // Watchdog thread ends up invoking this function (with 8420 // a null ProcessRecord) to add the stack file to dropbox. 8421 // Do not acquire a lock on this (am) in such cases, as it 8422 // could cause a potential deadlock, if and when watchdog 8423 // is invoked due to unavailability of lock on am and it 8424 // would prevent watchdog from killing system_server. 8425 if (process == null) { 8426 sb.append("Process: ").append(processName).append("\n"); 8427 return; 8428 } 8429 // Note: ProcessRecord 'process' is guarded by the service 8430 // instance. (notably process.pkgList, which could otherwise change 8431 // concurrently during execution of this method) 8432 synchronized (this) { 8433 sb.append("Process: ").append(processName).append("\n"); 8434 int flags = process.info.flags; 8435 IPackageManager pm = AppGlobals.getPackageManager(); 8436 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8437 for (String pkg : process.pkgList) { 8438 sb.append("Package: ").append(pkg); 8439 try { 8440 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8441 if (pi != null) { 8442 sb.append(" v").append(pi.versionCode); 8443 if (pi.versionName != null) { 8444 sb.append(" (").append(pi.versionName).append(")"); 8445 } 8446 } 8447 } catch (RemoteException e) { 8448 Slog.e(TAG, "Error getting package info: " + pkg, e); 8449 } 8450 sb.append("\n"); 8451 } 8452 } 8453 } 8454 processClass(ProcessRecord process)8455 private static String processClass(ProcessRecord process) { 8456 if (process == null || process.pid == MY_PID) { 8457 return "system_server"; 8458 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8459 return "system_app"; 8460 } else { 8461 return "data_app"; 8462 } 8463 } 8464 8465 /** 8466 * Write a description of an error (crash, WTF, ANR) to the drop box. 8467 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8468 * @param process which caused the error, null means the system server 8469 * @param activity which triggered the error, null if unknown 8470 * @param parent activity related to the error, null if unknown 8471 * @param subject line related to the error, null if absent 8472 * @param report in long form describing the error, null if absent 8473 * @param logFile to include in the report, null if none 8474 * @param crashInfo giving an application stack trace, null if absent 8475 */ addErrorToDropBox(String eventType, ProcessRecord process, String processName, ActivityRecord activity, ActivityRecord parent, String subject, final String report, final File logFile, final ApplicationErrorReport.CrashInfo crashInfo)8476 public void addErrorToDropBox(String eventType, 8477 ProcessRecord process, String processName, ActivityRecord activity, 8478 ActivityRecord parent, String subject, 8479 final String report, final File logFile, 8480 final ApplicationErrorReport.CrashInfo crashInfo) { 8481 // NOTE -- this must never acquire the ActivityManagerService lock, 8482 // otherwise the watchdog may be prevented from resetting the system. 8483 8484 final String dropboxTag = processClass(process) + "_" + eventType; 8485 final DropBoxManager dbox = (DropBoxManager) 8486 mContext.getSystemService(Context.DROPBOX_SERVICE); 8487 8488 // Exit early if the dropbox isn't configured to accept this report type. 8489 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8490 8491 final StringBuilder sb = new StringBuilder(1024); 8492 appendDropBoxProcessHeaders(process, processName, sb); 8493 if (activity != null) { 8494 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8495 } 8496 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8497 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8498 } 8499 if (parent != null && parent != activity) { 8500 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8501 } 8502 if (subject != null) { 8503 sb.append("Subject: ").append(subject).append("\n"); 8504 } 8505 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8506 if (Debug.isDebuggerConnected()) { 8507 sb.append("Debugger: Connected\n"); 8508 } 8509 sb.append("\n"); 8510 8511 // Do the rest in a worker thread to avoid blocking the caller on I/O 8512 // (After this point, we shouldn't access AMS internal data structures.) 8513 Thread worker = new Thread("Error dump: " + dropboxTag) { 8514 @Override 8515 public void run() { 8516 if (report != null) { 8517 sb.append(report); 8518 } 8519 if (logFile != null) { 8520 try { 8521 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8522 } catch (IOException e) { 8523 Slog.e(TAG, "Error reading " + logFile, e); 8524 } 8525 } 8526 if (crashInfo != null && crashInfo.stackTrace != null) { 8527 sb.append(crashInfo.stackTrace); 8528 } 8529 8530 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8531 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8532 if (lines > 0) { 8533 sb.append("\n"); 8534 8535 // Merge several logcat streams, and take the last N lines 8536 InputStreamReader input = null; 8537 try { 8538 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8539 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8540 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8541 8542 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8543 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8544 input = new InputStreamReader(logcat.getInputStream()); 8545 8546 int num; 8547 char[] buf = new char[8192]; 8548 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8549 } catch (IOException e) { 8550 Slog.e(TAG, "Error running logcat", e); 8551 } finally { 8552 if (input != null) try { input.close(); } catch (IOException e) {} 8553 } 8554 } 8555 8556 dbox.addText(dropboxTag, sb.toString()); 8557 } 8558 }; 8559 8560 if (process == null) { 8561 // If process is null, we are being called from some internal code 8562 // and may be about to die -- run this synchronously. 8563 worker.run(); 8564 } else { 8565 worker.start(); 8566 } 8567 } 8568 8569 /** 8570 * Bring up the "unexpected error" dialog box for a crashing app. 8571 * Deal with edge cases (intercepts from instrumented applications, 8572 * ActivityController, error intent receivers, that sort of thing). 8573 * @param r the application crashing 8574 * @param crashInfo describing the failure 8575 */ crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)8576 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8577 long timeMillis = System.currentTimeMillis(); 8578 String shortMsg = crashInfo.exceptionClassName; 8579 String longMsg = crashInfo.exceptionMessage; 8580 String stackTrace = crashInfo.stackTrace; 8581 if (shortMsg != null && longMsg != null) { 8582 longMsg = shortMsg + ": " + longMsg; 8583 } else if (shortMsg != null) { 8584 longMsg = shortMsg; 8585 } 8586 8587 AppErrorResult result = new AppErrorResult(); 8588 synchronized (this) { 8589 if (mController != null) { 8590 try { 8591 String name = r != null ? r.processName : null; 8592 int pid = r != null ? r.pid : Binder.getCallingPid(); 8593 if (!mController.appCrashed(name, pid, 8594 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8595 Slog.w(TAG, "Force-killing crashed app " + name 8596 + " at watcher's request"); 8597 Process.killProcess(pid); 8598 return; 8599 } 8600 } catch (RemoteException e) { 8601 mController = null; 8602 } 8603 } 8604 8605 final long origId = Binder.clearCallingIdentity(); 8606 8607 // If this process is running instrumentation, finish it. 8608 if (r != null && r.instrumentationClass != null) { 8609 Slog.w(TAG, "Error in app " + r.processName 8610 + " running instrumentation " + r.instrumentationClass + ":"); 8611 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8612 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8613 Bundle info = new Bundle(); 8614 info.putString("shortMsg", shortMsg); 8615 info.putString("longMsg", longMsg); 8616 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8617 Binder.restoreCallingIdentity(origId); 8618 return; 8619 } 8620 8621 // If we can't identify the process or it's already exceeded its crash quota, 8622 // quit right away without showing a crash dialog. 8623 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8624 Binder.restoreCallingIdentity(origId); 8625 return; 8626 } 8627 8628 Message msg = Message.obtain(); 8629 msg.what = SHOW_ERROR_MSG; 8630 HashMap data = new HashMap(); 8631 data.put("result", result); 8632 data.put("app", r); 8633 msg.obj = data; 8634 mHandler.sendMessage(msg); 8635 8636 Binder.restoreCallingIdentity(origId); 8637 } 8638 8639 int res = result.get(); 8640 8641 Intent appErrorIntent = null; 8642 synchronized (this) { 8643 if (r != null && !r.isolated) { 8644 // XXX Can't keep track of crash time for isolated processes, 8645 // since they don't have a persistent identity. 8646 mProcessCrashTimes.put(r.info.processName, r.uid, 8647 SystemClock.uptimeMillis()); 8648 } 8649 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8650 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8651 } 8652 } 8653 8654 if (appErrorIntent != null) { 8655 try { 8656 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8657 } catch (ActivityNotFoundException e) { 8658 Slog.w(TAG, "bug report receiver dissappeared", e); 8659 } 8660 } 8661 } 8662 createAppErrorIntentLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8663 Intent createAppErrorIntentLocked(ProcessRecord r, 8664 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8665 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8666 if (report == null) { 8667 return null; 8668 } 8669 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8670 result.setComponent(r.errorReportReceiver); 8671 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8672 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8673 return result; 8674 } 8675 createAppErrorReportLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8676 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8677 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8678 if (r.errorReportReceiver == null) { 8679 return null; 8680 } 8681 8682 if (!r.crashing && !r.notResponding) { 8683 return null; 8684 } 8685 8686 ApplicationErrorReport report = new ApplicationErrorReport(); 8687 report.packageName = r.info.packageName; 8688 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8689 report.processName = r.processName; 8690 report.time = timeMillis; 8691 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8692 8693 if (r.crashing) { 8694 report.type = ApplicationErrorReport.TYPE_CRASH; 8695 report.crashInfo = crashInfo; 8696 } else if (r.notResponding) { 8697 report.type = ApplicationErrorReport.TYPE_ANR; 8698 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8699 8700 report.anrInfo.activity = r.notRespondingReport.tag; 8701 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8702 report.anrInfo.info = r.notRespondingReport.longMsg; 8703 } 8704 8705 return report; 8706 } 8707 getProcessesInErrorState()8708 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8709 enforceNotIsolatedCaller("getProcessesInErrorState"); 8710 // assume our apps are happy - lazy create the list 8711 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8712 8713 final boolean allUsers = ActivityManager.checkUidPermission( 8714 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8715 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8716 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8717 8718 synchronized (this) { 8719 8720 // iterate across all processes 8721 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8722 ProcessRecord app = mLruProcesses.get(i); 8723 if (!allUsers && app.userId != userId) { 8724 continue; 8725 } 8726 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8727 // This one's in trouble, so we'll generate a report for it 8728 // crashes are higher priority (in case there's a crash *and* an anr) 8729 ActivityManager.ProcessErrorStateInfo report = null; 8730 if (app.crashing) { 8731 report = app.crashingReport; 8732 } else if (app.notResponding) { 8733 report = app.notRespondingReport; 8734 } 8735 8736 if (report != null) { 8737 if (errList == null) { 8738 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8739 } 8740 errList.add(report); 8741 } else { 8742 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8743 " crashing = " + app.crashing + 8744 " notResponding = " + app.notResponding); 8745 } 8746 } 8747 } 8748 } 8749 8750 return errList; 8751 } 8752 oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp)8753 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8754 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8755 if (currApp != null) { 8756 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8757 } 8758 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8759 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8760 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8761 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8762 if (currApp != null) { 8763 currApp.lru = 0; 8764 } 8765 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8766 } else if (adj >= ProcessList.SERVICE_ADJ) { 8767 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8768 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8769 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8770 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8771 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8772 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8773 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8774 } else { 8775 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8776 } 8777 } 8778 fillInProcMemInfo(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo)8779 private void fillInProcMemInfo(ProcessRecord app, 8780 ActivityManager.RunningAppProcessInfo outInfo) { 8781 outInfo.pid = app.pid; 8782 outInfo.uid = app.info.uid; 8783 if (mHeavyWeightProcess == app) { 8784 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8785 } 8786 if (app.persistent) { 8787 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8788 } 8789 if (app.hasActivities) { 8790 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8791 } 8792 outInfo.lastTrimLevel = app.trimMemoryLevel; 8793 int adj = app.curAdj; 8794 outInfo.importance = oomAdjToImportance(adj, outInfo); 8795 outInfo.importanceReasonCode = app.adjTypeCode; 8796 } 8797 getRunningAppProcesses()8798 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8799 enforceNotIsolatedCaller("getRunningAppProcesses"); 8800 // Lazy instantiation of list 8801 List<ActivityManager.RunningAppProcessInfo> runList = null; 8802 final boolean allUsers = ActivityManager.checkUidPermission( 8803 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8804 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8805 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8806 synchronized (this) { 8807 // Iterate across all processes 8808 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8809 ProcessRecord app = mLruProcesses.get(i); 8810 if (!allUsers && app.userId != userId) { 8811 continue; 8812 } 8813 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8814 // Generate process state info for running application 8815 ActivityManager.RunningAppProcessInfo currApp = 8816 new ActivityManager.RunningAppProcessInfo(app.processName, 8817 app.pid, app.getPackageList()); 8818 fillInProcMemInfo(app, currApp); 8819 if (app.adjSource instanceof ProcessRecord) { 8820 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8821 currApp.importanceReasonImportance = oomAdjToImportance( 8822 app.adjSourceOom, null); 8823 } else if (app.adjSource instanceof ActivityRecord) { 8824 ActivityRecord r = (ActivityRecord)app.adjSource; 8825 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8826 } 8827 if (app.adjTarget instanceof ComponentName) { 8828 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8829 } 8830 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8831 // + " lru=" + currApp.lru); 8832 if (runList == null) { 8833 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8834 } 8835 runList.add(currApp); 8836 } 8837 } 8838 } 8839 return runList; 8840 } 8841 getRunningExternalApplications()8842 public List<ApplicationInfo> getRunningExternalApplications() { 8843 enforceNotIsolatedCaller("getRunningExternalApplications"); 8844 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8845 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8846 if (runningApps != null && runningApps.size() > 0) { 8847 Set<String> extList = new HashSet<String>(); 8848 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8849 if (app.pkgList != null) { 8850 for (String pkg : app.pkgList) { 8851 extList.add(pkg); 8852 } 8853 } 8854 } 8855 IPackageManager pm = AppGlobals.getPackageManager(); 8856 for (String pkg : extList) { 8857 try { 8858 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8859 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8860 retList.add(info); 8861 } 8862 } catch (RemoteException e) { 8863 } 8864 } 8865 } 8866 return retList; 8867 } 8868 8869 @Override getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)8870 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8871 enforceNotIsolatedCaller("getMyMemoryState"); 8872 synchronized (this) { 8873 ProcessRecord proc; 8874 synchronized (mPidsSelfLocked) { 8875 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8876 } 8877 fillInProcMemInfo(proc, outInfo); 8878 } 8879 } 8880 8881 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)8882 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8883 if (checkCallingPermission(android.Manifest.permission.DUMP) 8884 != PackageManager.PERMISSION_GRANTED) { 8885 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8886 + Binder.getCallingPid() 8887 + ", uid=" + Binder.getCallingUid() 8888 + " without permission " 8889 + android.Manifest.permission.DUMP); 8890 return; 8891 } 8892 8893 boolean dumpAll = false; 8894 boolean dumpClient = false; 8895 String dumpPackage = null; 8896 8897 int opti = 0; 8898 while (opti < args.length) { 8899 String opt = args[opti]; 8900 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8901 break; 8902 } 8903 opti++; 8904 if ("-a".equals(opt)) { 8905 dumpAll = true; 8906 } else if ("-c".equals(opt)) { 8907 dumpClient = true; 8908 } else if ("-h".equals(opt)) { 8909 pw.println("Activity manager dump options:"); 8910 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8911 pw.println(" cmd may be one of:"); 8912 pw.println(" a[ctivities]: activity stack state"); 8913 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 8914 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8915 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8916 pw.println(" o[om]: out of memory management"); 8917 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8918 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8919 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8920 pw.println(" service [COMP_SPEC]: service client-side state"); 8921 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8922 pw.println(" all: dump all activities"); 8923 pw.println(" top: dump the top activity"); 8924 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8925 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8926 pw.println(" a partial substring in a component name, a"); 8927 pw.println(" hex object identifier."); 8928 pw.println(" -a: include all available server state."); 8929 pw.println(" -c: include client state."); 8930 return; 8931 } else { 8932 pw.println("Unknown argument: " + opt + "; use -h for help"); 8933 } 8934 } 8935 8936 long origId = Binder.clearCallingIdentity(); 8937 boolean more = false; 8938 // Is the caller requesting to dump a particular piece of data? 8939 if (opti < args.length) { 8940 String cmd = args[opti]; 8941 opti++; 8942 if ("activities".equals(cmd) || "a".equals(cmd)) { 8943 synchronized (this) { 8944 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8945 } 8946 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8947 String[] newArgs; 8948 String name; 8949 if (opti >= args.length) { 8950 name = null; 8951 newArgs = EMPTY_STRING_ARRAY; 8952 } else { 8953 name = args[opti]; 8954 opti++; 8955 newArgs = new String[args.length - opti]; 8956 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8957 args.length - opti); 8958 } 8959 synchronized (this) { 8960 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8961 } 8962 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8963 String[] newArgs; 8964 String name; 8965 if (opti >= args.length) { 8966 name = null; 8967 newArgs = EMPTY_STRING_ARRAY; 8968 } else { 8969 name = args[opti]; 8970 opti++; 8971 newArgs = new String[args.length - opti]; 8972 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8973 args.length - opti); 8974 } 8975 synchronized (this) { 8976 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8977 } 8978 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8979 String[] newArgs; 8980 String name; 8981 if (opti >= args.length) { 8982 name = null; 8983 newArgs = EMPTY_STRING_ARRAY; 8984 } else { 8985 name = args[opti]; 8986 opti++; 8987 newArgs = new String[args.length - opti]; 8988 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8989 args.length - opti); 8990 } 8991 synchronized (this) { 8992 dumpProcessesLocked(fd, pw, args, opti, true, name); 8993 } 8994 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8995 synchronized (this) { 8996 dumpOomLocked(fd, pw, args, opti, true); 8997 } 8998 } else if ("provider".equals(cmd)) { 8999 String[] newArgs; 9000 String name; 9001 if (opti >= args.length) { 9002 name = null; 9003 newArgs = EMPTY_STRING_ARRAY; 9004 } else { 9005 name = args[opti]; 9006 opti++; 9007 newArgs = new String[args.length - opti]; 9008 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9009 } 9010 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 9011 pw.println("No providers match: " + name); 9012 pw.println("Use -h for help."); 9013 } 9014 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9015 synchronized (this) { 9016 dumpProvidersLocked(fd, pw, args, opti, true, null); 9017 } 9018 } else if ("service".equals(cmd)) { 9019 String[] newArgs; 9020 String name; 9021 if (opti >= args.length) { 9022 name = null; 9023 newArgs = EMPTY_STRING_ARRAY; 9024 } else { 9025 name = args[opti]; 9026 opti++; 9027 newArgs = new String[args.length - opti]; 9028 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9029 args.length - opti); 9030 } 9031 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 9032 pw.println("No services match: " + name); 9033 pw.println("Use -h for help."); 9034 } 9035 } else if ("package".equals(cmd)) { 9036 String[] newArgs; 9037 if (opti >= args.length) { 9038 pw.println("package: no package name specified"); 9039 pw.println("Use -h for help."); 9040 } else { 9041 dumpPackage = args[opti]; 9042 opti++; 9043 newArgs = new String[args.length - opti]; 9044 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9045 args.length - opti); 9046 args = newArgs; 9047 opti = 0; 9048 more = true; 9049 } 9050 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9051 synchronized (this) { 9052 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9053 } 9054 } else { 9055 // Dumping a single activity? 9056 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9057 pw.println("Bad activity command, or no activities match: " + cmd); 9058 pw.println("Use -h for help."); 9059 } 9060 } 9061 if (!more) { 9062 Binder.restoreCallingIdentity(origId); 9063 return; 9064 } 9065 } 9066 9067 // No piece of data specified, dump everything. 9068 synchronized (this) { 9069 boolean needSep; 9070 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9071 if (needSep) { 9072 pw.println(" "); 9073 } 9074 if (dumpAll) { 9075 pw.println("-------------------------------------------------------------------------------"); 9076 } 9077 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9078 if (needSep) { 9079 pw.println(" "); 9080 } 9081 if (dumpAll) { 9082 pw.println("-------------------------------------------------------------------------------"); 9083 } 9084 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9085 if (needSep) { 9086 pw.println(" "); 9087 } 9088 if (dumpAll) { 9089 pw.println("-------------------------------------------------------------------------------"); 9090 } 9091 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9092 if (needSep) { 9093 pw.println(" "); 9094 } 9095 if (dumpAll) { 9096 pw.println("-------------------------------------------------------------------------------"); 9097 } 9098 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9099 if (needSep) { 9100 pw.println(" "); 9101 } 9102 if (dumpAll) { 9103 pw.println("-------------------------------------------------------------------------------"); 9104 } 9105 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9106 } 9107 Binder.restoreCallingIdentity(origId); 9108 } 9109 dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)9110 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9111 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9112 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9113 pw.println(" Main stack:"); 9114 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9115 dumpPackage); 9116 pw.println(" "); 9117 pw.println(" Running activities (most recent first):"); 9118 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9119 dumpPackage); 9120 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9121 pw.println(" "); 9122 pw.println(" Activities waiting for another to become visible:"); 9123 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9124 !dumpAll, false, dumpPackage); 9125 } 9126 if (mMainStack.mStoppingActivities.size() > 0) { 9127 pw.println(" "); 9128 pw.println(" Activities waiting to stop:"); 9129 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9130 !dumpAll, false, dumpPackage); 9131 } 9132 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9133 pw.println(" "); 9134 pw.println(" Activities waiting to sleep:"); 9135 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9136 !dumpAll, false, dumpPackage); 9137 } 9138 if (mMainStack.mFinishingActivities.size() > 0) { 9139 pw.println(" "); 9140 pw.println(" Activities waiting to finish:"); 9141 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9142 !dumpAll, false, dumpPackage); 9143 } 9144 9145 pw.println(" "); 9146 if (mMainStack.mPausingActivity != null) { 9147 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9148 } 9149 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9150 pw.println(" mFocusedActivity: " + mFocusedActivity); 9151 if (dumpAll) { 9152 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9153 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9154 pw.println(" mDismissKeyguardOnNextActivity: " 9155 + mMainStack.mDismissKeyguardOnNextActivity); 9156 } 9157 9158 if (mRecentTasks.size() > 0) { 9159 pw.println(); 9160 pw.println(" Recent tasks:"); 9161 9162 final int N = mRecentTasks.size(); 9163 for (int i=0; i<N; i++) { 9164 TaskRecord tr = mRecentTasks.get(i); 9165 if (dumpPackage != null) { 9166 if (tr.realActivity == null || 9167 !dumpPackage.equals(tr.realActivity)) { 9168 continue; 9169 } 9170 } 9171 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9172 pw.println(tr); 9173 if (dumpAll) { 9174 mRecentTasks.get(i).dump(pw, " "); 9175 } 9176 } 9177 } 9178 9179 if (dumpAll) { 9180 pw.println(" "); 9181 pw.println(" mCurTask: " + mCurTask); 9182 } 9183 9184 return true; 9185 } 9186 dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9187 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9188 int opti, boolean dumpAll, String dumpPackage) { 9189 boolean needSep = false; 9190 int numPers = 0; 9191 9192 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9193 9194 if (dumpAll) { 9195 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9196 final int NA = procs.size(); 9197 for (int ia=0; ia<NA; ia++) { 9198 ProcessRecord r = procs.valueAt(ia); 9199 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9200 continue; 9201 } 9202 if (!needSep) { 9203 pw.println(" All known processes:"); 9204 needSep = true; 9205 } 9206 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9207 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9208 pw.print(" "); pw.println(r); 9209 r.dump(pw, " "); 9210 if (r.persistent) { 9211 numPers++; 9212 } 9213 } 9214 } 9215 } 9216 9217 if (mIsolatedProcesses.size() > 0) { 9218 if (needSep) pw.println(" "); 9219 needSep = true; 9220 pw.println(" Isolated process list (sorted by uid):"); 9221 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9222 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9223 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9224 continue; 9225 } 9226 pw.println(String.format("%sIsolated #%2d: %s", 9227 " ", i, r.toString())); 9228 } 9229 } 9230 9231 if (mLruProcesses.size() > 0) { 9232 if (needSep) pw.println(" "); 9233 needSep = true; 9234 pw.println(" Process LRU list (sorted by oom_adj):"); 9235 dumpProcessOomList(pw, this, mLruProcesses, " ", 9236 "Proc", "PERS", false, dumpPackage); 9237 needSep = true; 9238 } 9239 9240 if (dumpAll) { 9241 synchronized (mPidsSelfLocked) { 9242 boolean printed = false; 9243 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9244 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9245 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9246 continue; 9247 } 9248 if (!printed) { 9249 if (needSep) pw.println(" "); 9250 needSep = true; 9251 pw.println(" PID mappings:"); 9252 printed = true; 9253 } 9254 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9255 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9256 } 9257 } 9258 } 9259 9260 if (mForegroundProcesses.size() > 0) { 9261 synchronized (mPidsSelfLocked) { 9262 boolean printed = false; 9263 for (int i=0; i<mForegroundProcesses.size(); i++) { 9264 ProcessRecord r = mPidsSelfLocked.get( 9265 mForegroundProcesses.valueAt(i).pid); 9266 if (dumpPackage != null && (r == null 9267 || !dumpPackage.equals(r.info.packageName))) { 9268 continue; 9269 } 9270 if (!printed) { 9271 if (needSep) pw.println(" "); 9272 needSep = true; 9273 pw.println(" Foreground Processes:"); 9274 printed = true; 9275 } 9276 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9277 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9278 } 9279 } 9280 } 9281 9282 if (mPersistentStartingProcesses.size() > 0) { 9283 if (needSep) pw.println(" "); 9284 needSep = true; 9285 pw.println(" Persisent processes that are starting:"); 9286 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9287 "Starting Norm", "Restarting PERS", dumpPackage); 9288 } 9289 9290 if (mRemovedProcesses.size() > 0) { 9291 if (needSep) pw.println(" "); 9292 needSep = true; 9293 pw.println(" Processes that are being removed:"); 9294 dumpProcessList(pw, this, mRemovedProcesses, " ", 9295 "Removed Norm", "Removed PERS", dumpPackage); 9296 } 9297 9298 if (mProcessesOnHold.size() > 0) { 9299 if (needSep) pw.println(" "); 9300 needSep = true; 9301 pw.println(" Processes that are on old until the system is ready:"); 9302 dumpProcessList(pw, this, mProcessesOnHold, " ", 9303 "OnHold Norm", "OnHold PERS", dumpPackage); 9304 } 9305 9306 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9307 9308 if (mProcessCrashTimes.getMap().size() > 0) { 9309 boolean printed = false; 9310 long now = SystemClock.uptimeMillis(); 9311 for (Map.Entry<String, SparseArray<Long>> procs 9312 : mProcessCrashTimes.getMap().entrySet()) { 9313 String pname = procs.getKey(); 9314 SparseArray<Long> uids = procs.getValue(); 9315 final int N = uids.size(); 9316 for (int i=0; i<N; i++) { 9317 int puid = uids.keyAt(i); 9318 ProcessRecord r = mProcessNames.get(pname, puid); 9319 if (dumpPackage != null && (r == null 9320 || !dumpPackage.equals(r.info.packageName))) { 9321 continue; 9322 } 9323 if (!printed) { 9324 if (needSep) pw.println(" "); 9325 needSep = true; 9326 pw.println(" Time since processes crashed:"); 9327 printed = true; 9328 } 9329 pw.print(" Process "); pw.print(pname); 9330 pw.print(" uid "); pw.print(puid); 9331 pw.print(": last crashed "); 9332 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9333 pw.println(" ago"); 9334 } 9335 } 9336 } 9337 9338 if (mBadProcesses.getMap().size() > 0) { 9339 boolean printed = false; 9340 for (Map.Entry<String, SparseArray<Long>> procs 9341 : mBadProcesses.getMap().entrySet()) { 9342 String pname = procs.getKey(); 9343 SparseArray<Long> uids = procs.getValue(); 9344 final int N = uids.size(); 9345 for (int i=0; i<N; i++) { 9346 int puid = uids.keyAt(i); 9347 ProcessRecord r = mProcessNames.get(pname, puid); 9348 if (dumpPackage != null && (r == null 9349 || !dumpPackage.equals(r.info.packageName))) { 9350 continue; 9351 } 9352 if (!printed) { 9353 if (needSep) pw.println(" "); 9354 needSep = true; 9355 pw.println(" Bad processes:"); 9356 } 9357 pw.print(" Bad process "); pw.print(pname); 9358 pw.print(" uid "); pw.print(puid); 9359 pw.print(": crashed at time "); 9360 pw.println(uids.valueAt(i)); 9361 } 9362 } 9363 } 9364 9365 pw.println(); 9366 pw.println(" mStartedUsers:"); 9367 for (int i=0; i<mStartedUsers.size(); i++) { 9368 UserStartedState uss = mStartedUsers.valueAt(i); 9369 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9370 pw.print(": "); uss.dump("", pw); 9371 } 9372 pw.print(" mStartedUserArray: ["); 9373 for (int i=0; i<mStartedUserArray.length; i++) { 9374 if (i > 0) pw.print(", "); 9375 pw.print(mStartedUserArray[i]); 9376 } 9377 pw.println("]"); 9378 pw.print(" mUserLru: ["); 9379 for (int i=0; i<mUserLru.size(); i++) { 9380 if (i > 0) pw.print(", "); 9381 pw.print(mUserLru.get(i)); 9382 } 9383 pw.println("]"); 9384 if (dumpAll) { 9385 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9386 } 9387 pw.println(" mHomeProcess: " + mHomeProcess); 9388 pw.println(" mPreviousProcess: " + mPreviousProcess); 9389 if (dumpAll) { 9390 StringBuilder sb = new StringBuilder(128); 9391 sb.append(" mPreviousProcessVisibleTime: "); 9392 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9393 pw.println(sb); 9394 } 9395 if (mHeavyWeightProcess != null) { 9396 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9397 } 9398 pw.println(" mConfiguration: " + mConfiguration); 9399 if (dumpAll) { 9400 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9401 if (mCompatModePackages.getPackages().size() > 0) { 9402 boolean printed = false; 9403 for (Map.Entry<String, Integer> entry 9404 : mCompatModePackages.getPackages().entrySet()) { 9405 String pkg = entry.getKey(); 9406 int mode = entry.getValue(); 9407 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9408 continue; 9409 } 9410 if (!printed) { 9411 pw.println(" mScreenCompatPackages:"); 9412 printed = true; 9413 } 9414 pw.print(" "); pw.print(pkg); pw.print(": "); 9415 pw.print(mode); pw.println(); 9416 } 9417 } 9418 } 9419 if (mSleeping || mWentToSleep || mLockScreenShown) { 9420 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9421 + " mLockScreenShown " + mLockScreenShown); 9422 } 9423 if (mShuttingDown) { 9424 pw.println(" mShuttingDown=" + mShuttingDown); 9425 } 9426 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9427 || mOrigWaitForDebugger) { 9428 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9429 + " mDebugTransient=" + mDebugTransient 9430 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9431 } 9432 if (mOpenGlTraceApp != null) { 9433 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9434 } 9435 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9436 || mProfileFd != null) { 9437 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9438 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9439 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9440 + mAutoStopProfiler); 9441 } 9442 if (mAlwaysFinishActivities || mController != null) { 9443 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9444 + " mController=" + mController); 9445 } 9446 if (dumpAll) { 9447 pw.println(" Total persistent processes: " + numPers); 9448 pw.println(" mStartRunning=" + mStartRunning 9449 + " mProcessesReady=" + mProcessesReady 9450 + " mSystemReady=" + mSystemReady); 9451 pw.println(" mBooting=" + mBooting 9452 + " mBooted=" + mBooted 9453 + " mFactoryTest=" + mFactoryTest); 9454 pw.print(" mLastPowerCheckRealtime="); 9455 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9456 pw.println(""); 9457 pw.print(" mLastPowerCheckUptime="); 9458 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9459 pw.println(""); 9460 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9461 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9462 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9463 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9464 + " mNumHiddenProcs=" + mNumHiddenProcs 9465 + " mNumServiceProcs=" + mNumServiceProcs 9466 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9467 } 9468 9469 return true; 9470 } 9471 dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean needSep, boolean dumpAll, String dumpPackage)9472 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9473 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9474 if (mProcessesToGc.size() > 0) { 9475 boolean printed = false; 9476 long now = SystemClock.uptimeMillis(); 9477 for (int i=0; i<mProcessesToGc.size(); i++) { 9478 ProcessRecord proc = mProcessesToGc.get(i); 9479 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9480 continue; 9481 } 9482 if (!printed) { 9483 if (needSep) pw.println(" "); 9484 needSep = true; 9485 pw.println(" Processes that are waiting to GC:"); 9486 printed = true; 9487 } 9488 pw.print(" Process "); pw.println(proc); 9489 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9490 pw.print(", last gced="); 9491 pw.print(now-proc.lastRequestedGc); 9492 pw.print(" ms ago, last lowMem="); 9493 pw.print(now-proc.lastLowMemory); 9494 pw.println(" ms ago"); 9495 9496 } 9497 } 9498 return needSep; 9499 } 9500 dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll)9501 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9502 int opti, boolean dumpAll) { 9503 boolean needSep = false; 9504 9505 if (mLruProcesses.size() > 0) { 9506 if (needSep) pw.println(" "); 9507 needSep = true; 9508 pw.println(" OOM levels:"); 9509 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9510 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9511 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9512 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9513 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9514 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9515 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9516 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9517 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9518 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9519 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9520 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9521 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9522 9523 if (needSep) pw.println(" "); 9524 needSep = true; 9525 pw.println(" Process OOM control:"); 9526 dumpProcessOomList(pw, this, mLruProcesses, " ", 9527 "Proc", "PERS", true, null); 9528 needSep = true; 9529 } 9530 9531 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9532 9533 pw.println(); 9534 pw.println(" mHomeProcess: " + mHomeProcess); 9535 pw.println(" mPreviousProcess: " + mPreviousProcess); 9536 if (mHeavyWeightProcess != null) { 9537 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9538 } 9539 9540 return true; 9541 } 9542 9543 /** 9544 * There are three ways to call this: 9545 * - no provider specified: dump all the providers 9546 * - a flattened component name that matched an existing provider was specified as the 9547 * first arg: dump that one provider 9548 * - the first arg isn't the flattened component name of an existing provider: 9549 * dump all providers whose component contains the first arg as a substring 9550 */ dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9551 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9552 int opti, boolean dumpAll) { 9553 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9554 } 9555 9556 static class ItemMatcher { 9557 ArrayList<ComponentName> components; 9558 ArrayList<String> strings; 9559 ArrayList<Integer> objects; 9560 boolean all; 9561 ItemMatcher()9562 ItemMatcher() { 9563 all = true; 9564 } 9565 build(String name)9566 void build(String name) { 9567 ComponentName componentName = ComponentName.unflattenFromString(name); 9568 if (componentName != null) { 9569 if (components == null) { 9570 components = new ArrayList<ComponentName>(); 9571 } 9572 components.add(componentName); 9573 all = false; 9574 } else { 9575 int objectId = 0; 9576 // Not a '/' separated full component name; maybe an object ID? 9577 try { 9578 objectId = Integer.parseInt(name, 16); 9579 if (objects == null) { 9580 objects = new ArrayList<Integer>(); 9581 } 9582 objects.add(objectId); 9583 all = false; 9584 } catch (RuntimeException e) { 9585 // Not an integer; just do string match. 9586 if (strings == null) { 9587 strings = new ArrayList<String>(); 9588 } 9589 strings.add(name); 9590 all = false; 9591 } 9592 } 9593 } 9594 build(String[] args, int opti)9595 int build(String[] args, int opti) { 9596 for (; opti<args.length; opti++) { 9597 String name = args[opti]; 9598 if ("--".equals(name)) { 9599 return opti+1; 9600 } 9601 build(name); 9602 } 9603 return opti; 9604 } 9605 match(Object object, ComponentName comp)9606 boolean match(Object object, ComponentName comp) { 9607 if (all) { 9608 return true; 9609 } 9610 if (components != null) { 9611 for (int i=0; i<components.size(); i++) { 9612 if (components.get(i).equals(comp)) { 9613 return true; 9614 } 9615 } 9616 } 9617 if (objects != null) { 9618 for (int i=0; i<objects.size(); i++) { 9619 if (System.identityHashCode(object) == objects.get(i)) { 9620 return true; 9621 } 9622 } 9623 } 9624 if (strings != null) { 9625 String flat = comp.flattenToString(); 9626 for (int i=0; i<strings.size(); i++) { 9627 if (flat.contains(strings.get(i))) { 9628 return true; 9629 } 9630 } 9631 } 9632 return false; 9633 } 9634 } 9635 9636 /** 9637 * There are three things that cmd can be: 9638 * - a flattened component name that matches an existing activity 9639 * - the cmd arg isn't the flattened component name of an existing activity: 9640 * dump all activity whose component contains the cmd as a substring 9641 * - A hex number of the ActivityRecord object instance. 9642 */ dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9643 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9644 int opti, boolean dumpAll) { 9645 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9646 9647 if ("all".equals(name)) { 9648 synchronized (this) { 9649 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9650 activities.add(r1); 9651 } 9652 } 9653 } else if ("top".equals(name)) { 9654 synchronized (this) { 9655 final int N = mMainStack.mHistory.size(); 9656 if (N > 0) { 9657 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9658 } 9659 } 9660 } else { 9661 ItemMatcher matcher = new ItemMatcher(); 9662 matcher.build(name); 9663 9664 synchronized (this) { 9665 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9666 if (matcher.match(r1, r1.intent.getComponent())) { 9667 activities.add(r1); 9668 } 9669 } 9670 } 9671 } 9672 9673 if (activities.size() <= 0) { 9674 return false; 9675 } 9676 9677 String[] newArgs = new String[args.length - opti]; 9678 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9679 9680 TaskRecord lastTask = null; 9681 boolean needSep = false; 9682 for (int i=activities.size()-1; i>=0; i--) { 9683 ActivityRecord r = (ActivityRecord)activities.get(i); 9684 if (needSep) { 9685 pw.println(); 9686 } 9687 needSep = true; 9688 synchronized (this) { 9689 if (lastTask != r.task) { 9690 lastTask = r.task; 9691 pw.print("TASK "); pw.print(lastTask.affinity); 9692 pw.print(" id="); pw.println(lastTask.taskId); 9693 if (dumpAll) { 9694 lastTask.dump(pw, " "); 9695 } 9696 } 9697 } 9698 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9699 } 9700 return true; 9701 } 9702 9703 /** 9704 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9705 * there is a thread associated with the activity. 9706 */ dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, final ActivityRecord r, String[] args, boolean dumpAll)9707 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9708 final ActivityRecord r, String[] args, boolean dumpAll) { 9709 String innerPrefix = prefix + " "; 9710 synchronized (this) { 9711 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9712 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9713 pw.print(" pid="); 9714 if (r.app != null) pw.println(r.app.pid); 9715 else pw.println("(not running)"); 9716 if (dumpAll) { 9717 r.dump(pw, innerPrefix); 9718 } 9719 } 9720 if (r.app != null && r.app.thread != null) { 9721 // flush anything that is already in the PrintWriter since the thread is going 9722 // to write to the file descriptor directly 9723 pw.flush(); 9724 try { 9725 TransferPipe tp = new TransferPipe(); 9726 try { 9727 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9728 r.appToken, innerPrefix, args); 9729 tp.go(fd); 9730 } finally { 9731 tp.kill(); 9732 } 9733 } catch (IOException e) { 9734 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9735 } catch (RemoteException e) { 9736 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9737 } 9738 } 9739 } 9740 dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9741 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9742 int opti, boolean dumpAll, String dumpPackage) { 9743 boolean needSep = false; 9744 boolean onlyHistory = false; 9745 9746 if ("history".equals(dumpPackage)) { 9747 if (opti < args.length && "-s".equals(args[opti])) { 9748 dumpAll = false; 9749 } 9750 onlyHistory = true; 9751 dumpPackage = null; 9752 } 9753 9754 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9755 if (!onlyHistory && dumpAll) { 9756 if (mRegisteredReceivers.size() > 0) { 9757 boolean printed = false; 9758 Iterator it = mRegisteredReceivers.values().iterator(); 9759 while (it.hasNext()) { 9760 ReceiverList r = (ReceiverList)it.next(); 9761 if (dumpPackage != null && (r.app == null || 9762 !dumpPackage.equals(r.app.info.packageName))) { 9763 continue; 9764 } 9765 if (!printed) { 9766 pw.println(" Registered Receivers:"); 9767 needSep = true; 9768 printed = true; 9769 } 9770 pw.print(" * "); pw.println(r); 9771 r.dump(pw, " "); 9772 } 9773 } 9774 9775 if (mReceiverResolver.dump(pw, needSep ? 9776 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9777 " ", dumpPackage, false)) { 9778 needSep = true; 9779 } 9780 } 9781 9782 for (BroadcastQueue q : mBroadcastQueues) { 9783 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9784 } 9785 9786 needSep = true; 9787 9788 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9789 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9790 if (needSep) { 9791 pw.println(); 9792 } 9793 needSep = true; 9794 pw.print(" Sticky broadcasts for user "); 9795 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9796 StringBuilder sb = new StringBuilder(128); 9797 for (Map.Entry<String, ArrayList<Intent>> ent 9798 : mStickyBroadcasts.valueAt(user).entrySet()) { 9799 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9800 if (dumpAll) { 9801 pw.println(":"); 9802 ArrayList<Intent> intents = ent.getValue(); 9803 final int N = intents.size(); 9804 for (int i=0; i<N; i++) { 9805 sb.setLength(0); 9806 sb.append(" Intent: "); 9807 intents.get(i).toShortString(sb, false, true, false, false); 9808 pw.println(sb.toString()); 9809 Bundle bundle = intents.get(i).getExtras(); 9810 if (bundle != null) { 9811 pw.print(" "); 9812 pw.println(bundle.toString()); 9813 } 9814 } 9815 } else { 9816 pw.println(""); 9817 } 9818 } 9819 } 9820 } 9821 9822 if (!onlyHistory && dumpAll) { 9823 pw.println(); 9824 for (BroadcastQueue queue : mBroadcastQueues) { 9825 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9826 + queue.mBroadcastsScheduled); 9827 } 9828 pw.println(" mHandler:"); 9829 mHandler.dump(new PrintWriterPrinter(pw), " "); 9830 needSep = true; 9831 } 9832 9833 return needSep; 9834 } 9835 dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9836 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9837 int opti, boolean dumpAll, String dumpPackage) { 9838 boolean needSep = true; 9839 9840 ItemMatcher matcher = new ItemMatcher(); 9841 matcher.build(args, opti); 9842 9843 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9844 9845 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9846 9847 if (mLaunchingProviders.size() > 0) { 9848 boolean printed = false; 9849 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9850 ContentProviderRecord r = mLaunchingProviders.get(i); 9851 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9852 continue; 9853 } 9854 if (!printed) { 9855 if (needSep) pw.println(" "); 9856 needSep = true; 9857 pw.println(" Launching content providers:"); 9858 printed = true; 9859 } 9860 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9861 pw.println(r); 9862 } 9863 } 9864 9865 if (mGrantedUriPermissions.size() > 0) { 9866 if (needSep) pw.println(); 9867 needSep = true; 9868 pw.println("Granted Uri Permissions:"); 9869 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9870 int uid = mGrantedUriPermissions.keyAt(i); 9871 HashMap<Uri, UriPermission> perms 9872 = mGrantedUriPermissions.valueAt(i); 9873 pw.print(" * UID "); pw.print(uid); 9874 pw.println(" holds:"); 9875 for (UriPermission perm : perms.values()) { 9876 pw.print(" "); pw.println(perm); 9877 if (dumpAll) { 9878 perm.dump(pw, " "); 9879 } 9880 } 9881 } 9882 needSep = true; 9883 } 9884 9885 return needSep; 9886 } 9887 dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9888 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9889 int opti, boolean dumpAll, String dumpPackage) { 9890 boolean needSep = false; 9891 9892 if (mIntentSenderRecords.size() > 0) { 9893 boolean printed = false; 9894 Iterator<WeakReference<PendingIntentRecord>> it 9895 = mIntentSenderRecords.values().iterator(); 9896 while (it.hasNext()) { 9897 WeakReference<PendingIntentRecord> ref = it.next(); 9898 PendingIntentRecord rec = ref != null ? ref.get(): null; 9899 if (dumpPackage != null && (rec == null 9900 || !dumpPackage.equals(rec.key.packageName))) { 9901 continue; 9902 } 9903 if (!printed) { 9904 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9905 printed = true; 9906 } 9907 needSep = true; 9908 if (rec != null) { 9909 pw.print(" * "); pw.println(rec); 9910 if (dumpAll) { 9911 rec.dump(pw, " "); 9912 } 9913 } else { 9914 pw.print(" * "); pw.println(ref); 9915 } 9916 } 9917 } 9918 9919 return needSep; 9920 } 9921 dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage)9922 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9923 String prefix, String label, boolean complete, boolean brief, boolean client, 9924 String dumpPackage) { 9925 TaskRecord lastTask = null; 9926 boolean needNL = false; 9927 final String innerPrefix = prefix + " "; 9928 final String[] args = new String[0]; 9929 for (int i=list.size()-1; i>=0; i--) { 9930 final ActivityRecord r = (ActivityRecord)list.get(i); 9931 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9932 continue; 9933 } 9934 final boolean full = !brief && (complete || !r.isInHistory()); 9935 if (needNL) { 9936 pw.println(" "); 9937 needNL = false; 9938 } 9939 if (lastTask != r.task) { 9940 lastTask = r.task; 9941 pw.print(prefix); 9942 pw.print(full ? "* " : " "); 9943 pw.println(lastTask); 9944 if (full) { 9945 lastTask.dump(pw, prefix + " "); 9946 } else if (complete) { 9947 // Complete + brief == give a summary. Isn't that obvious?!? 9948 if (lastTask.intent != null) { 9949 pw.print(prefix); pw.print(" "); 9950 pw.println(lastTask.intent.toInsecureStringWithClip()); 9951 } 9952 } 9953 } 9954 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9955 pw.print(" #"); pw.print(i); pw.print(": "); 9956 pw.println(r); 9957 if (full) { 9958 r.dump(pw, innerPrefix); 9959 } else if (complete) { 9960 // Complete + brief == give a summary. Isn't that obvious?!? 9961 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9962 if (r.app != null) { 9963 pw.print(innerPrefix); pw.println(r.app); 9964 } 9965 } 9966 if (client && r.app != null && r.app.thread != null) { 9967 // flush anything that is already in the PrintWriter since the thread is going 9968 // to write to the file descriptor directly 9969 pw.flush(); 9970 try { 9971 TransferPipe tp = new TransferPipe(); 9972 try { 9973 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9974 r.appToken, innerPrefix, args); 9975 // Short timeout, since blocking here can 9976 // deadlock with the application. 9977 tp.go(fd, 2000); 9978 } finally { 9979 tp.kill(); 9980 } 9981 } catch (IOException e) { 9982 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9983 } catch (RemoteException e) { 9984 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9985 } 9986 needNL = true; 9987 } 9988 } 9989 } 9990 buildOomTag(String prefix, String space, int val, int base)9991 private static String buildOomTag(String prefix, String space, int val, int base) { 9992 if (val == base) { 9993 if (space == null) return prefix; 9994 return prefix + " "; 9995 } 9996 return prefix + "+" + Integer.toString(val-base); 9997 } 9998 dumpProcessList(PrintWriter pw, ActivityManagerService service, List list, String prefix, String normalLabel, String persistentLabel, String dumpPackage)9999 private static final int dumpProcessList(PrintWriter pw, 10000 ActivityManagerService service, List list, 10001 String prefix, String normalLabel, String persistentLabel, 10002 String dumpPackage) { 10003 int numPers = 0; 10004 final int N = list.size()-1; 10005 for (int i=N; i>=0; i--) { 10006 ProcessRecord r = (ProcessRecord)list.get(i); 10007 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10008 continue; 10009 } 10010 pw.println(String.format("%s%s #%2d: %s", 10011 prefix, (r.persistent ? persistentLabel : normalLabel), 10012 i, r.toString())); 10013 if (r.persistent) { 10014 numPers++; 10015 } 10016 } 10017 return numPers; 10018 } 10019 dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)10020 private static final boolean dumpProcessOomList(PrintWriter pw, 10021 ActivityManagerService service, List<ProcessRecord> origList, 10022 String prefix, String normalLabel, String persistentLabel, 10023 boolean inclDetails, String dumpPackage) { 10024 10025 ArrayList<Pair<ProcessRecord, Integer>> list 10026 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 10027 for (int i=0; i<origList.size(); i++) { 10028 ProcessRecord r = origList.get(i); 10029 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10030 continue; 10031 } 10032 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 10033 } 10034 10035 if (list.size() <= 0) { 10036 return false; 10037 } 10038 10039 Comparator<Pair<ProcessRecord, Integer>> comparator 10040 = new Comparator<Pair<ProcessRecord, Integer>>() { 10041 @Override 10042 public int compare(Pair<ProcessRecord, Integer> object1, 10043 Pair<ProcessRecord, Integer> object2) { 10044 if (object1.first.setAdj != object2.first.setAdj) { 10045 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10046 } 10047 if (object1.second.intValue() != object2.second.intValue()) { 10048 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10049 } 10050 return 0; 10051 } 10052 }; 10053 10054 Collections.sort(list, comparator); 10055 10056 final long curRealtime = SystemClock.elapsedRealtime(); 10057 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10058 final long curUptime = SystemClock.uptimeMillis(); 10059 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10060 10061 for (int i=list.size()-1; i>=0; i--) { 10062 ProcessRecord r = list.get(i).first; 10063 String oomAdj; 10064 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10065 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10066 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10067 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10068 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10069 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10070 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10071 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10072 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10073 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10074 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10075 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10076 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10077 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10078 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10079 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10080 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10081 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10082 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10083 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10084 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10085 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10086 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10087 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10088 } else { 10089 oomAdj = Integer.toString(r.setAdj); 10090 } 10091 String schedGroup; 10092 switch (r.setSchedGroup) { 10093 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10094 schedGroup = "B"; 10095 break; 10096 case Process.THREAD_GROUP_DEFAULT: 10097 schedGroup = "F"; 10098 break; 10099 default: 10100 schedGroup = Integer.toString(r.setSchedGroup); 10101 break; 10102 } 10103 String foreground; 10104 if (r.foregroundActivities) { 10105 foreground = "A"; 10106 } else if (r.foregroundServices) { 10107 foreground = "S"; 10108 } else { 10109 foreground = " "; 10110 } 10111 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10112 prefix, (r.persistent ? persistentLabel : normalLabel), 10113 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10114 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10115 if (r.adjSource != null || r.adjTarget != null) { 10116 pw.print(prefix); 10117 pw.print(" "); 10118 if (r.adjTarget instanceof ComponentName) { 10119 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10120 } else if (r.adjTarget != null) { 10121 pw.print(r.adjTarget.toString()); 10122 } else { 10123 pw.print("{null}"); 10124 } 10125 pw.print("<="); 10126 if (r.adjSource instanceof ProcessRecord) { 10127 pw.print("Proc{"); 10128 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10129 pw.println("}"); 10130 } else if (r.adjSource != null) { 10131 pw.println(r.adjSource.toString()); 10132 } else { 10133 pw.println("{null}"); 10134 } 10135 } 10136 if (inclDetails) { 10137 pw.print(prefix); 10138 pw.print(" "); 10139 pw.print("oom: max="); pw.print(r.maxAdj); 10140 pw.print(" hidden="); pw.print(r.hiddenAdj); 10141 pw.print(" client="); pw.print(r.clientHiddenAdj); 10142 pw.print(" empty="); pw.print(r.emptyAdj); 10143 pw.print(" curRaw="); pw.print(r.curRawAdj); 10144 pw.print(" setRaw="); pw.print(r.setRawAdj); 10145 pw.print(" cur="); pw.print(r.curAdj); 10146 pw.print(" set="); pw.println(r.setAdj); 10147 pw.print(prefix); 10148 pw.print(" "); 10149 pw.print("keeping="); pw.print(r.keeping); 10150 pw.print(" hidden="); pw.print(r.hidden); 10151 pw.print(" empty="); pw.print(r.empty); 10152 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10153 10154 if (!r.keeping) { 10155 if (r.lastWakeTime != 0) { 10156 long wtime; 10157 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10158 synchronized (stats) { 10159 wtime = stats.getProcessWakeTime(r.info.uid, 10160 r.pid, curRealtime); 10161 } 10162 long timeUsed = wtime - r.lastWakeTime; 10163 pw.print(prefix); 10164 pw.print(" "); 10165 pw.print("keep awake over "); 10166 TimeUtils.formatDuration(realtimeSince, pw); 10167 pw.print(" used "); 10168 TimeUtils.formatDuration(timeUsed, pw); 10169 pw.print(" ("); 10170 pw.print((timeUsed*100)/realtimeSince); 10171 pw.println("%)"); 10172 } 10173 if (r.lastCpuTime != 0) { 10174 long timeUsed = r.curCpuTime - r.lastCpuTime; 10175 pw.print(prefix); 10176 pw.print(" "); 10177 pw.print("run cpu over "); 10178 TimeUtils.formatDuration(uptimeSince, pw); 10179 pw.print(" used "); 10180 TimeUtils.formatDuration(timeUsed, pw); 10181 pw.print(" ("); 10182 pw.print((timeUsed*100)/uptimeSince); 10183 pw.println("%)"); 10184 } 10185 } 10186 } 10187 } 10188 return true; 10189 } 10190 collectProcesses(PrintWriter pw, int start, String[] args)10191 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10192 ArrayList<ProcessRecord> procs; 10193 synchronized (this) { 10194 if (args != null && args.length > start 10195 && args[start].charAt(0) != '-') { 10196 procs = new ArrayList<ProcessRecord>(); 10197 int pid = -1; 10198 try { 10199 pid = Integer.parseInt(args[start]); 10200 } catch (NumberFormatException e) { 10201 10202 } 10203 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10204 ProcessRecord proc = mLruProcesses.get(i); 10205 if (proc.pid == pid) { 10206 procs.add(proc); 10207 } else if (proc.processName.equals(args[start])) { 10208 procs.add(proc); 10209 } 10210 } 10211 if (procs.size() <= 0) { 10212 pw.println("No process found for: " + args[start]); 10213 return null; 10214 } 10215 } else { 10216 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10217 } 10218 } 10219 return procs; 10220 } 10221 dumpGraphicsHardwareUsage(FileDescriptor fd, PrintWriter pw, String[] args)10222 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10223 PrintWriter pw, String[] args) { 10224 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10225 if (procs == null) { 10226 return; 10227 } 10228 10229 long uptime = SystemClock.uptimeMillis(); 10230 long realtime = SystemClock.elapsedRealtime(); 10231 pw.println("Applications Graphics Acceleration Info:"); 10232 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10233 10234 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10235 ProcessRecord r = procs.get(i); 10236 if (r.thread != null) { 10237 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10238 pw.flush(); 10239 try { 10240 TransferPipe tp = new TransferPipe(); 10241 try { 10242 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10243 tp.go(fd); 10244 } finally { 10245 tp.kill(); 10246 } 10247 } catch (IOException e) { 10248 pw.println("Failure while dumping the app: " + r); 10249 pw.flush(); 10250 } catch (RemoteException e) { 10251 pw.println("Got a RemoteException while dumping the app " + r); 10252 pw.flush(); 10253 } 10254 } 10255 } 10256 } 10257 dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args)10258 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10259 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10260 if (procs == null) { 10261 return; 10262 } 10263 10264 pw.println("Applications Database Info:"); 10265 10266 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10267 ProcessRecord r = procs.get(i); 10268 if (r.thread != null) { 10269 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10270 pw.flush(); 10271 try { 10272 TransferPipe tp = new TransferPipe(); 10273 try { 10274 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10275 tp.go(fd); 10276 } finally { 10277 tp.kill(); 10278 } 10279 } catch (IOException e) { 10280 pw.println("Failure while dumping the app: " + r); 10281 pw.flush(); 10282 } catch (RemoteException e) { 10283 pw.println("Got a RemoteException while dumping the app " + r); 10284 pw.flush(); 10285 } 10286 } 10287 } 10288 } 10289 10290 final static class MemItem { 10291 final String label; 10292 final String shortLabel; 10293 final long pss; 10294 final int id; 10295 ArrayList<MemItem> subitems; 10296 MemItem(String _label, String _shortLabel, long _pss, int _id)10297 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10298 label = _label; 10299 shortLabel = _shortLabel; 10300 pss = _pss; 10301 id = _id; 10302 } 10303 } 10304 dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, boolean sort)10305 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10306 boolean sort) { 10307 if (sort) { 10308 Collections.sort(items, new Comparator<MemItem>() { 10309 @Override 10310 public int compare(MemItem lhs, MemItem rhs) { 10311 if (lhs.pss < rhs.pss) { 10312 return 1; 10313 } else if (lhs.pss > rhs.pss) { 10314 return -1; 10315 } 10316 return 0; 10317 } 10318 }); 10319 } 10320 10321 for (int i=0; i<items.size(); i++) { 10322 MemItem mi = items.get(i); 10323 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10324 if (mi.subitems != null) { 10325 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10326 } 10327 } 10328 } 10329 10330 // These are in KB. 10331 static final long[] DUMP_MEM_BUCKETS = new long[] { 10332 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10333 120*1024, 160*1024, 200*1024, 10334 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10335 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10336 }; 10337 appendMemBucket(StringBuilder out, long memKB, String label, boolean stackLike)10338 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10339 boolean stackLike) { 10340 int start = label.lastIndexOf('.'); 10341 if (start >= 0) start++; 10342 else start = 0; 10343 int end = label.length(); 10344 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10345 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10346 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10347 out.append(bucket); 10348 out.append(stackLike ? "MB." : "MB "); 10349 out.append(label, start, end); 10350 return; 10351 } 10352 } 10353 out.append(memKB/1024); 10354 out.append(stackLike ? "MB." : "MB "); 10355 out.append(label, start, end); 10356 } 10357 10358 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10359 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10360 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10361 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10362 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10363 }; 10364 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10365 "System", "Persistent", "Foreground", 10366 "Visible", "Perceptible", "Heavy Weight", 10367 "Backup", "A Services", "Home", "Previous", 10368 "B Services", "Background" 10369 }; 10370 dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack)10371 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10372 PrintWriter pw, String prefix, String[] args, boolean brief, 10373 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10374 boolean dumpAll = false; 10375 boolean oomOnly = false; 10376 10377 int opti = 0; 10378 while (opti < args.length) { 10379 String opt = args[opti]; 10380 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10381 break; 10382 } 10383 opti++; 10384 if ("-a".equals(opt)) { 10385 dumpAll = true; 10386 } else if ("--oom".equals(opt)) { 10387 oomOnly = true; 10388 } else if ("-h".equals(opt)) { 10389 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10390 pw.println(" -a: include all available information for each process."); 10391 pw.println(" --oom: only show processes organized by oom adj."); 10392 pw.println("If [process] is specified it can be the name or "); 10393 pw.println("pid of a specific process to dump."); 10394 return; 10395 } else { 10396 pw.println("Unknown argument: " + opt + "; use -h for help"); 10397 } 10398 } 10399 10400 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10401 if (procs == null) { 10402 return; 10403 } 10404 10405 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10406 long uptime = SystemClock.uptimeMillis(); 10407 long realtime = SystemClock.elapsedRealtime(); 10408 10409 if (procs.size() == 1 || isCheckinRequest) { 10410 dumpAll = true; 10411 } 10412 10413 if (isCheckinRequest) { 10414 // short checkin version 10415 pw.println(uptime + "," + realtime); 10416 pw.flush(); 10417 } else { 10418 pw.println("Applications Memory Usage (kB):"); 10419 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10420 } 10421 10422 String[] innerArgs = new String[args.length-opti]; 10423 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10424 10425 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10426 long nativePss=0, dalvikPss=0, otherPss=0; 10427 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10428 10429 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10430 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10431 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10432 10433 long totalPss = 0; 10434 10435 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10436 ProcessRecord r = procs.get(i); 10437 if (r.thread != null) { 10438 if (!isCheckinRequest && dumpAll) { 10439 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10440 pw.flush(); 10441 } 10442 Debug.MemoryInfo mi = null; 10443 if (dumpAll) { 10444 try { 10445 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10446 } catch (RemoteException e) { 10447 if (!isCheckinRequest) { 10448 pw.println("Got RemoteException!"); 10449 pw.flush(); 10450 } 10451 } 10452 } else { 10453 mi = new Debug.MemoryInfo(); 10454 Debug.getMemoryInfo(r.pid, mi); 10455 } 10456 10457 if (!isCheckinRequest && mi != null) { 10458 long myTotalPss = mi.getTotalPss(); 10459 totalPss += myTotalPss; 10460 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10461 r.processName, myTotalPss, 0); 10462 procMems.add(pssItem); 10463 10464 nativePss += mi.nativePss; 10465 dalvikPss += mi.dalvikPss; 10466 otherPss += mi.otherPss; 10467 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10468 long mem = mi.getOtherPss(j); 10469 miscPss[j] += mem; 10470 otherPss -= mem; 10471 } 10472 10473 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10474 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10475 || oomIndex == (oomPss.length-1)) { 10476 oomPss[oomIndex] += myTotalPss; 10477 if (oomProcs[oomIndex] == null) { 10478 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10479 } 10480 oomProcs[oomIndex].add(pssItem); 10481 break; 10482 } 10483 } 10484 } 10485 } 10486 } 10487 10488 if (!isCheckinRequest && procs.size() > 1) { 10489 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10490 10491 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10492 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10493 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10494 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10495 String label = Debug.MemoryInfo.getOtherLabel(j); 10496 catMems.add(new MemItem(label, label, miscPss[j], j)); 10497 } 10498 10499 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10500 for (int j=0; j<oomPss.length; j++) { 10501 if (oomPss[j] != 0) { 10502 String label = DUMP_MEM_OOM_LABEL[j]; 10503 MemItem item = new MemItem(label, label, oomPss[j], 10504 DUMP_MEM_OOM_ADJ[j]); 10505 item.subitems = oomProcs[j]; 10506 oomMems.add(item); 10507 } 10508 } 10509 10510 if (outTag != null || outStack != null) { 10511 if (outTag != null) { 10512 appendMemBucket(outTag, totalPss, "total", false); 10513 } 10514 if (outStack != null) { 10515 appendMemBucket(outStack, totalPss, "total", true); 10516 } 10517 boolean firstLine = true; 10518 for (int i=0; i<oomMems.size(); i++) { 10519 MemItem miCat = oomMems.get(i); 10520 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10521 continue; 10522 } 10523 if (miCat.id < ProcessList.SERVICE_ADJ 10524 || miCat.id == ProcessList.HOME_APP_ADJ 10525 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10526 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10527 outTag.append(" / "); 10528 } 10529 if (outStack != null) { 10530 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10531 if (firstLine) { 10532 outStack.append(":"); 10533 firstLine = false; 10534 } 10535 outStack.append("\n\t at "); 10536 } else { 10537 outStack.append("$"); 10538 } 10539 } 10540 for (int j=0; j<miCat.subitems.size(); j++) { 10541 MemItem mi = miCat.subitems.get(j); 10542 if (j > 0) { 10543 if (outTag != null) { 10544 outTag.append(" "); 10545 } 10546 if (outStack != null) { 10547 outStack.append("$"); 10548 } 10549 } 10550 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10551 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10552 } 10553 if (outStack != null) { 10554 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10555 } 10556 } 10557 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10558 outStack.append("("); 10559 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10560 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10561 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10562 outStack.append(":"); 10563 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10564 } 10565 } 10566 outStack.append(")"); 10567 } 10568 } 10569 } 10570 } 10571 10572 if (!brief && !oomOnly) { 10573 pw.println(); 10574 pw.println("Total PSS by process:"); 10575 dumpMemItems(pw, " ", procMems, true); 10576 pw.println(); 10577 } 10578 pw.println("Total PSS by OOM adjustment:"); 10579 dumpMemItems(pw, " ", oomMems, false); 10580 if (!oomOnly) { 10581 PrintWriter out = categoryPw != null ? categoryPw : pw; 10582 out.println(); 10583 out.println("Total PSS by category:"); 10584 dumpMemItems(out, " ", catMems, true); 10585 } 10586 pw.println(); 10587 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10588 final int[] SINGLE_LONG_FORMAT = new int[] { 10589 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10590 }; 10591 long[] longOut = new long[1]; 10592 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10593 SINGLE_LONG_FORMAT, null, longOut, null); 10594 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10595 longOut[0] = 0; 10596 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10597 SINGLE_LONG_FORMAT, null, longOut, null); 10598 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10599 longOut[0] = 0; 10600 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10601 SINGLE_LONG_FORMAT, null, longOut, null); 10602 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10603 longOut[0] = 0; 10604 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10605 SINGLE_LONG_FORMAT, null, longOut, null); 10606 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10607 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10608 pw.print(shared); pw.println(" kB"); 10609 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10610 pw.print(voltile); pw.println(" kB volatile"); 10611 } 10612 } 10613 10614 /** 10615 * Searches array of arguments for the specified string 10616 * @param args array of argument strings 10617 * @param value value to search for 10618 * @return true if the value is contained in the array 10619 */ scanArgs(String[] args, String value)10620 private static boolean scanArgs(String[] args, String value) { 10621 if (args != null) { 10622 for (String arg : args) { 10623 if (value.equals(arg)) { 10624 return true; 10625 } 10626 } 10627 } 10628 return false; 10629 } 10630 removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always)10631 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10632 ContentProviderRecord cpr, boolean always) { 10633 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10634 10635 if (!inLaunching || always) { 10636 synchronized (cpr) { 10637 cpr.launchingApp = null; 10638 cpr.notifyAll(); 10639 } 10640 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10641 String names[] = cpr.info.authority.split(";"); 10642 for (int j = 0; j < names.length; j++) { 10643 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10644 } 10645 } 10646 10647 for (int i=0; i<cpr.connections.size(); i++) { 10648 ContentProviderConnection conn = cpr.connections.get(i); 10649 if (conn.waiting) { 10650 // If this connection is waiting for the provider, then we don't 10651 // need to mess with its process unless we are always removing 10652 // or for some reason the provider is not currently launching. 10653 if (inLaunching && !always) { 10654 continue; 10655 } 10656 } 10657 ProcessRecord capp = conn.client; 10658 conn.dead = true; 10659 if (conn.stableCount > 0) { 10660 if (!capp.persistent && capp.thread != null 10661 && capp.pid != 0 10662 && capp.pid != MY_PID) { 10663 Slog.i(TAG, "Kill " + capp.processName 10664 + " (pid " + capp.pid + "): provider " + cpr.info.name 10665 + " in dying process " + (proc != null ? proc.processName : "??")); 10666 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10667 capp.processName, capp.setAdj, "dying provider " 10668 + cpr.name.toShortString()); 10669 Process.killProcessQuiet(capp.pid); 10670 } 10671 } else if (capp.thread != null && conn.provider.provider != null) { 10672 try { 10673 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10674 } catch (RemoteException e) { 10675 } 10676 // In the protocol here, we don't expect the client to correctly 10677 // clean up this connection, we'll just remove it. 10678 cpr.connections.remove(i); 10679 conn.client.conProviders.remove(conn); 10680 } 10681 } 10682 10683 if (inLaunching && always) { 10684 mLaunchingProviders.remove(cpr); 10685 } 10686 return inLaunching; 10687 } 10688 10689 /** 10690 * Main code for cleaning up a process when it has gone away. This is 10691 * called both as a result of the process dying, or directly when stopping 10692 * a process when running in single process mode. 10693 */ cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index)10694 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10695 boolean restarting, boolean allowRestart, int index) { 10696 if (index >= 0) { 10697 mLruProcesses.remove(index); 10698 } 10699 10700 mProcessesToGc.remove(app); 10701 10702 // Dismiss any open dialogs. 10703 if (app.crashDialog != null) { 10704 app.crashDialog.dismiss(); 10705 app.crashDialog = null; 10706 } 10707 if (app.anrDialog != null) { 10708 app.anrDialog.dismiss(); 10709 app.anrDialog = null; 10710 } 10711 if (app.waitDialog != null) { 10712 app.waitDialog.dismiss(); 10713 app.waitDialog = null; 10714 } 10715 10716 app.crashing = false; 10717 app.notResponding = false; 10718 10719 app.resetPackageList(); 10720 app.unlinkDeathRecipient(); 10721 app.thread = null; 10722 app.forcingToForeground = null; 10723 app.foregroundServices = false; 10724 app.foregroundActivities = false; 10725 app.hasShownUi = false; 10726 app.hasAboveClient = false; 10727 10728 mServices.killServicesLocked(app, allowRestart); 10729 10730 boolean restart = false; 10731 10732 // Remove published content providers. 10733 if (!app.pubProviders.isEmpty()) { 10734 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10735 while (it.hasNext()) { 10736 ContentProviderRecord cpr = it.next(); 10737 10738 final boolean always = app.bad || !allowRestart; 10739 if (removeDyingProviderLocked(app, cpr, always) || always) { 10740 // We left the provider in the launching list, need to 10741 // restart it. 10742 restart = true; 10743 } 10744 10745 cpr.provider = null; 10746 cpr.proc = null; 10747 } 10748 app.pubProviders.clear(); 10749 } 10750 10751 // Take care of any launching providers waiting for this process. 10752 if (checkAppInLaunchingProvidersLocked(app, false)) { 10753 restart = true; 10754 } 10755 10756 // Unregister from connected content providers. 10757 if (!app.conProviders.isEmpty()) { 10758 for (int i=0; i<app.conProviders.size(); i++) { 10759 ContentProviderConnection conn = app.conProviders.get(i); 10760 conn.provider.connections.remove(conn); 10761 } 10762 app.conProviders.clear(); 10763 } 10764 10765 // At this point there may be remaining entries in mLaunchingProviders 10766 // where we were the only one waiting, so they are no longer of use. 10767 // Look for these and clean up if found. 10768 // XXX Commented out for now. Trying to figure out a way to reproduce 10769 // the actual situation to identify what is actually going on. 10770 if (false) { 10771 for (int i=0; i<mLaunchingProviders.size(); i++) { 10772 ContentProviderRecord cpr = (ContentProviderRecord) 10773 mLaunchingProviders.get(i); 10774 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10775 synchronized (cpr) { 10776 cpr.launchingApp = null; 10777 cpr.notifyAll(); 10778 } 10779 } 10780 } 10781 } 10782 10783 skipCurrentReceiverLocked(app); 10784 10785 // Unregister any receivers. 10786 if (app.receivers.size() > 0) { 10787 Iterator<ReceiverList> it = app.receivers.iterator(); 10788 while (it.hasNext()) { 10789 removeReceiverLocked(it.next()); 10790 } 10791 app.receivers.clear(); 10792 } 10793 10794 // If the app is undergoing backup, tell the backup manager about it 10795 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10796 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10797 + mBackupTarget.appInfo + " died during backup"); 10798 try { 10799 IBackupManager bm = IBackupManager.Stub.asInterface( 10800 ServiceManager.getService(Context.BACKUP_SERVICE)); 10801 bm.agentDisconnected(app.info.packageName); 10802 } catch (RemoteException e) { 10803 // can't happen; backup manager is local 10804 } 10805 } 10806 10807 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10808 ProcessChangeItem item = mPendingProcessChanges.get(i); 10809 if (item.pid == app.pid) { 10810 mPendingProcessChanges.remove(i); 10811 mAvailProcessChanges.add(item); 10812 } 10813 } 10814 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10815 10816 // If the caller is restarting this app, then leave it in its 10817 // current lists and let the caller take care of it. 10818 if (restarting) { 10819 return; 10820 } 10821 10822 if (!app.persistent || app.isolated) { 10823 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10824 "Removing non-persistent process during cleanup: " + app); 10825 mProcessNames.remove(app.processName, app.uid); 10826 mIsolatedProcesses.remove(app.uid); 10827 if (mHeavyWeightProcess == app) { 10828 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10829 mHeavyWeightProcess.userId, 0)); 10830 mHeavyWeightProcess = null; 10831 } 10832 } else if (!app.removed) { 10833 // This app is persistent, so we need to keep its record around. 10834 // If it is not already on the pending app list, add it there 10835 // and start a new process for it. 10836 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10837 mPersistentStartingProcesses.add(app); 10838 restart = true; 10839 } 10840 } 10841 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10842 "Clean-up removing on hold: " + app); 10843 mProcessesOnHold.remove(app); 10844 10845 if (app == mHomeProcess) { 10846 mHomeProcess = null; 10847 } 10848 if (app == mPreviousProcess) { 10849 mPreviousProcess = null; 10850 } 10851 10852 if (restart && !app.isolated) { 10853 // We have components that still need to be running in the 10854 // process, so re-launch it. 10855 mProcessNames.put(app.processName, app.uid, app); 10856 startProcessLocked(app, "restart", app.processName); 10857 } else if (app.pid > 0 && app.pid != MY_PID) { 10858 // Goodbye! 10859 synchronized (mPidsSelfLocked) { 10860 mPidsSelfLocked.remove(app.pid); 10861 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10862 } 10863 app.setPid(0); 10864 } 10865 } 10866 checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad)10867 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10868 // Look through the content providers we are waiting to have launched, 10869 // and if any run in this process then either schedule a restart of 10870 // the process or kill the client waiting for it if this process has 10871 // gone bad. 10872 int NL = mLaunchingProviders.size(); 10873 boolean restart = false; 10874 for (int i=0; i<NL; i++) { 10875 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10876 if (cpr.launchingApp == app) { 10877 if (!alwaysBad && !app.bad) { 10878 restart = true; 10879 } else { 10880 removeDyingProviderLocked(app, cpr, true); 10881 // cpr should have been removed from mLaunchingProviders 10882 NL = mLaunchingProviders.size(); 10883 i--; 10884 } 10885 } 10886 } 10887 return restart; 10888 } 10889 10890 // ========================================================= 10891 // SERVICES 10892 // ========================================================= 10893 getServices(int maxNum, int flags)10894 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10895 int flags) { 10896 enforceNotIsolatedCaller("getServices"); 10897 synchronized (this) { 10898 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10899 } 10900 } 10901 getRunningServiceControlPanel(ComponentName name)10902 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10903 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10904 synchronized (this) { 10905 return mServices.getRunningServiceControlPanelLocked(name); 10906 } 10907 } 10908 startService(IApplicationThread caller, Intent service, String resolvedType, int userId)10909 public ComponentName startService(IApplicationThread caller, Intent service, 10910 String resolvedType, int userId) { 10911 enforceNotIsolatedCaller("startService"); 10912 // Refuse possible leaked file descriptors 10913 if (service != null && service.hasFileDescriptors() == true) { 10914 throw new IllegalArgumentException("File descriptors passed in Intent"); 10915 } 10916 10917 if (DEBUG_SERVICE) 10918 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10919 synchronized(this) { 10920 final int callingPid = Binder.getCallingPid(); 10921 final int callingUid = Binder.getCallingUid(); 10922 checkValidCaller(callingUid, userId); 10923 final long origId = Binder.clearCallingIdentity(); 10924 ComponentName res = mServices.startServiceLocked(caller, service, 10925 resolvedType, callingPid, callingUid, userId); 10926 Binder.restoreCallingIdentity(origId); 10927 return res; 10928 } 10929 } 10930 startServiceInPackage(int uid, Intent service, String resolvedType, int userId)10931 ComponentName startServiceInPackage(int uid, 10932 Intent service, String resolvedType, int userId) { 10933 synchronized(this) { 10934 if (DEBUG_SERVICE) 10935 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10936 final long origId = Binder.clearCallingIdentity(); 10937 ComponentName res = mServices.startServiceLocked(null, service, 10938 resolvedType, -1, uid, userId); 10939 Binder.restoreCallingIdentity(origId); 10940 return res; 10941 } 10942 } 10943 stopService(IApplicationThread caller, Intent service, String resolvedType, int userId)10944 public int stopService(IApplicationThread caller, Intent service, 10945 String resolvedType, int userId) { 10946 enforceNotIsolatedCaller("stopService"); 10947 // Refuse possible leaked file descriptors 10948 if (service != null && service.hasFileDescriptors() == true) { 10949 throw new IllegalArgumentException("File descriptors passed in Intent"); 10950 } 10951 10952 checkValidCaller(Binder.getCallingUid(), userId); 10953 10954 synchronized(this) { 10955 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10956 } 10957 } 10958 peekService(Intent service, String resolvedType)10959 public IBinder peekService(Intent service, String resolvedType) { 10960 enforceNotIsolatedCaller("peekService"); 10961 // Refuse possible leaked file descriptors 10962 if (service != null && service.hasFileDescriptors() == true) { 10963 throw new IllegalArgumentException("File descriptors passed in Intent"); 10964 } 10965 synchronized(this) { 10966 return mServices.peekServiceLocked(service, resolvedType); 10967 } 10968 } 10969 stopServiceToken(ComponentName className, IBinder token, int startId)10970 public boolean stopServiceToken(ComponentName className, IBinder token, 10971 int startId) { 10972 synchronized(this) { 10973 return mServices.stopServiceTokenLocked(className, token, startId); 10974 } 10975 } 10976 setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)10977 public void setServiceForeground(ComponentName className, IBinder token, 10978 int id, Notification notification, boolean removeNotification) { 10979 synchronized(this) { 10980 mServices.setServiceForegroundLocked(className, token, id, notification, 10981 removeNotification); 10982 } 10983 } 10984 handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)10985 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10986 boolean requireFull, String name, String callerPackage) { 10987 final int callingUserId = UserHandle.getUserId(callingUid); 10988 if (callingUserId != userId) { 10989 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10990 if ((requireFull || checkComponentPermission( 10991 android.Manifest.permission.INTERACT_ACROSS_USERS, 10992 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10993 && checkComponentPermission( 10994 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10995 callingPid, callingUid, -1, true) 10996 != PackageManager.PERMISSION_GRANTED) { 10997 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10998 // In this case, they would like to just execute as their 10999 // owner user instead of failing. 11000 userId = callingUserId; 11001 } else { 11002 StringBuilder builder = new StringBuilder(128); 11003 builder.append("Permission Denial: "); 11004 builder.append(name); 11005 if (callerPackage != null) { 11006 builder.append(" from "); 11007 builder.append(callerPackage); 11008 } 11009 builder.append(" asks to run as user "); 11010 builder.append(userId); 11011 builder.append(" but is calling from user "); 11012 builder.append(UserHandle.getUserId(callingUid)); 11013 builder.append("; this requires "); 11014 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 11015 if (!requireFull) { 11016 builder.append(" or "); 11017 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 11018 } 11019 String msg = builder.toString(); 11020 Slog.w(TAG, msg); 11021 throw new SecurityException(msg); 11022 } 11023 } 11024 } 11025 if (userId == UserHandle.USER_CURRENT 11026 || userId == UserHandle.USER_CURRENT_OR_SELF) { 11027 // Note that we may be accessing this outside of a lock... 11028 // shouldn't be a big deal, if this is being called outside 11029 // of a locked context there is intrinsically a race with 11030 // the value the caller will receive and someone else changing it. 11031 userId = mCurrentUserId; 11032 } 11033 if (!allowAll && userId < 0) { 11034 throw new IllegalArgumentException( 11035 "Call does not support special user #" + userId); 11036 } 11037 } 11038 return userId; 11039 } 11040 isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags)11041 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11042 String className, int flags) { 11043 boolean result = false; 11044 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11045 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11046 if (ActivityManager.checkUidPermission( 11047 android.Manifest.permission.INTERACT_ACROSS_USERS, 11048 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11049 ComponentName comp = new ComponentName(aInfo.packageName, className); 11050 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11051 + " requests FLAG_SINGLE_USER, but app does not hold " 11052 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11053 Slog.w(TAG, msg); 11054 throw new SecurityException(msg); 11055 } 11056 result = true; 11057 } 11058 } else if (componentProcessName == aInfo.packageName) { 11059 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11060 } else if ("system".equals(componentProcessName)) { 11061 result = true; 11062 } 11063 if (DEBUG_MU) { 11064 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11065 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11066 } 11067 return result; 11068 } 11069 bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId)11070 public int bindService(IApplicationThread caller, IBinder token, 11071 Intent service, String resolvedType, 11072 IServiceConnection connection, int flags, int userId) { 11073 enforceNotIsolatedCaller("bindService"); 11074 // Refuse possible leaked file descriptors 11075 if (service != null && service.hasFileDescriptors() == true) { 11076 throw new IllegalArgumentException("File descriptors passed in Intent"); 11077 } 11078 11079 synchronized(this) { 11080 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11081 connection, flags, userId); 11082 } 11083 } 11084 unbindService(IServiceConnection connection)11085 public boolean unbindService(IServiceConnection connection) { 11086 synchronized (this) { 11087 return mServices.unbindServiceLocked(connection); 11088 } 11089 } 11090 publishService(IBinder token, Intent intent, IBinder service)11091 public void publishService(IBinder token, Intent intent, IBinder service) { 11092 // Refuse possible leaked file descriptors 11093 if (intent != null && intent.hasFileDescriptors() == true) { 11094 throw new IllegalArgumentException("File descriptors passed in Intent"); 11095 } 11096 11097 synchronized(this) { 11098 if (!(token instanceof ServiceRecord)) { 11099 throw new IllegalArgumentException("Invalid service token"); 11100 } 11101 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11102 } 11103 } 11104 unbindFinished(IBinder token, Intent intent, boolean doRebind)11105 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11106 // Refuse possible leaked file descriptors 11107 if (intent != null && intent.hasFileDescriptors() == true) { 11108 throw new IllegalArgumentException("File descriptors passed in Intent"); 11109 } 11110 11111 synchronized(this) { 11112 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11113 } 11114 } 11115 serviceDoneExecuting(IBinder token, int type, int startId, int res)11116 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11117 synchronized(this) { 11118 if (!(token instanceof ServiceRecord)) { 11119 throw new IllegalArgumentException("Invalid service token"); 11120 } 11121 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11122 } 11123 } 11124 11125 // ========================================================= 11126 // BACKUP AND RESTORE 11127 // ========================================================= 11128 11129 // Cause the target app to be launched if necessary and its backup agent 11130 // instantiated. The backup agent will invoke backupAgentCreated() on the 11131 // activity manager to announce its creation. bindBackupAgent(ApplicationInfo app, int backupMode)11132 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11133 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 11134 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 11135 11136 synchronized(this) { 11137 // !!! TODO: currently no check here that we're already bound 11138 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11139 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11140 synchronized (stats) { 11141 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11142 } 11143 11144 // Backup agent is now in use, its package can't be stopped. 11145 try { 11146 AppGlobals.getPackageManager().setPackageStoppedState( 11147 app.packageName, false, UserHandle.getUserId(app.uid)); 11148 } catch (RemoteException e) { 11149 } catch (IllegalArgumentException e) { 11150 Slog.w(TAG, "Failed trying to unstop package " 11151 + app.packageName + ": " + e); 11152 } 11153 11154 BackupRecord r = new BackupRecord(ss, app, backupMode); 11155 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11156 ? new ComponentName(app.packageName, app.backupAgentName) 11157 : new ComponentName("android", "FullBackupAgent"); 11158 // startProcessLocked() returns existing proc's record if it's already running 11159 ProcessRecord proc = startProcessLocked(app.processName, app, 11160 false, 0, "backup", hostingName, false, false); 11161 if (proc == null) { 11162 Slog.e(TAG, "Unable to start backup agent process " + r); 11163 return false; 11164 } 11165 11166 r.app = proc; 11167 mBackupTarget = r; 11168 mBackupAppName = app.packageName; 11169 11170 // Try not to kill the process during backup 11171 updateOomAdjLocked(proc); 11172 11173 // If the process is already attached, schedule the creation of the backup agent now. 11174 // If it is not yet live, this will be done when it attaches to the framework. 11175 if (proc.thread != null) { 11176 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11177 try { 11178 proc.thread.scheduleCreateBackupAgent(app, 11179 compatibilityInfoForPackageLocked(app), backupMode); 11180 } catch (RemoteException e) { 11181 // Will time out on the backup manager side 11182 } 11183 } else { 11184 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11185 } 11186 // Invariants: at this point, the target app process exists and the application 11187 // is either already running or in the process of coming up. mBackupTarget and 11188 // mBackupAppName describe the app, so that when it binds back to the AM we 11189 // know that it's scheduled for a backup-agent operation. 11190 } 11191 11192 return true; 11193 } 11194 11195 @Override clearPendingBackup()11196 public void clearPendingBackup() { 11197 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 11198 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 11199 11200 synchronized (this) { 11201 mBackupTarget = null; 11202 mBackupAppName = null; 11203 } 11204 } 11205 11206 // A backup agent has just come up backupAgentCreated(String agentPackageName, IBinder agent)11207 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11208 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11209 + " = " + agent); 11210 11211 synchronized(this) { 11212 if (!agentPackageName.equals(mBackupAppName)) { 11213 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11214 return; 11215 } 11216 } 11217 11218 long oldIdent = Binder.clearCallingIdentity(); 11219 try { 11220 IBackupManager bm = IBackupManager.Stub.asInterface( 11221 ServiceManager.getService(Context.BACKUP_SERVICE)); 11222 bm.agentConnected(agentPackageName, agent); 11223 } catch (RemoteException e) { 11224 // can't happen; the backup manager service is local 11225 } catch (Exception e) { 11226 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11227 e.printStackTrace(); 11228 } finally { 11229 Binder.restoreCallingIdentity(oldIdent); 11230 } 11231 } 11232 11233 // done with this agent unbindBackupAgent(ApplicationInfo appInfo)11234 public void unbindBackupAgent(ApplicationInfo appInfo) { 11235 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11236 if (appInfo == null) { 11237 Slog.w(TAG, "unbind backup agent for null app"); 11238 return; 11239 } 11240 11241 synchronized(this) { 11242 try { 11243 if (mBackupAppName == null) { 11244 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11245 return; 11246 } 11247 11248 if (!mBackupAppName.equals(appInfo.packageName)) { 11249 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11250 return; 11251 } 11252 11253 // Not backing this app up any more; reset its OOM adjustment 11254 final ProcessRecord proc = mBackupTarget.app; 11255 updateOomAdjLocked(proc); 11256 11257 // If the app crashed during backup, 'thread' will be null here 11258 if (proc.thread != null) { 11259 try { 11260 proc.thread.scheduleDestroyBackupAgent(appInfo, 11261 compatibilityInfoForPackageLocked(appInfo)); 11262 } catch (Exception e) { 11263 Slog.e(TAG, "Exception when unbinding backup agent:"); 11264 e.printStackTrace(); 11265 } 11266 } 11267 } finally { 11268 mBackupTarget = null; 11269 mBackupAppName = null; 11270 } 11271 } 11272 } 11273 // ========================================================= 11274 // BROADCASTS 11275 // ========================================================= 11276 getStickiesLocked(String action, IntentFilter filter, List cur, int userId)11277 private final List getStickiesLocked(String action, IntentFilter filter, 11278 List cur, int userId) { 11279 final ContentResolver resolver = mContext.getContentResolver(); 11280 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11281 if (stickies == null) { 11282 return cur; 11283 } 11284 final ArrayList<Intent> list = stickies.get(action); 11285 if (list == null) { 11286 return cur; 11287 } 11288 int N = list.size(); 11289 for (int i=0; i<N; i++) { 11290 Intent intent = list.get(i); 11291 if (filter.match(resolver, intent, true, TAG) >= 0) { 11292 if (cur == null) { 11293 cur = new ArrayList<Intent>(); 11294 } 11295 cur.add(intent); 11296 } 11297 } 11298 return cur; 11299 } 11300 isPendingBroadcastProcessLocked(int pid)11301 boolean isPendingBroadcastProcessLocked(int pid) { 11302 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11303 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11304 } 11305 skipPendingBroadcastLocked(int pid)11306 void skipPendingBroadcastLocked(int pid) { 11307 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11308 for (BroadcastQueue queue : mBroadcastQueues) { 11309 queue.skipPendingBroadcastLocked(pid); 11310 } 11311 } 11312 11313 // The app just attached; send any pending broadcasts that it should receive sendPendingBroadcastsLocked(ProcessRecord app)11314 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11315 boolean didSomething = false; 11316 for (BroadcastQueue queue : mBroadcastQueues) { 11317 didSomething |= queue.sendPendingBroadcastsLocked(app); 11318 } 11319 return didSomething; 11320 } 11321 registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId)11322 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11323 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11324 enforceNotIsolatedCaller("registerReceiver"); 11325 int callingUid; 11326 int callingPid; 11327 synchronized(this) { 11328 ProcessRecord callerApp = null; 11329 if (caller != null) { 11330 callerApp = getRecordForAppLocked(caller); 11331 if (callerApp == null) { 11332 throw new SecurityException( 11333 "Unable to find app for caller " + caller 11334 + " (pid=" + Binder.getCallingPid() 11335 + ") when registering receiver " + receiver); 11336 } 11337 if (callerApp.info.uid != Process.SYSTEM_UID && 11338 !callerApp.pkgList.contains(callerPackage)) { 11339 throw new SecurityException("Given caller package " + callerPackage 11340 + " is not running in process " + callerApp); 11341 } 11342 callingUid = callerApp.info.uid; 11343 callingPid = callerApp.pid; 11344 } else { 11345 callerPackage = null; 11346 callingUid = Binder.getCallingUid(); 11347 callingPid = Binder.getCallingPid(); 11348 } 11349 11350 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11351 true, true, "registerReceiver", callerPackage); 11352 11353 List allSticky = null; 11354 11355 // Look for any matching sticky broadcasts... 11356 Iterator actions = filter.actionsIterator(); 11357 if (actions != null) { 11358 while (actions.hasNext()) { 11359 String action = (String)actions.next(); 11360 allSticky = getStickiesLocked(action, filter, allSticky, 11361 UserHandle.USER_ALL); 11362 allSticky = getStickiesLocked(action, filter, allSticky, 11363 UserHandle.getUserId(callingUid)); 11364 } 11365 } else { 11366 allSticky = getStickiesLocked(null, filter, allSticky, 11367 UserHandle.USER_ALL); 11368 allSticky = getStickiesLocked(null, filter, allSticky, 11369 UserHandle.getUserId(callingUid)); 11370 } 11371 11372 // The first sticky in the list is returned directly back to 11373 // the client. 11374 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11375 11376 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11377 + ": " + sticky); 11378 11379 if (receiver == null) { 11380 return sticky; 11381 } 11382 11383 ReceiverList rl 11384 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11385 if (rl == null) { 11386 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11387 userId, receiver); 11388 if (rl.app != null) { 11389 rl.app.receivers.add(rl); 11390 } else { 11391 try { 11392 receiver.asBinder().linkToDeath(rl, 0); 11393 } catch (RemoteException e) { 11394 return sticky; 11395 } 11396 rl.linkedToDeath = true; 11397 } 11398 mRegisteredReceivers.put(receiver.asBinder(), rl); 11399 } else if (rl.uid != callingUid) { 11400 throw new IllegalArgumentException( 11401 "Receiver requested to register for uid " + callingUid 11402 + " was previously registered for uid " + rl.uid); 11403 } else if (rl.pid != callingPid) { 11404 throw new IllegalArgumentException( 11405 "Receiver requested to register for pid " + callingPid 11406 + " was previously registered for pid " + rl.pid); 11407 } else if (rl.userId != userId) { 11408 throw new IllegalArgumentException( 11409 "Receiver requested to register for user " + userId 11410 + " was previously registered for user " + rl.userId); 11411 } 11412 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11413 permission, callingUid, userId); 11414 rl.add(bf); 11415 if (!bf.debugCheck()) { 11416 Slog.w(TAG, "==> For Dynamic broadast"); 11417 } 11418 mReceiverResolver.addFilter(bf); 11419 11420 // Enqueue broadcasts for all existing stickies that match 11421 // this filter. 11422 if (allSticky != null) { 11423 ArrayList receivers = new ArrayList(); 11424 receivers.add(bf); 11425 11426 int N = allSticky.size(); 11427 for (int i=0; i<N; i++) { 11428 Intent intent = (Intent)allSticky.get(i); 11429 BroadcastQueue queue = broadcastQueueForIntent(intent); 11430 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11431 null, -1, -1, null, receivers, null, 0, null, null, 11432 false, true, true, -1); 11433 queue.enqueueParallelBroadcastLocked(r); 11434 queue.scheduleBroadcastsLocked(); 11435 } 11436 } 11437 11438 return sticky; 11439 } 11440 } 11441 unregisterReceiver(IIntentReceiver receiver)11442 public void unregisterReceiver(IIntentReceiver receiver) { 11443 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11444 11445 final long origId = Binder.clearCallingIdentity(); 11446 try { 11447 boolean doTrim = false; 11448 11449 synchronized(this) { 11450 ReceiverList rl 11451 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11452 if (rl != null) { 11453 if (rl.curBroadcast != null) { 11454 BroadcastRecord r = rl.curBroadcast; 11455 final boolean doNext = finishReceiverLocked( 11456 receiver.asBinder(), r.resultCode, r.resultData, 11457 r.resultExtras, r.resultAbort, true); 11458 if (doNext) { 11459 doTrim = true; 11460 r.queue.processNextBroadcast(false); 11461 } 11462 } 11463 11464 if (rl.app != null) { 11465 rl.app.receivers.remove(rl); 11466 } 11467 removeReceiverLocked(rl); 11468 if (rl.linkedToDeath) { 11469 rl.linkedToDeath = false; 11470 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11471 } 11472 } 11473 } 11474 11475 // If we actually concluded any broadcasts, we might now be able 11476 // to trim the recipients' apps from our working set 11477 if (doTrim) { 11478 trimApplications(); 11479 return; 11480 } 11481 11482 } finally { 11483 Binder.restoreCallingIdentity(origId); 11484 } 11485 } 11486 removeReceiverLocked(ReceiverList rl)11487 void removeReceiverLocked(ReceiverList rl) { 11488 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11489 int N = rl.size(); 11490 for (int i=0; i<N; i++) { 11491 mReceiverResolver.removeFilter(rl.get(i)); 11492 } 11493 } 11494 sendPackageBroadcastLocked(int cmd, String[] packages, int userId)11495 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11496 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11497 ProcessRecord r = mLruProcesses.get(i); 11498 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11499 try { 11500 r.thread.dispatchPackageBroadcast(cmd, packages); 11501 } catch (RemoteException ex) { 11502 } 11503 } 11504 } 11505 } 11506 collectReceiverComponents(Intent intent, String resolvedType, int[] users)11507 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11508 int[] users) { 11509 List<ResolveInfo> receivers = null; 11510 try { 11511 HashSet<ComponentName> singleUserReceivers = null; 11512 boolean scannedFirstReceivers = false; 11513 for (int user : users) { 11514 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11515 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11516 if (user != 0 && newReceivers != null) { 11517 // If this is not the primary user, we need to check for 11518 // any receivers that should be filtered out. 11519 for (int i=0; i<newReceivers.size(); i++) { 11520 ResolveInfo ri = newReceivers.get(i); 11521 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11522 newReceivers.remove(i); 11523 i--; 11524 } 11525 } 11526 } 11527 if (newReceivers != null && newReceivers.size() == 0) { 11528 newReceivers = null; 11529 } 11530 if (receivers == null) { 11531 receivers = newReceivers; 11532 } else if (newReceivers != null) { 11533 // We need to concatenate the additional receivers 11534 // found with what we have do far. This would be easy, 11535 // but we also need to de-dup any receivers that are 11536 // singleUser. 11537 if (!scannedFirstReceivers) { 11538 // Collect any single user receivers we had already retrieved. 11539 scannedFirstReceivers = true; 11540 for (int i=0; i<receivers.size(); i++) { 11541 ResolveInfo ri = receivers.get(i); 11542 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11543 ComponentName cn = new ComponentName( 11544 ri.activityInfo.packageName, ri.activityInfo.name); 11545 if (singleUserReceivers == null) { 11546 singleUserReceivers = new HashSet<ComponentName>(); 11547 } 11548 singleUserReceivers.add(cn); 11549 } 11550 } 11551 } 11552 // Add the new results to the existing results, tracking 11553 // and de-dupping single user receivers. 11554 for (int i=0; i<newReceivers.size(); i++) { 11555 ResolveInfo ri = newReceivers.get(i); 11556 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11557 ComponentName cn = new ComponentName( 11558 ri.activityInfo.packageName, ri.activityInfo.name); 11559 if (singleUserReceivers == null) { 11560 singleUserReceivers = new HashSet<ComponentName>(); 11561 } 11562 if (!singleUserReceivers.contains(cn)) { 11563 singleUserReceivers.add(cn); 11564 receivers.add(ri); 11565 } 11566 } else { 11567 receivers.add(ri); 11568 } 11569 } 11570 } 11571 } 11572 } catch (RemoteException ex) { 11573 // pm is in same process, this will never happen. 11574 } 11575 return receivers; 11576 } 11577 broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId)11578 private final int broadcastIntentLocked(ProcessRecord callerApp, 11579 String callerPackage, Intent intent, String resolvedType, 11580 IIntentReceiver resultTo, int resultCode, String resultData, 11581 Bundle map, String requiredPermission, 11582 boolean ordered, boolean sticky, int callingPid, int callingUid, 11583 int userId) { 11584 intent = new Intent(intent); 11585 11586 // By default broadcasts do not go to stopped apps. 11587 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11588 11589 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11590 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11591 + " ordered=" + ordered + " userid=" + userId); 11592 if ((resultTo != null) && !ordered) { 11593 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11594 } 11595 11596 userId = handleIncomingUser(callingPid, callingUid, userId, 11597 true, false, "broadcast", callerPackage); 11598 11599 // Make sure that the user who is receiving this broadcast is started. 11600 // If not, we will just skip it. 11601 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11602 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11603 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11604 Slog.w(TAG, "Skipping broadcast of " + intent 11605 + ": user " + userId + " is stopped"); 11606 return ActivityManager.BROADCAST_SUCCESS; 11607 } 11608 } 11609 11610 /* 11611 * Prevent non-system code (defined here to be non-persistent 11612 * processes) from sending protected broadcasts. 11613 */ 11614 int callingAppId = UserHandle.getAppId(callingUid); 11615 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11616 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11617 callingUid == 0) { 11618 // Always okay. 11619 } else if (callerApp == null || !callerApp.persistent) { 11620 try { 11621 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11622 intent.getAction())) { 11623 String msg = "Permission Denial: not allowed to send broadcast " 11624 + intent.getAction() + " from pid=" 11625 + callingPid + ", uid=" + callingUid; 11626 Slog.w(TAG, msg); 11627 throw new SecurityException(msg); 11628 } 11629 } catch (RemoteException e) { 11630 Slog.w(TAG, "Remote exception", e); 11631 return ActivityManager.BROADCAST_SUCCESS; 11632 } 11633 } 11634 11635 // Handle special intents: if this broadcast is from the package 11636 // manager about a package being removed, we need to remove all of 11637 // its activities from the history stack. 11638 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11639 intent.getAction()); 11640 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11641 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11642 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11643 || uidRemoved) { 11644 if (checkComponentPermission( 11645 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11646 callingPid, callingUid, -1, true) 11647 == PackageManager.PERMISSION_GRANTED) { 11648 if (uidRemoved) { 11649 final Bundle intentExtras = intent.getExtras(); 11650 final int uid = intentExtras != null 11651 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11652 if (uid >= 0) { 11653 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11654 synchronized (bs) { 11655 bs.removeUidStatsLocked(uid); 11656 } 11657 } 11658 } else { 11659 // If resources are unavailable just force stop all 11660 // those packages and flush the attribute cache as well. 11661 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11662 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11663 if (list != null && (list.length > 0)) { 11664 for (String pkg : list) { 11665 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11666 } 11667 sendPackageBroadcastLocked( 11668 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11669 } 11670 } else { 11671 Uri data = intent.getData(); 11672 String ssp; 11673 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11674 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11675 forceStopPackageLocked(ssp, 11676 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11677 false, userId); 11678 } 11679 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11680 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11681 new String[] {ssp}, userId); 11682 } 11683 } 11684 } 11685 } 11686 } else { 11687 String msg = "Permission Denial: " + intent.getAction() 11688 + " broadcast from " + callerPackage + " (pid=" + callingPid 11689 + ", uid=" + callingUid + ")" 11690 + " requires " 11691 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11692 Slog.w(TAG, msg); 11693 throw new SecurityException(msg); 11694 } 11695 11696 // Special case for adding a package: by default turn on compatibility 11697 // mode. 11698 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11699 Uri data = intent.getData(); 11700 String ssp; 11701 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11702 mCompatModePackages.handlePackageAddedLocked(ssp, 11703 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11704 } 11705 } 11706 11707 /* 11708 * If this is the time zone changed action, queue up a message that will reset the timezone 11709 * of all currently running processes. This message will get queued up before the broadcast 11710 * happens. 11711 */ 11712 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11713 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11714 } 11715 11716 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11717 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11718 } 11719 11720 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11721 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11722 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11723 } 11724 11725 // Add to the sticky list if requested. 11726 if (sticky) { 11727 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11728 callingPid, callingUid) 11729 != PackageManager.PERMISSION_GRANTED) { 11730 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11731 + callingPid + ", uid=" + callingUid 11732 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11733 Slog.w(TAG, msg); 11734 throw new SecurityException(msg); 11735 } 11736 if (requiredPermission != null) { 11737 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11738 + " and enforce permission " + requiredPermission); 11739 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11740 } 11741 if (intent.getComponent() != null) { 11742 throw new SecurityException( 11743 "Sticky broadcasts can't target a specific component"); 11744 } 11745 // We use userId directly here, since the "all" target is maintained 11746 // as a separate set of sticky broadcasts. 11747 if (userId != UserHandle.USER_ALL) { 11748 // But first, if this is not a broadcast to all users, then 11749 // make sure it doesn't conflict with an existing broadcast to 11750 // all users. 11751 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11752 UserHandle.USER_ALL); 11753 if (stickies != null) { 11754 ArrayList<Intent> list = stickies.get(intent.getAction()); 11755 if (list != null) { 11756 int N = list.size(); 11757 int i; 11758 for (i=0; i<N; i++) { 11759 if (intent.filterEquals(list.get(i))) { 11760 throw new IllegalArgumentException( 11761 "Sticky broadcast " + intent + " for user " 11762 + userId + " conflicts with existing global broadcast"); 11763 } 11764 } 11765 } 11766 } 11767 } 11768 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11769 if (stickies == null) { 11770 stickies = new HashMap<String, ArrayList<Intent>>(); 11771 mStickyBroadcasts.put(userId, stickies); 11772 } 11773 ArrayList<Intent> list = stickies.get(intent.getAction()); 11774 if (list == null) { 11775 list = new ArrayList<Intent>(); 11776 stickies.put(intent.getAction(), list); 11777 } 11778 int N = list.size(); 11779 int i; 11780 for (i=0; i<N; i++) { 11781 if (intent.filterEquals(list.get(i))) { 11782 // This sticky already exists, replace it. 11783 list.set(i, new Intent(intent)); 11784 break; 11785 } 11786 } 11787 if (i >= N) { 11788 list.add(new Intent(intent)); 11789 } 11790 } 11791 11792 int[] users; 11793 if (userId == UserHandle.USER_ALL) { 11794 // Caller wants broadcast to go to all started users. 11795 users = mStartedUserArray; 11796 } else { 11797 // Caller wants broadcast to go to one specific user. 11798 users = new int[] {userId}; 11799 } 11800 11801 // Figure out who all will receive this broadcast. 11802 List receivers = null; 11803 List<BroadcastFilter> registeredReceivers = null; 11804 // Need to resolve the intent to interested receivers... 11805 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11806 == 0) { 11807 receivers = collectReceiverComponents(intent, resolvedType, users); 11808 } 11809 if (intent.getComponent() == null) { 11810 registeredReceivers = mReceiverResolver.queryIntent(intent, 11811 resolvedType, false, userId); 11812 } 11813 11814 final boolean replacePending = 11815 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11816 11817 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11818 + " replacePending=" + replacePending); 11819 11820 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11821 if (!ordered && NR > 0) { 11822 // If we are not serializing this broadcast, then send the 11823 // registered receivers separately so they don't wait for the 11824 // components to be launched. 11825 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11826 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11827 callerPackage, callingPid, callingUid, requiredPermission, 11828 registeredReceivers, resultTo, resultCode, resultData, map, 11829 ordered, sticky, false, userId); 11830 if (DEBUG_BROADCAST) Slog.v( 11831 TAG, "Enqueueing parallel broadcast " + r); 11832 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11833 if (!replaced) { 11834 queue.enqueueParallelBroadcastLocked(r); 11835 queue.scheduleBroadcastsLocked(); 11836 } 11837 registeredReceivers = null; 11838 NR = 0; 11839 } 11840 11841 // Merge into one list. 11842 int ir = 0; 11843 if (receivers != null) { 11844 // A special case for PACKAGE_ADDED: do not allow the package 11845 // being added to see this broadcast. This prevents them from 11846 // using this as a back door to get run as soon as they are 11847 // installed. Maybe in the future we want to have a special install 11848 // broadcast or such for apps, but we'd like to deliberately make 11849 // this decision. 11850 String skipPackages[] = null; 11851 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11852 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11853 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11854 Uri data = intent.getData(); 11855 if (data != null) { 11856 String pkgName = data.getSchemeSpecificPart(); 11857 if (pkgName != null) { 11858 skipPackages = new String[] { pkgName }; 11859 } 11860 } 11861 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11862 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11863 } 11864 if (skipPackages != null && (skipPackages.length > 0)) { 11865 for (String skipPackage : skipPackages) { 11866 if (skipPackage != null) { 11867 int NT = receivers.size(); 11868 for (int it=0; it<NT; it++) { 11869 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11870 if (curt.activityInfo.packageName.equals(skipPackage)) { 11871 receivers.remove(it); 11872 it--; 11873 NT--; 11874 } 11875 } 11876 } 11877 } 11878 } 11879 11880 int NT = receivers != null ? receivers.size() : 0; 11881 int it = 0; 11882 ResolveInfo curt = null; 11883 BroadcastFilter curr = null; 11884 while (it < NT && ir < NR) { 11885 if (curt == null) { 11886 curt = (ResolveInfo)receivers.get(it); 11887 } 11888 if (curr == null) { 11889 curr = registeredReceivers.get(ir); 11890 } 11891 if (curr.getPriority() >= curt.priority) { 11892 // Insert this broadcast record into the final list. 11893 receivers.add(it, curr); 11894 ir++; 11895 curr = null; 11896 it++; 11897 NT++; 11898 } else { 11899 // Skip to the next ResolveInfo in the final list. 11900 it++; 11901 curt = null; 11902 } 11903 } 11904 } 11905 while (ir < NR) { 11906 if (receivers == null) { 11907 receivers = new ArrayList(); 11908 } 11909 receivers.add(registeredReceivers.get(ir)); 11910 ir++; 11911 } 11912 11913 if ((receivers != null && receivers.size() > 0) 11914 || resultTo != null) { 11915 BroadcastQueue queue = broadcastQueueForIntent(intent); 11916 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11917 callerPackage, callingPid, callingUid, requiredPermission, 11918 receivers, resultTo, resultCode, resultData, map, ordered, 11919 sticky, false, userId); 11920 if (DEBUG_BROADCAST) Slog.v( 11921 TAG, "Enqueueing ordered broadcast " + r 11922 + ": prev had " + queue.mOrderedBroadcasts.size()); 11923 if (DEBUG_BROADCAST) { 11924 int seq = r.intent.getIntExtra("seq", -1); 11925 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11926 } 11927 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11928 if (!replaced) { 11929 queue.enqueueOrderedBroadcastLocked(r); 11930 queue.scheduleBroadcastsLocked(); 11931 } 11932 } 11933 11934 return ActivityManager.BROADCAST_SUCCESS; 11935 } 11936 verifyBroadcastLocked(Intent intent)11937 final Intent verifyBroadcastLocked(Intent intent) { 11938 // Refuse possible leaked file descriptors 11939 if (intent != null && intent.hasFileDescriptors() == true) { 11940 throw new IllegalArgumentException("File descriptors passed in Intent"); 11941 } 11942 11943 int flags = intent.getFlags(); 11944 11945 if (!mProcessesReady) { 11946 // if the caller really truly claims to know what they're doing, go 11947 // ahead and allow the broadcast without launching any receivers 11948 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11949 intent = new Intent(intent); 11950 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11951 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11952 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11953 + " before boot completion"); 11954 throw new IllegalStateException("Cannot broadcast before boot completed"); 11955 } 11956 } 11957 11958 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11959 throw new IllegalArgumentException( 11960 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11961 } 11962 11963 return intent; 11964 } 11965 broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId)11966 public final int broadcastIntent(IApplicationThread caller, 11967 Intent intent, String resolvedType, IIntentReceiver resultTo, 11968 int resultCode, String resultData, Bundle map, 11969 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11970 enforceNotIsolatedCaller("broadcastIntent"); 11971 synchronized(this) { 11972 intent = verifyBroadcastLocked(intent); 11973 11974 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11975 final int callingPid = Binder.getCallingPid(); 11976 final int callingUid = Binder.getCallingUid(); 11977 final long origId = Binder.clearCallingIdentity(); 11978 int res = broadcastIntentLocked(callerApp, 11979 callerApp != null ? callerApp.info.packageName : null, 11980 intent, resolvedType, resultTo, 11981 resultCode, resultData, map, requiredPermission, serialized, sticky, 11982 callingPid, callingUid, userId); 11983 Binder.restoreCallingIdentity(origId); 11984 return res; 11985 } 11986 } 11987 broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId)11988 int broadcastIntentInPackage(String packageName, int uid, 11989 Intent intent, String resolvedType, IIntentReceiver resultTo, 11990 int resultCode, String resultData, Bundle map, 11991 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11992 synchronized(this) { 11993 intent = verifyBroadcastLocked(intent); 11994 11995 final long origId = Binder.clearCallingIdentity(); 11996 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11997 resultTo, resultCode, resultData, map, requiredPermission, 11998 serialized, sticky, -1, uid, userId); 11999 Binder.restoreCallingIdentity(origId); 12000 return res; 12001 } 12002 } 12003 unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)12004 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 12005 // Refuse possible leaked file descriptors 12006 if (intent != null && intent.hasFileDescriptors() == true) { 12007 throw new IllegalArgumentException("File descriptors passed in Intent"); 12008 } 12009 12010 userId = handleIncomingUser(Binder.getCallingPid(), 12011 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 12012 12013 synchronized(this) { 12014 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12015 != PackageManager.PERMISSION_GRANTED) { 12016 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12017 + Binder.getCallingPid() 12018 + ", uid=" + Binder.getCallingUid() 12019 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12020 Slog.w(TAG, msg); 12021 throw new SecurityException(msg); 12022 } 12023 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12024 if (stickies != null) { 12025 ArrayList<Intent> list = stickies.get(intent.getAction()); 12026 if (list != null) { 12027 int N = list.size(); 12028 int i; 12029 for (i=0; i<N; i++) { 12030 if (intent.filterEquals(list.get(i))) { 12031 list.remove(i); 12032 break; 12033 } 12034 } 12035 if (list.size() <= 0) { 12036 stickies.remove(intent.getAction()); 12037 } 12038 } 12039 if (stickies.size() <= 0) { 12040 mStickyBroadcasts.remove(userId); 12041 } 12042 } 12043 } 12044 } 12045 finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, boolean explicit)12046 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12047 String resultData, Bundle resultExtras, boolean resultAbort, 12048 boolean explicit) { 12049 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 12050 if (r == null) { 12051 Slog.w(TAG, "finishReceiver called but not found on queue"); 12052 return false; 12053 } 12054 12055 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12056 explicit); 12057 } 12058 finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)12059 public void finishReceiver(IBinder who, int resultCode, String resultData, 12060 Bundle resultExtras, boolean resultAbort) { 12061 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12062 12063 // Refuse possible leaked file descriptors 12064 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12065 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12066 } 12067 12068 final long origId = Binder.clearCallingIdentity(); 12069 try { 12070 boolean doNext = false; 12071 BroadcastRecord r = null; 12072 12073 synchronized(this) { 12074 r = broadcastRecordForReceiverLocked(who); 12075 if (r != null) { 12076 doNext = r.queue.finishReceiverLocked(r, resultCode, 12077 resultData, resultExtras, resultAbort, true); 12078 } 12079 } 12080 12081 if (doNext) { 12082 r.queue.processNextBroadcast(false); 12083 } 12084 trimApplications(); 12085 } finally { 12086 Binder.restoreCallingIdentity(origId); 12087 } 12088 } 12089 12090 // ========================================================= 12091 // INSTRUMENTATION 12092 // ========================================================= 12093 startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)12094 public boolean startInstrumentation(ComponentName className, 12095 String profileFile, int flags, Bundle arguments, 12096 IInstrumentationWatcher watcher, int userId) { 12097 enforceNotIsolatedCaller("startInstrumentation"); 12098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12099 userId, false, true, "startInstrumentation", null); 12100 // Refuse possible leaked file descriptors 12101 if (arguments != null && arguments.hasFileDescriptors()) { 12102 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12103 } 12104 12105 synchronized(this) { 12106 InstrumentationInfo ii = null; 12107 ApplicationInfo ai = null; 12108 try { 12109 ii = mContext.getPackageManager().getInstrumentationInfo( 12110 className, STOCK_PM_FLAGS); 12111 ai = AppGlobals.getPackageManager().getApplicationInfo( 12112 ii.targetPackage, STOCK_PM_FLAGS, userId); 12113 } catch (PackageManager.NameNotFoundException e) { 12114 } catch (RemoteException e) { 12115 } 12116 if (ii == null) { 12117 reportStartInstrumentationFailure(watcher, className, 12118 "Unable to find instrumentation info for: " + className); 12119 return false; 12120 } 12121 if (ai == null) { 12122 reportStartInstrumentationFailure(watcher, className, 12123 "Unable to find instrumentation target package: " + ii.targetPackage); 12124 return false; 12125 } 12126 12127 int match = mContext.getPackageManager().checkSignatures( 12128 ii.targetPackage, ii.packageName); 12129 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12130 String msg = "Permission Denial: starting instrumentation " 12131 + className + " from pid=" 12132 + Binder.getCallingPid() 12133 + ", uid=" + Binder.getCallingPid() 12134 + " not allowed because package " + ii.packageName 12135 + " does not have a signature matching the target " 12136 + ii.targetPackage; 12137 reportStartInstrumentationFailure(watcher, className, msg); 12138 throw new SecurityException(msg); 12139 } 12140 12141 final long origId = Binder.clearCallingIdentity(); 12142 // Instrumentation can kill and relaunch even persistent processes 12143 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12144 ProcessRecord app = addAppLocked(ai, false); 12145 app.instrumentationClass = className; 12146 app.instrumentationInfo = ai; 12147 app.instrumentationProfileFile = profileFile; 12148 app.instrumentationArguments = arguments; 12149 app.instrumentationWatcher = watcher; 12150 app.instrumentationResultClass = className; 12151 Binder.restoreCallingIdentity(origId); 12152 } 12153 12154 return true; 12155 } 12156 12157 /** 12158 * Report errors that occur while attempting to start Instrumentation. Always writes the 12159 * error to the logs, but if somebody is watching, send the report there too. This enables 12160 * the "am" command to report errors with more information. 12161 * 12162 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12163 * @param cn The component name of the instrumentation. 12164 * @param report The error report. 12165 */ reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)12166 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12167 ComponentName cn, String report) { 12168 Slog.w(TAG, report); 12169 try { 12170 if (watcher != null) { 12171 Bundle results = new Bundle(); 12172 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12173 results.putString("Error", report); 12174 watcher.instrumentationStatus(cn, -1, results); 12175 } 12176 } catch (RemoteException e) { 12177 Slog.w(TAG, e); 12178 } 12179 } 12180 finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)12181 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12182 if (app.instrumentationWatcher != null) { 12183 try { 12184 // NOTE: IInstrumentationWatcher *must* be oneway here 12185 app.instrumentationWatcher.instrumentationFinished( 12186 app.instrumentationClass, 12187 resultCode, 12188 results); 12189 } catch (RemoteException e) { 12190 } 12191 } 12192 app.instrumentationWatcher = null; 12193 app.instrumentationClass = null; 12194 app.instrumentationInfo = null; 12195 app.instrumentationProfileFile = null; 12196 app.instrumentationArguments = null; 12197 12198 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12199 } 12200 finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)12201 public void finishInstrumentation(IApplicationThread target, 12202 int resultCode, Bundle results) { 12203 int userId = UserHandle.getCallingUserId(); 12204 // Refuse possible leaked file descriptors 12205 if (results != null && results.hasFileDescriptors()) { 12206 throw new IllegalArgumentException("File descriptors passed in Intent"); 12207 } 12208 12209 synchronized(this) { 12210 ProcessRecord app = getRecordForAppLocked(target); 12211 if (app == null) { 12212 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12213 return; 12214 } 12215 final long origId = Binder.clearCallingIdentity(); 12216 finishInstrumentationLocked(app, resultCode, results); 12217 Binder.restoreCallingIdentity(origId); 12218 } 12219 } 12220 12221 // ========================================================= 12222 // CONFIGURATION 12223 // ========================================================= 12224 getDeviceConfigurationInfo()12225 public ConfigurationInfo getDeviceConfigurationInfo() { 12226 ConfigurationInfo config = new ConfigurationInfo(); 12227 synchronized (this) { 12228 config.reqTouchScreen = mConfiguration.touchscreen; 12229 config.reqKeyboardType = mConfiguration.keyboard; 12230 config.reqNavigation = mConfiguration.navigation; 12231 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12232 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12233 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12234 } 12235 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12236 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12237 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12238 } 12239 config.reqGlEsVersion = GL_ES_VERSION; 12240 } 12241 return config; 12242 } 12243 getConfiguration()12244 public Configuration getConfiguration() { 12245 Configuration ci; 12246 synchronized(this) { 12247 ci = new Configuration(mConfiguration); 12248 } 12249 return ci; 12250 } 12251 updatePersistentConfiguration(Configuration values)12252 public void updatePersistentConfiguration(Configuration values) { 12253 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12254 "updateConfiguration()"); 12255 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12256 "updateConfiguration()"); 12257 if (values == null) { 12258 throw new NullPointerException("Configuration must not be null"); 12259 } 12260 12261 synchronized(this) { 12262 final long origId = Binder.clearCallingIdentity(); 12263 updateConfigurationLocked(values, null, true, false); 12264 Binder.restoreCallingIdentity(origId); 12265 } 12266 } 12267 updateConfiguration(Configuration values)12268 public void updateConfiguration(Configuration values) { 12269 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12270 "updateConfiguration()"); 12271 12272 synchronized(this) { 12273 if (values == null && mWindowManager != null) { 12274 // sentinel: fetch the current configuration from the window manager 12275 values = mWindowManager.computeNewConfiguration(); 12276 } 12277 12278 if (mWindowManager != null) { 12279 mProcessList.applyDisplaySize(mWindowManager); 12280 } 12281 12282 final long origId = Binder.clearCallingIdentity(); 12283 if (values != null) { 12284 Settings.System.clearConfiguration(values); 12285 } 12286 updateConfigurationLocked(values, null, false, false); 12287 Binder.restoreCallingIdentity(origId); 12288 } 12289 } 12290 12291 /** 12292 * Do either or both things: (1) change the current configuration, and (2) 12293 * make sure the given activity is running with the (now) current 12294 * configuration. Returns true if the activity has been left running, or 12295 * false if <var>starting</var> is being destroyed to match the new 12296 * configuration. 12297 * @param persistent TODO 12298 */ updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean persistent, boolean initLocale)12299 boolean updateConfigurationLocked(Configuration values, 12300 ActivityRecord starting, boolean persistent, boolean initLocale) { 12301 // do nothing if we are headless 12302 if (mHeadless) return true; 12303 12304 int changes = 0; 12305 12306 boolean kept = true; 12307 12308 if (values != null) { 12309 Configuration newConfig = new Configuration(mConfiguration); 12310 changes = newConfig.updateFrom(values); 12311 if (changes != 0) { 12312 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12313 Slog.i(TAG, "Updating configuration to: " + values); 12314 } 12315 12316 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12317 12318 if (values.locale != null && !initLocale) { 12319 saveLocaleLocked(values.locale, 12320 !values.locale.equals(mConfiguration.locale), 12321 values.userSetLocale); 12322 } 12323 12324 mConfigurationSeq++; 12325 if (mConfigurationSeq <= 0) { 12326 mConfigurationSeq = 1; 12327 } 12328 newConfig.seq = mConfigurationSeq; 12329 mConfiguration = newConfig; 12330 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 12331 12332 final Configuration configCopy = new Configuration(mConfiguration); 12333 12334 // TODO: If our config changes, should we auto dismiss any currently 12335 // showing dialogs? 12336 mShowDialogs = shouldShowDialogs(newConfig); 12337 12338 AttributeCache ac = AttributeCache.instance(); 12339 if (ac != null) { 12340 ac.updateConfiguration(configCopy); 12341 } 12342 12343 // Make sure all resources in our process are updated 12344 // right now, so that anyone who is going to retrieve 12345 // resource values after we return will be sure to get 12346 // the new ones. This is especially important during 12347 // boot, where the first config change needs to guarantee 12348 // all resources have that config before following boot 12349 // code is executed. 12350 mSystemThread.applyConfigurationToResources(configCopy); 12351 12352 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12353 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12354 msg.obj = new Configuration(configCopy); 12355 mHandler.sendMessage(msg); 12356 } 12357 12358 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12359 ProcessRecord app = mLruProcesses.get(i); 12360 try { 12361 if (app.thread != null) { 12362 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12363 + app.processName + " new config " + mConfiguration); 12364 app.thread.scheduleConfigurationChanged(configCopy); 12365 } 12366 } catch (Exception e) { 12367 } 12368 } 12369 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12370 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12371 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12372 | Intent.FLAG_RECEIVER_FOREGROUND); 12373 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12374 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12375 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12376 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12377 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12378 broadcastIntentLocked(null, null, intent, 12379 null, null, 0, null, null, 12380 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12381 } 12382 } 12383 } 12384 12385 if (changes != 0 && starting == null) { 12386 // If the configuration changed, and the caller is not already 12387 // in the process of starting an activity, then find the top 12388 // activity to check if its configuration needs to change. 12389 starting = mMainStack.topRunningActivityLocked(null); 12390 } 12391 12392 if (starting != null) { 12393 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12394 // And we need to make sure at this point that all other activities 12395 // are made visible with the correct configuration. 12396 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12397 } 12398 12399 if (values != null && mWindowManager != null) { 12400 mWindowManager.setNewConfiguration(mConfiguration); 12401 } 12402 12403 return kept; 12404 } 12405 12406 /** 12407 * Decide based on the configuration whether we should shouw the ANR, 12408 * crash, etc dialogs. The idea is that if there is no affordnace to 12409 * press the on-screen buttons, we shouldn't show the dialog. 12410 * 12411 * A thought: SystemUI might also want to get told about this, the Power 12412 * dialog / global actions also might want different behaviors. 12413 */ shouldShowDialogs(Configuration config)12414 private static final boolean shouldShowDialogs(Configuration config) { 12415 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12416 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12417 } 12418 12419 /** 12420 * Save the locale. You must be inside a synchronized (this) block. 12421 */ saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)12422 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12423 if(isDiff) { 12424 SystemProperties.set("user.language", l.getLanguage()); 12425 SystemProperties.set("user.region", l.getCountry()); 12426 } 12427 12428 if(isPersist) { 12429 SystemProperties.set("persist.sys.language", l.getLanguage()); 12430 SystemProperties.set("persist.sys.country", l.getCountry()); 12431 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12432 } 12433 } 12434 12435 @Override targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)12436 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12437 ActivityRecord srec = ActivityRecord.forToken(token); 12438 return srec != null && srec.task.affinity != null && 12439 srec.task.affinity.equals(destAffinity); 12440 } 12441 navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData)12442 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12443 Intent resultData) { 12444 ComponentName dest = destIntent.getComponent(); 12445 12446 synchronized (this) { 12447 ActivityRecord srec = ActivityRecord.forToken(token); 12448 if (srec == null) { 12449 return false; 12450 } 12451 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12452 final int start = history.indexOf(srec); 12453 if (start < 0) { 12454 // Current activity is not in history stack; do nothing. 12455 return false; 12456 } 12457 int finishTo = start - 1; 12458 ActivityRecord parent = null; 12459 boolean foundParentInTask = false; 12460 if (dest != null) { 12461 TaskRecord tr = srec.task; 12462 for (int i = start - 1; i >= 0; i--) { 12463 ActivityRecord r = history.get(i); 12464 if (tr != r.task) { 12465 // Couldn't find parent in the same task; stop at the one above this. 12466 // (Root of current task; in-app "home" behavior) 12467 // Always at least finish the current activity. 12468 finishTo = Math.min(start - 1, i + 1); 12469 parent = history.get(finishTo); 12470 break; 12471 } else if (r.info.packageName.equals(dest.getPackageName()) && 12472 r.info.name.equals(dest.getClassName())) { 12473 finishTo = i; 12474 parent = r; 12475 foundParentInTask = true; 12476 break; 12477 } 12478 } 12479 } 12480 12481 if (mController != null) { 12482 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12483 if (next != null) { 12484 // ask watcher if this is allowed 12485 boolean resumeOK = true; 12486 try { 12487 resumeOK = mController.activityResuming(next.packageName); 12488 } catch (RemoteException e) { 12489 mController = null; 12490 } 12491 12492 if (!resumeOK) { 12493 return false; 12494 } 12495 } 12496 } 12497 final long origId = Binder.clearCallingIdentity(); 12498 for (int i = start; i > finishTo; i--) { 12499 ActivityRecord r = history.get(i); 12500 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12501 "navigate-up", true); 12502 // Only return the supplied result for the first activity finished 12503 resultCode = Activity.RESULT_CANCELED; 12504 resultData = null; 12505 } 12506 12507 if (parent != null && foundParentInTask) { 12508 final int parentLaunchMode = parent.info.launchMode; 12509 final int destIntentFlags = destIntent.getFlags(); 12510 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12511 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12512 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12513 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12514 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12515 } else { 12516 try { 12517 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12518 destIntent.getComponent(), 0, srec.userId); 12519 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12520 null, aInfo, parent.appToken, null, 12521 0, -1, parent.launchedFromUid, 0, null, true, null); 12522 foundParentInTask = res == ActivityManager.START_SUCCESS; 12523 } catch (RemoteException e) { 12524 foundParentInTask = false; 12525 } 12526 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12527 resultData, "navigate-up", true); 12528 } 12529 } 12530 Binder.restoreCallingIdentity(origId); 12531 return foundParentInTask; 12532 } 12533 } 12534 getLaunchedFromUid(IBinder activityToken)12535 public int getLaunchedFromUid(IBinder activityToken) { 12536 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12537 if (srec == null) { 12538 return -1; 12539 } 12540 return srec.launchedFromUid; 12541 } 12542 12543 // ========================================================= 12544 // LIFETIME MANAGEMENT 12545 // ========================================================= 12546 12547 // Returns which broadcast queue the app is the current [or imminent] receiver 12548 // on, or 'null' if the app is not an active broadcast recipient. isReceivingBroadcast(ProcessRecord app)12549 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12550 BroadcastRecord r = app.curReceiver; 12551 if (r != null) { 12552 return r.queue; 12553 } 12554 12555 // It's not the current receiver, but it might be starting up to become one 12556 synchronized (this) { 12557 for (BroadcastQueue queue : mBroadcastQueues) { 12558 r = queue.mPendingBroadcast; 12559 if (r != null && r.curApp == app) { 12560 // found it; report which queue it's in 12561 return queue; 12562 } 12563 } 12564 } 12565 12566 return null; 12567 } 12568 computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll)12569 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12570 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12571 if (mAdjSeq == app.adjSeq) { 12572 // This adjustment has already been computed. If we are calling 12573 // from the top, we may have already computed our adjustment with 12574 // an earlier hidden adjustment that isn't really for us... if 12575 // so, use the new hidden adjustment. 12576 if (!recursed && app.hidden) { 12577 if (app.hasActivities) { 12578 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12579 } else if (app.hasClientActivities) { 12580 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12581 } else { 12582 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12583 } 12584 } 12585 return app.curRawAdj; 12586 } 12587 12588 if (app.thread == null) { 12589 app.adjSeq = mAdjSeq; 12590 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12591 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12592 } 12593 12594 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12595 app.adjSource = null; 12596 app.adjTarget = null; 12597 app.empty = false; 12598 app.hidden = false; 12599 app.hasClientActivities = false; 12600 12601 final int activitiesSize = app.activities.size(); 12602 12603 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12604 // The max adjustment doesn't allow this app to be anything 12605 // below foreground, so it is not worth doing work for it. 12606 app.adjType = "fixed"; 12607 app.adjSeq = mAdjSeq; 12608 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12609 app.hasActivities = false; 12610 app.foregroundActivities = false; 12611 app.keeping = true; 12612 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12613 // System process can do UI, and when they do we want to have 12614 // them trim their memory after the user leaves the UI. To 12615 // facilitate this, here we need to determine whether or not it 12616 // is currently showing UI. 12617 app.systemNoUi = true; 12618 if (app == TOP_APP) { 12619 app.systemNoUi = false; 12620 app.hasActivities = true; 12621 } else if (activitiesSize > 0) { 12622 for (int j = 0; j < activitiesSize; j++) { 12623 final ActivityRecord r = app.activities.get(j); 12624 if (r.visible) { 12625 app.systemNoUi = false; 12626 } 12627 if (r.app == app) { 12628 app.hasActivities = true; 12629 } 12630 } 12631 } 12632 return (app.curAdj=app.maxAdj); 12633 } 12634 12635 app.keeping = false; 12636 app.systemNoUi = false; 12637 app.hasActivities = false; 12638 12639 // Determine the importance of the process, starting with most 12640 // important to least, and assign an appropriate OOM adjustment. 12641 int adj; 12642 int schedGroup; 12643 boolean foregroundActivities = false; 12644 boolean interesting = false; 12645 BroadcastQueue queue; 12646 if (app == TOP_APP) { 12647 // The last app on the list is the foreground app. 12648 adj = ProcessList.FOREGROUND_APP_ADJ; 12649 schedGroup = Process.THREAD_GROUP_DEFAULT; 12650 app.adjType = "top-activity"; 12651 foregroundActivities = true; 12652 interesting = true; 12653 app.hasActivities = true; 12654 } else if (app.instrumentationClass != null) { 12655 // Don't want to kill running instrumentation. 12656 adj = ProcessList.FOREGROUND_APP_ADJ; 12657 schedGroup = Process.THREAD_GROUP_DEFAULT; 12658 app.adjType = "instrumentation"; 12659 interesting = true; 12660 } else if ((queue = isReceivingBroadcast(app)) != null) { 12661 // An app that is currently receiving a broadcast also 12662 // counts as being in the foreground for OOM killer purposes. 12663 // It's placed in a sched group based on the nature of the 12664 // broadcast as reflected by which queue it's active in. 12665 adj = ProcessList.FOREGROUND_APP_ADJ; 12666 schedGroup = (queue == mFgBroadcastQueue) 12667 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12668 app.adjType = "broadcast"; 12669 } else if (app.executingServices.size() > 0) { 12670 // An app that is currently executing a service callback also 12671 // counts as being in the foreground. 12672 adj = ProcessList.FOREGROUND_APP_ADJ; 12673 schedGroup = Process.THREAD_GROUP_DEFAULT; 12674 app.adjType = "exec-service"; 12675 } else { 12676 // Assume process is hidden (has activities); we will correct 12677 // later if this is not the case. 12678 adj = hiddenAdj; 12679 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12680 app.hidden = true; 12681 app.adjType = "bg-act"; 12682 } 12683 12684 boolean hasStoppingActivities = false; 12685 12686 // Examine all activities if not already foreground. 12687 if (!foregroundActivities && activitiesSize > 0) { 12688 for (int j = 0; j < activitiesSize; j++) { 12689 final ActivityRecord r = app.activities.get(j); 12690 if (r.visible) { 12691 // App has a visible activity; only upgrade adjustment. 12692 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12693 adj = ProcessList.VISIBLE_APP_ADJ; 12694 app.adjType = "visible"; 12695 } 12696 schedGroup = Process.THREAD_GROUP_DEFAULT; 12697 app.hidden = false; 12698 app.hasActivities = true; 12699 foregroundActivities = true; 12700 break; 12701 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12702 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12703 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12704 app.adjType = "pausing"; 12705 } 12706 app.hidden = false; 12707 foregroundActivities = true; 12708 } else if (r.state == ActivityState.STOPPING) { 12709 // We will apply the actual adjustment later, because 12710 // we want to allow this process to immediately go through 12711 // any memory trimming that is in effect. 12712 app.hidden = false; 12713 foregroundActivities = true; 12714 hasStoppingActivities = true; 12715 } 12716 if (r.app == app) { 12717 app.hasActivities = true; 12718 } 12719 } 12720 } 12721 12722 if (adj == hiddenAdj && !app.hasActivities) { 12723 if (app.hasClientActivities) { 12724 adj = clientHiddenAdj; 12725 app.adjType = "bg-client-act"; 12726 } else { 12727 // Whoops, this process is completely empty as far as we know 12728 // at this point. 12729 adj = emptyAdj; 12730 app.empty = true; 12731 app.adjType = "bg-empty"; 12732 } 12733 } 12734 12735 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12736 if (app.foregroundServices) { 12737 // The user is aware of this app, so make it visible. 12738 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12739 app.hidden = false; 12740 app.adjType = "fg-service"; 12741 schedGroup = Process.THREAD_GROUP_DEFAULT; 12742 } else if (app.forcingToForeground != null) { 12743 // The user is aware of this app, so make it visible. 12744 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12745 app.hidden = false; 12746 app.adjType = "force-fg"; 12747 app.adjSource = app.forcingToForeground; 12748 schedGroup = Process.THREAD_GROUP_DEFAULT; 12749 } 12750 } 12751 12752 if (app.foregroundServices) { 12753 interesting = true; 12754 } 12755 12756 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12757 // We don't want to kill the current heavy-weight process. 12758 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12759 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12760 app.hidden = false; 12761 app.adjType = "heavy"; 12762 } 12763 12764 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12765 // This process is hosting what we currently consider to be the 12766 // home app, so we don't want to let it go into the background. 12767 adj = ProcessList.HOME_APP_ADJ; 12768 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12769 app.hidden = false; 12770 app.adjType = "home"; 12771 } 12772 12773 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12774 && app.activities.size() > 0) { 12775 // This was the previous process that showed UI to the user. 12776 // We want to try to keep it around more aggressively, to give 12777 // a good experience around switching between two apps. 12778 adj = ProcessList.PREVIOUS_APP_ADJ; 12779 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12780 app.hidden = false; 12781 app.adjType = "previous"; 12782 } 12783 12784 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12785 + " reason=" + app.adjType); 12786 12787 // By default, we use the computed adjustment. It may be changed if 12788 // there are applications dependent on our services or providers, but 12789 // this gives us a baseline and makes sure we don't get into an 12790 // infinite recursion. 12791 app.adjSeq = mAdjSeq; 12792 app.curRawAdj = app.nonStoppingAdj = adj; 12793 12794 if (mBackupTarget != null && app == mBackupTarget.app) { 12795 // If possible we want to avoid killing apps while they're being backed up 12796 if (adj > ProcessList.BACKUP_APP_ADJ) { 12797 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12798 adj = ProcessList.BACKUP_APP_ADJ; 12799 app.adjType = "backup"; 12800 app.hidden = false; 12801 } 12802 } 12803 12804 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12805 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12806 final long now = SystemClock.uptimeMillis(); 12807 // This process is more important if the top activity is 12808 // bound to the service. 12809 Iterator<ServiceRecord> jt = app.services.iterator(); 12810 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12811 ServiceRecord s = jt.next(); 12812 if (s.startRequested) { 12813 if (app.hasShownUi && app != mHomeProcess) { 12814 // If this process has shown some UI, let it immediately 12815 // go to the LRU list because it may be pretty heavy with 12816 // UI stuff. We'll tag it with a label just to help 12817 // debug and understand what is going on. 12818 if (adj > ProcessList.SERVICE_ADJ) { 12819 app.adjType = "started-bg-ui-services"; 12820 } 12821 } else { 12822 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12823 // This service has seen some activity within 12824 // recent memory, so we will keep its process ahead 12825 // of the background processes. 12826 if (adj > ProcessList.SERVICE_ADJ) { 12827 adj = ProcessList.SERVICE_ADJ; 12828 app.adjType = "started-services"; 12829 app.hidden = false; 12830 } 12831 } 12832 // If we have let the service slide into the background 12833 // state, still have some text describing what it is doing 12834 // even though the service no longer has an impact. 12835 if (adj > ProcessList.SERVICE_ADJ) { 12836 app.adjType = "started-bg-services"; 12837 } 12838 } 12839 // Don't kill this process because it is doing work; it 12840 // has said it is doing work. 12841 app.keeping = true; 12842 } 12843 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12844 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12845 Iterator<ArrayList<ConnectionRecord>> kt 12846 = s.connections.values().iterator(); 12847 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12848 ArrayList<ConnectionRecord> clist = kt.next(); 12849 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12850 // XXX should compute this based on the max of 12851 // all connected clients. 12852 ConnectionRecord cr = clist.get(i); 12853 if (cr.binding.client == app) { 12854 // Binding to ourself is not interesting. 12855 continue; 12856 } 12857 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12858 ProcessRecord client = cr.binding.client; 12859 int clientAdj = adj; 12860 int myHiddenAdj = hiddenAdj; 12861 if (myHiddenAdj > client.hiddenAdj) { 12862 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12863 myHiddenAdj = client.hiddenAdj; 12864 } else { 12865 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12866 } 12867 } 12868 int myClientHiddenAdj = clientHiddenAdj; 12869 if (myClientHiddenAdj > client.clientHiddenAdj) { 12870 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12871 myClientHiddenAdj = client.clientHiddenAdj; 12872 } else { 12873 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12874 } 12875 } 12876 int myEmptyAdj = emptyAdj; 12877 if (myEmptyAdj > client.emptyAdj) { 12878 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12879 myEmptyAdj = client.emptyAdj; 12880 } else { 12881 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12882 } 12883 } 12884 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12885 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12886 String adjType = null; 12887 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12888 // Not doing bind OOM management, so treat 12889 // this guy more like a started service. 12890 if (app.hasShownUi && app != mHomeProcess) { 12891 // If this process has shown some UI, let it immediately 12892 // go to the LRU list because it may be pretty heavy with 12893 // UI stuff. We'll tag it with a label just to help 12894 // debug and understand what is going on. 12895 if (adj > clientAdj) { 12896 adjType = "bound-bg-ui-services"; 12897 } 12898 app.hidden = false; 12899 clientAdj = adj; 12900 } else { 12901 if (now >= (s.lastActivity 12902 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12903 // This service has not seen activity within 12904 // recent memory, so allow it to drop to the 12905 // LRU list if there is no other reason to keep 12906 // it around. We'll also tag it with a label just 12907 // to help debug and undertand what is going on. 12908 if (adj > clientAdj) { 12909 adjType = "bound-bg-services"; 12910 } 12911 clientAdj = adj; 12912 } 12913 } 12914 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12915 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12916 // If this connection is keeping the service 12917 // created, then we want to try to better follow 12918 // its memory management semantics for activities. 12919 // That is, if it is sitting in the background 12920 // LRU list as a hidden process (with activities), 12921 // we don't want the service it is connected to 12922 // to go into the empty LRU and quickly get killed, 12923 // because I'll we'll do is just end up restarting 12924 // the service. 12925 app.hasClientActivities |= client.hasActivities; 12926 } 12927 } 12928 if (adj > clientAdj) { 12929 // If this process has recently shown UI, and 12930 // the process that is binding to it is less 12931 // important than being visible, then we don't 12932 // care about the binding as much as we care 12933 // about letting this process get into the LRU 12934 // list to be killed and restarted if needed for 12935 // memory. 12936 if (app.hasShownUi && app != mHomeProcess 12937 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12938 adjType = "bound-bg-ui-services"; 12939 } else { 12940 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12941 |Context.BIND_IMPORTANT)) != 0) { 12942 adj = clientAdj; 12943 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12944 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12945 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12946 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12947 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12948 adj = clientAdj; 12949 } else { 12950 app.pendingUiClean = true; 12951 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12952 adj = ProcessList.VISIBLE_APP_ADJ; 12953 } 12954 } 12955 if (!client.hidden) { 12956 app.hidden = false; 12957 } 12958 if (client.keeping) { 12959 app.keeping = true; 12960 } 12961 adjType = "service"; 12962 } 12963 } 12964 if (adjType != null) { 12965 app.adjType = adjType; 12966 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12967 .REASON_SERVICE_IN_USE; 12968 app.adjSource = cr.binding.client; 12969 app.adjSourceOom = clientAdj; 12970 app.adjTarget = s.name; 12971 } 12972 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12973 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12974 schedGroup = Process.THREAD_GROUP_DEFAULT; 12975 } 12976 } 12977 } 12978 final ActivityRecord a = cr.activity; 12979 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12980 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12981 (a.visible || a.state == ActivityState.RESUMED 12982 || a.state == ActivityState.PAUSING)) { 12983 adj = ProcessList.FOREGROUND_APP_ADJ; 12984 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12985 schedGroup = Process.THREAD_GROUP_DEFAULT; 12986 } 12987 app.hidden = false; 12988 app.adjType = "service"; 12989 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12990 .REASON_SERVICE_IN_USE; 12991 app.adjSource = a; 12992 app.adjSourceOom = adj; 12993 app.adjTarget = s.name; 12994 } 12995 } 12996 } 12997 } 12998 } 12999 } 13000 13001 // Finally, if this process has active services running in it, we 13002 // would like to avoid killing it unless it would prevent the current 13003 // application from running. By default we put the process in 13004 // with the rest of the background processes; as we scan through 13005 // its services we may bump it up from there. 13006 if (adj > hiddenAdj) { 13007 adj = hiddenAdj; 13008 app.hidden = false; 13009 app.adjType = "bg-services"; 13010 } 13011 } 13012 13013 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13014 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13015 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13016 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13017 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13018 ContentProviderRecord cpr = jt.next(); 13019 for (int i = cpr.connections.size()-1; 13020 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13021 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 13022 i--) { 13023 ContentProviderConnection conn = cpr.connections.get(i); 13024 ProcessRecord client = conn.client; 13025 if (client == app) { 13026 // Being our own client is not interesting. 13027 continue; 13028 } 13029 int myHiddenAdj = hiddenAdj; 13030 if (myHiddenAdj > client.hiddenAdj) { 13031 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13032 myHiddenAdj = client.hiddenAdj; 13033 } else { 13034 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13035 } 13036 } 13037 int myClientHiddenAdj = clientHiddenAdj; 13038 if (myClientHiddenAdj > client.clientHiddenAdj) { 13039 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 13040 myClientHiddenAdj = client.clientHiddenAdj; 13041 } else { 13042 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13043 } 13044 } 13045 int myEmptyAdj = emptyAdj; 13046 if (myEmptyAdj > client.emptyAdj) { 13047 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 13048 myEmptyAdj = client.emptyAdj; 13049 } else { 13050 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 13051 } 13052 } 13053 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13054 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13055 if (adj > clientAdj) { 13056 if (app.hasShownUi && app != mHomeProcess 13057 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13058 app.adjType = "bg-ui-provider"; 13059 } else { 13060 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13061 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13062 app.adjType = "provider"; 13063 } 13064 if (!client.hidden) { 13065 app.hidden = false; 13066 } 13067 if (client.keeping) { 13068 app.keeping = true; 13069 } 13070 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13071 .REASON_PROVIDER_IN_USE; 13072 app.adjSource = client; 13073 app.adjSourceOom = clientAdj; 13074 app.adjTarget = cpr.name; 13075 } 13076 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13077 schedGroup = Process.THREAD_GROUP_DEFAULT; 13078 } 13079 } 13080 // If the provider has external (non-framework) process 13081 // dependencies, ensure that its adjustment is at least 13082 // FOREGROUND_APP_ADJ. 13083 if (cpr.hasExternalProcessHandles()) { 13084 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13085 adj = ProcessList.FOREGROUND_APP_ADJ; 13086 schedGroup = Process.THREAD_GROUP_DEFAULT; 13087 app.hidden = false; 13088 app.keeping = true; 13089 app.adjType = "provider"; 13090 app.adjTarget = cpr.name; 13091 } 13092 } 13093 } 13094 } 13095 13096 if (adj == ProcessList.SERVICE_ADJ) { 13097 if (doingAll) { 13098 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13099 mNewNumServiceProcs++; 13100 } 13101 if (app.serviceb) { 13102 adj = ProcessList.SERVICE_B_ADJ; 13103 } 13104 } else { 13105 app.serviceb = false; 13106 } 13107 13108 app.nonStoppingAdj = adj; 13109 13110 if (hasStoppingActivities) { 13111 // Only upgrade adjustment. 13112 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13113 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13114 app.adjType = "stopping"; 13115 } 13116 } 13117 13118 app.curRawAdj = adj; 13119 13120 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13121 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13122 if (adj > app.maxAdj) { 13123 adj = app.maxAdj; 13124 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13125 schedGroup = Process.THREAD_GROUP_DEFAULT; 13126 } 13127 } 13128 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13129 app.keeping = true; 13130 } 13131 13132 if (app.hasAboveClient) { 13133 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13134 // then we need to drop its adjustment to be lower than the service's 13135 // in order to honor the request. We want to drop it by one adjustment 13136 // level... but there is special meaning applied to various levels so 13137 // we will skip some of them. 13138 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13139 // System process will not get dropped, ever 13140 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13141 adj = ProcessList.VISIBLE_APP_ADJ; 13142 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13143 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13144 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13145 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13146 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13147 adj++; 13148 } 13149 } 13150 13151 int importance = app.memImportance; 13152 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13153 app.curAdj = adj; 13154 app.curSchedGroup = schedGroup; 13155 if (!interesting) { 13156 // For this reporting, if there is not something explicitly 13157 // interesting in this process then we will push it to the 13158 // background importance. 13159 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13160 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13161 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13162 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13163 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13164 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13165 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13166 } else if (adj >= ProcessList.SERVICE_ADJ) { 13167 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13168 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13169 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13170 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13171 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13172 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13173 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13174 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13175 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13176 } else { 13177 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13178 } 13179 } 13180 13181 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13182 if (foregroundActivities != app.foregroundActivities) { 13183 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13184 } 13185 if (changes != 0) { 13186 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13187 app.memImportance = importance; 13188 app.foregroundActivities = foregroundActivities; 13189 int i = mPendingProcessChanges.size()-1; 13190 ProcessChangeItem item = null; 13191 while (i >= 0) { 13192 item = mPendingProcessChanges.get(i); 13193 if (item.pid == app.pid) { 13194 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13195 break; 13196 } 13197 i--; 13198 } 13199 if (i < 0) { 13200 // No existing item in pending changes; need a new one. 13201 final int NA = mAvailProcessChanges.size(); 13202 if (NA > 0) { 13203 item = mAvailProcessChanges.remove(NA-1); 13204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13205 } else { 13206 item = new ProcessChangeItem(); 13207 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13208 } 13209 item.changes = 0; 13210 item.pid = app.pid; 13211 item.uid = app.info.uid; 13212 if (mPendingProcessChanges.size() == 0) { 13213 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13214 "*** Enqueueing dispatch processes changed!"); 13215 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13216 } 13217 mPendingProcessChanges.add(item); 13218 } 13219 item.changes |= changes; 13220 item.importance = importance; 13221 item.foregroundActivities = foregroundActivities; 13222 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13223 + Integer.toHexString(System.identityHashCode(item)) 13224 + " " + app.toShortString() + ": changes=" + item.changes 13225 + " importance=" + item.importance 13226 + " foreground=" + item.foregroundActivities 13227 + " type=" + app.adjType + " source=" + app.adjSource 13228 + " target=" + app.adjTarget); 13229 } 13230 13231 return app.curRawAdj; 13232 } 13233 13234 /** 13235 * Ask a given process to GC right now. 13236 */ performAppGcLocked(ProcessRecord app)13237 final void performAppGcLocked(ProcessRecord app) { 13238 try { 13239 app.lastRequestedGc = SystemClock.uptimeMillis(); 13240 if (app.thread != null) { 13241 if (app.reportLowMemory) { 13242 app.reportLowMemory = false; 13243 app.thread.scheduleLowMemory(); 13244 } else { 13245 app.thread.processInBackground(); 13246 } 13247 } 13248 } catch (Exception e) { 13249 // whatever. 13250 } 13251 } 13252 13253 /** 13254 * Returns true if things are idle enough to perform GCs. 13255 */ canGcNowLocked()13256 private final boolean canGcNowLocked() { 13257 boolean processingBroadcasts = false; 13258 for (BroadcastQueue q : mBroadcastQueues) { 13259 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13260 processingBroadcasts = true; 13261 } 13262 } 13263 return !processingBroadcasts 13264 && (mSleeping || (mMainStack.mResumedActivity != null && 13265 mMainStack.mResumedActivity.idle)); 13266 } 13267 13268 /** 13269 * Perform GCs on all processes that are waiting for it, but only 13270 * if things are idle. 13271 */ performAppGcsLocked()13272 final void performAppGcsLocked() { 13273 final int N = mProcessesToGc.size(); 13274 if (N <= 0) { 13275 return; 13276 } 13277 if (canGcNowLocked()) { 13278 while (mProcessesToGc.size() > 0) { 13279 ProcessRecord proc = mProcessesToGc.remove(0); 13280 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13281 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13282 <= SystemClock.uptimeMillis()) { 13283 // To avoid spamming the system, we will GC processes one 13284 // at a time, waiting a few seconds between each. 13285 performAppGcLocked(proc); 13286 scheduleAppGcsLocked(); 13287 return; 13288 } else { 13289 // It hasn't been long enough since we last GCed this 13290 // process... put it in the list to wait for its time. 13291 addProcessToGcListLocked(proc); 13292 break; 13293 } 13294 } 13295 } 13296 13297 scheduleAppGcsLocked(); 13298 } 13299 } 13300 13301 /** 13302 * If all looks good, perform GCs on all processes waiting for them. 13303 */ performAppGcsIfAppropriateLocked()13304 final void performAppGcsIfAppropriateLocked() { 13305 if (canGcNowLocked()) { 13306 performAppGcsLocked(); 13307 return; 13308 } 13309 // Still not idle, wait some more. 13310 scheduleAppGcsLocked(); 13311 } 13312 13313 /** 13314 * Schedule the execution of all pending app GCs. 13315 */ scheduleAppGcsLocked()13316 final void scheduleAppGcsLocked() { 13317 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13318 13319 if (mProcessesToGc.size() > 0) { 13320 // Schedule a GC for the time to the next process. 13321 ProcessRecord proc = mProcessesToGc.get(0); 13322 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13323 13324 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13325 long now = SystemClock.uptimeMillis(); 13326 if (when < (now+GC_TIMEOUT)) { 13327 when = now + GC_TIMEOUT; 13328 } 13329 mHandler.sendMessageAtTime(msg, when); 13330 } 13331 } 13332 13333 /** 13334 * Add a process to the array of processes waiting to be GCed. Keeps the 13335 * list in sorted order by the last GC time. The process can't already be 13336 * on the list. 13337 */ addProcessToGcListLocked(ProcessRecord proc)13338 final void addProcessToGcListLocked(ProcessRecord proc) { 13339 boolean added = false; 13340 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13341 if (mProcessesToGc.get(i).lastRequestedGc < 13342 proc.lastRequestedGc) { 13343 added = true; 13344 mProcessesToGc.add(i+1, proc); 13345 break; 13346 } 13347 } 13348 if (!added) { 13349 mProcessesToGc.add(0, proc); 13350 } 13351 } 13352 13353 /** 13354 * Set up to ask a process to GC itself. This will either do it 13355 * immediately, or put it on the list of processes to gc the next 13356 * time things are idle. 13357 */ scheduleAppGcLocked(ProcessRecord app)13358 final void scheduleAppGcLocked(ProcessRecord app) { 13359 long now = SystemClock.uptimeMillis(); 13360 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13361 return; 13362 } 13363 if (!mProcessesToGc.contains(app)) { 13364 addProcessToGcListLocked(app); 13365 scheduleAppGcsLocked(); 13366 } 13367 } 13368 checkExcessivePowerUsageLocked(boolean doKills)13369 final void checkExcessivePowerUsageLocked(boolean doKills) { 13370 updateCpuStatsNow(); 13371 13372 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13373 boolean doWakeKills = doKills; 13374 boolean doCpuKills = doKills; 13375 if (mLastPowerCheckRealtime == 0) { 13376 doWakeKills = false; 13377 } 13378 if (mLastPowerCheckUptime == 0) { 13379 doCpuKills = false; 13380 } 13381 if (stats.isScreenOn()) { 13382 doWakeKills = false; 13383 } 13384 final long curRealtime = SystemClock.elapsedRealtime(); 13385 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13386 final long curUptime = SystemClock.uptimeMillis(); 13387 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13388 mLastPowerCheckRealtime = curRealtime; 13389 mLastPowerCheckUptime = curUptime; 13390 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13391 doWakeKills = false; 13392 } 13393 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13394 doCpuKills = false; 13395 } 13396 int i = mLruProcesses.size(); 13397 while (i > 0) { 13398 i--; 13399 ProcessRecord app = mLruProcesses.get(i); 13400 if (!app.keeping) { 13401 long wtime; 13402 synchronized (stats) { 13403 wtime = stats.getProcessWakeTime(app.info.uid, 13404 app.pid, curRealtime); 13405 } 13406 long wtimeUsed = wtime - app.lastWakeTime; 13407 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13408 if (DEBUG_POWER) { 13409 StringBuilder sb = new StringBuilder(128); 13410 sb.append("Wake for "); 13411 app.toShortString(sb); 13412 sb.append(": over "); 13413 TimeUtils.formatDuration(realtimeSince, sb); 13414 sb.append(" used "); 13415 TimeUtils.formatDuration(wtimeUsed, sb); 13416 sb.append(" ("); 13417 sb.append((wtimeUsed*100)/realtimeSince); 13418 sb.append("%)"); 13419 Slog.i(TAG, sb.toString()); 13420 sb.setLength(0); 13421 sb.append("CPU for "); 13422 app.toShortString(sb); 13423 sb.append(": over "); 13424 TimeUtils.formatDuration(uptimeSince, sb); 13425 sb.append(" used "); 13426 TimeUtils.formatDuration(cputimeUsed, sb); 13427 sb.append(" ("); 13428 sb.append((cputimeUsed*100)/uptimeSince); 13429 sb.append("%)"); 13430 Slog.i(TAG, sb.toString()); 13431 } 13432 // If a process has held a wake lock for more 13433 // than 50% of the time during this period, 13434 // that sounds bad. Kill! 13435 if (doWakeKills && realtimeSince > 0 13436 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13437 synchronized (stats) { 13438 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13439 realtimeSince, wtimeUsed); 13440 } 13441 Slog.w(TAG, "Excessive wake lock in " + app.processName 13442 + " (pid " + app.pid + "): held " + wtimeUsed 13443 + " during " + realtimeSince); 13444 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13445 app.processName, app.setAdj, "excessive wake lock"); 13446 Process.killProcessQuiet(app.pid); 13447 } else if (doCpuKills && uptimeSince > 0 13448 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13449 synchronized (stats) { 13450 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13451 uptimeSince, cputimeUsed); 13452 } 13453 Slog.w(TAG, "Excessive CPU in " + app.processName 13454 + " (pid " + app.pid + "): used " + cputimeUsed 13455 + " during " + uptimeSince); 13456 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13457 app.processName, app.setAdj, "excessive cpu"); 13458 Process.killProcessQuiet(app.pid); 13459 } else { 13460 app.lastWakeTime = wtime; 13461 app.lastCpuTime = app.curCpuTime; 13462 } 13463 } 13464 } 13465 } 13466 updateOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll)13467 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13468 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13469 app.hiddenAdj = hiddenAdj; 13470 app.clientHiddenAdj = clientHiddenAdj; 13471 app.emptyAdj = emptyAdj; 13472 13473 if (app.thread == null) { 13474 return false; 13475 } 13476 13477 final boolean wasKeeping = app.keeping; 13478 13479 boolean success = true; 13480 13481 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13482 13483 if (app.curRawAdj != app.setRawAdj) { 13484 if (wasKeeping && !app.keeping) { 13485 // This app is no longer something we want to keep. Note 13486 // its current wake lock time to later know to kill it if 13487 // it is not behaving well. 13488 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13489 synchronized (stats) { 13490 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13491 app.pid, SystemClock.elapsedRealtime()); 13492 } 13493 app.lastCpuTime = app.curCpuTime; 13494 } 13495 13496 app.setRawAdj = app.curRawAdj; 13497 } 13498 13499 if (app.curAdj != app.setAdj) { 13500 if (Process.setOomAdj(app.pid, app.curAdj)) { 13501 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13502 TAG, "Set " + app.pid + " " + app.processName + 13503 " adj " + app.curAdj + ": " + app.adjType); 13504 app.setAdj = app.curAdj; 13505 } else { 13506 success = false; 13507 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13508 } 13509 } 13510 if (app.setSchedGroup != app.curSchedGroup) { 13511 app.setSchedGroup = app.curSchedGroup; 13512 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13513 "Setting process group of " + app.processName 13514 + " to " + app.curSchedGroup); 13515 if (app.waitingToKill != null && 13516 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13517 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13518 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13519 app.processName, app.setAdj, app.waitingToKill); 13520 app.killedBackground = true; 13521 Process.killProcessQuiet(app.pid); 13522 success = false; 13523 } else { 13524 if (true) { 13525 long oldId = Binder.clearCallingIdentity(); 13526 try { 13527 Process.setProcessGroup(app.pid, app.curSchedGroup); 13528 } catch (Exception e) { 13529 Slog.w(TAG, "Failed setting process group of " + app.pid 13530 + " to " + app.curSchedGroup); 13531 e.printStackTrace(); 13532 } finally { 13533 Binder.restoreCallingIdentity(oldId); 13534 } 13535 } else { 13536 if (app.thread != null) { 13537 try { 13538 app.thread.setSchedulingGroup(app.curSchedGroup); 13539 } catch (RemoteException e) { 13540 } 13541 } 13542 } 13543 } 13544 } 13545 return success; 13546 } 13547 resumedAppLocked()13548 private final ActivityRecord resumedAppLocked() { 13549 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13550 if (resumedActivity == null || resumedActivity.app == null) { 13551 resumedActivity = mMainStack.mPausingActivity; 13552 if (resumedActivity == null || resumedActivity.app == null) { 13553 resumedActivity = mMainStack.topRunningActivityLocked(null); 13554 } 13555 } 13556 return resumedActivity; 13557 } 13558 updateOomAdjLocked(ProcessRecord app)13559 final boolean updateOomAdjLocked(ProcessRecord app) { 13560 final ActivityRecord TOP_ACT = resumedAppLocked(); 13561 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13562 int curAdj = app.curAdj; 13563 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13564 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13565 13566 mAdjSeq++; 13567 13568 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13569 app.emptyAdj, TOP_APP, false); 13570 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13571 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13572 if (nowHidden != wasHidden) { 13573 // Changed to/from hidden state, so apps after it in the LRU 13574 // list may also be changed. 13575 updateOomAdjLocked(); 13576 } 13577 return success; 13578 } 13579 updateOomAdjLocked()13580 final void updateOomAdjLocked() { 13581 final ActivityRecord TOP_ACT = resumedAppLocked(); 13582 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13583 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13584 13585 if (false) { 13586 RuntimeException e = new RuntimeException(); 13587 e.fillInStackTrace(); 13588 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13589 } 13590 13591 mAdjSeq++; 13592 mNewNumServiceProcs = 0; 13593 13594 final int emptyProcessLimit; 13595 final int hiddenProcessLimit; 13596 if (mProcessLimit <= 0) { 13597 emptyProcessLimit = hiddenProcessLimit = 0; 13598 } else if (mProcessLimit == 1) { 13599 emptyProcessLimit = 1; 13600 hiddenProcessLimit = 0; 13601 } else { 13602 emptyProcessLimit = (mProcessLimit*2)/3; 13603 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13604 } 13605 13606 // Let's determine how many processes we have running vs. 13607 // how many slots we have for background processes; we may want 13608 // to put multiple processes in a slot of there are enough of 13609 // them. 13610 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13611 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13612 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13613 if (numEmptyProcs > hiddenProcessLimit) { 13614 // If there are more empty processes than our limit on hidden 13615 // processes, then use the hidden process limit for the factor. 13616 // This ensures that the really old empty processes get pushed 13617 // down to the bottom, so if we are running low on memory we will 13618 // have a better chance at keeping around more hidden processes 13619 // instead of a gazillion empty processes. 13620 numEmptyProcs = hiddenProcessLimit; 13621 } 13622 int emptyFactor = numEmptyProcs/numSlots; 13623 if (emptyFactor < 1) emptyFactor = 1; 13624 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13625 if (hiddenFactor < 1) hiddenFactor = 1; 13626 int stepHidden = 0; 13627 int stepEmpty = 0; 13628 int numHidden = 0; 13629 int numEmpty = 0; 13630 int numTrimming = 0; 13631 13632 mNumNonHiddenProcs = 0; 13633 mNumHiddenProcs = 0; 13634 13635 // First update the OOM adjustment for each of the 13636 // application processes based on their current state. 13637 int i = mLruProcesses.size(); 13638 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13639 int nextHiddenAdj = curHiddenAdj+1; 13640 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13641 int nextEmptyAdj = curEmptyAdj+2; 13642 int curClientHiddenAdj = curEmptyAdj; 13643 while (i > 0) { 13644 i--; 13645 ProcessRecord app = mLruProcesses.get(i); 13646 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13647 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13648 if (!app.killedBackground) { 13649 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13650 // This process was assigned as a hidden process... step the 13651 // hidden level. 13652 mNumHiddenProcs++; 13653 if (curHiddenAdj != nextHiddenAdj) { 13654 stepHidden++; 13655 if (stepHidden >= hiddenFactor) { 13656 stepHidden = 0; 13657 curHiddenAdj = nextHiddenAdj; 13658 nextHiddenAdj += 2; 13659 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13660 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13661 } 13662 if (curClientHiddenAdj <= curHiddenAdj) { 13663 curClientHiddenAdj = curHiddenAdj + 1; 13664 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13665 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13666 } 13667 } 13668 } 13669 } 13670 numHidden++; 13671 if (numHidden > hiddenProcessLimit) { 13672 Slog.i(TAG, "No longer want " + app.processName 13673 + " (pid " + app.pid + "): hidden #" + numHidden); 13674 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13675 app.processName, app.setAdj, "too many background"); 13676 app.killedBackground = true; 13677 Process.killProcessQuiet(app.pid); 13678 } 13679 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13680 // This process has a client that has activities. We will have 13681 // given it the current hidden adj; here we will just leave it 13682 // without stepping the hidden adj. 13683 curClientHiddenAdj++; 13684 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13685 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13686 } 13687 } else { 13688 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13689 // This process was assigned as an empty process... step the 13690 // empty level. 13691 if (curEmptyAdj != nextEmptyAdj) { 13692 stepEmpty++; 13693 if (stepEmpty >= emptyFactor) { 13694 stepEmpty = 0; 13695 curEmptyAdj = nextEmptyAdj; 13696 nextEmptyAdj += 2; 13697 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13698 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13699 } 13700 } 13701 } 13702 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13703 mNumNonHiddenProcs++; 13704 } 13705 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13706 && !app.hasClientActivities) { 13707 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13708 && app.lastActivityTime < oldTime) { 13709 Slog.i(TAG, "No longer want " + app.processName 13710 + " (pid " + app.pid + "): empty for " 13711 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13712 / 1000) + "s"); 13713 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13714 app.processName, app.setAdj, "old background process"); 13715 app.killedBackground = true; 13716 Process.killProcessQuiet(app.pid); 13717 } else { 13718 numEmpty++; 13719 if (numEmpty > emptyProcessLimit) { 13720 Slog.i(TAG, "No longer want " + app.processName 13721 + " (pid " + app.pid + "): empty #" + numEmpty); 13722 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13723 app.processName, app.setAdj, "too many background"); 13724 app.killedBackground = true; 13725 Process.killProcessQuiet(app.pid); 13726 } 13727 } 13728 } 13729 } 13730 if (app.isolated && app.services.size() <= 0) { 13731 // If this is an isolated process, and there are no 13732 // services running in it, then the process is no longer 13733 // needed. We agressively kill these because we can by 13734 // definition not re-use the same process again, and it is 13735 // good to avoid having whatever code was running in them 13736 // left sitting around after no longer needed. 13737 Slog.i(TAG, "Isolated process " + app.processName 13738 + " (pid " + app.pid + ") no longer needed"); 13739 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13740 app.processName, app.setAdj, "isolated not needed"); 13741 app.killedBackground = true; 13742 Process.killProcessQuiet(app.pid); 13743 } 13744 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13745 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13746 && !app.killedBackground) { 13747 numTrimming++; 13748 } 13749 } 13750 } 13751 13752 mNumServiceProcs = mNewNumServiceProcs; 13753 13754 // Now determine the memory trimming level of background processes. 13755 // Unfortunately we need to start at the back of the list to do this 13756 // properly. We only do this if the number of background apps we 13757 // are managing to keep around is less than half the maximum we desire; 13758 // if we are keeping a good number around, we'll let them use whatever 13759 // memory they want. 13760 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13761 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13762 final int numHiddenAndEmpty = numHidden + numEmpty; 13763 final int N = mLruProcesses.size(); 13764 int factor = numTrimming/3; 13765 int minFactor = 2; 13766 if (mHomeProcess != null) minFactor++; 13767 if (mPreviousProcess != null) minFactor++; 13768 if (factor < minFactor) factor = minFactor; 13769 int step = 0; 13770 int fgTrimLevel; 13771 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13772 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13773 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13774 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13775 } else { 13776 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13777 } 13778 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13779 for (i=0; i<N; i++) { 13780 ProcessRecord app = mLruProcesses.get(i); 13781 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13782 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13783 && !app.killedBackground) { 13784 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13785 try { 13786 app.thread.scheduleTrimMemory(curLevel); 13787 } catch (RemoteException e) { 13788 } 13789 if (false) { 13790 // For now we won't do this; our memory trimming seems 13791 // to be good enough at this point that destroying 13792 // activities causes more harm than good. 13793 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13794 && app != mHomeProcess && app != mPreviousProcess) { 13795 // Need to do this on its own message because the stack may not 13796 // be in a consistent state at this point. 13797 // For these apps we will also finish their activities 13798 // to help them free memory. 13799 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13800 } 13801 } 13802 } 13803 app.trimMemoryLevel = curLevel; 13804 step++; 13805 if (step >= factor) { 13806 step = 0; 13807 switch (curLevel) { 13808 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13809 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13810 break; 13811 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13812 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13813 break; 13814 } 13815 } 13816 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13817 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13818 && app.thread != null) { 13819 try { 13820 app.thread.scheduleTrimMemory( 13821 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13822 } catch (RemoteException e) { 13823 } 13824 } 13825 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13826 } else { 13827 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13828 && app.pendingUiClean) { 13829 // If this application is now in the background and it 13830 // had done UI, then give it the special trim level to 13831 // have it free UI resources. 13832 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13833 if (app.trimMemoryLevel < level && app.thread != null) { 13834 try { 13835 app.thread.scheduleTrimMemory(level); 13836 } catch (RemoteException e) { 13837 } 13838 } 13839 app.pendingUiClean = false; 13840 } 13841 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13842 try { 13843 app.thread.scheduleTrimMemory(fgTrimLevel); 13844 } catch (RemoteException e) { 13845 } 13846 } 13847 app.trimMemoryLevel = fgTrimLevel; 13848 } 13849 } 13850 } else { 13851 final int N = mLruProcesses.size(); 13852 for (i=0; i<N; i++) { 13853 ProcessRecord app = mLruProcesses.get(i); 13854 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13855 && app.pendingUiClean) { 13856 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13857 && app.thread != null) { 13858 try { 13859 app.thread.scheduleTrimMemory( 13860 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13861 } catch (RemoteException e) { 13862 } 13863 } 13864 app.pendingUiClean = false; 13865 } 13866 app.trimMemoryLevel = 0; 13867 } 13868 } 13869 13870 if (mAlwaysFinishActivities) { 13871 // Need to do this on its own message because the stack may not 13872 // be in a consistent state at this point. 13873 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13874 } 13875 } 13876 trimApplications()13877 final void trimApplications() { 13878 synchronized (this) { 13879 int i; 13880 13881 // First remove any unused application processes whose package 13882 // has been removed. 13883 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13884 final ProcessRecord app = mRemovedProcesses.get(i); 13885 if (app.activities.size() == 0 13886 && app.curReceiver == null && app.services.size() == 0) { 13887 Slog.i( 13888 TAG, "Exiting empty application process " 13889 + app.processName + " (" 13890 + (app.thread != null ? app.thread.asBinder() : null) 13891 + ")\n"); 13892 if (app.pid > 0 && app.pid != MY_PID) { 13893 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13894 app.processName, app.setAdj, "empty"); 13895 Process.killProcessQuiet(app.pid); 13896 } else { 13897 try { 13898 app.thread.scheduleExit(); 13899 } catch (Exception e) { 13900 // Ignore exceptions. 13901 } 13902 } 13903 cleanUpApplicationRecordLocked(app, false, true, -1); 13904 mRemovedProcesses.remove(i); 13905 13906 if (app.persistent) { 13907 if (app.persistent) { 13908 addAppLocked(app.info, false); 13909 } 13910 } 13911 } 13912 } 13913 13914 // Now update the oom adj for all processes. 13915 updateOomAdjLocked(); 13916 } 13917 } 13918 13919 /** This method sends the specified signal to each of the persistent apps */ signalPersistentProcesses(int sig)13920 public void signalPersistentProcesses(int sig) throws RemoteException { 13921 if (sig != Process.SIGNAL_USR1) { 13922 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13923 } 13924 13925 synchronized (this) { 13926 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13927 != PackageManager.PERMISSION_GRANTED) { 13928 throw new SecurityException("Requires permission " 13929 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13930 } 13931 13932 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13933 ProcessRecord r = mLruProcesses.get(i); 13934 if (r.thread != null && r.persistent) { 13935 Process.sendSignal(r.pid, sig); 13936 } 13937 } 13938 } 13939 } 13940 stopProfilerLocked(ProcessRecord proc, String path, int profileType)13941 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13942 if (proc == null || proc == mProfileProc) { 13943 proc = mProfileProc; 13944 path = mProfileFile; 13945 profileType = mProfileType; 13946 clearProfilerLocked(); 13947 } 13948 if (proc == null) { 13949 return; 13950 } 13951 try { 13952 proc.thread.profilerControl(false, path, null, profileType); 13953 } catch (RemoteException e) { 13954 throw new IllegalStateException("Process disappeared"); 13955 } 13956 } 13957 clearProfilerLocked()13958 private void clearProfilerLocked() { 13959 if (mProfileFd != null) { 13960 try { 13961 mProfileFd.close(); 13962 } catch (IOException e) { 13963 } 13964 } 13965 mProfileApp = null; 13966 mProfileProc = null; 13967 mProfileFile = null; 13968 mProfileType = 0; 13969 mAutoStopProfiler = false; 13970 } 13971 profileControl(String process, int userId, boolean start, String path, ParcelFileDescriptor fd, int profileType)13972 public boolean profileControl(String process, int userId, boolean start, 13973 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13974 13975 try { 13976 synchronized (this) { 13977 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13978 // its own permission. 13979 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13980 != PackageManager.PERMISSION_GRANTED) { 13981 throw new SecurityException("Requires permission " 13982 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13983 } 13984 13985 if (start && fd == null) { 13986 throw new IllegalArgumentException("null fd"); 13987 } 13988 13989 ProcessRecord proc = null; 13990 if (process != null) { 13991 proc = findProcessLocked(process, userId, "profileControl"); 13992 } 13993 13994 if (start && (proc == null || proc.thread == null)) { 13995 throw new IllegalArgumentException("Unknown process: " + process); 13996 } 13997 13998 if (start) { 13999 stopProfilerLocked(null, null, 0); 14000 setProfileApp(proc.info, proc.processName, path, fd, false); 14001 mProfileProc = proc; 14002 mProfileType = profileType; 14003 try { 14004 fd = fd.dup(); 14005 } catch (IOException e) { 14006 fd = null; 14007 } 14008 proc.thread.profilerControl(start, path, fd, profileType); 14009 fd = null; 14010 mProfileFd = null; 14011 } else { 14012 stopProfilerLocked(proc, path, profileType); 14013 if (fd != null) { 14014 try { 14015 fd.close(); 14016 } catch (IOException e) { 14017 } 14018 } 14019 } 14020 14021 return true; 14022 } 14023 } catch (RemoteException e) { 14024 throw new IllegalStateException("Process disappeared"); 14025 } finally { 14026 if (fd != null) { 14027 try { 14028 fd.close(); 14029 } catch (IOException e) { 14030 } 14031 } 14032 } 14033 } 14034 findProcessLocked(String process, int userId, String callName)14035 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 14036 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14037 userId, true, true, callName, null); 14038 ProcessRecord proc = null; 14039 try { 14040 int pid = Integer.parseInt(process); 14041 synchronized (mPidsSelfLocked) { 14042 proc = mPidsSelfLocked.get(pid); 14043 } 14044 } catch (NumberFormatException e) { 14045 } 14046 14047 if (proc == null) { 14048 HashMap<String, SparseArray<ProcessRecord>> all 14049 = mProcessNames.getMap(); 14050 SparseArray<ProcessRecord> procs = all.get(process); 14051 if (procs != null && procs.size() > 0) { 14052 proc = procs.valueAt(0); 14053 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14054 for (int i=1; i<procs.size(); i++) { 14055 ProcessRecord thisProc = procs.valueAt(i); 14056 if (thisProc.userId == userId) { 14057 proc = thisProc; 14058 break; 14059 } 14060 } 14061 } 14062 } 14063 } 14064 14065 return proc; 14066 } 14067 dumpHeap(String process, int userId, boolean managed, String path, ParcelFileDescriptor fd)14068 public boolean dumpHeap(String process, int userId, boolean managed, 14069 String path, ParcelFileDescriptor fd) throws RemoteException { 14070 14071 try { 14072 synchronized (this) { 14073 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14074 // its own permission (same as profileControl). 14075 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14076 != PackageManager.PERMISSION_GRANTED) { 14077 throw new SecurityException("Requires permission " 14078 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14079 } 14080 14081 if (fd == null) { 14082 throw new IllegalArgumentException("null fd"); 14083 } 14084 14085 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14086 if (proc == null || proc.thread == null) { 14087 throw new IllegalArgumentException("Unknown process: " + process); 14088 } 14089 14090 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14091 if (!isDebuggable) { 14092 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14093 throw new SecurityException("Process not debuggable: " + proc); 14094 } 14095 } 14096 14097 proc.thread.dumpHeap(managed, path, fd); 14098 fd = null; 14099 return true; 14100 } 14101 } catch (RemoteException e) { 14102 throw new IllegalStateException("Process disappeared"); 14103 } finally { 14104 if (fd != null) { 14105 try { 14106 fd.close(); 14107 } catch (IOException e) { 14108 } 14109 } 14110 } 14111 } 14112 14113 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ monitor()14114 public void monitor() { 14115 synchronized (this) { } 14116 } 14117 onCoreSettingsChange(Bundle settings)14118 void onCoreSettingsChange(Bundle settings) { 14119 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14120 ProcessRecord processRecord = mLruProcesses.get(i); 14121 try { 14122 if (processRecord.thread != null) { 14123 processRecord.thread.setCoreSettings(settings); 14124 } 14125 } catch (RemoteException re) { 14126 /* ignore */ 14127 } 14128 } 14129 } 14130 14131 // Multi-user methods 14132 14133 @Override switchUser(final int userId)14134 public boolean switchUser(final int userId) { 14135 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14136 != PackageManager.PERMISSION_GRANTED) { 14137 String msg = "Permission Denial: switchUser() from pid=" 14138 + Binder.getCallingPid() 14139 + ", uid=" + Binder.getCallingUid() 14140 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14141 Slog.w(TAG, msg); 14142 throw new SecurityException(msg); 14143 } 14144 14145 final long ident = Binder.clearCallingIdentity(); 14146 try { 14147 synchronized (this) { 14148 final int oldUserId = mCurrentUserId; 14149 if (oldUserId == userId) { 14150 return true; 14151 } 14152 14153 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14154 if (userInfo == null) { 14155 Slog.w(TAG, "No user info for user #" + userId); 14156 return false; 14157 } 14158 14159 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14160 R.anim.screen_user_enter); 14161 14162 boolean needStart = false; 14163 14164 // If the user we are switching to is not currently started, then 14165 // we need to start it now. 14166 if (mStartedUsers.get(userId) == null) { 14167 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14168 updateStartedUserArrayLocked(); 14169 needStart = true; 14170 } 14171 14172 mCurrentUserId = userId; 14173 mCurrentUserArray = new int[] { userId }; 14174 final Integer userIdInt = Integer.valueOf(userId); 14175 mUserLru.remove(userIdInt); 14176 mUserLru.add(userIdInt); 14177 14178 mWindowManager.setCurrentUser(userId); 14179 14180 // Once the internal notion of the active user has switched, we lock the device 14181 // with the option to show the user switcher on the keyguard. 14182 mWindowManager.lockNow(null); 14183 14184 final UserStartedState uss = mStartedUsers.get(userId); 14185 14186 // Make sure user is in the started state. If it is currently 14187 // stopping, we need to knock that off. 14188 if (uss.mState == UserStartedState.STATE_STOPPING) { 14189 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 14190 // so we can just fairly silently bring the user back from 14191 // the almost-dead. 14192 uss.mState = UserStartedState.STATE_RUNNING; 14193 updateStartedUserArrayLocked(); 14194 needStart = true; 14195 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 14196 // This means ACTION_SHUTDOWN has been sent, so we will 14197 // need to treat this as a new boot of the user. 14198 uss.mState = UserStartedState.STATE_BOOTING; 14199 updateStartedUserArrayLocked(); 14200 needStart = true; 14201 } 14202 14203 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14204 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14205 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14206 oldUserId, userId, uss)); 14207 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14208 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14209 if (needStart) { 14210 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14212 | Intent.FLAG_RECEIVER_FOREGROUND); 14213 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14214 broadcastIntentLocked(null, null, intent, 14215 null, null, 0, null, null, null, 14216 false, false, MY_PID, Process.SYSTEM_UID, userId); 14217 } 14218 14219 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14220 if (userId != 0) { 14221 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14222 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14223 broadcastIntentLocked(null, null, intent, null, 14224 new IIntentReceiver.Stub() { 14225 public void performReceive(Intent intent, int resultCode, 14226 String data, Bundle extras, boolean ordered, 14227 boolean sticky, int sendingUser) { 14228 userInitialized(uss, userId); 14229 } 14230 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14231 userId); 14232 uss.initializing = true; 14233 } else { 14234 getUserManagerLocked().makeInitialized(userInfo.id); 14235 } 14236 } 14237 14238 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14239 if (!haveActivities) { 14240 startHomeActivityLocked(userId); 14241 } 14242 14243 EventLogTags.writeAmSwitchUser(userId); 14244 getUserManagerLocked().userForeground(userId); 14245 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14246 if (needStart) { 14247 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 14248 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14249 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14250 broadcastIntentLocked(null, null, intent, 14251 null, new IIntentReceiver.Stub() { 14252 @Override 14253 public void performReceive(Intent intent, int resultCode, String data, 14254 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14255 throws RemoteException { 14256 } 14257 }, 0, null, null, 14258 android.Manifest.permission.INTERACT_ACROSS_USERS, 14259 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14260 } 14261 } 14262 } finally { 14263 Binder.restoreCallingIdentity(ident); 14264 } 14265 14266 return true; 14267 } 14268 sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId)14269 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14270 long ident = Binder.clearCallingIdentity(); 14271 try { 14272 Intent intent; 14273 if (oldUserId >= 0) { 14274 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14275 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14276 | Intent.FLAG_RECEIVER_FOREGROUND); 14277 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14278 broadcastIntentLocked(null, null, intent, 14279 null, null, 0, null, null, null, 14280 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14281 } 14282 if (newUserId >= 0) { 14283 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14284 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14285 | Intent.FLAG_RECEIVER_FOREGROUND); 14286 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14287 broadcastIntentLocked(null, null, intent, 14288 null, null, 0, null, null, null, 14289 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14290 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14291 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14292 | Intent.FLAG_RECEIVER_FOREGROUND); 14293 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14294 broadcastIntentLocked(null, null, intent, 14295 null, null, 0, null, null, 14296 android.Manifest.permission.MANAGE_USERS, 14297 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14298 } 14299 } finally { 14300 Binder.restoreCallingIdentity(ident); 14301 } 14302 } 14303 dispatchUserSwitch(final UserStartedState uss, final int oldUserId, final int newUserId)14304 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14305 final int newUserId) { 14306 final int N = mUserSwitchObservers.beginBroadcast(); 14307 if (N > 0) { 14308 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14309 int mCount = 0; 14310 @Override 14311 public void sendResult(Bundle data) throws RemoteException { 14312 synchronized (ActivityManagerService.this) { 14313 if (mCurUserSwitchCallback == this) { 14314 mCount++; 14315 if (mCount == N) { 14316 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14317 } 14318 } 14319 } 14320 } 14321 }; 14322 synchronized (this) { 14323 uss.switching = true; 14324 mCurUserSwitchCallback = callback; 14325 } 14326 for (int i=0; i<N; i++) { 14327 try { 14328 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14329 newUserId, callback); 14330 } catch (RemoteException e) { 14331 } 14332 } 14333 } else { 14334 synchronized (this) { 14335 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14336 } 14337 } 14338 mUserSwitchObservers.finishBroadcast(); 14339 } 14340 timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14341 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14342 synchronized (this) { 14343 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14344 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14345 } 14346 } 14347 sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId)14348 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14349 mCurUserSwitchCallback = null; 14350 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14351 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14352 oldUserId, newUserId, uss)); 14353 } 14354 userInitialized(UserStartedState uss, int newUserId)14355 void userInitialized(UserStartedState uss, int newUserId) { 14356 completeSwitchAndInitalize(uss, newUserId, true, false); 14357 } 14358 continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14359 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14360 completeSwitchAndInitalize(uss, newUserId, false, true); 14361 } 14362 completeSwitchAndInitalize(UserStartedState uss, int newUserId, boolean clearInitializing, boolean clearSwitching)14363 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 14364 boolean clearInitializing, boolean clearSwitching) { 14365 boolean unfrozen = false; 14366 synchronized (this) { 14367 if (clearInitializing) { 14368 uss.initializing = false; 14369 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14370 } 14371 if (clearSwitching) { 14372 uss.switching = false; 14373 } 14374 if (!uss.switching && !uss.initializing) { 14375 mWindowManager.stopFreezingScreen(); 14376 unfrozen = true; 14377 } 14378 } 14379 if (unfrozen) { 14380 final int N = mUserSwitchObservers.beginBroadcast(); 14381 for (int i=0; i<N; i++) { 14382 try { 14383 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14384 } catch (RemoteException e) { 14385 } 14386 } 14387 mUserSwitchObservers.finishBroadcast(); 14388 } 14389 } 14390 finishUserSwitch(UserStartedState uss)14391 void finishUserSwitch(UserStartedState uss) { 14392 synchronized (this) { 14393 if (uss.mState == UserStartedState.STATE_BOOTING 14394 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14395 uss.mState = UserStartedState.STATE_RUNNING; 14396 final int userId = uss.mHandle.getIdentifier(); 14397 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14398 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14399 broadcastIntentLocked(null, null, intent, 14400 null, null, 0, null, null, 14401 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14402 false, false, MY_PID, Process.SYSTEM_UID, userId); 14403 } 14404 int num = mUserLru.size(); 14405 int i = 0; 14406 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14407 Integer oldUserId = mUserLru.get(i); 14408 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14409 if (oldUss == null) { 14410 // Shouldn't happen, but be sane if it does. 14411 mUserLru.remove(i); 14412 num--; 14413 continue; 14414 } 14415 if (oldUss.mState == UserStartedState.STATE_STOPPING 14416 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 14417 // This user is already stopping, doesn't count. 14418 num--; 14419 i++; 14420 continue; 14421 } 14422 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14423 // Owner and current can't be stopped, but count as running. 14424 i++; 14425 continue; 14426 } 14427 // This is a user to be stopped. 14428 stopUserLocked(oldUserId, null); 14429 num--; 14430 i++; 14431 } 14432 } 14433 } 14434 14435 @Override stopUser(final int userId, final IStopUserCallback callback)14436 public int stopUser(final int userId, final IStopUserCallback callback) { 14437 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14438 != PackageManager.PERMISSION_GRANTED) { 14439 String msg = "Permission Denial: switchUser() from pid=" 14440 + Binder.getCallingPid() 14441 + ", uid=" + Binder.getCallingUid() 14442 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14443 Slog.w(TAG, msg); 14444 throw new SecurityException(msg); 14445 } 14446 if (userId <= 0) { 14447 throw new IllegalArgumentException("Can't stop primary user " + userId); 14448 } 14449 synchronized (this) { 14450 return stopUserLocked(userId, callback); 14451 } 14452 } 14453 stopUserLocked(final int userId, final IStopUserCallback callback)14454 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14455 if (mCurrentUserId == userId) { 14456 return ActivityManager.USER_OP_IS_CURRENT; 14457 } 14458 14459 final UserStartedState uss = mStartedUsers.get(userId); 14460 if (uss == null) { 14461 // User is not started, nothing to do... but we do need to 14462 // callback if requested. 14463 if (callback != null) { 14464 mHandler.post(new Runnable() { 14465 @Override 14466 public void run() { 14467 try { 14468 callback.userStopped(userId); 14469 } catch (RemoteException e) { 14470 } 14471 } 14472 }); 14473 } 14474 return ActivityManager.USER_OP_SUCCESS; 14475 } 14476 14477 if (callback != null) { 14478 uss.mStopCallbacks.add(callback); 14479 } 14480 14481 if (uss.mState != UserStartedState.STATE_STOPPING 14482 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14483 uss.mState = UserStartedState.STATE_STOPPING; 14484 updateStartedUserArrayLocked(); 14485 14486 long ident = Binder.clearCallingIdentity(); 14487 try { 14488 // We are going to broadcast ACTION_USER_STOPPING and then 14489 // once that is done send a final ACTION_SHUTDOWN and then 14490 // stop the user. 14491 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 14492 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14493 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14494 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 14495 // This is the result receiver for the final shutdown broadcast. 14496 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 14497 @Override 14498 public void performReceive(Intent intent, int resultCode, String data, 14499 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14500 finishUserStop(uss); 14501 } 14502 }; 14503 // This is the result receiver for the initial stopping broadcast. 14504 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 14505 @Override 14506 public void performReceive(Intent intent, int resultCode, String data, 14507 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14508 // On to the next. 14509 synchronized (ActivityManagerService.this) { 14510 if (uss.mState != UserStartedState.STATE_STOPPING) { 14511 // Whoops, we are being started back up. Abort, abort! 14512 return; 14513 } 14514 uss.mState = UserStartedState.STATE_SHUTDOWN; 14515 } 14516 broadcastIntentLocked(null, null, shutdownIntent, 14517 null, shutdownReceiver, 0, null, null, null, 14518 true, false, MY_PID, Process.SYSTEM_UID, userId); 14519 } 14520 }; 14521 // Kick things off. 14522 broadcastIntentLocked(null, null, stoppingIntent, 14523 null, stoppingReceiver, 0, null, null, 14524 android.Manifest.permission.INTERACT_ACROSS_USERS, 14525 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14526 } finally { 14527 Binder.restoreCallingIdentity(ident); 14528 } 14529 } 14530 14531 return ActivityManager.USER_OP_SUCCESS; 14532 } 14533 finishUserStop(UserStartedState uss)14534 void finishUserStop(UserStartedState uss) { 14535 final int userId = uss.mHandle.getIdentifier(); 14536 boolean stopped; 14537 ArrayList<IStopUserCallback> callbacks; 14538 synchronized (this) { 14539 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14540 if (mStartedUsers.get(userId) != uss) { 14541 stopped = false; 14542 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 14543 stopped = false; 14544 } else { 14545 stopped = true; 14546 // User can no longer run. 14547 mStartedUsers.remove(userId); 14548 mUserLru.remove(Integer.valueOf(userId)); 14549 updateStartedUserArrayLocked(); 14550 14551 // Clean up all state and processes associated with the user. 14552 // Kill all the processes for the user. 14553 forceStopUserLocked(userId); 14554 AttributeCache ac = AttributeCache.instance(); 14555 if (ac != null) { 14556 ac.removeUser(userId); 14557 } 14558 } 14559 } 14560 14561 for (int i=0; i<callbacks.size(); i++) { 14562 try { 14563 if (stopped) callbacks.get(i).userStopped(userId); 14564 else callbacks.get(i).userStopAborted(userId); 14565 } catch (RemoteException e) { 14566 } 14567 } 14568 } 14569 14570 @Override getCurrentUser()14571 public UserInfo getCurrentUser() { 14572 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14573 != PackageManager.PERMISSION_GRANTED) && ( 14574 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14575 != PackageManager.PERMISSION_GRANTED)) { 14576 String msg = "Permission Denial: getCurrentUser() from pid=" 14577 + Binder.getCallingPid() 14578 + ", uid=" + Binder.getCallingUid() 14579 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14580 Slog.w(TAG, msg); 14581 throw new SecurityException(msg); 14582 } 14583 synchronized (this) { 14584 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14585 } 14586 } 14587 getCurrentUserIdLocked()14588 int getCurrentUserIdLocked() { 14589 return mCurrentUserId; 14590 } 14591 14592 @Override isUserRunning(int userId, boolean orStopped)14593 public boolean isUserRunning(int userId, boolean orStopped) { 14594 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14595 != PackageManager.PERMISSION_GRANTED) { 14596 String msg = "Permission Denial: isUserRunning() from pid=" 14597 + Binder.getCallingPid() 14598 + ", uid=" + Binder.getCallingUid() 14599 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14600 Slog.w(TAG, msg); 14601 throw new SecurityException(msg); 14602 } 14603 synchronized (this) { 14604 return isUserRunningLocked(userId, orStopped); 14605 } 14606 } 14607 isUserRunningLocked(int userId, boolean orStopped)14608 boolean isUserRunningLocked(int userId, boolean orStopped) { 14609 UserStartedState state = mStartedUsers.get(userId); 14610 if (state == null) { 14611 return false; 14612 } 14613 if (orStopped) { 14614 return true; 14615 } 14616 return state.mState != UserStartedState.STATE_STOPPING 14617 && state.mState != UserStartedState.STATE_SHUTDOWN; 14618 } 14619 14620 @Override getRunningUserIds()14621 public int[] getRunningUserIds() { 14622 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14623 != PackageManager.PERMISSION_GRANTED) { 14624 String msg = "Permission Denial: isUserRunning() from pid=" 14625 + Binder.getCallingPid() 14626 + ", uid=" + Binder.getCallingUid() 14627 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14628 Slog.w(TAG, msg); 14629 throw new SecurityException(msg); 14630 } 14631 synchronized (this) { 14632 return mStartedUserArray; 14633 } 14634 } 14635 updateStartedUserArrayLocked()14636 private void updateStartedUserArrayLocked() { 14637 int num = 0; 14638 for (int i=0; i<mStartedUsers.size(); i++) { 14639 UserStartedState uss = mStartedUsers.valueAt(i); 14640 // This list does not include stopping users. 14641 if (uss.mState != UserStartedState.STATE_STOPPING 14642 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14643 num++; 14644 } 14645 } 14646 mStartedUserArray = new int[num]; 14647 num = 0; 14648 for (int i=0; i<mStartedUsers.size(); i++) { 14649 UserStartedState uss = mStartedUsers.valueAt(i); 14650 if (uss.mState != UserStartedState.STATE_STOPPING 14651 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14652 mStartedUserArray[num] = mStartedUsers.keyAt(i); 14653 num++; 14654 } 14655 } 14656 } 14657 14658 @Override registerUserSwitchObserver(IUserSwitchObserver observer)14659 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14660 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14661 != PackageManager.PERMISSION_GRANTED) { 14662 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14663 + Binder.getCallingPid() 14664 + ", uid=" + Binder.getCallingUid() 14665 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14666 Slog.w(TAG, msg); 14667 throw new SecurityException(msg); 14668 } 14669 14670 mUserSwitchObservers.register(observer); 14671 } 14672 14673 @Override unregisterUserSwitchObserver(IUserSwitchObserver observer)14674 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14675 mUserSwitchObservers.unregister(observer); 14676 } 14677 userExists(int userId)14678 private boolean userExists(int userId) { 14679 if (userId == 0) { 14680 return true; 14681 } 14682 UserManagerService ums = getUserManagerLocked(); 14683 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14684 } 14685 getUsersLocked()14686 int[] getUsersLocked() { 14687 UserManagerService ums = getUserManagerLocked(); 14688 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14689 } 14690 getUserManagerLocked()14691 UserManagerService getUserManagerLocked() { 14692 if (mUserManager == null) { 14693 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14694 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14695 } 14696 return mUserManager; 14697 } 14698 checkValidCaller(int uid, int userId)14699 private void checkValidCaller(int uid, int userId) { 14700 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14701 14702 throw new SecurityException("Caller uid=" + uid 14703 + " is not privileged to communicate with user=" + userId); 14704 } 14705 applyUserId(int uid, int userId)14706 private int applyUserId(int uid, int userId) { 14707 return UserHandle.getUid(userId, uid); 14708 } 14709 getAppInfoForUser(ApplicationInfo info, int userId)14710 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14711 if (info == null) return null; 14712 ApplicationInfo newInfo = new ApplicationInfo(info); 14713 newInfo.uid = applyUserId(info.uid, userId); 14714 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14715 + info.packageName; 14716 return newInfo; 14717 } 14718 getActivityInfoForUser(ActivityInfo aInfo, int userId)14719 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14720 if (aInfo == null 14721 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14722 return aInfo; 14723 } 14724 14725 ActivityInfo info = new ActivityInfo(aInfo); 14726 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14727 return info; 14728 } 14729 } 14730