ActivityManagerService.java revision e091f22e226f7177e45e23850670c1ad9b63fd75
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 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.Instrumentation; 53import android.app.Notification; 54import android.app.NotificationManager; 55import android.app.PendingIntent; 56import android.app.backup.IBackupManager; 57import android.content.ActivityNotFoundException; 58import android.content.BroadcastReceiver; 59import android.content.ClipData; 60import android.content.ComponentCallbacks2; 61import android.content.ComponentName; 62import android.content.ContentProvider; 63import android.content.ContentResolver; 64import android.content.Context; 65import android.content.DialogInterface; 66import android.content.IContentProvider; 67import android.content.IIntentReceiver; 68import android.content.IIntentSender; 69import android.content.Intent; 70import android.content.IntentFilter; 71import android.content.IntentSender; 72import android.content.pm.ActivityInfo; 73import android.content.pm.ApplicationInfo; 74import android.content.pm.ConfigurationInfo; 75import android.content.pm.IPackageDataObserver; 76import android.content.pm.IPackageManager; 77import android.content.pm.InstrumentationInfo; 78import android.content.pm.PackageInfo; 79import android.content.pm.PackageManager; 80import android.content.pm.UserInfo; 81import android.content.pm.PackageManager.NameNotFoundException; 82import android.content.pm.PathPermission; 83import android.content.pm.ProviderInfo; 84import android.content.pm.ResolveInfo; 85import android.content.pm.ServiceInfo; 86import android.content.res.CompatibilityInfo; 87import android.content.res.Configuration; 88import android.graphics.Bitmap; 89import android.net.Proxy; 90import android.net.ProxyProperties; 91import android.net.Uri; 92import android.os.Binder; 93import android.os.Build; 94import android.os.Bundle; 95import android.os.Debug; 96import android.os.DropBoxManager; 97import android.os.Environment; 98import android.os.FileObserver; 99import android.os.FileUtils; 100import android.os.Handler; 101import android.os.IBinder; 102import android.os.IPermissionController; 103import android.os.IUserManager; 104import android.os.Looper; 105import android.os.Message; 106import android.os.Parcel; 107import android.os.ParcelFileDescriptor; 108import android.os.Process; 109import android.os.RemoteCallbackList; 110import android.os.RemoteException; 111import android.os.SELinux; 112import android.os.ServiceManager; 113import android.os.StrictMode; 114import android.os.SystemClock; 115import android.os.SystemProperties; 116import android.os.UserHandle; 117import android.provider.Settings; 118import android.text.format.Time; 119import android.util.EventLog; 120import android.util.Log; 121import android.util.Pair; 122import android.util.PrintWriterPrinter; 123import android.util.Slog; 124import android.util.SparseArray; 125import android.util.TimeUtils; 126import android.view.Gravity; 127import android.view.LayoutInflater; 128import android.view.View; 129import android.view.WindowManager; 130import android.view.WindowManagerPolicy; 131 132import java.io.BufferedInputStream; 133import java.io.BufferedOutputStream; 134import java.io.BufferedReader; 135import java.io.DataInputStream; 136import java.io.DataOutputStream; 137import java.io.File; 138import java.io.FileDescriptor; 139import java.io.FileInputStream; 140import java.io.FileNotFoundException; 141import java.io.FileOutputStream; 142import java.io.IOException; 143import java.io.InputStreamReader; 144import java.io.PrintWriter; 145import java.io.StringWriter; 146import java.lang.ref.WeakReference; 147import java.util.ArrayList; 148import java.util.Collections; 149import java.util.Comparator; 150import java.util.HashMap; 151import java.util.HashSet; 152import java.util.Iterator; 153import java.util.List; 154import java.util.Locale; 155import java.util.Map; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait until we timeout on key dispatching. 245 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 246 247 // How long we wait until we timeout on key dispatching during instrumentation. 248 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 249 250 static final int MY_PID = Process.myPid(); 251 252 static final String[] EMPTY_STRING_ARRAY = new String[0]; 253 254 public ActivityStack mMainStack; 255 256 private final boolean mHeadless; 257 258 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 259 // default actuion automatically. Important for devices without direct input 260 // devices. 261 private boolean mShowDialogs = true; 262 263 /** 264 * Description of a request to start a new activity, which has been held 265 * due to app switches being disabled. 266 */ 267 static class PendingActivityLaunch { 268 ActivityRecord r; 269 ActivityRecord sourceRecord; 270 int startFlags; 271 } 272 273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 274 = new ArrayList<PendingActivityLaunch>(); 275 276 277 BroadcastQueue mFgBroadcastQueue; 278 BroadcastQueue mBgBroadcastQueue; 279 // Convenient for easy iteration over the queues. Foreground is first 280 // so that dispatch of foreground broadcasts gets precedence. 281 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 282 283 BroadcastQueue broadcastQueueForIntent(Intent intent) { 284 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 285 if (DEBUG_BACKGROUND_BROADCAST) { 286 Slog.i(TAG, "Broadcast intent " + intent + " on " 287 + (isFg ? "foreground" : "background") 288 + " queue"); 289 } 290 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 291 } 292 293 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 294 for (BroadcastQueue queue : mBroadcastQueues) { 295 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 296 if (r != null) { 297 return r; 298 } 299 } 300 return null; 301 } 302 303 /** 304 * Activity we have told the window manager to have key focus. 305 */ 306 ActivityRecord mFocusedActivity = null; 307 /** 308 * List of intents that were used to start the most recent tasks. 309 */ 310 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 311 312 /** 313 * Process management. 314 */ 315 final ProcessList mProcessList = new ProcessList(); 316 317 /** 318 * All of the applications we currently have running organized by name. 319 * The keys are strings of the application package name (as 320 * returned by the package manager), and the keys are ApplicationRecord 321 * objects. 322 */ 323 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 324 325 /** 326 * The currently running isolated processes. 327 */ 328 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 329 330 /** 331 * Counter for assigning isolated process uids, to avoid frequently reusing the 332 * same ones. 333 */ 334 int mNextIsolatedProcessUid = 0; 335 336 /** 337 * The currently running heavy-weight process, if any. 338 */ 339 ProcessRecord mHeavyWeightProcess = null; 340 341 /** 342 * The last time that various processes have crashed. 343 */ 344 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 345 346 /** 347 * Set of applications that we consider to be bad, and will reject 348 * incoming broadcasts from (which the user has no control over). 349 * Processes are added to this set when they have crashed twice within 350 * a minimum amount of time; they are removed from it when they are 351 * later restarted (hopefully due to some user action). The value is the 352 * time it was added to the list. 353 */ 354 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 355 356 /** 357 * All of the processes we currently have running organized by pid. 358 * The keys are the pid running the application. 359 * 360 * <p>NOTE: This object is protected by its own lock, NOT the global 361 * activity manager lock! 362 */ 363 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 364 365 /** 366 * All of the processes that have been forced to be foreground. The key 367 * is the pid of the caller who requested it (we hold a death 368 * link on it). 369 */ 370 abstract class ForegroundToken implements IBinder.DeathRecipient { 371 int pid; 372 IBinder token; 373 } 374 final SparseArray<ForegroundToken> mForegroundProcesses 375 = new SparseArray<ForegroundToken>(); 376 377 /** 378 * List of records for processes that someone had tried to start before the 379 * system was ready. We don't start them at that point, but ensure they 380 * are started by the time booting is complete. 381 */ 382 final ArrayList<ProcessRecord> mProcessesOnHold 383 = new ArrayList<ProcessRecord>(); 384 385 /** 386 * List of persistent applications that are in the process 387 * of being started. 388 */ 389 final ArrayList<ProcessRecord> mPersistentStartingProcesses 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * Processes that are being forcibly torn down. 394 */ 395 final ArrayList<ProcessRecord> mRemovedProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of running applications, sorted by recent usage. 400 * The first entry in the list is the least recently used. 401 * It contains ApplicationRecord objects. This list does NOT include 402 * any persistent application records (since we never want to exit them). 403 */ 404 final ArrayList<ProcessRecord> mLruProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of processes that should gc as soon as things are idle. 409 */ 410 final ArrayList<ProcessRecord> mProcessesToGc 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * This is the process holding what we currently consider to be 415 * the "home" activity. 416 */ 417 ProcessRecord mHomeProcess; 418 419 /** 420 * This is the process holding the activity the user last visited that 421 * is in a different process from the one they are currently in. 422 */ 423 ProcessRecord mPreviousProcess; 424 425 /** 426 * The time at which the previous process was last visible. 427 */ 428 long mPreviousProcessVisibleTime; 429 430 /** 431 * Which uses have been started, so are allowed to run code. 432 */ 433 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 434 435 /** 436 * LRU list of history of current users. Most recently current is at the end. 437 */ 438 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 439 440 /** 441 * Packages that the user has asked to have run in screen size 442 * compatibility mode instead of filling the screen. 443 */ 444 final CompatModePackages mCompatModePackages; 445 446 /** 447 * Set of PendingResultRecord objects that are currently active. 448 */ 449 final HashSet mPendingResultRecords = new HashSet(); 450 451 /** 452 * Set of IntentSenderRecord objects that are currently active. 453 */ 454 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 455 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 456 457 /** 458 * Fingerprints (hashCode()) of stack traces that we've 459 * already logged DropBox entries for. Guarded by itself. If 460 * something (rogue user app) forces this over 461 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 462 */ 463 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 464 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 465 466 /** 467 * Strict Mode background batched logging state. 468 * 469 * The string buffer is guarded by itself, and its lock is also 470 * used to determine if another batched write is already 471 * in-flight. 472 */ 473 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 474 475 /** 476 * Keeps track of all IIntentReceivers that have been registered for 477 * broadcasts. Hash keys are the receiver IBinder, hash value is 478 * a ReceiverList. 479 */ 480 final HashMap mRegisteredReceivers = new HashMap(); 481 482 /** 483 * Resolver for broadcast intents to registered receivers. 484 * Holds BroadcastFilter (subclass of IntentFilter). 485 */ 486 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 487 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 488 @Override 489 protected boolean allowFilterResult( 490 BroadcastFilter filter, List<BroadcastFilter> dest) { 491 IBinder target = filter.receiverList.receiver.asBinder(); 492 for (int i=dest.size()-1; i>=0; i--) { 493 if (dest.get(i).receiverList.receiver.asBinder() == target) { 494 return false; 495 } 496 } 497 return true; 498 } 499 500 @Override 501 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 502 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 503 || userId == filter.owningUserId) { 504 return super.newResult(filter, match, userId); 505 } 506 return null; 507 } 508 509 @Override 510 protected BroadcastFilter[] newArray(int size) { 511 return new BroadcastFilter[size]; 512 } 513 514 @Override 515 protected String packageForFilter(BroadcastFilter filter) { 516 return filter.packageName; 517 } 518 }; 519 520 /** 521 * State of all active sticky broadcasts per user. Keys are the action of the 522 * sticky Intent, values are an ArrayList of all broadcasted intents with 523 * that action (which should usually be one). The SparseArray is keyed 524 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 525 * for stickies that are sent to all users. 526 */ 527 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 528 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 529 530 final ActiveServices mServices; 531 532 /** 533 * Backup/restore process management 534 */ 535 String mBackupAppName = null; 536 BackupRecord mBackupTarget = null; 537 538 /** 539 * List of PendingThumbnailsRecord objects of clients who are still 540 * waiting to receive all of the thumbnails for a task. 541 */ 542 final ArrayList mPendingThumbnails = new ArrayList(); 543 544 /** 545 * List of HistoryRecord objects that have been finished and must 546 * still report back to a pending thumbnail receiver. 547 */ 548 final ArrayList mCancelledThumbnails = new ArrayList(); 549 550 final ProviderMap mProviderMap; 551 552 /** 553 * List of content providers who have clients waiting for them. The 554 * application is currently being launched and the provider will be 555 * removed from this list once it is published. 556 */ 557 final ArrayList<ContentProviderRecord> mLaunchingProviders 558 = new ArrayList<ContentProviderRecord>(); 559 560 /** 561 * Global set of specific Uri permissions that have been granted. 562 */ 563 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 564 = new SparseArray<HashMap<Uri, UriPermission>>(); 565 566 CoreSettingsObserver mCoreSettingsObserver; 567 568 /** 569 * Thread-local storage used to carry caller permissions over through 570 * indirect content-provider access. 571 * @see #ActivityManagerService.openContentUri() 572 */ 573 private class Identity { 574 public int pid; 575 public int uid; 576 577 Identity(int _pid, int _uid) { 578 pid = _pid; 579 uid = _uid; 580 } 581 } 582 583 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 584 585 /** 586 * All information we have collected about the runtime performance of 587 * any user id that can impact battery performance. 588 */ 589 final BatteryStatsService mBatteryStatsService; 590 591 /** 592 * information about component usage 593 */ 594 final UsageStatsService mUsageStatsService; 595 596 /** 597 * Current configuration information. HistoryRecord objects are given 598 * a reference to this object to indicate which configuration they are 599 * currently running in, so this object must be kept immutable. 600 */ 601 Configuration mConfiguration = new Configuration(); 602 603 /** 604 * Current sequencing integer of the configuration, for skipping old 605 * configurations. 606 */ 607 int mConfigurationSeq = 0; 608 609 /** 610 * Hardware-reported OpenGLES version. 611 */ 612 final int GL_ES_VERSION; 613 614 /** 615 * List of initialization arguments to pass to all processes when binding applications to them. 616 * For example, references to the commonly used services. 617 */ 618 HashMap<String, IBinder> mAppBindArgs; 619 620 /** 621 * Temporary to avoid allocations. Protected by main lock. 622 */ 623 final StringBuilder mStringBuilder = new StringBuilder(256); 624 625 /** 626 * Used to control how we initialize the service. 627 */ 628 boolean mStartRunning = false; 629 ComponentName mTopComponent; 630 String mTopAction; 631 String mTopData; 632 boolean mProcessesReady = false; 633 boolean mSystemReady = false; 634 boolean mBooting = false; 635 boolean mWaitingUpdate = false; 636 boolean mDidUpdate = false; 637 boolean mOnBattery = false; 638 boolean mLaunchWarningShown = false; 639 640 Context mContext; 641 642 int mFactoryTest; 643 644 boolean mCheckedForSetup; 645 646 /** 647 * The time at which we will allow normal application switches again, 648 * after a call to {@link #stopAppSwitches()}. 649 */ 650 long mAppSwitchesAllowedTime; 651 652 /** 653 * This is set to true after the first switch after mAppSwitchesAllowedTime 654 * is set; any switches after that will clear the time. 655 */ 656 boolean mDidAppSwitch; 657 658 /** 659 * Last time (in realtime) at which we checked for power usage. 660 */ 661 long mLastPowerCheckRealtime; 662 663 /** 664 * Last time (in uptime) at which we checked for power usage. 665 */ 666 long mLastPowerCheckUptime; 667 668 /** 669 * Set while we are wanting to sleep, to prevent any 670 * activities from being started/resumed. 671 */ 672 boolean mSleeping = false; 673 674 /** 675 * State of external calls telling us if the device is asleep. 676 */ 677 boolean mWentToSleep = false; 678 679 /** 680 * State of external call telling us if the lock screen is shown. 681 */ 682 boolean mLockScreenShown = false; 683 684 /** 685 * Set if we are shutting down the system, similar to sleeping. 686 */ 687 boolean mShuttingDown = false; 688 689 /** 690 * Task identifier that activities are currently being started 691 * in. Incremented each time a new task is created. 692 * todo: Replace this with a TokenSpace class that generates non-repeating 693 * integers that won't wrap. 694 */ 695 int mCurTask = 1; 696 697 /** 698 * Current sequence id for oom_adj computation traversal. 699 */ 700 int mAdjSeq = 0; 701 702 /** 703 * Current sequence id for process LRU updating. 704 */ 705 int mLruSeq = 0; 706 707 /** 708 * Keep track of the non-hidden/empty process we last found, to help 709 * determine how to distribute hidden/empty processes next time. 710 */ 711 int mNumNonHiddenProcs = 0; 712 713 /** 714 * Keep track of the number of hidden procs, to balance oom adj 715 * distribution between those and empty procs. 716 */ 717 int mNumHiddenProcs = 0; 718 719 /** 720 * Keep track of the number of service processes we last found, to 721 * determine on the next iteration which should be B services. 722 */ 723 int mNumServiceProcs = 0; 724 int mNewNumServiceProcs = 0; 725 726 /** 727 * System monitoring: number of processes that died since the last 728 * N procs were started. 729 */ 730 int[] mProcDeaths = new int[20]; 731 732 /** 733 * This is set if we had to do a delayed dexopt of an app before launching 734 * it, to increasing the ANR timeouts in that case. 735 */ 736 boolean mDidDexOpt; 737 738 String mDebugApp = null; 739 boolean mWaitForDebugger = false; 740 boolean mDebugTransient = false; 741 String mOrigDebugApp = null; 742 boolean mOrigWaitForDebugger = false; 743 boolean mAlwaysFinishActivities = false; 744 IActivityController mController = null; 745 String mProfileApp = null; 746 ProcessRecord mProfileProc = null; 747 String mProfileFile; 748 ParcelFileDescriptor mProfileFd; 749 int mProfileType = 0; 750 boolean mAutoStopProfiler = false; 751 String mOpenGlTraceApp = null; 752 753 static class ProcessChangeItem { 754 static final int CHANGE_ACTIVITIES = 1<<0; 755 static final int CHANGE_IMPORTANCE= 1<<1; 756 int changes; 757 int uid; 758 int pid; 759 int importance; 760 boolean foregroundActivities; 761 } 762 763 final RemoteCallbackList<IProcessObserver> mProcessObservers 764 = new RemoteCallbackList<IProcessObserver>(); 765 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 766 767 final ArrayList<ProcessChangeItem> mPendingProcessChanges 768 = new ArrayList<ProcessChangeItem>(); 769 final ArrayList<ProcessChangeItem> mAvailProcessChanges 770 = new ArrayList<ProcessChangeItem>(); 771 772 /** 773 * Callback of last caller to {@link #requestPss}. 774 */ 775 Runnable mRequestPssCallback; 776 777 /** 778 * Remaining processes for which we are waiting results from the last 779 * call to {@link #requestPss}. 780 */ 781 final ArrayList<ProcessRecord> mRequestPssList 782 = new ArrayList<ProcessRecord>(); 783 784 /** 785 * Runtime statistics collection thread. This object's lock is used to 786 * protect all related state. 787 */ 788 final Thread mProcessStatsThread; 789 790 /** 791 * Used to collect process stats when showing not responding dialog. 792 * Protected by mProcessStatsThread. 793 */ 794 final ProcessStats mProcessStats = new ProcessStats( 795 MONITOR_THREAD_CPU_USAGE); 796 final AtomicLong mLastCpuTime = new AtomicLong(0); 797 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 798 799 long mLastWriteTime = 0; 800 801 /** 802 * Set to true after the system has finished booting. 803 */ 804 boolean mBooted = false; 805 806 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 807 int mProcessLimitOverride = -1; 808 809 WindowManagerService mWindowManager; 810 811 static ActivityManagerService mSelf; 812 static ActivityThread mSystemThread; 813 814 private int mCurrentUserId; 815 private UserManagerService mUserManager; 816 817 private final class AppDeathRecipient implements IBinder.DeathRecipient { 818 final ProcessRecord mApp; 819 final int mPid; 820 final IApplicationThread mAppThread; 821 822 AppDeathRecipient(ProcessRecord app, int pid, 823 IApplicationThread thread) { 824 if (localLOGV) Slog.v( 825 TAG, "New death recipient " + this 826 + " for thread " + thread.asBinder()); 827 mApp = app; 828 mPid = pid; 829 mAppThread = thread; 830 } 831 832 public void binderDied() { 833 if (localLOGV) Slog.v( 834 TAG, "Death received in " + this 835 + " for thread " + mAppThread.asBinder()); 836 synchronized(ActivityManagerService.this) { 837 appDiedLocked(mApp, mPid, mAppThread); 838 } 839 } 840 } 841 842 static final int SHOW_ERROR_MSG = 1; 843 static final int SHOW_NOT_RESPONDING_MSG = 2; 844 static final int SHOW_FACTORY_ERROR_MSG = 3; 845 static final int UPDATE_CONFIGURATION_MSG = 4; 846 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 847 static final int WAIT_FOR_DEBUGGER_MSG = 6; 848 static final int SERVICE_TIMEOUT_MSG = 12; 849 static final int UPDATE_TIME_ZONE = 13; 850 static final int SHOW_UID_ERROR_MSG = 14; 851 static final int IM_FEELING_LUCKY_MSG = 15; 852 static final int PROC_START_TIMEOUT_MSG = 20; 853 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 854 static final int KILL_APPLICATION_MSG = 22; 855 static final int FINALIZE_PENDING_INTENT_MSG = 23; 856 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 857 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 858 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 859 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 860 static final int CLEAR_DNS_CACHE = 28; 861 static final int UPDATE_HTTP_PROXY = 29; 862 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 863 static final int DISPATCH_PROCESSES_CHANGED = 31; 864 static final int DISPATCH_PROCESS_DIED = 32; 865 static final int REPORT_MEM_USAGE = 33; 866 867 static final int FIRST_ACTIVITY_STACK_MSG = 100; 868 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 869 static final int FIRST_COMPAT_MODE_MSG = 300; 870 871 AlertDialog mUidAlert; 872 CompatModeDialog mCompatModeDialog; 873 long mLastMemUsageReportTime = 0; 874 875 final Handler mHandler = new Handler() { 876 //public Handler() { 877 // if (localLOGV) Slog.v(TAG, "Handler started!"); 878 //} 879 880 public void handleMessage(Message msg) { 881 switch (msg.what) { 882 case SHOW_ERROR_MSG: { 883 HashMap data = (HashMap) msg.obj; 884 synchronized (ActivityManagerService.this) { 885 ProcessRecord proc = (ProcessRecord)data.get("app"); 886 if (proc != null && proc.crashDialog != null) { 887 Slog.e(TAG, "App already has crash dialog: " + proc); 888 return; 889 } 890 AppErrorResult res = (AppErrorResult) data.get("result"); 891 if (mShowDialogs && !mSleeping && !mShuttingDown) { 892 Dialog d = new AppErrorDialog(mContext, res, proc); 893 d.show(); 894 proc.crashDialog = d; 895 } else { 896 // The device is asleep, so just pretend that the user 897 // saw a crash dialog and hit "force quit". 898 res.set(0); 899 } 900 } 901 902 ensureBootCompleted(); 903 } break; 904 case SHOW_NOT_RESPONDING_MSG: { 905 synchronized (ActivityManagerService.this) { 906 HashMap data = (HashMap) msg.obj; 907 ProcessRecord proc = (ProcessRecord)data.get("app"); 908 if (proc != null && proc.anrDialog != null) { 909 Slog.e(TAG, "App already has anr dialog: " + proc); 910 return; 911 } 912 913 Intent intent = new Intent("android.intent.action.ANR"); 914 if (!mProcessesReady) { 915 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 916 | Intent.FLAG_RECEIVER_FOREGROUND); 917 } 918 broadcastIntentLocked(null, null, intent, 919 null, null, 0, null, null, null, 920 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 921 922 if (mShowDialogs) { 923 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 924 mContext, proc, (ActivityRecord)data.get("activity")); 925 d.show(); 926 proc.anrDialog = d; 927 } else { 928 // Just kill the app if there is no dialog to be shown. 929 killAppAtUsersRequest(proc, null); 930 } 931 } 932 933 ensureBootCompleted(); 934 } break; 935 case SHOW_STRICT_MODE_VIOLATION_MSG: { 936 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 937 synchronized (ActivityManagerService.this) { 938 ProcessRecord proc = (ProcessRecord) data.get("app"); 939 if (proc == null) { 940 Slog.e(TAG, "App not found when showing strict mode dialog."); 941 break; 942 } 943 if (proc.crashDialog != null) { 944 Slog.e(TAG, "App already has strict mode dialog: " + proc); 945 return; 946 } 947 AppErrorResult res = (AppErrorResult) data.get("result"); 948 if (mShowDialogs && !mSleeping && !mShuttingDown) { 949 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 950 d.show(); 951 proc.crashDialog = d; 952 } else { 953 // The device is asleep, so just pretend that the user 954 // saw a crash dialog and hit "force quit". 955 res.set(0); 956 } 957 } 958 ensureBootCompleted(); 959 } break; 960 case SHOW_FACTORY_ERROR_MSG: { 961 Dialog d = new FactoryErrorDialog( 962 mContext, msg.getData().getCharSequence("msg")); 963 d.show(); 964 ensureBootCompleted(); 965 } break; 966 case UPDATE_CONFIGURATION_MSG: { 967 final ContentResolver resolver = mContext.getContentResolver(); 968 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 969 } break; 970 case GC_BACKGROUND_PROCESSES_MSG: { 971 synchronized (ActivityManagerService.this) { 972 performAppGcsIfAppropriateLocked(); 973 } 974 } break; 975 case WAIT_FOR_DEBUGGER_MSG: { 976 synchronized (ActivityManagerService.this) { 977 ProcessRecord app = (ProcessRecord)msg.obj; 978 if (msg.arg1 != 0) { 979 if (!app.waitedForDebugger) { 980 Dialog d = new AppWaitingForDebuggerDialog( 981 ActivityManagerService.this, 982 mContext, app); 983 app.waitDialog = d; 984 app.waitedForDebugger = true; 985 d.show(); 986 } 987 } else { 988 if (app.waitDialog != null) { 989 app.waitDialog.dismiss(); 990 app.waitDialog = null; 991 } 992 } 993 } 994 } break; 995 case SERVICE_TIMEOUT_MSG: { 996 if (mDidDexOpt) { 997 mDidDexOpt = false; 998 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 999 nmsg.obj = msg.obj; 1000 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1001 return; 1002 } 1003 mServices.serviceTimeout((ProcessRecord)msg.obj); 1004 } break; 1005 case UPDATE_TIME_ZONE: { 1006 synchronized (ActivityManagerService.this) { 1007 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1008 ProcessRecord r = mLruProcesses.get(i); 1009 if (r.thread != null) { 1010 try { 1011 r.thread.updateTimeZone(); 1012 } catch (RemoteException ex) { 1013 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1014 } 1015 } 1016 } 1017 } 1018 } break; 1019 case CLEAR_DNS_CACHE: { 1020 synchronized (ActivityManagerService.this) { 1021 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1022 ProcessRecord r = mLruProcesses.get(i); 1023 if (r.thread != null) { 1024 try { 1025 r.thread.clearDnsCache(); 1026 } catch (RemoteException ex) { 1027 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1028 } 1029 } 1030 } 1031 } 1032 } break; 1033 case UPDATE_HTTP_PROXY: { 1034 ProxyProperties proxy = (ProxyProperties)msg.obj; 1035 String host = ""; 1036 String port = ""; 1037 String exclList = ""; 1038 if (proxy != null) { 1039 host = proxy.getHost(); 1040 port = Integer.toString(proxy.getPort()); 1041 exclList = proxy.getExclusionList(); 1042 } 1043 synchronized (ActivityManagerService.this) { 1044 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1045 ProcessRecord r = mLruProcesses.get(i); 1046 if (r.thread != null) { 1047 try { 1048 r.thread.setHttpProxy(host, port, exclList); 1049 } catch (RemoteException ex) { 1050 Slog.w(TAG, "Failed to update http proxy for: " + 1051 r.info.processName); 1052 } 1053 } 1054 } 1055 } 1056 } break; 1057 case SHOW_UID_ERROR_MSG: { 1058 String title = "System UIDs Inconsistent"; 1059 String text = "UIDs on the system are inconsistent, you need to wipe your" 1060 + " data partition or your device will be unstable."; 1061 Log.e(TAG, title + ": " + text); 1062 if (mShowDialogs) { 1063 // XXX This is a temporary dialog, no need to localize. 1064 AlertDialog d = new BaseErrorDialog(mContext); 1065 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1066 d.setCancelable(false); 1067 d.setTitle(title); 1068 d.setMessage(text); 1069 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1070 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1071 mUidAlert = d; 1072 d.show(); 1073 } 1074 } break; 1075 case IM_FEELING_LUCKY_MSG: { 1076 if (mUidAlert != null) { 1077 mUidAlert.dismiss(); 1078 mUidAlert = null; 1079 } 1080 } break; 1081 case PROC_START_TIMEOUT_MSG: { 1082 if (mDidDexOpt) { 1083 mDidDexOpt = false; 1084 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1085 nmsg.obj = msg.obj; 1086 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1087 return; 1088 } 1089 ProcessRecord app = (ProcessRecord)msg.obj; 1090 synchronized (ActivityManagerService.this) { 1091 processStartTimedOutLocked(app); 1092 } 1093 } break; 1094 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1095 synchronized (ActivityManagerService.this) { 1096 doPendingActivityLaunchesLocked(true); 1097 } 1098 } break; 1099 case KILL_APPLICATION_MSG: { 1100 synchronized (ActivityManagerService.this) { 1101 int appid = msg.arg1; 1102 boolean restart = (msg.arg2 == 1); 1103 String pkg = (String) msg.obj; 1104 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1105 UserHandle.USER_ALL); 1106 } 1107 } break; 1108 case FINALIZE_PENDING_INTENT_MSG: { 1109 ((PendingIntentRecord)msg.obj).completeFinalize(); 1110 } break; 1111 case POST_HEAVY_NOTIFICATION_MSG: { 1112 INotificationManager inm = NotificationManager.getService(); 1113 if (inm == null) { 1114 return; 1115 } 1116 1117 ActivityRecord root = (ActivityRecord)msg.obj; 1118 ProcessRecord process = root.app; 1119 if (process == null) { 1120 return; 1121 } 1122 1123 try { 1124 Context context = mContext.createPackageContext(process.info.packageName, 0); 1125 String text = mContext.getString(R.string.heavy_weight_notification, 1126 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1127 Notification notification = new Notification(); 1128 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1129 notification.when = 0; 1130 notification.flags = Notification.FLAG_ONGOING_EVENT; 1131 notification.tickerText = text; 1132 notification.defaults = 0; // please be quiet 1133 notification.sound = null; 1134 notification.vibrate = null; 1135 notification.setLatestEventInfo(context, text, 1136 mContext.getText(R.string.heavy_weight_notification_detail), 1137 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1138 PendingIntent.FLAG_CANCEL_CURRENT, null, 1139 new UserHandle(root.userId))); 1140 1141 try { 1142 int[] outId = new int[1]; 1143 inm.enqueueNotificationWithTag("android", null, 1144 R.string.heavy_weight_notification, 1145 notification, outId, root.userId); 1146 } catch (RuntimeException e) { 1147 Slog.w(ActivityManagerService.TAG, 1148 "Error showing notification for heavy-weight app", e); 1149 } catch (RemoteException e) { 1150 } 1151 } catch (NameNotFoundException e) { 1152 Slog.w(TAG, "Unable to create context for heavy notification", e); 1153 } 1154 } break; 1155 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1156 INotificationManager inm = NotificationManager.getService(); 1157 if (inm == null) { 1158 return; 1159 } 1160 try { 1161 inm.cancelNotificationWithTag("android", null, 1162 R.string.heavy_weight_notification, msg.arg1); 1163 } catch (RuntimeException e) { 1164 Slog.w(ActivityManagerService.TAG, 1165 "Error canceling notification for service", e); 1166 } catch (RemoteException e) { 1167 } 1168 } break; 1169 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1170 synchronized (ActivityManagerService.this) { 1171 checkExcessivePowerUsageLocked(true); 1172 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1173 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1174 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1175 } 1176 } break; 1177 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1178 synchronized (ActivityManagerService.this) { 1179 ActivityRecord ar = (ActivityRecord)msg.obj; 1180 if (mCompatModeDialog != null) { 1181 if (mCompatModeDialog.mAppInfo.packageName.equals( 1182 ar.info.applicationInfo.packageName)) { 1183 return; 1184 } 1185 mCompatModeDialog.dismiss(); 1186 mCompatModeDialog = null; 1187 } 1188 if (ar != null && false) { 1189 if (mCompatModePackages.getPackageAskCompatModeLocked( 1190 ar.packageName)) { 1191 int mode = mCompatModePackages.computeCompatModeLocked( 1192 ar.info.applicationInfo); 1193 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1194 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1195 mCompatModeDialog = new CompatModeDialog( 1196 ActivityManagerService.this, mContext, 1197 ar.info.applicationInfo); 1198 mCompatModeDialog.show(); 1199 } 1200 } 1201 } 1202 } 1203 break; 1204 } 1205 case DISPATCH_PROCESSES_CHANGED: { 1206 dispatchProcessesChanged(); 1207 break; 1208 } 1209 case DISPATCH_PROCESS_DIED: { 1210 final int pid = msg.arg1; 1211 final int uid = msg.arg2; 1212 dispatchProcessDied(pid, uid); 1213 break; 1214 } 1215 case REPORT_MEM_USAGE: { 1216 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1217 if (!isDebuggable) { 1218 return; 1219 } 1220 synchronized (ActivityManagerService.this) { 1221 long now = SystemClock.uptimeMillis(); 1222 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1223 // Don't report more than every 5 minutes to somewhat 1224 // avoid spamming. 1225 return; 1226 } 1227 mLastMemUsageReportTime = now; 1228 } 1229 Thread thread = new Thread() { 1230 @Override public void run() { 1231 StringBuilder dropBuilder = new StringBuilder(1024); 1232 StringBuilder logBuilder = new StringBuilder(1024); 1233 StringWriter oomSw = new StringWriter(); 1234 PrintWriter oomPw = new PrintWriter(oomSw); 1235 StringWriter catSw = new StringWriter(); 1236 PrintWriter catPw = new PrintWriter(catSw); 1237 String[] emptyArgs = new String[] { }; 1238 StringBuilder tag = new StringBuilder(128); 1239 StringBuilder stack = new StringBuilder(128); 1240 tag.append("Low on memory -- "); 1241 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1242 tag, stack); 1243 dropBuilder.append(stack); 1244 dropBuilder.append('\n'); 1245 dropBuilder.append('\n'); 1246 String oomString = oomSw.toString(); 1247 dropBuilder.append(oomString); 1248 dropBuilder.append('\n'); 1249 logBuilder.append(oomString); 1250 try { 1251 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1252 "procrank", }); 1253 final InputStreamReader converter = new InputStreamReader( 1254 proc.getInputStream()); 1255 BufferedReader in = new BufferedReader(converter); 1256 String line; 1257 while (true) { 1258 line = in.readLine(); 1259 if (line == null) { 1260 break; 1261 } 1262 if (line.length() > 0) { 1263 logBuilder.append(line); 1264 logBuilder.append('\n'); 1265 } 1266 dropBuilder.append(line); 1267 dropBuilder.append('\n'); 1268 } 1269 converter.close(); 1270 } catch (IOException e) { 1271 } 1272 synchronized (ActivityManagerService.this) { 1273 catPw.println(); 1274 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1275 catPw.println(); 1276 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1277 false, false, null); 1278 catPw.println(); 1279 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1280 } 1281 dropBuilder.append(catSw.toString()); 1282 addErrorToDropBox("lowmem", null, "system_server", null, 1283 null, tag.toString(), dropBuilder.toString(), null, null); 1284 Slog.i(TAG, logBuilder.toString()); 1285 synchronized (ActivityManagerService.this) { 1286 long now = SystemClock.uptimeMillis(); 1287 if (mLastMemUsageReportTime < now) { 1288 mLastMemUsageReportTime = now; 1289 } 1290 } 1291 } 1292 }; 1293 thread.start(); 1294 break; 1295 } 1296 } 1297 } 1298 }; 1299 1300 public static void setSystemProcess() { 1301 try { 1302 ActivityManagerService m = mSelf; 1303 1304 ServiceManager.addService("activity", m, true); 1305 ServiceManager.addService("meminfo", new MemBinder(m)); 1306 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1307 ServiceManager.addService("dbinfo", new DbBinder(m)); 1308 if (MONITOR_CPU_USAGE) { 1309 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1310 } 1311 ServiceManager.addService("permission", new PermissionController(m)); 1312 1313 ApplicationInfo info = 1314 mSelf.mContext.getPackageManager().getApplicationInfo( 1315 "android", STOCK_PM_FLAGS); 1316 mSystemThread.installSystemApplicationInfo(info); 1317 1318 synchronized (mSelf) { 1319 ProcessRecord app = mSelf.newProcessRecordLocked( 1320 mSystemThread.getApplicationThread(), info, 1321 info.processName, false); 1322 app.persistent = true; 1323 app.pid = MY_PID; 1324 app.maxAdj = ProcessList.SYSTEM_ADJ; 1325 mSelf.mProcessNames.put(app.processName, app.uid, app); 1326 synchronized (mSelf.mPidsSelfLocked) { 1327 mSelf.mPidsSelfLocked.put(app.pid, app); 1328 } 1329 mSelf.updateLruProcessLocked(app, true, true); 1330 } 1331 } catch (PackageManager.NameNotFoundException e) { 1332 throw new RuntimeException( 1333 "Unable to find android system package", e); 1334 } 1335 } 1336 1337 public void setWindowManager(WindowManagerService wm) { 1338 mWindowManager = wm; 1339 } 1340 1341 public static final Context main(int factoryTest) { 1342 AThread thr = new AThread(); 1343 thr.start(); 1344 1345 synchronized (thr) { 1346 while (thr.mService == null) { 1347 try { 1348 thr.wait(); 1349 } catch (InterruptedException e) { 1350 } 1351 } 1352 } 1353 1354 ActivityManagerService m = thr.mService; 1355 mSelf = m; 1356 ActivityThread at = ActivityThread.systemMain(); 1357 mSystemThread = at; 1358 Context context = at.getSystemContext(); 1359 context.setTheme(android.R.style.Theme_Holo); 1360 m.mContext = context; 1361 m.mFactoryTest = factoryTest; 1362 m.mMainStack = new ActivityStack(m, context, true); 1363 1364 m.mBatteryStatsService.publish(context); 1365 m.mUsageStatsService.publish(context); 1366 1367 synchronized (thr) { 1368 thr.mReady = true; 1369 thr.notifyAll(); 1370 } 1371 1372 m.startRunning(null, null, null, null); 1373 1374 return context; 1375 } 1376 1377 public static ActivityManagerService self() { 1378 return mSelf; 1379 } 1380 1381 static class AThread extends Thread { 1382 ActivityManagerService mService; 1383 boolean mReady = false; 1384 1385 public AThread() { 1386 super("ActivityManager"); 1387 } 1388 1389 public void run() { 1390 Looper.prepare(); 1391 1392 android.os.Process.setThreadPriority( 1393 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1394 android.os.Process.setCanSelfBackground(false); 1395 1396 ActivityManagerService m = new ActivityManagerService(); 1397 1398 synchronized (this) { 1399 mService = m; 1400 notifyAll(); 1401 } 1402 1403 synchronized (this) { 1404 while (!mReady) { 1405 try { 1406 wait(); 1407 } catch (InterruptedException e) { 1408 } 1409 } 1410 } 1411 1412 // For debug builds, log event loop stalls to dropbox for analysis. 1413 if (StrictMode.conditionallyEnableDebugLogging()) { 1414 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1415 } 1416 1417 Looper.loop(); 1418 } 1419 } 1420 1421 static class MemBinder extends Binder { 1422 ActivityManagerService mActivityManagerService; 1423 MemBinder(ActivityManagerService activityManagerService) { 1424 mActivityManagerService = activityManagerService; 1425 } 1426 1427 @Override 1428 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1429 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1430 != PackageManager.PERMISSION_GRANTED) { 1431 pw.println("Permission Denial: can't dump meminfo from from pid=" 1432 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1433 + " without permission " + android.Manifest.permission.DUMP); 1434 return; 1435 } 1436 1437 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1438 false, null, null, null); 1439 } 1440 } 1441 1442 static class GraphicsBinder extends Binder { 1443 ActivityManagerService mActivityManagerService; 1444 GraphicsBinder(ActivityManagerService activityManagerService) { 1445 mActivityManagerService = activityManagerService; 1446 } 1447 1448 @Override 1449 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1450 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1451 != PackageManager.PERMISSION_GRANTED) { 1452 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1453 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1454 + " without permission " + android.Manifest.permission.DUMP); 1455 return; 1456 } 1457 1458 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1459 } 1460 } 1461 1462 static class DbBinder extends Binder { 1463 ActivityManagerService mActivityManagerService; 1464 DbBinder(ActivityManagerService activityManagerService) { 1465 mActivityManagerService = activityManagerService; 1466 } 1467 1468 @Override 1469 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1470 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1471 != PackageManager.PERMISSION_GRANTED) { 1472 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1473 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1474 + " without permission " + android.Manifest.permission.DUMP); 1475 return; 1476 } 1477 1478 mActivityManagerService.dumpDbInfo(fd, pw, args); 1479 } 1480 } 1481 1482 static class CpuBinder extends Binder { 1483 ActivityManagerService mActivityManagerService; 1484 CpuBinder(ActivityManagerService activityManagerService) { 1485 mActivityManagerService = activityManagerService; 1486 } 1487 1488 @Override 1489 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1490 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1491 != PackageManager.PERMISSION_GRANTED) { 1492 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1493 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1494 + " without permission " + android.Manifest.permission.DUMP); 1495 return; 1496 } 1497 1498 synchronized (mActivityManagerService.mProcessStatsThread) { 1499 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1500 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1501 SystemClock.uptimeMillis())); 1502 } 1503 } 1504 } 1505 1506 private ActivityManagerService() { 1507 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1508 1509 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1510 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1511 mBroadcastQueues[0] = mFgBroadcastQueue; 1512 mBroadcastQueues[1] = mBgBroadcastQueue; 1513 1514 mServices = new ActiveServices(this); 1515 mProviderMap = new ProviderMap(this); 1516 1517 File dataDir = Environment.getDataDirectory(); 1518 File systemDir = new File(dataDir, "system"); 1519 systemDir.mkdirs(); 1520 mBatteryStatsService = new BatteryStatsService(new File( 1521 systemDir, "batterystats.bin").toString()); 1522 mBatteryStatsService.getActiveStatistics().readLocked(); 1523 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1524 mOnBattery = DEBUG_POWER ? true 1525 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1526 mBatteryStatsService.getActiveStatistics().setCallback(this); 1527 1528 mUsageStatsService = new UsageStatsService(new File( 1529 systemDir, "usagestats").toString()); 1530 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1531 1532 // User 0 is the first and only user that runs at boot. 1533 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1534 mUserLru.add(Integer.valueOf(0)); 1535 1536 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1537 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1538 1539 mConfiguration.setToDefaults(); 1540 mConfiguration.setLocale(Locale.getDefault()); 1541 1542 mConfigurationSeq = mConfiguration.seq = 1; 1543 mProcessStats.init(); 1544 1545 mCompatModePackages = new CompatModePackages(this, systemDir); 1546 1547 // Add ourself to the Watchdog monitors. 1548 Watchdog.getInstance().addMonitor(this); 1549 1550 mProcessStatsThread = new Thread("ProcessStats") { 1551 public void run() { 1552 while (true) { 1553 try { 1554 try { 1555 synchronized(this) { 1556 final long now = SystemClock.uptimeMillis(); 1557 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1558 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1559 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1560 // + ", write delay=" + nextWriteDelay); 1561 if (nextWriteDelay < nextCpuDelay) { 1562 nextCpuDelay = nextWriteDelay; 1563 } 1564 if (nextCpuDelay > 0) { 1565 mProcessStatsMutexFree.set(true); 1566 this.wait(nextCpuDelay); 1567 } 1568 } 1569 } catch (InterruptedException e) { 1570 } 1571 updateCpuStatsNow(); 1572 } catch (Exception e) { 1573 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1574 } 1575 } 1576 } 1577 }; 1578 mProcessStatsThread.start(); 1579 } 1580 1581 @Override 1582 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1583 throws RemoteException { 1584 if (code == SYSPROPS_TRANSACTION) { 1585 // We need to tell all apps about the system property change. 1586 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1587 synchronized(this) { 1588 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1589 final int NA = apps.size(); 1590 for (int ia=0; ia<NA; ia++) { 1591 ProcessRecord app = apps.valueAt(ia); 1592 if (app.thread != null) { 1593 procs.add(app.thread.asBinder()); 1594 } 1595 } 1596 } 1597 } 1598 1599 int N = procs.size(); 1600 for (int i=0; i<N; i++) { 1601 Parcel data2 = Parcel.obtain(); 1602 try { 1603 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1604 } catch (RemoteException e) { 1605 } 1606 data2.recycle(); 1607 } 1608 } 1609 try { 1610 return super.onTransact(code, data, reply, flags); 1611 } catch (RuntimeException e) { 1612 // The activity manager only throws security exceptions, so let's 1613 // log all others. 1614 if (!(e instanceof SecurityException)) { 1615 Slog.e(TAG, "Activity Manager Crash", e); 1616 } 1617 throw e; 1618 } 1619 } 1620 1621 void updateCpuStats() { 1622 final long now = SystemClock.uptimeMillis(); 1623 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1624 return; 1625 } 1626 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1627 synchronized (mProcessStatsThread) { 1628 mProcessStatsThread.notify(); 1629 } 1630 } 1631 } 1632 1633 void updateCpuStatsNow() { 1634 synchronized (mProcessStatsThread) { 1635 mProcessStatsMutexFree.set(false); 1636 final long now = SystemClock.uptimeMillis(); 1637 boolean haveNewCpuStats = false; 1638 1639 if (MONITOR_CPU_USAGE && 1640 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1641 mLastCpuTime.set(now); 1642 haveNewCpuStats = true; 1643 mProcessStats.update(); 1644 //Slog.i(TAG, mProcessStats.printCurrentState()); 1645 //Slog.i(TAG, "Total CPU usage: " 1646 // + mProcessStats.getTotalCpuPercent() + "%"); 1647 1648 // Slog the cpu usage if the property is set. 1649 if ("true".equals(SystemProperties.get("events.cpu"))) { 1650 int user = mProcessStats.getLastUserTime(); 1651 int system = mProcessStats.getLastSystemTime(); 1652 int iowait = mProcessStats.getLastIoWaitTime(); 1653 int irq = mProcessStats.getLastIrqTime(); 1654 int softIrq = mProcessStats.getLastSoftIrqTime(); 1655 int idle = mProcessStats.getLastIdleTime(); 1656 1657 int total = user + system + iowait + irq + softIrq + idle; 1658 if (total == 0) total = 1; 1659 1660 EventLog.writeEvent(EventLogTags.CPU, 1661 ((user+system+iowait+irq+softIrq) * 100) / total, 1662 (user * 100) / total, 1663 (system * 100) / total, 1664 (iowait * 100) / total, 1665 (irq * 100) / total, 1666 (softIrq * 100) / total); 1667 } 1668 } 1669 1670 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1671 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1672 synchronized(bstats) { 1673 synchronized(mPidsSelfLocked) { 1674 if (haveNewCpuStats) { 1675 if (mOnBattery) { 1676 int perc = bstats.startAddingCpuLocked(); 1677 int totalUTime = 0; 1678 int totalSTime = 0; 1679 final int N = mProcessStats.countStats(); 1680 for (int i=0; i<N; i++) { 1681 ProcessStats.Stats st = mProcessStats.getStats(i); 1682 if (!st.working) { 1683 continue; 1684 } 1685 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1686 int otherUTime = (st.rel_utime*perc)/100; 1687 int otherSTime = (st.rel_stime*perc)/100; 1688 totalUTime += otherUTime; 1689 totalSTime += otherSTime; 1690 if (pr != null) { 1691 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1692 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1693 st.rel_stime-otherSTime); 1694 ps.addSpeedStepTimes(cpuSpeedTimes); 1695 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1696 } else { 1697 BatteryStatsImpl.Uid.Proc ps = 1698 bstats.getProcessStatsLocked(st.name, st.pid); 1699 if (ps != null) { 1700 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1701 st.rel_stime-otherSTime); 1702 ps.addSpeedStepTimes(cpuSpeedTimes); 1703 } 1704 } 1705 } 1706 bstats.finishAddingCpuLocked(perc, totalUTime, 1707 totalSTime, cpuSpeedTimes); 1708 } 1709 } 1710 } 1711 1712 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1713 mLastWriteTime = now; 1714 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1715 } 1716 } 1717 } 1718 } 1719 1720 @Override 1721 public void batteryNeedsCpuUpdate() { 1722 updateCpuStatsNow(); 1723 } 1724 1725 @Override 1726 public void batteryPowerChanged(boolean onBattery) { 1727 // When plugging in, update the CPU stats first before changing 1728 // the plug state. 1729 updateCpuStatsNow(); 1730 synchronized (this) { 1731 synchronized(mPidsSelfLocked) { 1732 mOnBattery = DEBUG_POWER ? true : onBattery; 1733 } 1734 } 1735 } 1736 1737 /** 1738 * Initialize the application bind args. These are passed to each 1739 * process when the bindApplication() IPC is sent to the process. They're 1740 * lazily setup to make sure the services are running when they're asked for. 1741 */ 1742 private HashMap<String, IBinder> getCommonServicesLocked() { 1743 if (mAppBindArgs == null) { 1744 mAppBindArgs = new HashMap<String, IBinder>(); 1745 1746 // Setup the application init args 1747 mAppBindArgs.put("package", ServiceManager.getService("package")); 1748 mAppBindArgs.put("window", ServiceManager.getService("window")); 1749 mAppBindArgs.put(Context.ALARM_SERVICE, 1750 ServiceManager.getService(Context.ALARM_SERVICE)); 1751 } 1752 return mAppBindArgs; 1753 } 1754 1755 final void setFocusedActivityLocked(ActivityRecord r) { 1756 if (mFocusedActivity != r) { 1757 mFocusedActivity = r; 1758 if (r != null) { 1759 mWindowManager.setFocusedApp(r.appToken, true); 1760 } 1761 } 1762 } 1763 1764 private final void updateLruProcessInternalLocked(ProcessRecord app, 1765 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1766 // put it on the LRU to keep track of when it should be exited. 1767 int lrui = mLruProcesses.indexOf(app); 1768 if (lrui >= 0) mLruProcesses.remove(lrui); 1769 1770 int i = mLruProcesses.size()-1; 1771 int skipTop = 0; 1772 1773 app.lruSeq = mLruSeq; 1774 1775 // compute the new weight for this process. 1776 if (updateActivityTime) { 1777 app.lastActivityTime = SystemClock.uptimeMillis(); 1778 } 1779 if (app.activities.size() > 0) { 1780 // If this process has activities, we more strongly want to keep 1781 // it around. 1782 app.lruWeight = app.lastActivityTime; 1783 } else if (app.pubProviders.size() > 0) { 1784 // If this process contains content providers, we want to keep 1785 // it a little more strongly. 1786 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1787 // Also don't let it kick out the first few "real" hidden processes. 1788 skipTop = ProcessList.MIN_HIDDEN_APPS; 1789 } else { 1790 // If this process doesn't have activities, we less strongly 1791 // want to keep it around, and generally want to avoid getting 1792 // in front of any very recently used activities. 1793 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1794 // Also don't let it kick out the first few "real" hidden processes. 1795 skipTop = ProcessList.MIN_HIDDEN_APPS; 1796 } 1797 1798 while (i >= 0) { 1799 ProcessRecord p = mLruProcesses.get(i); 1800 // If this app shouldn't be in front of the first N background 1801 // apps, then skip over that many that are currently hidden. 1802 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1803 skipTop--; 1804 } 1805 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1806 mLruProcesses.add(i+1, app); 1807 break; 1808 } 1809 i--; 1810 } 1811 if (i < 0) { 1812 mLruProcesses.add(0, app); 1813 } 1814 1815 // If the app is currently using a content provider or service, 1816 // bump those processes as well. 1817 if (app.connections.size() > 0) { 1818 for (ConnectionRecord cr : app.connections) { 1819 if (cr.binding != null && cr.binding.service != null 1820 && cr.binding.service.app != null 1821 && cr.binding.service.app.lruSeq != mLruSeq) { 1822 updateLruProcessInternalLocked(cr.binding.service.app, false, 1823 updateActivityTime, i+1); 1824 } 1825 } 1826 } 1827 for (int j=app.conProviders.size()-1; j>=0; j--) { 1828 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1829 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1830 updateLruProcessInternalLocked(cpr.proc, false, 1831 updateActivityTime, i+1); 1832 } 1833 } 1834 1835 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1836 if (oomAdj) { 1837 updateOomAdjLocked(); 1838 } 1839 } 1840 1841 final void updateLruProcessLocked(ProcessRecord app, 1842 boolean oomAdj, boolean updateActivityTime) { 1843 mLruSeq++; 1844 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1845 } 1846 1847 final ProcessRecord getProcessRecordLocked( 1848 String processName, int uid) { 1849 if (uid == Process.SYSTEM_UID) { 1850 // The system gets to run in any process. If there are multiple 1851 // processes with the same uid, just pick the first (this 1852 // should never happen). 1853 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1854 processName); 1855 if (procs == null) return null; 1856 final int N = procs.size(); 1857 for (int i = 0; i < N; i++) { 1858 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1859 } 1860 } 1861 ProcessRecord proc = mProcessNames.get(processName, uid); 1862 return proc; 1863 } 1864 1865 void ensurePackageDexOpt(String packageName) { 1866 IPackageManager pm = AppGlobals.getPackageManager(); 1867 try { 1868 if (pm.performDexOpt(packageName)) { 1869 mDidDexOpt = true; 1870 } 1871 } catch (RemoteException e) { 1872 } 1873 } 1874 1875 boolean isNextTransitionForward() { 1876 int transit = mWindowManager.getPendingAppTransition(); 1877 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1878 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1879 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1880 } 1881 1882 final ProcessRecord startProcessLocked(String processName, 1883 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1884 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1885 boolean isolated) { 1886 ProcessRecord app; 1887 if (!isolated) { 1888 app = getProcessRecordLocked(processName, info.uid); 1889 } else { 1890 // If this is an isolated process, it can't re-use an existing process. 1891 app = null; 1892 } 1893 // We don't have to do anything more if: 1894 // (1) There is an existing application record; and 1895 // (2) The caller doesn't think it is dead, OR there is no thread 1896 // object attached to it so we know it couldn't have crashed; and 1897 // (3) There is a pid assigned to it, so it is either starting or 1898 // already running. 1899 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1900 + " app=" + app + " knownToBeDead=" + knownToBeDead 1901 + " thread=" + (app != null ? app.thread : null) 1902 + " pid=" + (app != null ? app.pid : -1)); 1903 if (app != null && app.pid > 0) { 1904 if (!knownToBeDead || app.thread == null) { 1905 // We already have the app running, or are waiting for it to 1906 // come up (we have a pid but not yet its thread), so keep it. 1907 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1908 // If this is a new package in the process, add the package to the list 1909 app.addPackage(info.packageName); 1910 return app; 1911 } else { 1912 // An application record is attached to a previous process, 1913 // clean it up now. 1914 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1915 handleAppDiedLocked(app, true, true); 1916 } 1917 } 1918 1919 String hostingNameStr = hostingName != null 1920 ? hostingName.flattenToShortString() : null; 1921 1922 if (!isolated) { 1923 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1924 // If we are in the background, then check to see if this process 1925 // is bad. If so, we will just silently fail. 1926 if (mBadProcesses.get(info.processName, info.uid) != null) { 1927 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1928 + "/" + info.processName); 1929 return null; 1930 } 1931 } else { 1932 // When the user is explicitly starting a process, then clear its 1933 // crash count so that we won't make it bad until they see at 1934 // least one crash dialog again, and make the process good again 1935 // if it had been bad. 1936 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1937 + "/" + info.processName); 1938 mProcessCrashTimes.remove(info.processName, info.uid); 1939 if (mBadProcesses.get(info.processName, info.uid) != null) { 1940 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1941 info.processName); 1942 mBadProcesses.remove(info.processName, info.uid); 1943 if (app != null) { 1944 app.bad = false; 1945 } 1946 } 1947 } 1948 } 1949 1950 if (app == null) { 1951 app = newProcessRecordLocked(null, info, processName, isolated); 1952 if (app == null) { 1953 Slog.w(TAG, "Failed making new process record for " 1954 + processName + "/" + info.uid + " isolated=" + isolated); 1955 return null; 1956 } 1957 mProcessNames.put(processName, app.uid, app); 1958 if (isolated) { 1959 mIsolatedProcesses.put(app.uid, app); 1960 } 1961 } else { 1962 // If this is a new package in the process, add the package to the list 1963 app.addPackage(info.packageName); 1964 } 1965 1966 // If the system is not ready yet, then hold off on starting this 1967 // process until it is. 1968 if (!mProcessesReady 1969 && !isAllowedWhileBooting(info) 1970 && !allowWhileBooting) { 1971 if (!mProcessesOnHold.contains(app)) { 1972 mProcessesOnHold.add(app); 1973 } 1974 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1975 return app; 1976 } 1977 1978 startProcessLocked(app, hostingType, hostingNameStr); 1979 return (app.pid != 0) ? app : null; 1980 } 1981 1982 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1983 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1984 } 1985 1986 private final void startProcessLocked(ProcessRecord app, 1987 String hostingType, String hostingNameStr) { 1988 if (app.pid > 0 && app.pid != MY_PID) { 1989 synchronized (mPidsSelfLocked) { 1990 mPidsSelfLocked.remove(app.pid); 1991 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1992 } 1993 app.setPid(0); 1994 } 1995 1996 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1997 "startProcessLocked removing on hold: " + app); 1998 mProcessesOnHold.remove(app); 1999 2000 updateCpuStats(); 2001 2002 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2003 mProcDeaths[0] = 0; 2004 2005 try { 2006 int uid = app.uid; 2007 2008 int[] gids = null; 2009 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2010 if (!app.isolated) { 2011 int[] permGids = null; 2012 try { 2013 final PackageManager pm = mContext.getPackageManager(); 2014 permGids = pm.getPackageGids(app.info.packageName); 2015 2016 if (Environment.isExternalStorageEmulated()) { 2017 if (pm.checkPermission( 2018 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2019 app.info.packageName) == PERMISSION_GRANTED) { 2020 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2021 } else { 2022 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2023 } 2024 } 2025 } catch (PackageManager.NameNotFoundException e) { 2026 Slog.w(TAG, "Unable to retrieve gids", e); 2027 } 2028 2029 /* 2030 * Add shared application GID so applications can share some 2031 * resources like shared libraries 2032 */ 2033 if (permGids == null) { 2034 gids = new int[1]; 2035 } else { 2036 gids = new int[permGids.length + 1]; 2037 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2038 } 2039 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2040 } 2041 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2042 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2043 && mTopComponent != null 2044 && app.processName.equals(mTopComponent.getPackageName())) { 2045 uid = 0; 2046 } 2047 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2048 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2049 uid = 0; 2050 } 2051 } 2052 int debugFlags = 0; 2053 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2054 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2055 // Also turn on CheckJNI for debuggable apps. It's quite 2056 // awkward to turn on otherwise. 2057 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2058 } 2059 // Run the app in safe mode if its manifest requests so or the 2060 // system is booted in safe mode. 2061 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2062 Zygote.systemInSafeMode == true) { 2063 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2064 } 2065 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2066 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2067 } 2068 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2069 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2070 } 2071 if ("1".equals(SystemProperties.get("debug.assert"))) { 2072 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2073 } 2074 2075 // Start the process. It will either succeed and return a result containing 2076 // the PID of the new process, or else throw a RuntimeException. 2077 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2078 app.processName, uid, uid, gids, debugFlags, mountExternal, 2079 app.info.targetSdkVersion, null, null); 2080 2081 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2082 synchronized (bs) { 2083 if (bs.isOnBattery()) { 2084 app.batteryStats.incStartsLocked(); 2085 } 2086 } 2087 2088 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2089 app.processName, hostingType, 2090 hostingNameStr != null ? hostingNameStr : ""); 2091 2092 if (app.persistent) { 2093 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2094 } 2095 2096 StringBuilder buf = mStringBuilder; 2097 buf.setLength(0); 2098 buf.append("Start proc "); 2099 buf.append(app.processName); 2100 buf.append(" for "); 2101 buf.append(hostingType); 2102 if (hostingNameStr != null) { 2103 buf.append(" "); 2104 buf.append(hostingNameStr); 2105 } 2106 buf.append(": pid="); 2107 buf.append(startResult.pid); 2108 buf.append(" uid="); 2109 buf.append(uid); 2110 buf.append(" gids={"); 2111 if (gids != null) { 2112 for (int gi=0; gi<gids.length; gi++) { 2113 if (gi != 0) buf.append(", "); 2114 buf.append(gids[gi]); 2115 2116 } 2117 } 2118 buf.append("}"); 2119 Slog.i(TAG, buf.toString()); 2120 app.setPid(startResult.pid); 2121 app.usingWrapper = startResult.usingWrapper; 2122 app.removed = false; 2123 synchronized (mPidsSelfLocked) { 2124 this.mPidsSelfLocked.put(startResult.pid, app); 2125 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2126 msg.obj = app; 2127 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2128 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2129 } 2130 } catch (RuntimeException e) { 2131 // XXX do better error recovery. 2132 app.setPid(0); 2133 Slog.e(TAG, "Failure starting process " + app.processName, e); 2134 } 2135 } 2136 2137 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2138 if (resumed) { 2139 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2140 } else { 2141 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2142 } 2143 } 2144 2145 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2146 if (mHeadless) { 2147 // Added because none of the other calls to ensureBootCompleted seem to fire 2148 // when running headless. 2149 ensureBootCompleted(); 2150 return false; 2151 } 2152 2153 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2154 && mTopAction == null) { 2155 // We are running in factory test mode, but unable to find 2156 // the factory test app, so just sit around displaying the 2157 // error message and don't try to start anything. 2158 return false; 2159 } 2160 Intent intent = new Intent( 2161 mTopAction, 2162 mTopData != null ? Uri.parse(mTopData) : null); 2163 intent.setComponent(mTopComponent); 2164 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2165 intent.addCategory(Intent.CATEGORY_HOME); 2166 } 2167 ActivityInfo aInfo = 2168 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2169 if (aInfo != null) { 2170 intent.setComponent(new ComponentName( 2171 aInfo.applicationInfo.packageName, aInfo.name)); 2172 // Don't do this if the home app is currently being 2173 // instrumented. 2174 aInfo = new ActivityInfo(aInfo); 2175 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2176 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2177 aInfo.applicationInfo.uid); 2178 if (app == null || app.instrumentationClass == null) { 2179 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2180 mMainStack.startActivityLocked(null, intent, null, aInfo, 2181 null, null, 0, 0, 0, 0, null, false, null); 2182 } 2183 } 2184 if (startingUser != null) { 2185 mMainStack.addStartingUserLocked(startingUser); 2186 } 2187 2188 return true; 2189 } 2190 2191 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2192 ActivityInfo ai = null; 2193 ComponentName comp = intent.getComponent(); 2194 try { 2195 if (comp != null) { 2196 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2197 } else { 2198 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2199 intent, 2200 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2201 flags, userId); 2202 2203 if (info != null) { 2204 ai = info.activityInfo; 2205 } 2206 } 2207 } catch (RemoteException e) { 2208 // ignore 2209 } 2210 2211 return ai; 2212 } 2213 2214 /** 2215 * Starts the "new version setup screen" if appropriate. 2216 */ 2217 void startSetupActivityLocked() { 2218 // Only do this once per boot. 2219 if (mCheckedForSetup) { 2220 return; 2221 } 2222 2223 // We will show this screen if the current one is a different 2224 // version than the last one shown, and we are not running in 2225 // low-level factory test mode. 2226 final ContentResolver resolver = mContext.getContentResolver(); 2227 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2228 Settings.Secure.getInt(resolver, 2229 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2230 mCheckedForSetup = true; 2231 2232 // See if we should be showing the platform update setup UI. 2233 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2234 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2235 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2236 2237 // We don't allow third party apps to replace this. 2238 ResolveInfo ri = null; 2239 for (int i=0; ris != null && i<ris.size(); i++) { 2240 if ((ris.get(i).activityInfo.applicationInfo.flags 2241 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2242 ri = ris.get(i); 2243 break; 2244 } 2245 } 2246 2247 if (ri != null) { 2248 String vers = ri.activityInfo.metaData != null 2249 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2250 : null; 2251 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2252 vers = ri.activityInfo.applicationInfo.metaData.getString( 2253 Intent.METADATA_SETUP_VERSION); 2254 } 2255 String lastVers = Settings.Secure.getString( 2256 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2257 if (vers != null && !vers.equals(lastVers)) { 2258 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2259 intent.setComponent(new ComponentName( 2260 ri.activityInfo.packageName, ri.activityInfo.name)); 2261 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2262 null, null, 0, 0, 0, 0, null, false, null); 2263 } 2264 } 2265 } 2266 } 2267 2268 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2269 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2270 } 2271 2272 void enforceNotIsolatedCaller(String caller) { 2273 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2274 throw new SecurityException("Isolated process not allowed to call " + caller); 2275 } 2276 } 2277 2278 public int getFrontActivityScreenCompatMode() { 2279 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2280 synchronized (this) { 2281 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2282 } 2283 } 2284 2285 public void setFrontActivityScreenCompatMode(int mode) { 2286 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2287 "setFrontActivityScreenCompatMode"); 2288 synchronized (this) { 2289 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2290 } 2291 } 2292 2293 public int getPackageScreenCompatMode(String packageName) { 2294 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2295 synchronized (this) { 2296 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2297 } 2298 } 2299 2300 public void setPackageScreenCompatMode(String packageName, int mode) { 2301 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2302 "setPackageScreenCompatMode"); 2303 synchronized (this) { 2304 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2305 } 2306 } 2307 2308 public boolean getPackageAskScreenCompat(String packageName) { 2309 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2310 synchronized (this) { 2311 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2312 } 2313 } 2314 2315 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2316 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2317 "setPackageAskScreenCompat"); 2318 synchronized (this) { 2319 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2320 } 2321 } 2322 2323 void reportResumedActivityLocked(ActivityRecord r) { 2324 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2325 updateUsageStats(r, true); 2326 } 2327 2328 private void dispatchProcessesChanged() { 2329 int N; 2330 synchronized (this) { 2331 N = mPendingProcessChanges.size(); 2332 if (mActiveProcessChanges.length < N) { 2333 mActiveProcessChanges = new ProcessChangeItem[N]; 2334 } 2335 mPendingProcessChanges.toArray(mActiveProcessChanges); 2336 mAvailProcessChanges.addAll(mPendingProcessChanges); 2337 mPendingProcessChanges.clear(); 2338 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2339 } 2340 int i = mProcessObservers.beginBroadcast(); 2341 while (i > 0) { 2342 i--; 2343 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2344 if (observer != null) { 2345 try { 2346 for (int j=0; j<N; j++) { 2347 ProcessChangeItem item = mActiveProcessChanges[j]; 2348 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2349 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2350 + item.pid + " uid=" + item.uid + ": " 2351 + item.foregroundActivities); 2352 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2353 item.foregroundActivities); 2354 } 2355 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2356 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2357 + item.pid + " uid=" + item.uid + ": " + item.importance); 2358 observer.onImportanceChanged(item.pid, item.uid, 2359 item.importance); 2360 } 2361 } 2362 } catch (RemoteException e) { 2363 } 2364 } 2365 } 2366 mProcessObservers.finishBroadcast(); 2367 } 2368 2369 private void dispatchProcessDied(int pid, int uid) { 2370 int i = mProcessObservers.beginBroadcast(); 2371 while (i > 0) { 2372 i--; 2373 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2374 if (observer != null) { 2375 try { 2376 observer.onProcessDied(pid, uid); 2377 } catch (RemoteException e) { 2378 } 2379 } 2380 } 2381 mProcessObservers.finishBroadcast(); 2382 } 2383 2384 final void doPendingActivityLaunchesLocked(boolean doResume) { 2385 final int N = mPendingActivityLaunches.size(); 2386 if (N <= 0) { 2387 return; 2388 } 2389 for (int i=0; i<N; i++) { 2390 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2391 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2392 pal.startFlags, doResume && i == (N-1), null); 2393 } 2394 mPendingActivityLaunches.clear(); 2395 } 2396 2397 public final int startActivity(IApplicationThread caller, 2398 Intent intent, String resolvedType, IBinder resultTo, 2399 String resultWho, int requestCode, int startFlags, 2400 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2401 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2402 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2403 } 2404 2405 public final int startActivityAsUser(IApplicationThread caller, 2406 Intent intent, String resolvedType, IBinder resultTo, 2407 String resultWho, int requestCode, int startFlags, 2408 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2409 enforceNotIsolatedCaller("startActivity"); 2410 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2411 false, true, "startActivity", null); 2412 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2413 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2414 null, null, options, userId); 2415 } 2416 2417 public final WaitResult startActivityAndWait(IApplicationThread caller, 2418 Intent intent, String resolvedType, IBinder resultTo, 2419 String resultWho, int requestCode, int startFlags, String profileFile, 2420 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2421 enforceNotIsolatedCaller("startActivityAndWait"); 2422 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2423 false, true, "startActivityAndWait", null); 2424 WaitResult res = new WaitResult(); 2425 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2426 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2427 res, null, options, UserHandle.getCallingUserId()); 2428 return res; 2429 } 2430 2431 public final int startActivityWithConfig(IApplicationThread caller, 2432 Intent intent, String resolvedType, IBinder resultTo, 2433 String resultWho, int requestCode, int startFlags, Configuration config, 2434 Bundle options, int userId) { 2435 enforceNotIsolatedCaller("startActivityWithConfig"); 2436 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2437 false, true, "startActivityWithConfig", null); 2438 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2439 resultTo, resultWho, requestCode, startFlags, 2440 null, null, null, config, options, userId); 2441 return ret; 2442 } 2443 2444 public int startActivityIntentSender(IApplicationThread caller, 2445 IntentSender intent, Intent fillInIntent, String resolvedType, 2446 IBinder resultTo, String resultWho, int requestCode, 2447 int flagsMask, int flagsValues, Bundle options) { 2448 enforceNotIsolatedCaller("startActivityIntentSender"); 2449 // Refuse possible leaked file descriptors 2450 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2451 throw new IllegalArgumentException("File descriptors passed in Intent"); 2452 } 2453 2454 IIntentSender sender = intent.getTarget(); 2455 if (!(sender instanceof PendingIntentRecord)) { 2456 throw new IllegalArgumentException("Bad PendingIntent object"); 2457 } 2458 2459 PendingIntentRecord pir = (PendingIntentRecord)sender; 2460 2461 synchronized (this) { 2462 // If this is coming from the currently resumed activity, it is 2463 // effectively saying that app switches are allowed at this point. 2464 if (mMainStack.mResumedActivity != null 2465 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2466 Binder.getCallingUid()) { 2467 mAppSwitchesAllowedTime = 0; 2468 } 2469 } 2470 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2471 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2472 return ret; 2473 } 2474 2475 public boolean startNextMatchingActivity(IBinder callingActivity, 2476 Intent intent, Bundle options) { 2477 // Refuse possible leaked file descriptors 2478 if (intent != null && intent.hasFileDescriptors() == true) { 2479 throw new IllegalArgumentException("File descriptors passed in Intent"); 2480 } 2481 2482 synchronized (this) { 2483 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2484 if (r == null) { 2485 ActivityOptions.abort(options); 2486 return false; 2487 } 2488 if (r.app == null || r.app.thread == null) { 2489 // The caller is not running... d'oh! 2490 ActivityOptions.abort(options); 2491 return false; 2492 } 2493 intent = new Intent(intent); 2494 // The caller is not allowed to change the data. 2495 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2496 // And we are resetting to find the next component... 2497 intent.setComponent(null); 2498 2499 ActivityInfo aInfo = null; 2500 try { 2501 List<ResolveInfo> resolves = 2502 AppGlobals.getPackageManager().queryIntentActivities( 2503 intent, r.resolvedType, 2504 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2505 UserHandle.getCallingUserId()); 2506 2507 // Look for the original activity in the list... 2508 final int N = resolves != null ? resolves.size() : 0; 2509 for (int i=0; i<N; i++) { 2510 ResolveInfo rInfo = resolves.get(i); 2511 if (rInfo.activityInfo.packageName.equals(r.packageName) 2512 && rInfo.activityInfo.name.equals(r.info.name)) { 2513 // We found the current one... the next matching is 2514 // after it. 2515 i++; 2516 if (i<N) { 2517 aInfo = resolves.get(i).activityInfo; 2518 } 2519 break; 2520 } 2521 } 2522 } catch (RemoteException e) { 2523 } 2524 2525 if (aInfo == null) { 2526 // Nobody who is next! 2527 ActivityOptions.abort(options); 2528 return false; 2529 } 2530 2531 intent.setComponent(new ComponentName( 2532 aInfo.applicationInfo.packageName, aInfo.name)); 2533 intent.setFlags(intent.getFlags()&~( 2534 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2535 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2536 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2537 Intent.FLAG_ACTIVITY_NEW_TASK)); 2538 2539 // Okay now we need to start the new activity, replacing the 2540 // currently running activity. This is a little tricky because 2541 // we want to start the new one as if the current one is finished, 2542 // but not finish the current one first so that there is no flicker. 2543 // And thus... 2544 final boolean wasFinishing = r.finishing; 2545 r.finishing = true; 2546 2547 // Propagate reply information over to the new activity. 2548 final ActivityRecord resultTo = r.resultTo; 2549 final String resultWho = r.resultWho; 2550 final int requestCode = r.requestCode; 2551 r.resultTo = null; 2552 if (resultTo != null) { 2553 resultTo.removeResultsLocked(r, resultWho, requestCode); 2554 } 2555 2556 final long origId = Binder.clearCallingIdentity(); 2557 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2558 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2559 resultWho, requestCode, -1, r.launchedFromUid, 0, 2560 options, false, null); 2561 Binder.restoreCallingIdentity(origId); 2562 2563 r.finishing = wasFinishing; 2564 if (res != ActivityManager.START_SUCCESS) { 2565 return false; 2566 } 2567 return true; 2568 } 2569 } 2570 2571 final int startActivityInPackage(int uid, 2572 Intent intent, String resolvedType, IBinder resultTo, 2573 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2574 2575 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2576 false, true, "startActivityInPackage", null); 2577 2578 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2579 resultTo, resultWho, requestCode, startFlags, 2580 null, null, null, null, options, userId); 2581 return ret; 2582 } 2583 2584 public final int startActivities(IApplicationThread caller, 2585 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2586 enforceNotIsolatedCaller("startActivities"); 2587 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2588 options, UserHandle.getCallingUserId()); 2589 return ret; 2590 } 2591 2592 final int startActivitiesInPackage(int uid, 2593 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2594 Bundle options, int userId) { 2595 2596 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2597 false, true, "startActivityInPackage", null); 2598 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2599 options, userId); 2600 return ret; 2601 } 2602 2603 final void addRecentTaskLocked(TaskRecord task) { 2604 int N = mRecentTasks.size(); 2605 // Quick case: check if the top-most recent task is the same. 2606 if (N > 0 && mRecentTasks.get(0) == task) { 2607 return; 2608 } 2609 // Remove any existing entries that are the same kind of task. 2610 for (int i=0; i<N; i++) { 2611 TaskRecord tr = mRecentTasks.get(i); 2612 if (task.userId == tr.userId 2613 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2614 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2615 mRecentTasks.remove(i); 2616 i--; 2617 N--; 2618 if (task.intent == null) { 2619 // If the new recent task we are adding is not fully 2620 // specified, then replace it with the existing recent task. 2621 task = tr; 2622 } 2623 } 2624 } 2625 if (N >= MAX_RECENT_TASKS) { 2626 mRecentTasks.remove(N-1); 2627 } 2628 mRecentTasks.add(0, task); 2629 } 2630 2631 public void setRequestedOrientation(IBinder token, 2632 int requestedOrientation) { 2633 synchronized (this) { 2634 ActivityRecord r = mMainStack.isInStackLocked(token); 2635 if (r == null) { 2636 return; 2637 } 2638 final long origId = Binder.clearCallingIdentity(); 2639 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2640 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2641 mConfiguration, 2642 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2643 if (config != null) { 2644 r.frozenBeforeDestroy = true; 2645 if (!updateConfigurationLocked(config, r, false, false)) { 2646 mMainStack.resumeTopActivityLocked(null); 2647 } 2648 } 2649 Binder.restoreCallingIdentity(origId); 2650 } 2651 } 2652 2653 public int getRequestedOrientation(IBinder token) { 2654 synchronized (this) { 2655 ActivityRecord r = mMainStack.isInStackLocked(token); 2656 if (r == null) { 2657 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2658 } 2659 return mWindowManager.getAppOrientation(r.appToken); 2660 } 2661 } 2662 2663 /** 2664 * This is the internal entry point for handling Activity.finish(). 2665 * 2666 * @param token The Binder token referencing the Activity we want to finish. 2667 * @param resultCode Result code, if any, from this Activity. 2668 * @param resultData Result data (Intent), if any, from this Activity. 2669 * 2670 * @return Returns true if the activity successfully finished, or false if it is still running. 2671 */ 2672 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2673 // Refuse possible leaked file descriptors 2674 if (resultData != null && resultData.hasFileDescriptors() == true) { 2675 throw new IllegalArgumentException("File descriptors passed in Intent"); 2676 } 2677 2678 synchronized(this) { 2679 if (mController != null) { 2680 // Find the first activity that is not finishing. 2681 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2682 if (next != null) { 2683 // ask watcher if this is allowed 2684 boolean resumeOK = true; 2685 try { 2686 resumeOK = mController.activityResuming(next.packageName); 2687 } catch (RemoteException e) { 2688 mController = null; 2689 } 2690 2691 if (!resumeOK) { 2692 return false; 2693 } 2694 } 2695 } 2696 final long origId = Binder.clearCallingIdentity(); 2697 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2698 resultData, "app-request", true); 2699 Binder.restoreCallingIdentity(origId); 2700 return res; 2701 } 2702 } 2703 2704 public final void finishHeavyWeightApp() { 2705 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2706 != PackageManager.PERMISSION_GRANTED) { 2707 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2708 + Binder.getCallingPid() 2709 + ", uid=" + Binder.getCallingUid() 2710 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2711 Slog.w(TAG, msg); 2712 throw new SecurityException(msg); 2713 } 2714 2715 synchronized(this) { 2716 if (mHeavyWeightProcess == null) { 2717 return; 2718 } 2719 2720 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2721 mHeavyWeightProcess.activities); 2722 for (int i=0; i<activities.size(); i++) { 2723 ActivityRecord r = activities.get(i); 2724 if (!r.finishing) { 2725 int index = mMainStack.indexOfTokenLocked(r.appToken); 2726 if (index >= 0) { 2727 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2728 null, "finish-heavy", true); 2729 } 2730 } 2731 } 2732 2733 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2734 mHeavyWeightProcess.userId, 0)); 2735 mHeavyWeightProcess = null; 2736 } 2737 } 2738 2739 public void crashApplication(int uid, int initialPid, String packageName, 2740 String message) { 2741 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2742 != PackageManager.PERMISSION_GRANTED) { 2743 String msg = "Permission Denial: crashApplication() from pid=" 2744 + Binder.getCallingPid() 2745 + ", uid=" + Binder.getCallingUid() 2746 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2747 Slog.w(TAG, msg); 2748 throw new SecurityException(msg); 2749 } 2750 2751 synchronized(this) { 2752 ProcessRecord proc = null; 2753 2754 // Figure out which process to kill. We don't trust that initialPid 2755 // still has any relation to current pids, so must scan through the 2756 // list. 2757 synchronized (mPidsSelfLocked) { 2758 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2759 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2760 if (p.uid != uid) { 2761 continue; 2762 } 2763 if (p.pid == initialPid) { 2764 proc = p; 2765 break; 2766 } 2767 for (String str : p.pkgList) { 2768 if (str.equals(packageName)) { 2769 proc = p; 2770 } 2771 } 2772 } 2773 } 2774 2775 if (proc == null) { 2776 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2777 + " initialPid=" + initialPid 2778 + " packageName=" + packageName); 2779 return; 2780 } 2781 2782 if (proc.thread != null) { 2783 if (proc.pid == Process.myPid()) { 2784 Log.w(TAG, "crashApplication: trying to crash self!"); 2785 return; 2786 } 2787 long ident = Binder.clearCallingIdentity(); 2788 try { 2789 proc.thread.scheduleCrash(message); 2790 } catch (RemoteException e) { 2791 } 2792 Binder.restoreCallingIdentity(ident); 2793 } 2794 } 2795 } 2796 2797 public final void finishSubActivity(IBinder token, String resultWho, 2798 int requestCode) { 2799 synchronized(this) { 2800 final long origId = Binder.clearCallingIdentity(); 2801 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2802 Binder.restoreCallingIdentity(origId); 2803 } 2804 } 2805 2806 public boolean finishActivityAffinity(IBinder token) { 2807 synchronized(this) { 2808 final long origId = Binder.clearCallingIdentity(); 2809 boolean res = mMainStack.finishActivityAffinityLocked(token); 2810 Binder.restoreCallingIdentity(origId); 2811 return res; 2812 } 2813 } 2814 2815 public boolean willActivityBeVisible(IBinder token) { 2816 synchronized(this) { 2817 int i; 2818 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2819 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2820 if (r.appToken == token) { 2821 return true; 2822 } 2823 if (r.fullscreen && !r.finishing) { 2824 return false; 2825 } 2826 } 2827 return true; 2828 } 2829 } 2830 2831 public void overridePendingTransition(IBinder token, String packageName, 2832 int enterAnim, int exitAnim) { 2833 synchronized(this) { 2834 ActivityRecord self = mMainStack.isInStackLocked(token); 2835 if (self == null) { 2836 return; 2837 } 2838 2839 final long origId = Binder.clearCallingIdentity(); 2840 2841 if (self.state == ActivityState.RESUMED 2842 || self.state == ActivityState.PAUSING) { 2843 mWindowManager.overridePendingAppTransition(packageName, 2844 enterAnim, exitAnim, null); 2845 } 2846 2847 Binder.restoreCallingIdentity(origId); 2848 } 2849 } 2850 2851 /** 2852 * Main function for removing an existing process from the activity manager 2853 * as a result of that process going away. Clears out all connections 2854 * to the process. 2855 */ 2856 private final void handleAppDiedLocked(ProcessRecord app, 2857 boolean restarting, boolean allowRestart) { 2858 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2859 if (!restarting) { 2860 mLruProcesses.remove(app); 2861 } 2862 2863 if (mProfileProc == app) { 2864 clearProfilerLocked(); 2865 } 2866 2867 // Just in case... 2868 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2869 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2870 mMainStack.mPausingActivity = null; 2871 } 2872 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2873 mMainStack.mLastPausedActivity = null; 2874 } 2875 2876 // Remove this application's activities from active lists. 2877 mMainStack.removeHistoryRecordsForAppLocked(app); 2878 2879 boolean atTop = true; 2880 boolean hasVisibleActivities = false; 2881 2882 // Clean out the history list. 2883 int i = mMainStack.mHistory.size(); 2884 if (localLOGV) Slog.v( 2885 TAG, "Removing app " + app + " from history with " + i + " entries"); 2886 while (i > 0) { 2887 i--; 2888 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2889 if (localLOGV) Slog.v( 2890 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2891 if (r.app == app) { 2892 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2893 if (ActivityStack.DEBUG_ADD_REMOVE) { 2894 RuntimeException here = new RuntimeException("here"); 2895 here.fillInStackTrace(); 2896 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2897 + ": haveState=" + r.haveState 2898 + " stateNotNeeded=" + r.stateNotNeeded 2899 + " finishing=" + r.finishing 2900 + " state=" + r.state, here); 2901 } 2902 if (!r.finishing) { 2903 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2904 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2905 System.identityHashCode(r), 2906 r.task.taskId, r.shortComponentName, 2907 "proc died without state saved"); 2908 } 2909 mMainStack.removeActivityFromHistoryLocked(r); 2910 2911 } else { 2912 // We have the current state for this activity, so 2913 // it can be restarted later when needed. 2914 if (localLOGV) Slog.v( 2915 TAG, "Keeping entry, setting app to null"); 2916 if (r.visible) { 2917 hasVisibleActivities = true; 2918 } 2919 r.app = null; 2920 r.nowVisible = false; 2921 if (!r.haveState) { 2922 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2923 "App died, clearing saved state of " + r); 2924 r.icicle = null; 2925 } 2926 } 2927 2928 r.stack.cleanUpActivityLocked(r, true, true); 2929 } 2930 atTop = false; 2931 } 2932 2933 app.activities.clear(); 2934 2935 if (app.instrumentationClass != null) { 2936 Slog.w(TAG, "Crash of app " + app.processName 2937 + " running instrumentation " + app.instrumentationClass); 2938 Bundle info = new Bundle(); 2939 info.putString("shortMsg", "Process crashed."); 2940 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2941 } 2942 2943 if (!restarting) { 2944 if (!mMainStack.resumeTopActivityLocked(null)) { 2945 // If there was nothing to resume, and we are not already 2946 // restarting this process, but there is a visible activity that 2947 // is hosted by the process... then make sure all visible 2948 // activities are running, taking care of restarting this 2949 // process. 2950 if (hasVisibleActivities) { 2951 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2952 } 2953 } 2954 } 2955 } 2956 2957 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2958 IBinder threadBinder = thread.asBinder(); 2959 // Find the application record. 2960 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2961 ProcessRecord rec = mLruProcesses.get(i); 2962 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2963 return i; 2964 } 2965 } 2966 return -1; 2967 } 2968 2969 final ProcessRecord getRecordForAppLocked( 2970 IApplicationThread thread) { 2971 if (thread == null) { 2972 return null; 2973 } 2974 2975 int appIndex = getLRURecordIndexForAppLocked(thread); 2976 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2977 } 2978 2979 final void appDiedLocked(ProcessRecord app, int pid, 2980 IApplicationThread thread) { 2981 2982 mProcDeaths[0]++; 2983 2984 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2985 synchronized (stats) { 2986 stats.noteProcessDiedLocked(app.info.uid, pid); 2987 } 2988 2989 // Clean up already done if the process has been re-started. 2990 if (app.pid == pid && app.thread != null && 2991 app.thread.asBinder() == thread.asBinder()) { 2992 if (!app.killedBackground) { 2993 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2994 + ") has died."); 2995 } 2996 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2997 if (localLOGV) Slog.v( 2998 TAG, "Dying app: " + app + ", pid: " + pid 2999 + ", thread: " + thread.asBinder()); 3000 boolean doLowMem = app.instrumentationClass == null; 3001 handleAppDiedLocked(app, false, true); 3002 3003 if (doLowMem) { 3004 // If there are no longer any background processes running, 3005 // and the app that died was not running instrumentation, 3006 // then tell everyone we are now low on memory. 3007 boolean haveBg = false; 3008 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3009 ProcessRecord rec = mLruProcesses.get(i); 3010 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3011 haveBg = true; 3012 break; 3013 } 3014 } 3015 3016 if (!haveBg) { 3017 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3018 long now = SystemClock.uptimeMillis(); 3019 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3020 ProcessRecord rec = mLruProcesses.get(i); 3021 if (rec != app && rec.thread != null && 3022 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3023 // The low memory report is overriding any current 3024 // state for a GC request. Make sure to do 3025 // heavy/important/visible/foreground processes first. 3026 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3027 rec.lastRequestedGc = 0; 3028 } else { 3029 rec.lastRequestedGc = rec.lastLowMemory; 3030 } 3031 rec.reportLowMemory = true; 3032 rec.lastLowMemory = now; 3033 mProcessesToGc.remove(rec); 3034 addProcessToGcListLocked(rec); 3035 } 3036 } 3037 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3038 scheduleAppGcsLocked(); 3039 } 3040 } 3041 } else if (app.pid != pid) { 3042 // A new process has already been started. 3043 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3044 + ") has died and restarted (pid " + app.pid + ")."); 3045 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3046 } else if (DEBUG_PROCESSES) { 3047 Slog.d(TAG, "Received spurious death notification for thread " 3048 + thread.asBinder()); 3049 } 3050 } 3051 3052 /** 3053 * If a stack trace dump file is configured, dump process stack traces. 3054 * @param clearTraces causes the dump file to be erased prior to the new 3055 * traces being written, if true; when false, the new traces will be 3056 * appended to any existing file content. 3057 * @param firstPids of dalvik VM processes to dump stack traces for first 3058 * @param lastPids of dalvik VM processes to dump stack traces for last 3059 * @param nativeProcs optional list of native process names to dump stack crawls 3060 * @return file containing stack traces, or null if no dump file is configured 3061 */ 3062 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3063 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3064 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3065 if (tracesPath == null || tracesPath.length() == 0) { 3066 return null; 3067 } 3068 3069 File tracesFile = new File(tracesPath); 3070 try { 3071 File tracesDir = tracesFile.getParentFile(); 3072 if (!tracesDir.exists()) { 3073 tracesFile.mkdirs(); 3074 if (!SELinux.restorecon(tracesDir)) { 3075 return null; 3076 } 3077 } 3078 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3079 3080 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3081 tracesFile.createNewFile(); 3082 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3083 } catch (IOException e) { 3084 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3085 return null; 3086 } 3087 3088 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3089 return tracesFile; 3090 } 3091 3092 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3093 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3094 // Use a FileObserver to detect when traces finish writing. 3095 // The order of traces is considered important to maintain for legibility. 3096 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3097 public synchronized void onEvent(int event, String path) { notify(); } 3098 }; 3099 3100 try { 3101 observer.startWatching(); 3102 3103 // First collect all of the stacks of the most important pids. 3104 if (firstPids != null) { 3105 try { 3106 int num = firstPids.size(); 3107 for (int i = 0; i < num; i++) { 3108 synchronized (observer) { 3109 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3110 observer.wait(200); // Wait for write-close, give up after 200msec 3111 } 3112 } 3113 } catch (InterruptedException e) { 3114 Log.wtf(TAG, e); 3115 } 3116 } 3117 3118 // Next measure CPU usage. 3119 if (processStats != null) { 3120 processStats.init(); 3121 System.gc(); 3122 processStats.update(); 3123 try { 3124 synchronized (processStats) { 3125 processStats.wait(500); // measure over 1/2 second. 3126 } 3127 } catch (InterruptedException e) { 3128 } 3129 processStats.update(); 3130 3131 // We'll take the stack crawls of just the top apps using CPU. 3132 final int N = processStats.countWorkingStats(); 3133 int numProcs = 0; 3134 for (int i=0; i<N && numProcs<5; i++) { 3135 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3136 if (lastPids.indexOfKey(stats.pid) >= 0) { 3137 numProcs++; 3138 try { 3139 synchronized (observer) { 3140 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3141 observer.wait(200); // Wait for write-close, give up after 200msec 3142 } 3143 } catch (InterruptedException e) { 3144 Log.wtf(TAG, e); 3145 } 3146 3147 } 3148 } 3149 } 3150 3151 } finally { 3152 observer.stopWatching(); 3153 } 3154 3155 if (nativeProcs != null) { 3156 int[] pids = Process.getPidsForCommands(nativeProcs); 3157 if (pids != null) { 3158 for (int pid : pids) { 3159 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3160 } 3161 } 3162 } 3163 } 3164 3165 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3166 if (true || IS_USER_BUILD) { 3167 return; 3168 } 3169 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3170 if (tracesPath == null || tracesPath.length() == 0) { 3171 return; 3172 } 3173 3174 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3175 StrictMode.allowThreadDiskWrites(); 3176 try { 3177 final File tracesFile = new File(tracesPath); 3178 final File tracesDir = tracesFile.getParentFile(); 3179 final File tracesTmp = new File(tracesDir, "__tmp__"); 3180 try { 3181 if (!tracesDir.exists()) { 3182 tracesFile.mkdirs(); 3183 if (!SELinux.restorecon(tracesDir.getPath())) { 3184 return; 3185 } 3186 } 3187 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3188 3189 if (tracesFile.exists()) { 3190 tracesTmp.delete(); 3191 tracesFile.renameTo(tracesTmp); 3192 } 3193 StringBuilder sb = new StringBuilder(); 3194 Time tobj = new Time(); 3195 tobj.set(System.currentTimeMillis()); 3196 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3197 sb.append(": "); 3198 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3199 sb.append(" since "); 3200 sb.append(msg); 3201 FileOutputStream fos = new FileOutputStream(tracesFile); 3202 fos.write(sb.toString().getBytes()); 3203 if (app == null) { 3204 fos.write("\n*** No application process!".getBytes()); 3205 } 3206 fos.close(); 3207 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3208 } catch (IOException e) { 3209 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3210 return; 3211 } 3212 3213 if (app != null) { 3214 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3215 firstPids.add(app.pid); 3216 dumpStackTraces(tracesPath, firstPids, null, null, null); 3217 } 3218 3219 File lastTracesFile = null; 3220 File curTracesFile = null; 3221 for (int i=9; i>=0; i--) { 3222 String name = String.format("slow%02d.txt", i); 3223 curTracesFile = new File(tracesDir, name); 3224 if (curTracesFile.exists()) { 3225 if (lastTracesFile != null) { 3226 curTracesFile.renameTo(lastTracesFile); 3227 } else { 3228 curTracesFile.delete(); 3229 } 3230 } 3231 lastTracesFile = curTracesFile; 3232 } 3233 tracesFile.renameTo(curTracesFile); 3234 if (tracesTmp.exists()) { 3235 tracesTmp.renameTo(tracesFile); 3236 } 3237 } finally { 3238 StrictMode.setThreadPolicy(oldPolicy); 3239 } 3240 } 3241 3242 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3243 ActivityRecord parent, final String annotation) { 3244 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3245 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3246 3247 if (mController != null) { 3248 try { 3249 // 0 == continue, -1 = kill process immediately 3250 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3251 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3252 } catch (RemoteException e) { 3253 mController = null; 3254 } 3255 } 3256 3257 long anrTime = SystemClock.uptimeMillis(); 3258 if (MONITOR_CPU_USAGE) { 3259 updateCpuStatsNow(); 3260 } 3261 3262 synchronized (this) { 3263 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3264 if (mShuttingDown) { 3265 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3266 return; 3267 } else if (app.notResponding) { 3268 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3269 return; 3270 } else if (app.crashing) { 3271 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3272 return; 3273 } 3274 3275 // In case we come through here for the same app before completing 3276 // this one, mark as anring now so we will bail out. 3277 app.notResponding = true; 3278 3279 // Log the ANR to the event log. 3280 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3281 annotation); 3282 3283 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3284 firstPids.add(app.pid); 3285 3286 int parentPid = app.pid; 3287 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3288 if (parentPid != app.pid) firstPids.add(parentPid); 3289 3290 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3291 3292 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3293 ProcessRecord r = mLruProcesses.get(i); 3294 if (r != null && r.thread != null) { 3295 int pid = r.pid; 3296 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3297 if (r.persistent) { 3298 firstPids.add(pid); 3299 } else { 3300 lastPids.put(pid, Boolean.TRUE); 3301 } 3302 } 3303 } 3304 } 3305 } 3306 3307 // Log the ANR to the main log. 3308 StringBuilder info = new StringBuilder(); 3309 info.setLength(0); 3310 info.append("ANR in ").append(app.processName); 3311 if (activity != null && activity.shortComponentName != null) { 3312 info.append(" (").append(activity.shortComponentName).append(")"); 3313 } 3314 info.append("\n"); 3315 if (annotation != null) { 3316 info.append("Reason: ").append(annotation).append("\n"); 3317 } 3318 if (parent != null && parent != activity) { 3319 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3320 } 3321 3322 final ProcessStats processStats = new ProcessStats(true); 3323 3324 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3325 3326 String cpuInfo = null; 3327 if (MONITOR_CPU_USAGE) { 3328 updateCpuStatsNow(); 3329 synchronized (mProcessStatsThread) { 3330 cpuInfo = mProcessStats.printCurrentState(anrTime); 3331 } 3332 info.append(processStats.printCurrentLoad()); 3333 info.append(cpuInfo); 3334 } 3335 3336 info.append(processStats.printCurrentState(anrTime)); 3337 3338 Slog.e(TAG, info.toString()); 3339 if (tracesFile == null) { 3340 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3341 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3342 } 3343 3344 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3345 cpuInfo, tracesFile, null); 3346 3347 if (mController != null) { 3348 try { 3349 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3350 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3351 if (res != 0) { 3352 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3353 return; 3354 } 3355 } catch (RemoteException e) { 3356 mController = null; 3357 } 3358 } 3359 3360 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3361 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3362 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3363 3364 synchronized (this) { 3365 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3366 Slog.w(TAG, "Killing " + app + ": background ANR"); 3367 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3368 app.processName, app.setAdj, "background ANR"); 3369 Process.killProcessQuiet(app.pid); 3370 return; 3371 } 3372 3373 // Set the app's notResponding state, and look up the errorReportReceiver 3374 makeAppNotRespondingLocked(app, 3375 activity != null ? activity.shortComponentName : null, 3376 annotation != null ? "ANR " + annotation : "ANR", 3377 info.toString()); 3378 3379 // Bring up the infamous App Not Responding dialog 3380 Message msg = Message.obtain(); 3381 HashMap map = new HashMap(); 3382 msg.what = SHOW_NOT_RESPONDING_MSG; 3383 msg.obj = map; 3384 map.put("app", app); 3385 if (activity != null) { 3386 map.put("activity", activity); 3387 } 3388 3389 mHandler.sendMessage(msg); 3390 } 3391 } 3392 3393 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3394 if (!mLaunchWarningShown) { 3395 mLaunchWarningShown = true; 3396 mHandler.post(new Runnable() { 3397 @Override 3398 public void run() { 3399 synchronized (ActivityManagerService.this) { 3400 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3401 d.show(); 3402 mHandler.postDelayed(new Runnable() { 3403 @Override 3404 public void run() { 3405 synchronized (ActivityManagerService.this) { 3406 d.dismiss(); 3407 mLaunchWarningShown = false; 3408 } 3409 } 3410 }, 4000); 3411 } 3412 } 3413 }); 3414 } 3415 } 3416 3417 public boolean clearApplicationUserData(final String packageName, 3418 final IPackageDataObserver observer, int userId) { 3419 enforceNotIsolatedCaller("clearApplicationUserData"); 3420 int uid = Binder.getCallingUid(); 3421 int pid = Binder.getCallingPid(); 3422 userId = handleIncomingUserLocked(pid, uid, 3423 userId, false, true, "clearApplicationUserData", null); 3424 long callingId = Binder.clearCallingIdentity(); 3425 try { 3426 IPackageManager pm = AppGlobals.getPackageManager(); 3427 int pkgUid = -1; 3428 synchronized(this) { 3429 try { 3430 pkgUid = pm.getPackageUid(packageName, userId); 3431 } catch (RemoteException e) { 3432 } 3433 if (pkgUid == -1) { 3434 Slog.w(TAG, "Invalid packageName:" + packageName); 3435 return false; 3436 } 3437 if (uid == pkgUid || checkComponentPermission( 3438 android.Manifest.permission.CLEAR_APP_USER_DATA, 3439 pid, uid, -1, true) 3440 == PackageManager.PERMISSION_GRANTED) { 3441 forceStopPackageLocked(packageName, pkgUid); 3442 } else { 3443 throw new SecurityException(pid+" does not have permission:"+ 3444 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3445 "for process:"+packageName); 3446 } 3447 } 3448 3449 try { 3450 //clear application user data 3451 pm.clearApplicationUserData(packageName, observer, userId); 3452 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3453 Uri.fromParts("package", packageName, null)); 3454 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3455 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3456 null, null, 0, null, null, null, false, false, userId); 3457 } catch (RemoteException e) { 3458 } 3459 } finally { 3460 Binder.restoreCallingIdentity(callingId); 3461 } 3462 return true; 3463 } 3464 3465 public void killBackgroundProcesses(final String packageName, int userId) { 3466 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3467 != PackageManager.PERMISSION_GRANTED && 3468 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3469 != PackageManager.PERMISSION_GRANTED) { 3470 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3471 + Binder.getCallingPid() 3472 + ", uid=" + Binder.getCallingUid() 3473 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3474 Slog.w(TAG, msg); 3475 throw new SecurityException(msg); 3476 } 3477 3478 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3479 userId, true, true, "killBackgroundProcesses", null); 3480 long callingId = Binder.clearCallingIdentity(); 3481 try { 3482 IPackageManager pm = AppGlobals.getPackageManager(); 3483 synchronized(this) { 3484 int appId = -1; 3485 try { 3486 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3487 } catch (RemoteException e) { 3488 } 3489 if (appId == -1) { 3490 Slog.w(TAG, "Invalid packageName: " + packageName); 3491 return; 3492 } 3493 killPackageProcessesLocked(packageName, appId, userId, 3494 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3495 } 3496 } finally { 3497 Binder.restoreCallingIdentity(callingId); 3498 } 3499 } 3500 3501 public void killAllBackgroundProcesses() { 3502 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3503 != PackageManager.PERMISSION_GRANTED) { 3504 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3505 + Binder.getCallingPid() 3506 + ", uid=" + Binder.getCallingUid() 3507 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3508 Slog.w(TAG, msg); 3509 throw new SecurityException(msg); 3510 } 3511 3512 long callingId = Binder.clearCallingIdentity(); 3513 try { 3514 synchronized(this) { 3515 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3516 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3517 final int NA = apps.size(); 3518 for (int ia=0; ia<NA; ia++) { 3519 ProcessRecord app = apps.valueAt(ia); 3520 if (app.persistent) { 3521 // we don't kill persistent processes 3522 continue; 3523 } 3524 if (app.removed) { 3525 procs.add(app); 3526 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3527 app.removed = true; 3528 procs.add(app); 3529 } 3530 } 3531 } 3532 3533 int N = procs.size(); 3534 for (int i=0; i<N; i++) { 3535 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3536 } 3537 } 3538 } finally { 3539 Binder.restoreCallingIdentity(callingId); 3540 } 3541 } 3542 3543 public void forceStopPackage(final String packageName, int userId) { 3544 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3545 != PackageManager.PERMISSION_GRANTED) { 3546 String msg = "Permission Denial: forceStopPackage() from pid=" 3547 + Binder.getCallingPid() 3548 + ", uid=" + Binder.getCallingUid() 3549 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3550 Slog.w(TAG, msg); 3551 throw new SecurityException(msg); 3552 } 3553 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3554 userId, true, true, "forceStopPackage", null); 3555 long callingId = Binder.clearCallingIdentity(); 3556 try { 3557 IPackageManager pm = AppGlobals.getPackageManager(); 3558 synchronized(this) { 3559 int[] users = userId == UserHandle.USER_ALL 3560 ? getUsersLocked() : new int[] { userId }; 3561 for (int user : users) { 3562 int pkgUid = -1; 3563 try { 3564 pkgUid = pm.getPackageUid(packageName, user); 3565 } catch (RemoteException e) { 3566 } 3567 if (pkgUid == -1) { 3568 Slog.w(TAG, "Invalid packageName: " + packageName); 3569 continue; 3570 } 3571 try { 3572 pm.setPackageStoppedState(packageName, true, user); 3573 } catch (RemoteException e) { 3574 } catch (IllegalArgumentException e) { 3575 Slog.w(TAG, "Failed trying to unstop package " 3576 + packageName + ": " + e); 3577 } 3578 if (isUserRunningLocked(user)) { 3579 forceStopPackageLocked(packageName, pkgUid); 3580 } 3581 } 3582 } 3583 } finally { 3584 Binder.restoreCallingIdentity(callingId); 3585 } 3586 } 3587 3588 /* 3589 * The pkg name and app id have to be specified. 3590 */ 3591 public void killApplicationWithAppId(String pkg, int appid) { 3592 if (pkg == null) { 3593 return; 3594 } 3595 // Make sure the uid is valid. 3596 if (appid < 0) { 3597 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3598 return; 3599 } 3600 int callerUid = Binder.getCallingUid(); 3601 // Only the system server can kill an application 3602 if (callerUid == Process.SYSTEM_UID) { 3603 // Post an aysnc message to kill the application 3604 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3605 msg.arg1 = appid; 3606 msg.arg2 = 0; 3607 msg.obj = pkg; 3608 mHandler.sendMessage(msg); 3609 } else { 3610 throw new SecurityException(callerUid + " cannot kill pkg: " + 3611 pkg); 3612 } 3613 } 3614 3615 public void closeSystemDialogs(String reason) { 3616 enforceNotIsolatedCaller("closeSystemDialogs"); 3617 3618 final int pid = Binder.getCallingPid(); 3619 final int uid = Binder.getCallingUid(); 3620 final long origId = Binder.clearCallingIdentity(); 3621 try { 3622 synchronized (this) { 3623 // Only allow this from foreground processes, so that background 3624 // applications can't abuse it to prevent system UI from being shown. 3625 if (uid >= Process.FIRST_APPLICATION_UID) { 3626 ProcessRecord proc; 3627 synchronized (mPidsSelfLocked) { 3628 proc = mPidsSelfLocked.get(pid); 3629 } 3630 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3631 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3632 + " from background process " + proc); 3633 return; 3634 } 3635 } 3636 closeSystemDialogsLocked(reason); 3637 } 3638 } finally { 3639 Binder.restoreCallingIdentity(origId); 3640 } 3641 } 3642 3643 void closeSystemDialogsLocked(String reason) { 3644 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3645 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3646 if (reason != null) { 3647 intent.putExtra("reason", reason); 3648 } 3649 mWindowManager.closeSystemDialogs(reason); 3650 3651 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3652 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3653 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3654 r.stack.finishActivityLocked(r, i, 3655 Activity.RESULT_CANCELED, null, "close-sys", true); 3656 } 3657 } 3658 3659 broadcastIntentLocked(null, null, intent, null, 3660 null, 0, null, null, null, false, false, -1, 3661 Process.SYSTEM_UID, UserHandle.USER_ALL); 3662 } 3663 3664 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3665 throws RemoteException { 3666 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3667 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3668 for (int i=pids.length-1; i>=0; i--) { 3669 infos[i] = new Debug.MemoryInfo(); 3670 Debug.getMemoryInfo(pids[i], infos[i]); 3671 } 3672 return infos; 3673 } 3674 3675 public long[] getProcessPss(int[] pids) throws RemoteException { 3676 enforceNotIsolatedCaller("getProcessPss"); 3677 long[] pss = new long[pids.length]; 3678 for (int i=pids.length-1; i>=0; i--) { 3679 pss[i] = Debug.getPss(pids[i]); 3680 } 3681 return pss; 3682 } 3683 3684 public void killApplicationProcess(String processName, int uid) { 3685 if (processName == null) { 3686 return; 3687 } 3688 3689 int callerUid = Binder.getCallingUid(); 3690 // Only the system server can kill an application 3691 if (callerUid == Process.SYSTEM_UID) { 3692 synchronized (this) { 3693 ProcessRecord app = getProcessRecordLocked(processName, uid); 3694 if (app != null && app.thread != null) { 3695 try { 3696 app.thread.scheduleSuicide(); 3697 } catch (RemoteException e) { 3698 // If the other end already died, then our work here is done. 3699 } 3700 } else { 3701 Slog.w(TAG, "Process/uid not found attempting kill of " 3702 + processName + " / " + uid); 3703 } 3704 } 3705 } else { 3706 throw new SecurityException(callerUid + " cannot kill app process: " + 3707 processName); 3708 } 3709 } 3710 3711 private void forceStopPackageLocked(final String packageName, int uid) { 3712 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3713 false, true, false, UserHandle.getUserId(uid)); 3714 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3715 Uri.fromParts("package", packageName, null)); 3716 if (!mProcessesReady) { 3717 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3718 } 3719 intent.putExtra(Intent.EXTRA_UID, uid); 3720 broadcastIntentLocked(null, null, intent, 3721 null, null, 0, null, null, null, 3722 false, false, 3723 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3724 } 3725 3726 private void forceStopUserLocked(int userId) { 3727 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3728 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3729 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3730 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3731 broadcastIntentLocked(null, null, intent, 3732 null, null, 0, null, null, null, 3733 false, false, 3734 MY_PID, Process.SYSTEM_UID, userId); 3735 } 3736 3737 private final boolean killPackageProcessesLocked(String packageName, int appId, 3738 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3739 boolean doit, boolean evenPersistent, String reason) { 3740 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3741 3742 // Remove all processes this package may have touched: all with the 3743 // same UID (except for the system or root user), and all whose name 3744 // matches the package name. 3745 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3746 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3747 final int NA = apps.size(); 3748 for (int ia=0; ia<NA; ia++) { 3749 ProcessRecord app = apps.valueAt(ia); 3750 if (app.persistent && !evenPersistent) { 3751 // we don't kill persistent processes 3752 continue; 3753 } 3754 if (app.removed) { 3755 if (doit) { 3756 procs.add(app); 3757 } 3758 continue; 3759 } 3760 3761 // Skip process if it doesn't meet our oom adj requirement. 3762 if (app.setAdj < minOomAdj) { 3763 continue; 3764 } 3765 3766 // If no package is specified, we call all processes under the 3767 // give user id. 3768 if (packageName == null) { 3769 if (app.userId != userId) { 3770 continue; 3771 } 3772 // Package has been specified, we want to hit all processes 3773 // that match it. We need to qualify this by the processes 3774 // that are running under the specified app and user ID. 3775 } else { 3776 if (UserHandle.getAppId(app.uid) != appId) { 3777 continue; 3778 } 3779 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3780 continue; 3781 } 3782 if (!app.pkgList.contains(packageName)) { 3783 continue; 3784 } 3785 } 3786 3787 // Process has passed all conditions, kill it! 3788 if (!doit) { 3789 return true; 3790 } 3791 app.removed = true; 3792 procs.add(app); 3793 } 3794 } 3795 3796 int N = procs.size(); 3797 for (int i=0; i<N; i++) { 3798 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3799 } 3800 return N > 0; 3801 } 3802 3803 private final boolean forceStopPackageLocked(String name, int appId, 3804 boolean callerWillRestart, boolean purgeCache, boolean doit, 3805 boolean evenPersistent, int userId) { 3806 int i; 3807 int N; 3808 3809 if (userId == UserHandle.USER_ALL && name == null) { 3810 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3811 } 3812 3813 if (appId < 0 && name != null) { 3814 try { 3815 appId = UserHandle.getAppId( 3816 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3817 } catch (RemoteException e) { 3818 } 3819 } 3820 3821 if (doit) { 3822 if (name != null) { 3823 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3824 + " user=" + userId); 3825 } else { 3826 Slog.i(TAG, "Force stopping user " + userId); 3827 } 3828 3829 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3830 while (badApps.hasNext()) { 3831 SparseArray<Long> ba = badApps.next(); 3832 for (i=ba.size()-1; i>=0; i--) { 3833 boolean remove = false; 3834 final int entUid = ba.keyAt(i); 3835 if (name != null) { 3836 if (userId == UserHandle.USER_ALL) { 3837 if (UserHandle.getAppId(entUid) == appId) { 3838 remove = true; 3839 } 3840 } else { 3841 if (entUid == UserHandle.getUid(userId, appId)) { 3842 remove = true; 3843 } 3844 } 3845 } else if (UserHandle.getUserId(entUid) == userId) { 3846 remove = true; 3847 } 3848 if (remove) { 3849 ba.removeAt(i); 3850 } 3851 } 3852 if (ba.size() == 0) { 3853 badApps.remove(); 3854 } 3855 } 3856 } 3857 3858 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3859 -100, callerWillRestart, false, doit, evenPersistent, 3860 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3861 3862 TaskRecord lastTask = null; 3863 for (i=0; i<mMainStack.mHistory.size(); i++) { 3864 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3865 final boolean samePackage = r.packageName.equals(name) 3866 || (name == null && r.userId == userId); 3867 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3868 && (samePackage || r.task == lastTask) 3869 && (r.app == null || evenPersistent || !r.app.persistent)) { 3870 if (!doit) { 3871 if (r.finishing) { 3872 // If this activity is just finishing, then it is not 3873 // interesting as far as something to stop. 3874 continue; 3875 } 3876 return true; 3877 } 3878 didSomething = true; 3879 Slog.i(TAG, " Force finishing activity " + r); 3880 if (samePackage) { 3881 if (r.app != null) { 3882 r.app.removed = true; 3883 } 3884 r.app = null; 3885 } 3886 lastTask = r.task; 3887 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3888 null, "force-stop", true)) { 3889 i--; 3890 } 3891 } 3892 } 3893 3894 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3895 if (!doit) { 3896 return true; 3897 } 3898 didSomething = true; 3899 } 3900 3901 if (name == null) { 3902 // Remove all sticky broadcasts from this user. 3903 mStickyBroadcasts.remove(userId); 3904 } 3905 3906 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3907 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3908 userId, providers)) { 3909 if (!doit) { 3910 return true; 3911 } 3912 didSomething = true; 3913 } 3914 N = providers.size(); 3915 for (i=0; i<N; i++) { 3916 removeDyingProviderLocked(null, providers.get(i), true); 3917 } 3918 3919 if (mIntentSenderRecords.size() > 0) { 3920 Iterator<WeakReference<PendingIntentRecord>> it 3921 = mIntentSenderRecords.values().iterator(); 3922 while (it.hasNext()) { 3923 WeakReference<PendingIntentRecord> wpir = it.next(); 3924 if (wpir == null) { 3925 it.remove(); 3926 continue; 3927 } 3928 PendingIntentRecord pir = wpir.get(); 3929 if (pir == null) { 3930 it.remove(); 3931 continue; 3932 } 3933 if (name == null) { 3934 // Stopping user, remove all objects for the user. 3935 if (pir.key.userId != userId) { 3936 // Not the same user, skip it. 3937 continue; 3938 } 3939 } else { 3940 if (UserHandle.getAppId(pir.uid) != appId) { 3941 // Different app id, skip it. 3942 continue; 3943 } 3944 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3945 // Different user, skip it. 3946 continue; 3947 } 3948 if (!pir.key.packageName.equals(name)) { 3949 // Different package, skip it. 3950 continue; 3951 } 3952 } 3953 if (!doit) { 3954 return true; 3955 } 3956 didSomething = true; 3957 it.remove(); 3958 pir.canceled = true; 3959 if (pir.key.activity != null) { 3960 pir.key.activity.pendingResults.remove(pir.ref); 3961 } 3962 } 3963 } 3964 3965 if (doit) { 3966 if (purgeCache && name != null) { 3967 AttributeCache ac = AttributeCache.instance(); 3968 if (ac != null) { 3969 ac.removePackage(name); 3970 } 3971 } 3972 if (mBooted) { 3973 mMainStack.resumeTopActivityLocked(null); 3974 mMainStack.scheduleIdleLocked(); 3975 } 3976 } 3977 3978 return didSomething; 3979 } 3980 3981 private final boolean removeProcessLocked(ProcessRecord app, 3982 boolean callerWillRestart, boolean allowRestart, String reason) { 3983 final String name = app.processName; 3984 final int uid = app.uid; 3985 if (DEBUG_PROCESSES) Slog.d( 3986 TAG, "Force removing proc " + app.toShortString() + " (" + name 3987 + "/" + uid + ")"); 3988 3989 mProcessNames.remove(name, uid); 3990 mIsolatedProcesses.remove(app.uid); 3991 if (mHeavyWeightProcess == app) { 3992 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3993 mHeavyWeightProcess.userId, 0)); 3994 mHeavyWeightProcess = null; 3995 } 3996 boolean needRestart = false; 3997 if (app.pid > 0 && app.pid != MY_PID) { 3998 int pid = app.pid; 3999 synchronized (mPidsSelfLocked) { 4000 mPidsSelfLocked.remove(pid); 4001 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4002 } 4003 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4004 handleAppDiedLocked(app, true, allowRestart); 4005 mLruProcesses.remove(app); 4006 Process.killProcessQuiet(pid); 4007 4008 if (app.persistent && !app.isolated) { 4009 if (!callerWillRestart) { 4010 addAppLocked(app.info, false); 4011 } else { 4012 needRestart = true; 4013 } 4014 } 4015 } else { 4016 mRemovedProcesses.add(app); 4017 } 4018 4019 return needRestart; 4020 } 4021 4022 private final void processStartTimedOutLocked(ProcessRecord app) { 4023 final int pid = app.pid; 4024 boolean gone = false; 4025 synchronized (mPidsSelfLocked) { 4026 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4027 if (knownApp != null && knownApp.thread == null) { 4028 mPidsSelfLocked.remove(pid); 4029 gone = true; 4030 } 4031 } 4032 4033 if (gone) { 4034 Slog.w(TAG, "Process " + app + " failed to attach"); 4035 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4036 app.processName); 4037 mProcessNames.remove(app.processName, app.uid); 4038 mIsolatedProcesses.remove(app.uid); 4039 if (mHeavyWeightProcess == app) { 4040 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4041 mHeavyWeightProcess.userId, 0)); 4042 mHeavyWeightProcess = null; 4043 } 4044 // Take care of any launching providers waiting for this process. 4045 checkAppInLaunchingProvidersLocked(app, true); 4046 // Take care of any services that are waiting for the process. 4047 mServices.processStartTimedOutLocked(app); 4048 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4049 app.processName, app.setAdj, "start timeout"); 4050 Process.killProcessQuiet(pid); 4051 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4052 Slog.w(TAG, "Unattached app died before backup, skipping"); 4053 try { 4054 IBackupManager bm = IBackupManager.Stub.asInterface( 4055 ServiceManager.getService(Context.BACKUP_SERVICE)); 4056 bm.agentDisconnected(app.info.packageName); 4057 } catch (RemoteException e) { 4058 // Can't happen; the backup manager is local 4059 } 4060 } 4061 if (isPendingBroadcastProcessLocked(pid)) { 4062 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4063 skipPendingBroadcastLocked(pid); 4064 } 4065 } else { 4066 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4067 } 4068 } 4069 4070 private final boolean attachApplicationLocked(IApplicationThread thread, 4071 int pid) { 4072 4073 // Find the application record that is being attached... either via 4074 // the pid if we are running in multiple processes, or just pull the 4075 // next app record if we are emulating process with anonymous threads. 4076 ProcessRecord app; 4077 if (pid != MY_PID && pid >= 0) { 4078 synchronized (mPidsSelfLocked) { 4079 app = mPidsSelfLocked.get(pid); 4080 } 4081 } else { 4082 app = null; 4083 } 4084 4085 if (app == null) { 4086 Slog.w(TAG, "No pending application record for pid " + pid 4087 + " (IApplicationThread " + thread + "); dropping process"); 4088 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4089 if (pid > 0 && pid != MY_PID) { 4090 Process.killProcessQuiet(pid); 4091 } else { 4092 try { 4093 thread.scheduleExit(); 4094 } catch (Exception e) { 4095 // Ignore exceptions. 4096 } 4097 } 4098 return false; 4099 } 4100 4101 // If this application record is still attached to a previous 4102 // process, clean it up now. 4103 if (app.thread != null) { 4104 handleAppDiedLocked(app, true, true); 4105 } 4106 4107 // Tell the process all about itself. 4108 4109 if (localLOGV) Slog.v( 4110 TAG, "Binding process pid " + pid + " to record " + app); 4111 4112 String processName = app.processName; 4113 try { 4114 AppDeathRecipient adr = new AppDeathRecipient( 4115 app, pid, thread); 4116 thread.asBinder().linkToDeath(adr, 0); 4117 app.deathRecipient = adr; 4118 } catch (RemoteException e) { 4119 app.resetPackageList(); 4120 startProcessLocked(app, "link fail", processName); 4121 return false; 4122 } 4123 4124 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4125 4126 app.thread = thread; 4127 app.curAdj = app.setAdj = -100; 4128 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4129 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4130 app.forcingToForeground = null; 4131 app.foregroundServices = false; 4132 app.hasShownUi = false; 4133 app.debugging = false; 4134 4135 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4136 4137 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4138 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4139 4140 if (!normalMode) { 4141 Slog.i(TAG, "Launching preboot mode app: " + app); 4142 } 4143 4144 if (localLOGV) Slog.v( 4145 TAG, "New app record " + app 4146 + " thread=" + thread.asBinder() + " pid=" + pid); 4147 try { 4148 int testMode = IApplicationThread.DEBUG_OFF; 4149 if (mDebugApp != null && mDebugApp.equals(processName)) { 4150 testMode = mWaitForDebugger 4151 ? IApplicationThread.DEBUG_WAIT 4152 : IApplicationThread.DEBUG_ON; 4153 app.debugging = true; 4154 if (mDebugTransient) { 4155 mDebugApp = mOrigDebugApp; 4156 mWaitForDebugger = mOrigWaitForDebugger; 4157 } 4158 } 4159 String profileFile = app.instrumentationProfileFile; 4160 ParcelFileDescriptor profileFd = null; 4161 boolean profileAutoStop = false; 4162 if (mProfileApp != null && mProfileApp.equals(processName)) { 4163 mProfileProc = app; 4164 profileFile = mProfileFile; 4165 profileFd = mProfileFd; 4166 profileAutoStop = mAutoStopProfiler; 4167 } 4168 boolean enableOpenGlTrace = false; 4169 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4170 enableOpenGlTrace = true; 4171 mOpenGlTraceApp = null; 4172 } 4173 4174 // If the app is being launched for restore or full backup, set it up specially 4175 boolean isRestrictedBackupMode = false; 4176 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4177 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4178 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4179 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4180 } 4181 4182 ensurePackageDexOpt(app.instrumentationInfo != null 4183 ? app.instrumentationInfo.packageName 4184 : app.info.packageName); 4185 if (app.instrumentationClass != null) { 4186 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4187 } 4188 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4189 + processName + " with config " + mConfiguration); 4190 ApplicationInfo appInfo = app.instrumentationInfo != null 4191 ? app.instrumentationInfo : app.info; 4192 app.compat = compatibilityInfoForPackageLocked(appInfo); 4193 if (profileFd != null) { 4194 profileFd = profileFd.dup(); 4195 } 4196 thread.bindApplication(processName, appInfo, providers, 4197 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4198 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4199 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4200 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4201 mCoreSettingsObserver.getCoreSettingsLocked()); 4202 updateLruProcessLocked(app, false, true); 4203 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4204 } catch (Exception e) { 4205 // todo: Yikes! What should we do? For now we will try to 4206 // start another process, but that could easily get us in 4207 // an infinite loop of restarting processes... 4208 Slog.w(TAG, "Exception thrown during bind!", e); 4209 4210 app.resetPackageList(); 4211 app.unlinkDeathRecipient(); 4212 startProcessLocked(app, "bind fail", processName); 4213 return false; 4214 } 4215 4216 // Remove this record from the list of starting applications. 4217 mPersistentStartingProcesses.remove(app); 4218 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4219 "Attach application locked removing on hold: " + app); 4220 mProcessesOnHold.remove(app); 4221 4222 boolean badApp = false; 4223 boolean didSomething = false; 4224 4225 // See if the top visible activity is waiting to run in this process... 4226 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4227 if (hr != null && normalMode) { 4228 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4229 && processName.equals(hr.processName)) { 4230 try { 4231 if (mHeadless) { 4232 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4233 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4234 didSomething = true; 4235 } 4236 } catch (Exception e) { 4237 Slog.w(TAG, "Exception in new application when starting activity " 4238 + hr.intent.getComponent().flattenToShortString(), e); 4239 badApp = true; 4240 } 4241 } else { 4242 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4243 } 4244 } 4245 4246 // Find any services that should be running in this process... 4247 if (!badApp) { 4248 try { 4249 didSomething |= mServices.attachApplicationLocked(app, processName); 4250 } catch (Exception e) { 4251 badApp = true; 4252 } 4253 } 4254 4255 // Check if a next-broadcast receiver is in this process... 4256 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4257 try { 4258 didSomething = sendPendingBroadcastsLocked(app); 4259 } catch (Exception e) { 4260 // If the app died trying to launch the receiver we declare it 'bad' 4261 badApp = true; 4262 } 4263 } 4264 4265 // Check whether the next backup agent is in this process... 4266 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4267 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4268 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4269 try { 4270 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4271 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4272 mBackupTarget.backupMode); 4273 } catch (Exception e) { 4274 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4275 e.printStackTrace(); 4276 } 4277 } 4278 4279 if (badApp) { 4280 // todo: Also need to kill application to deal with all 4281 // kinds of exceptions. 4282 handleAppDiedLocked(app, false, true); 4283 return false; 4284 } 4285 4286 if (!didSomething) { 4287 updateOomAdjLocked(); 4288 } 4289 4290 return true; 4291 } 4292 4293 public final void attachApplication(IApplicationThread thread) { 4294 synchronized (this) { 4295 int callingPid = Binder.getCallingPid(); 4296 final long origId = Binder.clearCallingIdentity(); 4297 attachApplicationLocked(thread, callingPid); 4298 Binder.restoreCallingIdentity(origId); 4299 } 4300 } 4301 4302 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4303 final long origId = Binder.clearCallingIdentity(); 4304 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4305 if (stopProfiling) { 4306 synchronized (this) { 4307 if (mProfileProc == r.app) { 4308 if (mProfileFd != null) { 4309 try { 4310 mProfileFd.close(); 4311 } catch (IOException e) { 4312 } 4313 clearProfilerLocked(); 4314 } 4315 } 4316 } 4317 } 4318 Binder.restoreCallingIdentity(origId); 4319 } 4320 4321 void enableScreenAfterBoot() { 4322 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4323 SystemClock.uptimeMillis()); 4324 mWindowManager.enableScreenAfterBoot(); 4325 4326 synchronized (this) { 4327 updateEventDispatchingLocked(); 4328 } 4329 } 4330 4331 public void showBootMessage(final CharSequence msg, final boolean always) { 4332 enforceNotIsolatedCaller("showBootMessage"); 4333 mWindowManager.showBootMessage(msg, always); 4334 } 4335 4336 public void dismissKeyguardOnNextActivity() { 4337 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4338 final long token = Binder.clearCallingIdentity(); 4339 try { 4340 synchronized (this) { 4341 if (mLockScreenShown) { 4342 mLockScreenShown = false; 4343 comeOutOfSleepIfNeededLocked(); 4344 } 4345 mMainStack.dismissKeyguardOnNextActivityLocked(); 4346 } 4347 } finally { 4348 Binder.restoreCallingIdentity(token); 4349 } 4350 } 4351 4352 final void finishBooting() { 4353 IntentFilter pkgFilter = new IntentFilter(); 4354 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4355 pkgFilter.addDataScheme("package"); 4356 mContext.registerReceiver(new BroadcastReceiver() { 4357 @Override 4358 public void onReceive(Context context, Intent intent) { 4359 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4360 if (pkgs != null) { 4361 for (String pkg : pkgs) { 4362 synchronized (ActivityManagerService.this) { 4363 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4364 setResultCode(Activity.RESULT_OK); 4365 return; 4366 } 4367 } 4368 } 4369 } 4370 } 4371 }, pkgFilter); 4372 4373 synchronized (this) { 4374 // Ensure that any processes we had put on hold are now started 4375 // up. 4376 final int NP = mProcessesOnHold.size(); 4377 if (NP > 0) { 4378 ArrayList<ProcessRecord> procs = 4379 new ArrayList<ProcessRecord>(mProcessesOnHold); 4380 for (int ip=0; ip<NP; ip++) { 4381 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4382 + procs.get(ip)); 4383 startProcessLocked(procs.get(ip), "on-hold", null); 4384 } 4385 } 4386 4387 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4388 // Start looking for apps that are abusing wake locks. 4389 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4390 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4391 // Tell anyone interested that we are done booting! 4392 SystemProperties.set("sys.boot_completed", "1"); 4393 SystemProperties.set("dev.bootcomplete", "1"); 4394 for (int i=0; i<mStartedUsers.size(); i++) { 4395 UserStartedState uss = mStartedUsers.valueAt(i); 4396 if (uss.mState == UserStartedState.STATE_BOOTING) { 4397 uss.mState = UserStartedState.STATE_RUNNING; 4398 final int userId = mStartedUsers.keyAt(i); 4399 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4400 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4401 broadcastIntentLocked(null, null, intent, 4402 null, null, 0, null, null, 4403 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4404 false, false, MY_PID, Process.SYSTEM_UID, userId); 4405 } 4406 } 4407 } 4408 } 4409 } 4410 4411 final void ensureBootCompleted() { 4412 boolean booting; 4413 boolean enableScreen; 4414 synchronized (this) { 4415 booting = mBooting; 4416 mBooting = false; 4417 enableScreen = !mBooted; 4418 mBooted = true; 4419 } 4420 4421 if (booting) { 4422 finishBooting(); 4423 } 4424 4425 if (enableScreen) { 4426 enableScreenAfterBoot(); 4427 } 4428 } 4429 4430 public final void activityPaused(IBinder token) { 4431 final long origId = Binder.clearCallingIdentity(); 4432 mMainStack.activityPaused(token, false); 4433 Binder.restoreCallingIdentity(origId); 4434 } 4435 4436 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4437 CharSequence description) { 4438 if (localLOGV) Slog.v( 4439 TAG, "Activity stopped: token=" + token); 4440 4441 // Refuse possible leaked file descriptors 4442 if (icicle != null && icicle.hasFileDescriptors()) { 4443 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4444 } 4445 4446 ActivityRecord r = null; 4447 4448 final long origId = Binder.clearCallingIdentity(); 4449 4450 synchronized (this) { 4451 r = mMainStack.isInStackLocked(token); 4452 if (r != null) { 4453 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4454 } 4455 } 4456 4457 if (r != null) { 4458 sendPendingThumbnail(r, null, null, null, false); 4459 } 4460 4461 trimApplications(); 4462 4463 Binder.restoreCallingIdentity(origId); 4464 } 4465 4466 public final void activityDestroyed(IBinder token) { 4467 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4468 mMainStack.activityDestroyed(token); 4469 } 4470 4471 public String getCallingPackage(IBinder token) { 4472 synchronized (this) { 4473 ActivityRecord r = getCallingRecordLocked(token); 4474 return r != null && r.app != null ? r.info.packageName : null; 4475 } 4476 } 4477 4478 public ComponentName getCallingActivity(IBinder token) { 4479 synchronized (this) { 4480 ActivityRecord r = getCallingRecordLocked(token); 4481 return r != null ? r.intent.getComponent() : null; 4482 } 4483 } 4484 4485 private ActivityRecord getCallingRecordLocked(IBinder token) { 4486 ActivityRecord r = mMainStack.isInStackLocked(token); 4487 if (r == null) { 4488 return null; 4489 } 4490 return r.resultTo; 4491 } 4492 4493 public ComponentName getActivityClassForToken(IBinder token) { 4494 synchronized(this) { 4495 ActivityRecord r = mMainStack.isInStackLocked(token); 4496 if (r == null) { 4497 return null; 4498 } 4499 return r.intent.getComponent(); 4500 } 4501 } 4502 4503 public String getPackageForToken(IBinder token) { 4504 synchronized(this) { 4505 ActivityRecord r = mMainStack.isInStackLocked(token); 4506 if (r == null) { 4507 return null; 4508 } 4509 return r.packageName; 4510 } 4511 } 4512 4513 public IIntentSender getIntentSender(int type, 4514 String packageName, IBinder token, String resultWho, 4515 int requestCode, Intent[] intents, String[] resolvedTypes, 4516 int flags, Bundle options, int userId) { 4517 enforceNotIsolatedCaller("getIntentSender"); 4518 // Refuse possible leaked file descriptors 4519 if (intents != null) { 4520 if (intents.length < 1) { 4521 throw new IllegalArgumentException("Intents array length must be >= 1"); 4522 } 4523 for (int i=0; i<intents.length; i++) { 4524 Intent intent = intents[i]; 4525 if (intent != null) { 4526 if (intent.hasFileDescriptors()) { 4527 throw new IllegalArgumentException("File descriptors passed in Intent"); 4528 } 4529 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4530 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4531 throw new IllegalArgumentException( 4532 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4533 } 4534 intents[i] = new Intent(intent); 4535 } 4536 } 4537 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4538 throw new IllegalArgumentException( 4539 "Intent array length does not match resolvedTypes length"); 4540 } 4541 } 4542 if (options != null) { 4543 if (options.hasFileDescriptors()) { 4544 throw new IllegalArgumentException("File descriptors passed in options"); 4545 } 4546 } 4547 4548 synchronized(this) { 4549 int callingUid = Binder.getCallingUid(); 4550 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4551 false, true, "getIntentSender", null); 4552 try { 4553 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4554 int uid = AppGlobals.getPackageManager() 4555 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4556 if (!UserHandle.isSameApp(callingUid, uid)) { 4557 String msg = "Permission Denial: getIntentSender() from pid=" 4558 + Binder.getCallingPid() 4559 + ", uid=" + Binder.getCallingUid() 4560 + ", (need uid=" + uid + ")" 4561 + " is not allowed to send as package " + packageName; 4562 Slog.w(TAG, msg); 4563 throw new SecurityException(msg); 4564 } 4565 } 4566 4567 return getIntentSenderLocked(type, packageName, callingUid, userId, 4568 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4569 4570 } catch (RemoteException e) { 4571 throw new SecurityException(e); 4572 } 4573 } 4574 } 4575 4576 IIntentSender getIntentSenderLocked(int type, String packageName, 4577 int callingUid, int userId, IBinder token, String resultWho, 4578 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4579 Bundle options) { 4580 if (DEBUG_MU) 4581 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4582 ActivityRecord activity = null; 4583 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4584 activity = mMainStack.isInStackLocked(token); 4585 if (activity == null) { 4586 return null; 4587 } 4588 if (activity.finishing) { 4589 return null; 4590 } 4591 } 4592 4593 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4594 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4595 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4596 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4597 |PendingIntent.FLAG_UPDATE_CURRENT); 4598 4599 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4600 type, packageName, activity, resultWho, 4601 requestCode, intents, resolvedTypes, flags, options, userId); 4602 WeakReference<PendingIntentRecord> ref; 4603 ref = mIntentSenderRecords.get(key); 4604 PendingIntentRecord rec = ref != null ? ref.get() : null; 4605 if (rec != null) { 4606 if (!cancelCurrent) { 4607 if (updateCurrent) { 4608 if (rec.key.requestIntent != null) { 4609 rec.key.requestIntent.replaceExtras(intents != null ? 4610 intents[intents.length - 1] : null); 4611 } 4612 if (intents != null) { 4613 intents[intents.length-1] = rec.key.requestIntent; 4614 rec.key.allIntents = intents; 4615 rec.key.allResolvedTypes = resolvedTypes; 4616 } else { 4617 rec.key.allIntents = null; 4618 rec.key.allResolvedTypes = null; 4619 } 4620 } 4621 return rec; 4622 } 4623 rec.canceled = true; 4624 mIntentSenderRecords.remove(key); 4625 } 4626 if (noCreate) { 4627 return rec; 4628 } 4629 rec = new PendingIntentRecord(this, key, callingUid); 4630 mIntentSenderRecords.put(key, rec.ref); 4631 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4632 if (activity.pendingResults == null) { 4633 activity.pendingResults 4634 = new HashSet<WeakReference<PendingIntentRecord>>(); 4635 } 4636 activity.pendingResults.add(rec.ref); 4637 } 4638 return rec; 4639 } 4640 4641 public void cancelIntentSender(IIntentSender sender) { 4642 if (!(sender instanceof PendingIntentRecord)) { 4643 return; 4644 } 4645 synchronized(this) { 4646 PendingIntentRecord rec = (PendingIntentRecord)sender; 4647 try { 4648 int uid = AppGlobals.getPackageManager() 4649 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4650 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4651 String msg = "Permission Denial: cancelIntentSender() from pid=" 4652 + Binder.getCallingPid() 4653 + ", uid=" + Binder.getCallingUid() 4654 + " is not allowed to cancel packges " 4655 + rec.key.packageName; 4656 Slog.w(TAG, msg); 4657 throw new SecurityException(msg); 4658 } 4659 } catch (RemoteException e) { 4660 throw new SecurityException(e); 4661 } 4662 cancelIntentSenderLocked(rec, true); 4663 } 4664 } 4665 4666 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4667 rec.canceled = true; 4668 mIntentSenderRecords.remove(rec.key); 4669 if (cleanActivity && rec.key.activity != null) { 4670 rec.key.activity.pendingResults.remove(rec.ref); 4671 } 4672 } 4673 4674 public String getPackageForIntentSender(IIntentSender pendingResult) { 4675 if (!(pendingResult instanceof PendingIntentRecord)) { 4676 return null; 4677 } 4678 try { 4679 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4680 return res.key.packageName; 4681 } catch (ClassCastException e) { 4682 } 4683 return null; 4684 } 4685 4686 public int getUidForIntentSender(IIntentSender sender) { 4687 if (sender instanceof PendingIntentRecord) { 4688 try { 4689 PendingIntentRecord res = (PendingIntentRecord)sender; 4690 return res.uid; 4691 } catch (ClassCastException e) { 4692 } 4693 } 4694 return -1; 4695 } 4696 4697 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4698 if (!(pendingResult instanceof PendingIntentRecord)) { 4699 return false; 4700 } 4701 try { 4702 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4703 if (res.key.allIntents == null) { 4704 return false; 4705 } 4706 for (int i=0; i<res.key.allIntents.length; i++) { 4707 Intent intent = res.key.allIntents[i]; 4708 if (intent.getPackage() != null && intent.getComponent() != null) { 4709 return false; 4710 } 4711 } 4712 return true; 4713 } catch (ClassCastException e) { 4714 } 4715 return false; 4716 } 4717 4718 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4719 if (!(pendingResult instanceof PendingIntentRecord)) { 4720 return false; 4721 } 4722 try { 4723 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4724 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4725 return true; 4726 } 4727 return false; 4728 } catch (ClassCastException e) { 4729 } 4730 return false; 4731 } 4732 4733 public void setProcessLimit(int max) { 4734 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4735 "setProcessLimit()"); 4736 synchronized (this) { 4737 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4738 mProcessLimitOverride = max; 4739 } 4740 trimApplications(); 4741 } 4742 4743 public int getProcessLimit() { 4744 synchronized (this) { 4745 return mProcessLimitOverride; 4746 } 4747 } 4748 4749 void foregroundTokenDied(ForegroundToken token) { 4750 synchronized (ActivityManagerService.this) { 4751 synchronized (mPidsSelfLocked) { 4752 ForegroundToken cur 4753 = mForegroundProcesses.get(token.pid); 4754 if (cur != token) { 4755 return; 4756 } 4757 mForegroundProcesses.remove(token.pid); 4758 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4759 if (pr == null) { 4760 return; 4761 } 4762 pr.forcingToForeground = null; 4763 pr.foregroundServices = false; 4764 } 4765 updateOomAdjLocked(); 4766 } 4767 } 4768 4769 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4770 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4771 "setProcessForeground()"); 4772 synchronized(this) { 4773 boolean changed = false; 4774 4775 synchronized (mPidsSelfLocked) { 4776 ProcessRecord pr = mPidsSelfLocked.get(pid); 4777 if (pr == null && isForeground) { 4778 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4779 return; 4780 } 4781 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4782 if (oldToken != null) { 4783 oldToken.token.unlinkToDeath(oldToken, 0); 4784 mForegroundProcesses.remove(pid); 4785 if (pr != null) { 4786 pr.forcingToForeground = null; 4787 } 4788 changed = true; 4789 } 4790 if (isForeground && token != null) { 4791 ForegroundToken newToken = new ForegroundToken() { 4792 public void binderDied() { 4793 foregroundTokenDied(this); 4794 } 4795 }; 4796 newToken.pid = pid; 4797 newToken.token = token; 4798 try { 4799 token.linkToDeath(newToken, 0); 4800 mForegroundProcesses.put(pid, newToken); 4801 pr.forcingToForeground = token; 4802 changed = true; 4803 } catch (RemoteException e) { 4804 // If the process died while doing this, we will later 4805 // do the cleanup with the process death link. 4806 } 4807 } 4808 } 4809 4810 if (changed) { 4811 updateOomAdjLocked(); 4812 } 4813 } 4814 } 4815 4816 // ========================================================= 4817 // PERMISSIONS 4818 // ========================================================= 4819 4820 static class PermissionController extends IPermissionController.Stub { 4821 ActivityManagerService mActivityManagerService; 4822 PermissionController(ActivityManagerService activityManagerService) { 4823 mActivityManagerService = activityManagerService; 4824 } 4825 4826 public boolean checkPermission(String permission, int pid, int uid) { 4827 return mActivityManagerService.checkPermission(permission, pid, 4828 uid) == PackageManager.PERMISSION_GRANTED; 4829 } 4830 } 4831 4832 /** 4833 * This can be called with or without the global lock held. 4834 */ 4835 int checkComponentPermission(String permission, int pid, int uid, 4836 int owningUid, boolean exported) { 4837 // We might be performing an operation on behalf of an indirect binder 4838 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4839 // client identity accordingly before proceeding. 4840 Identity tlsIdentity = sCallerIdentity.get(); 4841 if (tlsIdentity != null) { 4842 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4843 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4844 uid = tlsIdentity.uid; 4845 pid = tlsIdentity.pid; 4846 } 4847 4848 if (pid == MY_PID) { 4849 return PackageManager.PERMISSION_GRANTED; 4850 } 4851 4852 return ActivityManager.checkComponentPermission(permission, uid, 4853 owningUid, exported); 4854 } 4855 4856 /** 4857 * As the only public entry point for permissions checking, this method 4858 * can enforce the semantic that requesting a check on a null global 4859 * permission is automatically denied. (Internally a null permission 4860 * string is used when calling {@link #checkComponentPermission} in cases 4861 * when only uid-based security is needed.) 4862 * 4863 * This can be called with or without the global lock held. 4864 */ 4865 public int checkPermission(String permission, int pid, int uid) { 4866 if (permission == null) { 4867 return PackageManager.PERMISSION_DENIED; 4868 } 4869 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4870 } 4871 4872 /** 4873 * Binder IPC calls go through the public entry point. 4874 * This can be called with or without the global lock held. 4875 */ 4876 int checkCallingPermission(String permission) { 4877 return checkPermission(permission, 4878 Binder.getCallingPid(), 4879 UserHandle.getAppId(Binder.getCallingUid())); 4880 } 4881 4882 /** 4883 * This can be called with or without the global lock held. 4884 */ 4885 void enforceCallingPermission(String permission, String func) { 4886 if (checkCallingPermission(permission) 4887 == PackageManager.PERMISSION_GRANTED) { 4888 return; 4889 } 4890 4891 String msg = "Permission Denial: " + func + " from pid=" 4892 + Binder.getCallingPid() 4893 + ", uid=" + Binder.getCallingUid() 4894 + " requires " + permission; 4895 Slog.w(TAG, msg); 4896 throw new SecurityException(msg); 4897 } 4898 4899 /** 4900 * Determine if UID is holding permissions required to access {@link Uri} in 4901 * the given {@link ProviderInfo}. Final permission checking is always done 4902 * in {@link ContentProvider}. 4903 */ 4904 private final boolean checkHoldingPermissionsLocked( 4905 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4906 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4907 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4908 4909 if (pi.applicationInfo.uid == uid) { 4910 return true; 4911 } else if (!pi.exported) { 4912 return false; 4913 } 4914 4915 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4916 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4917 try { 4918 // check if target holds top-level <provider> permissions 4919 if (!readMet && pi.readPermission != null 4920 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4921 readMet = true; 4922 } 4923 if (!writeMet && pi.writePermission != null 4924 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4925 writeMet = true; 4926 } 4927 4928 // track if unprotected read/write is allowed; any denied 4929 // <path-permission> below removes this ability 4930 boolean allowDefaultRead = pi.readPermission == null; 4931 boolean allowDefaultWrite = pi.writePermission == null; 4932 4933 // check if target holds any <path-permission> that match uri 4934 final PathPermission[] pps = pi.pathPermissions; 4935 if (pps != null) { 4936 final String path = uri.getPath(); 4937 int i = pps.length; 4938 while (i > 0 && (!readMet || !writeMet)) { 4939 i--; 4940 PathPermission pp = pps[i]; 4941 if (pp.match(path)) { 4942 if (!readMet) { 4943 final String pprperm = pp.getReadPermission(); 4944 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4945 + pprperm + " for " + pp.getPath() 4946 + ": match=" + pp.match(path) 4947 + " check=" + pm.checkUidPermission(pprperm, uid)); 4948 if (pprperm != null) { 4949 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4950 readMet = true; 4951 } else { 4952 allowDefaultRead = false; 4953 } 4954 } 4955 } 4956 if (!writeMet) { 4957 final String ppwperm = pp.getWritePermission(); 4958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4959 + ppwperm + " for " + pp.getPath() 4960 + ": match=" + pp.match(path) 4961 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4962 if (ppwperm != null) { 4963 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4964 writeMet = true; 4965 } else { 4966 allowDefaultWrite = false; 4967 } 4968 } 4969 } 4970 } 4971 } 4972 } 4973 4974 // grant unprotected <provider> read/write, if not blocked by 4975 // <path-permission> above 4976 if (allowDefaultRead) readMet = true; 4977 if (allowDefaultWrite) writeMet = true; 4978 4979 } catch (RemoteException e) { 4980 return false; 4981 } 4982 4983 return readMet && writeMet; 4984 } 4985 4986 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4987 int modeFlags) { 4988 // Root gets to do everything. 4989 if (uid == 0) { 4990 return true; 4991 } 4992 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4993 if (perms == null) return false; 4994 UriPermission perm = perms.get(uri); 4995 if (perm == null) return false; 4996 return (modeFlags&perm.modeFlags) == modeFlags; 4997 } 4998 4999 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5000 enforceNotIsolatedCaller("checkUriPermission"); 5001 5002 // Another redirected-binder-call permissions check as in 5003 // {@link checkComponentPermission}. 5004 Identity tlsIdentity = sCallerIdentity.get(); 5005 if (tlsIdentity != null) { 5006 uid = tlsIdentity.uid; 5007 pid = tlsIdentity.pid; 5008 } 5009 5010 uid = UserHandle.getAppId(uid); 5011 // Our own process gets to do everything. 5012 if (pid == MY_PID) { 5013 return PackageManager.PERMISSION_GRANTED; 5014 } 5015 synchronized(this) { 5016 return checkUriPermissionLocked(uri, uid, modeFlags) 5017 ? PackageManager.PERMISSION_GRANTED 5018 : PackageManager.PERMISSION_DENIED; 5019 } 5020 } 5021 5022 /** 5023 * Check if the targetPkg can be granted permission to access uri by 5024 * the callingUid using the given modeFlags. Throws a security exception 5025 * if callingUid is not allowed to do this. Returns the uid of the target 5026 * if the URI permission grant should be performed; returns -1 if it is not 5027 * needed (for example targetPkg already has permission to access the URI). 5028 * If you already know the uid of the target, you can supply it in 5029 * lastTargetUid else set that to -1. 5030 */ 5031 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5032 Uri uri, int modeFlags, int lastTargetUid) { 5033 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5034 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5035 if (modeFlags == 0) { 5036 return -1; 5037 } 5038 5039 if (targetPkg != null) { 5040 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5041 "Checking grant " + targetPkg + " permission to " + uri); 5042 } 5043 5044 final IPackageManager pm = AppGlobals.getPackageManager(); 5045 5046 // If this is not a content: uri, we can't do anything with it. 5047 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5048 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5049 "Can't grant URI permission for non-content URI: " + uri); 5050 return -1; 5051 } 5052 5053 String name = uri.getAuthority(); 5054 ProviderInfo pi = null; 5055 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5056 UserHandle.getUserId(callingUid)); 5057 if (cpr != null) { 5058 pi = cpr.info; 5059 } else { 5060 try { 5061 pi = pm.resolveContentProvider(name, 5062 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 5063 } catch (RemoteException ex) { 5064 } 5065 } 5066 if (pi == null) { 5067 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5068 return -1; 5069 } 5070 5071 int targetUid = lastTargetUid; 5072 if (targetUid < 0 && targetPkg != null) { 5073 try { 5074 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5075 if (targetUid < 0) { 5076 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5077 "Can't grant URI permission no uid for: " + targetPkg); 5078 return -1; 5079 } 5080 } catch (RemoteException ex) { 5081 return -1; 5082 } 5083 } 5084 5085 if (targetUid >= 0) { 5086 // First... does the target actually need this permission? 5087 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5088 // No need to grant the target this permission. 5089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5090 "Target " + targetPkg + " already has full permission to " + uri); 5091 return -1; 5092 } 5093 } else { 5094 // First... there is no target package, so can anyone access it? 5095 boolean allowed = pi.exported; 5096 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5097 if (pi.readPermission != null) { 5098 allowed = false; 5099 } 5100 } 5101 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5102 if (pi.writePermission != null) { 5103 allowed = false; 5104 } 5105 } 5106 if (allowed) { 5107 return -1; 5108 } 5109 } 5110 5111 // Second... is the provider allowing granting of URI permissions? 5112 if (!pi.grantUriPermissions) { 5113 throw new SecurityException("Provider " + pi.packageName 5114 + "/" + pi.name 5115 + " does not allow granting of Uri permissions (uri " 5116 + uri + ")"); 5117 } 5118 if (pi.uriPermissionPatterns != null) { 5119 final int N = pi.uriPermissionPatterns.length; 5120 boolean allowed = false; 5121 for (int i=0; i<N; i++) { 5122 if (pi.uriPermissionPatterns[i] != null 5123 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5124 allowed = true; 5125 break; 5126 } 5127 } 5128 if (!allowed) { 5129 throw new SecurityException("Provider " + pi.packageName 5130 + "/" + pi.name 5131 + " does not allow granting of permission to path of Uri " 5132 + uri); 5133 } 5134 } 5135 5136 // Third... does the caller itself have permission to access 5137 // this uri? 5138 if (callingUid != Process.myUid()) { 5139 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5140 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5141 throw new SecurityException("Uid " + callingUid 5142 + " does not have permission to uri " + uri); 5143 } 5144 } 5145 } 5146 5147 return targetUid; 5148 } 5149 5150 public int checkGrantUriPermission(int callingUid, String targetPkg, 5151 Uri uri, int modeFlags) { 5152 enforceNotIsolatedCaller("checkGrantUriPermission"); 5153 synchronized(this) { 5154 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5155 } 5156 } 5157 5158 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5159 Uri uri, int modeFlags, UriPermissionOwner owner) { 5160 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5161 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5162 if (modeFlags == 0) { 5163 return; 5164 } 5165 5166 // So here we are: the caller has the assumed permission 5167 // to the uri, and the target doesn't. Let's now give this to 5168 // the target. 5169 5170 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5171 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5172 5173 HashMap<Uri, UriPermission> targetUris 5174 = mGrantedUriPermissions.get(targetUid); 5175 if (targetUris == null) { 5176 targetUris = new HashMap<Uri, UriPermission>(); 5177 mGrantedUriPermissions.put(targetUid, targetUris); 5178 } 5179 5180 UriPermission perm = targetUris.get(uri); 5181 if (perm == null) { 5182 perm = new UriPermission(targetUid, uri); 5183 targetUris.put(uri, perm); 5184 } 5185 5186 perm.modeFlags |= modeFlags; 5187 if (owner == null) { 5188 perm.globalModeFlags |= modeFlags; 5189 } else { 5190 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5191 perm.readOwners.add(owner); 5192 owner.addReadPermission(perm); 5193 } 5194 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5195 perm.writeOwners.add(owner); 5196 owner.addWritePermission(perm); 5197 } 5198 } 5199 } 5200 5201 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5202 int modeFlags, UriPermissionOwner owner) { 5203 if (targetPkg == null) { 5204 throw new NullPointerException("targetPkg"); 5205 } 5206 5207 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5208 if (targetUid < 0) { 5209 return; 5210 } 5211 5212 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5213 } 5214 5215 static class NeededUriGrants extends ArrayList<Uri> { 5216 final String targetPkg; 5217 final int targetUid; 5218 final int flags; 5219 5220 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5221 targetPkg = _targetPkg; 5222 targetUid = _targetUid; 5223 flags = _flags; 5224 } 5225 } 5226 5227 /** 5228 * Like checkGrantUriPermissionLocked, but takes an Intent. 5229 */ 5230 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5231 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5232 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5233 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5234 + " clip=" + (intent != null ? intent.getClipData() : null) 5235 + " from " + intent + "; flags=0x" 5236 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5237 5238 if (targetPkg == null) { 5239 throw new NullPointerException("targetPkg"); 5240 } 5241 5242 if (intent == null) { 5243 return null; 5244 } 5245 Uri data = intent.getData(); 5246 ClipData clip = intent.getClipData(); 5247 if (data == null && clip == null) { 5248 return null; 5249 } 5250 if (data != null) { 5251 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5252 mode, needed != null ? needed.targetUid : -1); 5253 if (target > 0) { 5254 if (needed == null) { 5255 needed = new NeededUriGrants(targetPkg, target, mode); 5256 } 5257 needed.add(data); 5258 } 5259 } 5260 if (clip != null) { 5261 for (int i=0; i<clip.getItemCount(); i++) { 5262 Uri uri = clip.getItemAt(i).getUri(); 5263 if (uri != null) { 5264 int target = -1; 5265 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5266 mode, needed != null ? needed.targetUid : -1); 5267 if (target > 0) { 5268 if (needed == null) { 5269 needed = new NeededUriGrants(targetPkg, target, mode); 5270 } 5271 needed.add(uri); 5272 } 5273 } else { 5274 Intent clipIntent = clip.getItemAt(i).getIntent(); 5275 if (clipIntent != null) { 5276 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5277 callingUid, targetPkg, clipIntent, mode, needed); 5278 if (newNeeded != null) { 5279 needed = newNeeded; 5280 } 5281 } 5282 } 5283 } 5284 } 5285 5286 return needed; 5287 } 5288 5289 /** 5290 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5291 */ 5292 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5293 UriPermissionOwner owner) { 5294 if (needed != null) { 5295 for (int i=0; i<needed.size(); i++) { 5296 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5297 needed.get(i), needed.flags, owner); 5298 } 5299 } 5300 } 5301 5302 void grantUriPermissionFromIntentLocked(int callingUid, 5303 String targetPkg, Intent intent, UriPermissionOwner owner) { 5304 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5305 intent, intent != null ? intent.getFlags() : 0, null); 5306 if (needed == null) { 5307 return; 5308 } 5309 5310 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5311 } 5312 5313 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5314 Uri uri, int modeFlags) { 5315 enforceNotIsolatedCaller("grantUriPermission"); 5316 synchronized(this) { 5317 final ProcessRecord r = getRecordForAppLocked(caller); 5318 if (r == null) { 5319 throw new SecurityException("Unable to find app for caller " 5320 + caller 5321 + " when granting permission to uri " + uri); 5322 } 5323 if (targetPkg == null) { 5324 throw new IllegalArgumentException("null target"); 5325 } 5326 if (uri == null) { 5327 throw new IllegalArgumentException("null uri"); 5328 } 5329 5330 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5331 null); 5332 } 5333 } 5334 5335 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5336 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5337 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5338 HashMap<Uri, UriPermission> perms 5339 = mGrantedUriPermissions.get(perm.uid); 5340 if (perms != null) { 5341 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5342 "Removing " + perm.uid + " permission to " + perm.uri); 5343 perms.remove(perm.uri); 5344 if (perms.size() == 0) { 5345 mGrantedUriPermissions.remove(perm.uid); 5346 } 5347 } 5348 } 5349 } 5350 5351 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5352 int modeFlags) { 5353 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5354 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5355 if (modeFlags == 0) { 5356 return; 5357 } 5358 5359 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5360 "Revoking all granted permissions to " + uri); 5361 5362 final IPackageManager pm = AppGlobals.getPackageManager(); 5363 5364 final String authority = uri.getAuthority(); 5365 ProviderInfo pi = null; 5366 int userId = UserHandle.getUserId(callingUid); 5367 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5368 if (cpr != null) { 5369 pi = cpr.info; 5370 } else { 5371 try { 5372 pi = pm.resolveContentProvider(authority, 5373 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5374 } catch (RemoteException ex) { 5375 } 5376 } 5377 if (pi == null) { 5378 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5379 return; 5380 } 5381 5382 // Does the caller have this permission on the URI? 5383 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5384 // Right now, if you are not the original owner of the permission, 5385 // you are not allowed to revoke it. 5386 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5387 throw new SecurityException("Uid " + callingUid 5388 + " does not have permission to uri " + uri); 5389 //} 5390 } 5391 5392 // Go through all of the permissions and remove any that match. 5393 final List<String> SEGMENTS = uri.getPathSegments(); 5394 if (SEGMENTS != null) { 5395 final int NS = SEGMENTS.size(); 5396 int N = mGrantedUriPermissions.size(); 5397 for (int i=0; i<N; i++) { 5398 HashMap<Uri, UriPermission> perms 5399 = mGrantedUriPermissions.valueAt(i); 5400 Iterator<UriPermission> it = perms.values().iterator(); 5401 toploop: 5402 while (it.hasNext()) { 5403 UriPermission perm = it.next(); 5404 Uri targetUri = perm.uri; 5405 if (!authority.equals(targetUri.getAuthority())) { 5406 continue; 5407 } 5408 List<String> targetSegments = targetUri.getPathSegments(); 5409 if (targetSegments == null) { 5410 continue; 5411 } 5412 if (targetSegments.size() < NS) { 5413 continue; 5414 } 5415 for (int j=0; j<NS; j++) { 5416 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5417 continue toploop; 5418 } 5419 } 5420 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5421 "Revoking " + perm.uid + " permission to " + perm.uri); 5422 perm.clearModes(modeFlags); 5423 if (perm.modeFlags == 0) { 5424 it.remove(); 5425 } 5426 } 5427 if (perms.size() == 0) { 5428 mGrantedUriPermissions.remove( 5429 mGrantedUriPermissions.keyAt(i)); 5430 N--; 5431 i--; 5432 } 5433 } 5434 } 5435 } 5436 5437 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5438 int modeFlags) { 5439 enforceNotIsolatedCaller("revokeUriPermission"); 5440 synchronized(this) { 5441 final ProcessRecord r = getRecordForAppLocked(caller); 5442 if (r == null) { 5443 throw new SecurityException("Unable to find app for caller " 5444 + caller 5445 + " when revoking permission to uri " + uri); 5446 } 5447 if (uri == null) { 5448 Slog.w(TAG, "revokeUriPermission: null uri"); 5449 return; 5450 } 5451 5452 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5453 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5454 if (modeFlags == 0) { 5455 return; 5456 } 5457 5458 final IPackageManager pm = AppGlobals.getPackageManager(); 5459 5460 final String authority = uri.getAuthority(); 5461 ProviderInfo pi = null; 5462 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5463 if (cpr != null) { 5464 pi = cpr.info; 5465 } else { 5466 try { 5467 pi = pm.resolveContentProvider(authority, 5468 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5469 } catch (RemoteException ex) { 5470 } 5471 } 5472 if (pi == null) { 5473 Slog.w(TAG, "No content provider found for permission revoke: " 5474 + uri.toSafeString()); 5475 return; 5476 } 5477 5478 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5479 } 5480 } 5481 5482 @Override 5483 public IBinder newUriPermissionOwner(String name) { 5484 enforceNotIsolatedCaller("newUriPermissionOwner"); 5485 synchronized(this) { 5486 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5487 return owner.getExternalTokenLocked(); 5488 } 5489 } 5490 5491 @Override 5492 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5493 Uri uri, int modeFlags) { 5494 synchronized(this) { 5495 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5496 if (owner == null) { 5497 throw new IllegalArgumentException("Unknown owner: " + token); 5498 } 5499 if (fromUid != Binder.getCallingUid()) { 5500 if (Binder.getCallingUid() != Process.myUid()) { 5501 // Only system code can grant URI permissions on behalf 5502 // of other users. 5503 throw new SecurityException("nice try"); 5504 } 5505 } 5506 if (targetPkg == null) { 5507 throw new IllegalArgumentException("null target"); 5508 } 5509 if (uri == null) { 5510 throw new IllegalArgumentException("null uri"); 5511 } 5512 5513 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5514 } 5515 } 5516 5517 @Override 5518 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5519 synchronized(this) { 5520 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5521 if (owner == null) { 5522 throw new IllegalArgumentException("Unknown owner: " + token); 5523 } 5524 5525 if (uri == null) { 5526 owner.removeUriPermissionsLocked(mode); 5527 } else { 5528 owner.removeUriPermissionLocked(uri, mode); 5529 } 5530 } 5531 } 5532 5533 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5534 synchronized (this) { 5535 ProcessRecord app = 5536 who != null ? getRecordForAppLocked(who) : null; 5537 if (app == null) return; 5538 5539 Message msg = Message.obtain(); 5540 msg.what = WAIT_FOR_DEBUGGER_MSG; 5541 msg.obj = app; 5542 msg.arg1 = waiting ? 1 : 0; 5543 mHandler.sendMessage(msg); 5544 } 5545 } 5546 5547 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5548 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5549 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5550 outInfo.availMem = Process.getFreeMemory(); 5551 outInfo.totalMem = Process.getTotalMemory(); 5552 outInfo.threshold = homeAppMem; 5553 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5554 outInfo.hiddenAppThreshold = hiddenAppMem; 5555 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5556 ProcessList.SERVICE_ADJ); 5557 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5558 ProcessList.VISIBLE_APP_ADJ); 5559 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5560 ProcessList.FOREGROUND_APP_ADJ); 5561 } 5562 5563 // ========================================================= 5564 // TASK MANAGEMENT 5565 // ========================================================= 5566 5567 public List getTasks(int maxNum, int flags, 5568 IThumbnailReceiver receiver) { 5569 ArrayList list = new ArrayList(); 5570 5571 PendingThumbnailsRecord pending = null; 5572 IApplicationThread topThumbnail = null; 5573 ActivityRecord topRecord = null; 5574 5575 synchronized(this) { 5576 if (localLOGV) Slog.v( 5577 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5578 + ", receiver=" + receiver); 5579 5580 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5581 != PackageManager.PERMISSION_GRANTED) { 5582 if (receiver != null) { 5583 // If the caller wants to wait for pending thumbnails, 5584 // it ain't gonna get them. 5585 try { 5586 receiver.finished(); 5587 } catch (RemoteException ex) { 5588 } 5589 } 5590 String msg = "Permission Denial: getTasks() from pid=" 5591 + Binder.getCallingPid() 5592 + ", uid=" + Binder.getCallingUid() 5593 + " requires " + android.Manifest.permission.GET_TASKS; 5594 Slog.w(TAG, msg); 5595 throw new SecurityException(msg); 5596 } 5597 5598 int pos = mMainStack.mHistory.size()-1; 5599 ActivityRecord next = 5600 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5601 ActivityRecord top = null; 5602 TaskRecord curTask = null; 5603 int numActivities = 0; 5604 int numRunning = 0; 5605 while (pos >= 0 && maxNum > 0) { 5606 final ActivityRecord r = next; 5607 pos--; 5608 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5609 5610 // Initialize state for next task if needed. 5611 if (top == null || 5612 (top.state == ActivityState.INITIALIZING 5613 && top.task == r.task)) { 5614 top = r; 5615 curTask = r.task; 5616 numActivities = numRunning = 0; 5617 } 5618 5619 // Add 'r' into the current task. 5620 numActivities++; 5621 if (r.app != null && r.app.thread != null) { 5622 numRunning++; 5623 } 5624 5625 if (localLOGV) Slog.v( 5626 TAG, r.intent.getComponent().flattenToShortString() 5627 + ": task=" + r.task); 5628 5629 // If the next one is a different task, generate a new 5630 // TaskInfo entry for what we have. 5631 if (next == null || next.task != curTask) { 5632 ActivityManager.RunningTaskInfo ci 5633 = new ActivityManager.RunningTaskInfo(); 5634 ci.id = curTask.taskId; 5635 ci.baseActivity = r.intent.getComponent(); 5636 ci.topActivity = top.intent.getComponent(); 5637 if (top.thumbHolder != null) { 5638 ci.description = top.thumbHolder.lastDescription; 5639 } 5640 ci.numActivities = numActivities; 5641 ci.numRunning = numRunning; 5642 //System.out.println( 5643 // "#" + maxNum + ": " + " descr=" + ci.description); 5644 if (ci.thumbnail == null && receiver != null) { 5645 if (localLOGV) Slog.v( 5646 TAG, "State=" + top.state + "Idle=" + top.idle 5647 + " app=" + top.app 5648 + " thr=" + (top.app != null ? top.app.thread : null)); 5649 if (top.state == ActivityState.RESUMED 5650 || top.state == ActivityState.PAUSING) { 5651 if (top.idle && top.app != null 5652 && top.app.thread != null) { 5653 topRecord = top; 5654 topThumbnail = top.app.thread; 5655 } else { 5656 top.thumbnailNeeded = true; 5657 } 5658 } 5659 if (pending == null) { 5660 pending = new PendingThumbnailsRecord(receiver); 5661 } 5662 pending.pendingRecords.add(top); 5663 } 5664 list.add(ci); 5665 maxNum--; 5666 top = null; 5667 } 5668 } 5669 5670 if (pending != null) { 5671 mPendingThumbnails.add(pending); 5672 } 5673 } 5674 5675 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5676 5677 if (topThumbnail != null) { 5678 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5679 try { 5680 topThumbnail.requestThumbnail(topRecord.appToken); 5681 } catch (Exception e) { 5682 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5683 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5684 } 5685 } 5686 5687 if (pending == null && receiver != null) { 5688 // In this case all thumbnails were available and the client 5689 // is being asked to be told when the remaining ones come in... 5690 // which is unusually, since the top-most currently running 5691 // activity should never have a canned thumbnail! Oh well. 5692 try { 5693 receiver.finished(); 5694 } catch (RemoteException ex) { 5695 } 5696 } 5697 5698 return list; 5699 } 5700 5701 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5702 int flags, int userId) { 5703 final int callingUid = Binder.getCallingUid(); 5704 if (userId != UserHandle.getCallingUserId()) { 5705 // Check if the caller is holding permissions for cross-user requests. 5706 if (checkComponentPermission( 5707 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5708 Binder.getCallingPid(), callingUid, -1, true) 5709 != PackageManager.PERMISSION_GRANTED) { 5710 String msg = "Permission Denial: " 5711 + "Request to get recent tasks for user " + userId 5712 + " but is calling from user " + UserHandle.getUserId(callingUid) 5713 + "; this requires " 5714 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5715 Slog.w(TAG, msg); 5716 throw new SecurityException(msg); 5717 } else { 5718 if (userId == UserHandle.USER_CURRENT) { 5719 userId = mCurrentUserId; 5720 } 5721 } 5722 } 5723 5724 synchronized (this) { 5725 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5726 "getRecentTasks()"); 5727 final boolean detailed = checkCallingPermission( 5728 android.Manifest.permission.GET_DETAILED_TASKS) 5729 == PackageManager.PERMISSION_GRANTED; 5730 5731 IPackageManager pm = AppGlobals.getPackageManager(); 5732 5733 final int N = mRecentTasks.size(); 5734 ArrayList<ActivityManager.RecentTaskInfo> res 5735 = new ArrayList<ActivityManager.RecentTaskInfo>( 5736 maxNum < N ? maxNum : N); 5737 for (int i=0; i<N && maxNum > 0; i++) { 5738 TaskRecord tr = mRecentTasks.get(i); 5739 // Only add calling user's recent tasks 5740 if (tr.userId != userId) continue; 5741 // Return the entry if desired by the caller. We always return 5742 // the first entry, because callers always expect this to be the 5743 // foreground app. We may filter others if the caller has 5744 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5745 // we should exclude the entry. 5746 5747 if (i == 0 5748 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5749 || (tr.intent == null) 5750 || ((tr.intent.getFlags() 5751 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5752 ActivityManager.RecentTaskInfo rti 5753 = new ActivityManager.RecentTaskInfo(); 5754 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5755 rti.persistentId = tr.taskId; 5756 rti.baseIntent = new Intent( 5757 tr.intent != null ? tr.intent : tr.affinityIntent); 5758 if (!detailed) { 5759 rti.baseIntent.replaceExtras((Bundle)null); 5760 } 5761 rti.origActivity = tr.origActivity; 5762 rti.description = tr.lastDescription; 5763 5764 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5765 // Check whether this activity is currently available. 5766 try { 5767 if (rti.origActivity != null) { 5768 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5769 == null) { 5770 continue; 5771 } 5772 } else if (rti.baseIntent != null) { 5773 if (pm.queryIntentActivities(rti.baseIntent, 5774 null, 0, userId) == null) { 5775 continue; 5776 } 5777 } 5778 } catch (RemoteException e) { 5779 // Will never happen. 5780 } 5781 } 5782 5783 res.add(rti); 5784 maxNum--; 5785 } 5786 } 5787 return res; 5788 } 5789 } 5790 5791 private TaskRecord taskForIdLocked(int id) { 5792 final int N = mRecentTasks.size(); 5793 for (int i=0; i<N; i++) { 5794 TaskRecord tr = mRecentTasks.get(i); 5795 if (tr.taskId == id) { 5796 return tr; 5797 } 5798 } 5799 return null; 5800 } 5801 5802 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5803 synchronized (this) { 5804 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5805 "getTaskThumbnails()"); 5806 TaskRecord tr = taskForIdLocked(id); 5807 if (tr != null) { 5808 return mMainStack.getTaskThumbnailsLocked(tr); 5809 } 5810 } 5811 return null; 5812 } 5813 5814 public boolean removeSubTask(int taskId, int subTaskIndex) { 5815 synchronized (this) { 5816 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5817 "removeSubTask()"); 5818 long ident = Binder.clearCallingIdentity(); 5819 try { 5820 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5821 true) != null; 5822 } finally { 5823 Binder.restoreCallingIdentity(ident); 5824 } 5825 } 5826 } 5827 5828 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5829 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5830 Intent baseIntent = new Intent( 5831 tr.intent != null ? tr.intent : tr.affinityIntent); 5832 ComponentName component = baseIntent.getComponent(); 5833 if (component == null) { 5834 Slog.w(TAG, "Now component for base intent of task: " + tr); 5835 return; 5836 } 5837 5838 // Find any running services associated with this app. 5839 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5840 5841 if (killProcesses) { 5842 // Find any running processes associated with this app. 5843 final String pkg = component.getPackageName(); 5844 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5845 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5846 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5847 for (int i=0; i<uids.size(); i++) { 5848 ProcessRecord proc = uids.valueAt(i); 5849 if (proc.userId != tr.userId) { 5850 continue; 5851 } 5852 if (!proc.pkgList.contains(pkg)) { 5853 continue; 5854 } 5855 procs.add(proc); 5856 } 5857 } 5858 5859 // Kill the running processes. 5860 for (int i=0; i<procs.size(); i++) { 5861 ProcessRecord pr = procs.get(i); 5862 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5863 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5864 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5865 pr.processName, pr.setAdj, "remove task"); 5866 pr.killedBackground = true; 5867 Process.killProcessQuiet(pr.pid); 5868 } else { 5869 pr.waitingToKill = "remove task"; 5870 } 5871 } 5872 } 5873 } 5874 5875 public boolean removeTask(int taskId, int flags) { 5876 synchronized (this) { 5877 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5878 "removeTask()"); 5879 long ident = Binder.clearCallingIdentity(); 5880 try { 5881 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5882 false); 5883 if (r != null) { 5884 mRecentTasks.remove(r.task); 5885 cleanUpRemovedTaskLocked(r.task, flags); 5886 return true; 5887 } else { 5888 TaskRecord tr = null; 5889 int i=0; 5890 while (i < mRecentTasks.size()) { 5891 TaskRecord t = mRecentTasks.get(i); 5892 if (t.taskId == taskId) { 5893 tr = t; 5894 break; 5895 } 5896 i++; 5897 } 5898 if (tr != null) { 5899 if (tr.numActivities <= 0) { 5900 // Caller is just removing a recent task that is 5901 // not actively running. That is easy! 5902 mRecentTasks.remove(i); 5903 cleanUpRemovedTaskLocked(tr, flags); 5904 return true; 5905 } else { 5906 Slog.w(TAG, "removeTask: task " + taskId 5907 + " does not have activities to remove, " 5908 + " but numActivities=" + tr.numActivities 5909 + ": " + tr); 5910 } 5911 } 5912 } 5913 } finally { 5914 Binder.restoreCallingIdentity(ident); 5915 } 5916 } 5917 return false; 5918 } 5919 5920 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5921 int j; 5922 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5923 TaskRecord jt = startTask; 5924 5925 // First look backwards 5926 for (j=startIndex-1; j>=0; j--) { 5927 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5928 if (r.task != jt) { 5929 jt = r.task; 5930 if (affinity.equals(jt.affinity)) { 5931 return j; 5932 } 5933 } 5934 } 5935 5936 // Now look forwards 5937 final int N = mMainStack.mHistory.size(); 5938 jt = startTask; 5939 for (j=startIndex+1; j<N; j++) { 5940 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5941 if (r.task != jt) { 5942 if (affinity.equals(jt.affinity)) { 5943 return j; 5944 } 5945 jt = r.task; 5946 } 5947 } 5948 5949 // Might it be at the top? 5950 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5951 return N-1; 5952 } 5953 5954 return -1; 5955 } 5956 5957 /** 5958 * TODO: Add mController hook 5959 */ 5960 public void moveTaskToFront(int task, int flags, Bundle options) { 5961 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5962 "moveTaskToFront()"); 5963 5964 synchronized(this) { 5965 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5966 Binder.getCallingUid(), "Task to front")) { 5967 ActivityOptions.abort(options); 5968 return; 5969 } 5970 final long origId = Binder.clearCallingIdentity(); 5971 try { 5972 TaskRecord tr = taskForIdLocked(task); 5973 if (tr != null) { 5974 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5975 mMainStack.mUserLeaving = true; 5976 } 5977 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5978 // Caller wants the home activity moved with it. To accomplish this, 5979 // we'll just move the home task to the top first. 5980 mMainStack.moveHomeToFrontLocked(); 5981 } 5982 mMainStack.moveTaskToFrontLocked(tr, null, options); 5983 return; 5984 } 5985 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5986 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5987 if (hr.task.taskId == task) { 5988 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5989 mMainStack.mUserLeaving = true; 5990 } 5991 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5992 // Caller wants the home activity moved with it. To accomplish this, 5993 // we'll just move the home task to the top first. 5994 mMainStack.moveHomeToFrontLocked(); 5995 } 5996 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5997 return; 5998 } 5999 } 6000 } finally { 6001 Binder.restoreCallingIdentity(origId); 6002 } 6003 ActivityOptions.abort(options); 6004 } 6005 } 6006 6007 public void moveTaskToBack(int task) { 6008 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6009 "moveTaskToBack()"); 6010 6011 synchronized(this) { 6012 if (mMainStack.mResumedActivity != null 6013 && mMainStack.mResumedActivity.task.taskId == task) { 6014 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6015 Binder.getCallingUid(), "Task to back")) { 6016 return; 6017 } 6018 } 6019 final long origId = Binder.clearCallingIdentity(); 6020 mMainStack.moveTaskToBackLocked(task, null); 6021 Binder.restoreCallingIdentity(origId); 6022 } 6023 } 6024 6025 /** 6026 * Moves an activity, and all of the other activities within the same task, to the bottom 6027 * of the history stack. The activity's order within the task is unchanged. 6028 * 6029 * @param token A reference to the activity we wish to move 6030 * @param nonRoot If false then this only works if the activity is the root 6031 * of a task; if true it will work for any activity in a task. 6032 * @return Returns true if the move completed, false if not. 6033 */ 6034 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6035 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6036 synchronized(this) { 6037 final long origId = Binder.clearCallingIdentity(); 6038 int taskId = getTaskForActivityLocked(token, !nonRoot); 6039 if (taskId >= 0) { 6040 return mMainStack.moveTaskToBackLocked(taskId, null); 6041 } 6042 Binder.restoreCallingIdentity(origId); 6043 } 6044 return false; 6045 } 6046 6047 public void moveTaskBackwards(int task) { 6048 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6049 "moveTaskBackwards()"); 6050 6051 synchronized(this) { 6052 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6053 Binder.getCallingUid(), "Task backwards")) { 6054 return; 6055 } 6056 final long origId = Binder.clearCallingIdentity(); 6057 moveTaskBackwardsLocked(task); 6058 Binder.restoreCallingIdentity(origId); 6059 } 6060 } 6061 6062 private final void moveTaskBackwardsLocked(int task) { 6063 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6064 } 6065 6066 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6067 synchronized(this) { 6068 return getTaskForActivityLocked(token, onlyRoot); 6069 } 6070 } 6071 6072 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6073 final int N = mMainStack.mHistory.size(); 6074 TaskRecord lastTask = null; 6075 for (int i=0; i<N; i++) { 6076 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6077 if (r.appToken == token) { 6078 if (!onlyRoot || lastTask != r.task) { 6079 return r.task.taskId; 6080 } 6081 return -1; 6082 } 6083 lastTask = r.task; 6084 } 6085 6086 return -1; 6087 } 6088 6089 // ========================================================= 6090 // THUMBNAILS 6091 // ========================================================= 6092 6093 public void reportThumbnail(IBinder token, 6094 Bitmap thumbnail, CharSequence description) { 6095 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6096 final long origId = Binder.clearCallingIdentity(); 6097 sendPendingThumbnail(null, token, thumbnail, description, true); 6098 Binder.restoreCallingIdentity(origId); 6099 } 6100 6101 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6102 Bitmap thumbnail, CharSequence description, boolean always) { 6103 TaskRecord task = null; 6104 ArrayList receivers = null; 6105 6106 //System.out.println("Send pending thumbnail: " + r); 6107 6108 synchronized(this) { 6109 if (r == null) { 6110 r = mMainStack.isInStackLocked(token); 6111 if (r == null) { 6112 return; 6113 } 6114 } 6115 if (thumbnail == null && r.thumbHolder != null) { 6116 thumbnail = r.thumbHolder.lastThumbnail; 6117 description = r.thumbHolder.lastDescription; 6118 } 6119 if (thumbnail == null && !always) { 6120 // If there is no thumbnail, and this entry is not actually 6121 // going away, then abort for now and pick up the next 6122 // thumbnail we get. 6123 return; 6124 } 6125 task = r.task; 6126 6127 int N = mPendingThumbnails.size(); 6128 int i=0; 6129 while (i<N) { 6130 PendingThumbnailsRecord pr = 6131 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6132 //System.out.println("Looking in " + pr.pendingRecords); 6133 if (pr.pendingRecords.remove(r)) { 6134 if (receivers == null) { 6135 receivers = new ArrayList(); 6136 } 6137 receivers.add(pr); 6138 if (pr.pendingRecords.size() == 0) { 6139 pr.finished = true; 6140 mPendingThumbnails.remove(i); 6141 N--; 6142 continue; 6143 } 6144 } 6145 i++; 6146 } 6147 } 6148 6149 if (receivers != null) { 6150 final int N = receivers.size(); 6151 for (int i=0; i<N; i++) { 6152 try { 6153 PendingThumbnailsRecord pr = 6154 (PendingThumbnailsRecord)receivers.get(i); 6155 pr.receiver.newThumbnail( 6156 task != null ? task.taskId : -1, thumbnail, description); 6157 if (pr.finished) { 6158 pr.receiver.finished(); 6159 } 6160 } catch (Exception e) { 6161 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6162 } 6163 } 6164 } 6165 } 6166 6167 // ========================================================= 6168 // CONTENT PROVIDERS 6169 // ========================================================= 6170 6171 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6172 List<ProviderInfo> providers = null; 6173 try { 6174 providers = AppGlobals.getPackageManager(). 6175 queryContentProviders(app.processName, app.uid, 6176 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6177 } catch (RemoteException ex) { 6178 } 6179 if (DEBUG_MU) 6180 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6181 int userId = app.userId; 6182 if (providers != null) { 6183 int N = providers.size(); 6184 for (int i=0; i<N; i++) { 6185 ProviderInfo cpi = 6186 (ProviderInfo)providers.get(i); 6187 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6188 cpi.name, cpi.flags); 6189 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6190 // This is a singleton provider, but a user besides the 6191 // default user is asking to initialize a process it runs 6192 // in... well, no, it doesn't actually run in this process, 6193 // it runs in the process of the default user. Get rid of it. 6194 providers.remove(i); 6195 N--; 6196 continue; 6197 } 6198 6199 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6200 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6201 if (cpr == null) { 6202 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6203 mProviderMap.putProviderByClass(comp, cpr); 6204 } 6205 if (DEBUG_MU) 6206 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6207 app.pubProviders.put(cpi.name, cpr); 6208 app.addPackage(cpi.applicationInfo.packageName); 6209 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6210 } 6211 } 6212 return providers; 6213 } 6214 6215 /** 6216 * Check if {@link ProcessRecord} has a possible chance at accessing the 6217 * given {@link ProviderInfo}. Final permission checking is always done 6218 * in {@link ContentProvider}. 6219 */ 6220 private final String checkContentProviderPermissionLocked( 6221 ProviderInfo cpi, ProcessRecord r) { 6222 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6223 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6224 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6225 cpi.applicationInfo.uid, cpi.exported) 6226 == PackageManager.PERMISSION_GRANTED) { 6227 return null; 6228 } 6229 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6230 cpi.applicationInfo.uid, cpi.exported) 6231 == PackageManager.PERMISSION_GRANTED) { 6232 return null; 6233 } 6234 6235 PathPermission[] pps = cpi.pathPermissions; 6236 if (pps != null) { 6237 int i = pps.length; 6238 while (i > 0) { 6239 i--; 6240 PathPermission pp = pps[i]; 6241 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6242 cpi.applicationInfo.uid, cpi.exported) 6243 == PackageManager.PERMISSION_GRANTED) { 6244 return null; 6245 } 6246 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6247 cpi.applicationInfo.uid, cpi.exported) 6248 == PackageManager.PERMISSION_GRANTED) { 6249 return null; 6250 } 6251 } 6252 } 6253 6254 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6255 if (perms != null) { 6256 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6257 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6258 return null; 6259 } 6260 } 6261 } 6262 6263 String msg; 6264 if (!cpi.exported) { 6265 msg = "Permission Denial: opening provider " + cpi.name 6266 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6267 + ", uid=" + callingUid + ") that is not exported from uid " 6268 + cpi.applicationInfo.uid; 6269 } else { 6270 msg = "Permission Denial: opening provider " + cpi.name 6271 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6272 + ", uid=" + callingUid + ") requires " 6273 + cpi.readPermission + " or " + cpi.writePermission; 6274 } 6275 Slog.w(TAG, msg); 6276 return msg; 6277 } 6278 6279 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6280 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6281 if (r != null) { 6282 for (int i=0; i<r.conProviders.size(); i++) { 6283 ContentProviderConnection conn = r.conProviders.get(i); 6284 if (conn.provider == cpr) { 6285 if (DEBUG_PROVIDER) Slog.v(TAG, 6286 "Adding provider requested by " 6287 + r.processName + " from process " 6288 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6289 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6290 if (stable) { 6291 conn.stableCount++; 6292 conn.numStableIncs++; 6293 } else { 6294 conn.unstableCount++; 6295 conn.numUnstableIncs++; 6296 } 6297 return conn; 6298 } 6299 } 6300 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6301 if (stable) { 6302 conn.stableCount = 1; 6303 conn.numStableIncs = 1; 6304 } else { 6305 conn.unstableCount = 1; 6306 conn.numUnstableIncs = 1; 6307 } 6308 cpr.connections.add(conn); 6309 r.conProviders.add(conn); 6310 return conn; 6311 } 6312 cpr.addExternalProcessHandleLocked(externalProcessToken); 6313 return null; 6314 } 6315 6316 boolean decProviderCountLocked(ContentProviderConnection conn, 6317 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6318 if (conn != null) { 6319 cpr = conn.provider; 6320 if (DEBUG_PROVIDER) Slog.v(TAG, 6321 "Removing provider requested by " 6322 + conn.client.processName + " from process " 6323 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6324 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6325 if (stable) { 6326 conn.stableCount--; 6327 } else { 6328 conn.unstableCount--; 6329 } 6330 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6331 cpr.connections.remove(conn); 6332 conn.client.conProviders.remove(conn); 6333 return true; 6334 } 6335 return false; 6336 } 6337 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6338 return false; 6339 } 6340 6341 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6342 String name, IBinder token, boolean stable, int userId) { 6343 ContentProviderRecord cpr; 6344 ContentProviderConnection conn = null; 6345 ProviderInfo cpi = null; 6346 6347 synchronized(this) { 6348 ProcessRecord r = null; 6349 if (caller != null) { 6350 r = getRecordForAppLocked(caller); 6351 if (r == null) { 6352 throw new SecurityException( 6353 "Unable to find app for caller " + caller 6354 + " (pid=" + Binder.getCallingPid() 6355 + ") when getting content provider " + name); 6356 } 6357 if (r.userId != userId) { 6358 throw new SecurityException("Calling requested user " + userId 6359 + " but app is user " + r.userId); 6360 } 6361 } 6362 6363 // First check if this content provider has been published... 6364 cpr = mProviderMap.getProviderByName(name, userId); 6365 boolean providerRunning = cpr != null; 6366 if (providerRunning) { 6367 cpi = cpr.info; 6368 String msg; 6369 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6370 throw new SecurityException(msg); 6371 } 6372 6373 if (r != null && cpr.canRunHere(r)) { 6374 // This provider has been published or is in the process 6375 // of being published... but it is also allowed to run 6376 // in the caller's process, so don't make a connection 6377 // and just let the caller instantiate its own instance. 6378 ContentProviderHolder holder = cpr.newHolder(null); 6379 // don't give caller the provider object, it needs 6380 // to make its own. 6381 holder.provider = null; 6382 return holder; 6383 } 6384 6385 final long origId = Binder.clearCallingIdentity(); 6386 6387 // In this case the provider instance already exists, so we can 6388 // return it right away. 6389 conn = incProviderCountLocked(r, cpr, token, stable); 6390 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6391 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6392 // If this is a perceptible app accessing the provider, 6393 // make sure to count it as being accessed and thus 6394 // back up on the LRU list. This is good because 6395 // content providers are often expensive to start. 6396 updateLruProcessLocked(cpr.proc, false, true); 6397 } 6398 } 6399 6400 if (cpr.proc != null) { 6401 if (false) { 6402 if (cpr.name.flattenToShortString().equals( 6403 "com.android.providers.calendar/.CalendarProvider2")) { 6404 Slog.v(TAG, "****************** KILLING " 6405 + cpr.name.flattenToShortString()); 6406 Process.killProcess(cpr.proc.pid); 6407 } 6408 } 6409 boolean success = updateOomAdjLocked(cpr.proc); 6410 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6411 // NOTE: there is still a race here where a signal could be 6412 // pending on the process even though we managed to update its 6413 // adj level. Not sure what to do about this, but at least 6414 // the race is now smaller. 6415 if (!success) { 6416 // Uh oh... it looks like the provider's process 6417 // has been killed on us. We need to wait for a new 6418 // process to be started, and make sure its death 6419 // doesn't kill our process. 6420 Slog.i(TAG, 6421 "Existing provider " + cpr.name.flattenToShortString() 6422 + " is crashing; detaching " + r); 6423 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6424 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6425 if (!lastRef) { 6426 // This wasn't the last ref our process had on 6427 // the provider... we have now been killed, bail. 6428 return null; 6429 } 6430 providerRunning = false; 6431 conn = null; 6432 } 6433 } 6434 6435 Binder.restoreCallingIdentity(origId); 6436 } 6437 6438 boolean singleton; 6439 if (!providerRunning) { 6440 try { 6441 cpi = AppGlobals.getPackageManager(). 6442 resolveContentProvider(name, 6443 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6444 } catch (RemoteException ex) { 6445 } 6446 if (cpi == null) { 6447 return null; 6448 } 6449 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6450 cpi.name, cpi.flags); 6451 if (singleton) { 6452 userId = 0; 6453 } 6454 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6455 6456 String msg; 6457 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6458 throw new SecurityException(msg); 6459 } 6460 6461 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6462 && !cpi.processName.equals("system")) { 6463 // If this content provider does not run in the system 6464 // process, and the system is not yet ready to run other 6465 // processes, then fail fast instead of hanging. 6466 throw new IllegalArgumentException( 6467 "Attempt to launch content provider before system ready"); 6468 } 6469 6470 // Make sure that the user who owns this provider is started. If not, 6471 // we don't want to allow it to run. 6472 if (mStartedUsers.get(userId) == null) { 6473 Slog.w(TAG, "Unable to launch app " 6474 + cpi.applicationInfo.packageName + "/" 6475 + cpi.applicationInfo.uid + " for provider " 6476 + name + ": user " + userId + " is stopped"); 6477 return null; 6478 } 6479 6480 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6481 cpr = mProviderMap.getProviderByClass(comp, userId); 6482 final boolean firstClass = cpr == null; 6483 if (firstClass) { 6484 try { 6485 ApplicationInfo ai = 6486 AppGlobals.getPackageManager(). 6487 getApplicationInfo( 6488 cpi.applicationInfo.packageName, 6489 STOCK_PM_FLAGS, userId); 6490 if (ai == null) { 6491 Slog.w(TAG, "No package info for content provider " 6492 + cpi.name); 6493 return null; 6494 } 6495 ai = getAppInfoForUser(ai, userId); 6496 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6497 } catch (RemoteException ex) { 6498 // pm is in same process, this will never happen. 6499 } 6500 } 6501 6502 if (r != null && cpr.canRunHere(r)) { 6503 // If this is a multiprocess provider, then just return its 6504 // info and allow the caller to instantiate it. Only do 6505 // this if the provider is the same user as the caller's 6506 // process, or can run as root (so can be in any process). 6507 return cpr.newHolder(null); 6508 } 6509 6510 if (DEBUG_PROVIDER) { 6511 RuntimeException e = new RuntimeException("here"); 6512 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6513 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6514 } 6515 6516 // This is single process, and our app is now connecting to it. 6517 // See if we are already in the process of launching this 6518 // provider. 6519 final int N = mLaunchingProviders.size(); 6520 int i; 6521 for (i=0; i<N; i++) { 6522 if (mLaunchingProviders.get(i) == cpr) { 6523 break; 6524 } 6525 } 6526 6527 // If the provider is not already being launched, then get it 6528 // started. 6529 if (i >= N) { 6530 final long origId = Binder.clearCallingIdentity(); 6531 6532 try { 6533 // Content provider is now in use, its package can't be stopped. 6534 try { 6535 AppGlobals.getPackageManager().setPackageStoppedState( 6536 cpr.appInfo.packageName, false, userId); 6537 } catch (RemoteException e) { 6538 } catch (IllegalArgumentException e) { 6539 Slog.w(TAG, "Failed trying to unstop package " 6540 + cpr.appInfo.packageName + ": " + e); 6541 } 6542 6543 ProcessRecord proc = startProcessLocked(cpi.processName, 6544 cpr.appInfo, false, 0, "content provider", 6545 new ComponentName(cpi.applicationInfo.packageName, 6546 cpi.name), false, false); 6547 if (proc == null) { 6548 Slog.w(TAG, "Unable to launch app " 6549 + cpi.applicationInfo.packageName + "/" 6550 + cpi.applicationInfo.uid + " for provider " 6551 + name + ": process is bad"); 6552 return null; 6553 } 6554 cpr.launchingApp = proc; 6555 mLaunchingProviders.add(cpr); 6556 } finally { 6557 Binder.restoreCallingIdentity(origId); 6558 } 6559 } 6560 6561 // Make sure the provider is published (the same provider class 6562 // may be published under multiple names). 6563 if (firstClass) { 6564 mProviderMap.putProviderByClass(comp, cpr); 6565 } 6566 6567 mProviderMap.putProviderByName(name, cpr); 6568 conn = incProviderCountLocked(r, cpr, token, stable); 6569 if (conn != null) { 6570 conn.waiting = true; 6571 } 6572 } 6573 } 6574 6575 // Wait for the provider to be published... 6576 synchronized (cpr) { 6577 while (cpr.provider == null) { 6578 if (cpr.launchingApp == null) { 6579 Slog.w(TAG, "Unable to launch app " 6580 + cpi.applicationInfo.packageName + "/" 6581 + cpi.applicationInfo.uid + " for provider " 6582 + name + ": launching app became null"); 6583 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6584 cpi.applicationInfo.packageName, 6585 cpi.applicationInfo.uid, name); 6586 return null; 6587 } 6588 try { 6589 if (DEBUG_MU) { 6590 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6591 + cpr.launchingApp); 6592 } 6593 if (conn != null) { 6594 conn.waiting = true; 6595 } 6596 cpr.wait(); 6597 } catch (InterruptedException ex) { 6598 } finally { 6599 if (conn != null) { 6600 conn.waiting = false; 6601 } 6602 } 6603 } 6604 } 6605 return cpr != null ? cpr.newHolder(conn) : null; 6606 } 6607 6608 public final ContentProviderHolder getContentProvider( 6609 IApplicationThread caller, String name, boolean stable) { 6610 enforceNotIsolatedCaller("getContentProvider"); 6611 if (caller == null) { 6612 String msg = "null IApplicationThread when getting content provider " 6613 + name; 6614 Slog.w(TAG, msg); 6615 throw new SecurityException(msg); 6616 } 6617 6618 return getContentProviderImpl(caller, name, null, stable, 6619 UserHandle.getCallingUserId()); 6620 } 6621 6622 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6623 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6624 "Do not have permission in call getContentProviderExternal()"); 6625 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6626 } 6627 6628 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6629 IBinder token, int userId) { 6630 return getContentProviderImpl(null, name, token, true, userId); 6631 } 6632 6633 /** 6634 * Drop a content provider from a ProcessRecord's bookkeeping 6635 * @param cpr 6636 */ 6637 public void removeContentProvider(IBinder connection, boolean stable) { 6638 enforceNotIsolatedCaller("removeContentProvider"); 6639 synchronized (this) { 6640 ContentProviderConnection conn; 6641 try { 6642 conn = (ContentProviderConnection)connection; 6643 } catch (ClassCastException e) { 6644 String msg ="removeContentProvider: " + connection 6645 + " not a ContentProviderConnection"; 6646 Slog.w(TAG, msg); 6647 throw new IllegalArgumentException(msg); 6648 } 6649 if (conn == null) { 6650 throw new NullPointerException("connection is null"); 6651 } 6652 if (decProviderCountLocked(conn, null, null, stable)) { 6653 updateOomAdjLocked(); 6654 } 6655 } 6656 } 6657 6658 public void removeContentProviderExternal(String name, IBinder token) { 6659 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6660 "Do not have permission in call removeContentProviderExternal()"); 6661 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6662 } 6663 6664 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6665 synchronized (this) { 6666 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6667 if(cpr == null) { 6668 //remove from mProvidersByClass 6669 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6670 return; 6671 } 6672 6673 //update content provider record entry info 6674 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6675 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6676 if (localCpr.hasExternalProcessHandles()) { 6677 if (localCpr.removeExternalProcessHandleLocked(token)) { 6678 updateOomAdjLocked(); 6679 } else { 6680 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6681 + " with no external reference for token: " 6682 + token + "."); 6683 } 6684 } else { 6685 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6686 + " with no external references."); 6687 } 6688 } 6689 } 6690 6691 public final void publishContentProviders(IApplicationThread caller, 6692 List<ContentProviderHolder> providers) { 6693 if (providers == null) { 6694 return; 6695 } 6696 6697 enforceNotIsolatedCaller("publishContentProviders"); 6698 synchronized (this) { 6699 final ProcessRecord r = getRecordForAppLocked(caller); 6700 if (DEBUG_MU) 6701 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6702 if (r == null) { 6703 throw new SecurityException( 6704 "Unable to find app for caller " + caller 6705 + " (pid=" + Binder.getCallingPid() 6706 + ") when publishing content providers"); 6707 } 6708 6709 final long origId = Binder.clearCallingIdentity(); 6710 6711 final int N = providers.size(); 6712 for (int i=0; i<N; i++) { 6713 ContentProviderHolder src = providers.get(i); 6714 if (src == null || src.info == null || src.provider == null) { 6715 continue; 6716 } 6717 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6718 if (DEBUG_MU) 6719 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6720 if (dst != null) { 6721 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6722 mProviderMap.putProviderByClass(comp, dst); 6723 String names[] = dst.info.authority.split(";"); 6724 for (int j = 0; j < names.length; j++) { 6725 mProviderMap.putProviderByName(names[j], dst); 6726 } 6727 6728 int NL = mLaunchingProviders.size(); 6729 int j; 6730 for (j=0; j<NL; j++) { 6731 if (mLaunchingProviders.get(j) == dst) { 6732 mLaunchingProviders.remove(j); 6733 j--; 6734 NL--; 6735 } 6736 } 6737 synchronized (dst) { 6738 dst.provider = src.provider; 6739 dst.proc = r; 6740 dst.notifyAll(); 6741 } 6742 updateOomAdjLocked(r); 6743 } 6744 } 6745 6746 Binder.restoreCallingIdentity(origId); 6747 } 6748 } 6749 6750 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6751 ContentProviderConnection conn; 6752 try { 6753 conn = (ContentProviderConnection)connection; 6754 } catch (ClassCastException e) { 6755 String msg ="refContentProvider: " + connection 6756 + " not a ContentProviderConnection"; 6757 Slog.w(TAG, msg); 6758 throw new IllegalArgumentException(msg); 6759 } 6760 if (conn == null) { 6761 throw new NullPointerException("connection is null"); 6762 } 6763 6764 synchronized (this) { 6765 if (stable > 0) { 6766 conn.numStableIncs += stable; 6767 } 6768 stable = conn.stableCount + stable; 6769 if (stable < 0) { 6770 throw new IllegalStateException("stableCount < 0: " + stable); 6771 } 6772 6773 if (unstable > 0) { 6774 conn.numUnstableIncs += unstable; 6775 } 6776 unstable = conn.unstableCount + unstable; 6777 if (unstable < 0) { 6778 throw new IllegalStateException("unstableCount < 0: " + unstable); 6779 } 6780 6781 if ((stable+unstable) <= 0) { 6782 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6783 + stable + " unstable=" + unstable); 6784 } 6785 conn.stableCount = stable; 6786 conn.unstableCount = unstable; 6787 return !conn.dead; 6788 } 6789 } 6790 6791 public void unstableProviderDied(IBinder connection) { 6792 ContentProviderConnection conn; 6793 try { 6794 conn = (ContentProviderConnection)connection; 6795 } catch (ClassCastException e) { 6796 String msg ="refContentProvider: " + connection 6797 + " not a ContentProviderConnection"; 6798 Slog.w(TAG, msg); 6799 throw new IllegalArgumentException(msg); 6800 } 6801 if (conn == null) { 6802 throw new NullPointerException("connection is null"); 6803 } 6804 6805 // Safely retrieve the content provider associated with the connection. 6806 IContentProvider provider; 6807 synchronized (this) { 6808 provider = conn.provider.provider; 6809 } 6810 6811 if (provider == null) { 6812 // Um, yeah, we're way ahead of you. 6813 return; 6814 } 6815 6816 // Make sure the caller is being honest with us. 6817 if (provider.asBinder().pingBinder()) { 6818 // Er, no, still looks good to us. 6819 synchronized (this) { 6820 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6821 + " says " + conn + " died, but we don't agree"); 6822 return; 6823 } 6824 } 6825 6826 // Well look at that! It's dead! 6827 synchronized (this) { 6828 if (conn.provider.provider != provider) { 6829 // But something changed... good enough. 6830 return; 6831 } 6832 6833 ProcessRecord proc = conn.provider.proc; 6834 if (proc == null || proc.thread == null) { 6835 // Seems like the process is already cleaned up. 6836 return; 6837 } 6838 6839 // As far as we're concerned, this is just like receiving a 6840 // death notification... just a bit prematurely. 6841 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6842 + ") early provider death"); 6843 final long ident = Binder.clearCallingIdentity(); 6844 try { 6845 appDiedLocked(proc, proc.pid, proc.thread); 6846 } finally { 6847 Binder.restoreCallingIdentity(ident); 6848 } 6849 } 6850 } 6851 6852 public static final void installSystemProviders() { 6853 List<ProviderInfo> providers; 6854 synchronized (mSelf) { 6855 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6856 providers = mSelf.generateApplicationProvidersLocked(app); 6857 if (providers != null) { 6858 for (int i=providers.size()-1; i>=0; i--) { 6859 ProviderInfo pi = (ProviderInfo)providers.get(i); 6860 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6861 Slog.w(TAG, "Not installing system proc provider " + pi.name 6862 + ": not system .apk"); 6863 providers.remove(i); 6864 } 6865 } 6866 } 6867 } 6868 if (providers != null) { 6869 mSystemThread.installSystemProviders(providers); 6870 } 6871 6872 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6873 6874 mSelf.mUsageStatsService.monitorPackages(); 6875 } 6876 6877 /** 6878 * Allows app to retrieve the MIME type of a URI without having permission 6879 * to access its content provider. 6880 * 6881 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6882 * 6883 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6884 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6885 */ 6886 public String getProviderMimeType(Uri uri, int userId) { 6887 enforceNotIsolatedCaller("getProviderMimeType"); 6888 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6889 userId, false, true, "getProviderMimeType", null); 6890 final String name = uri.getAuthority(); 6891 final long ident = Binder.clearCallingIdentity(); 6892 ContentProviderHolder holder = null; 6893 6894 try { 6895 holder = getContentProviderExternalUnchecked(name, null, userId); 6896 if (holder != null) { 6897 return holder.provider.getType(uri); 6898 } 6899 } catch (RemoteException e) { 6900 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6901 return null; 6902 } finally { 6903 if (holder != null) { 6904 removeContentProviderExternalUnchecked(name, null, userId); 6905 } 6906 Binder.restoreCallingIdentity(ident); 6907 } 6908 6909 return null; 6910 } 6911 6912 // ========================================================= 6913 // GLOBAL MANAGEMENT 6914 // ========================================================= 6915 6916 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6917 ApplicationInfo info, String customProcess, boolean isolated) { 6918 String proc = customProcess != null ? customProcess : info.processName; 6919 BatteryStatsImpl.Uid.Proc ps = null; 6920 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6921 int uid = info.uid; 6922 if (isolated) { 6923 int userId = UserHandle.getUserId(uid); 6924 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6925 uid = 0; 6926 while (true) { 6927 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6928 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6929 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6930 } 6931 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6932 mNextIsolatedProcessUid++; 6933 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6934 // No process for this uid, use it. 6935 break; 6936 } 6937 stepsLeft--; 6938 if (stepsLeft <= 0) { 6939 return null; 6940 } 6941 } 6942 } 6943 synchronized (stats) { 6944 ps = stats.getProcessStatsLocked(info.uid, proc); 6945 } 6946 return new ProcessRecord(ps, thread, info, proc, uid); 6947 } 6948 6949 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6950 ProcessRecord app; 6951 if (!isolated) { 6952 app = getProcessRecordLocked(info.processName, info.uid); 6953 } else { 6954 app = null; 6955 } 6956 6957 if (app == null) { 6958 app = newProcessRecordLocked(null, info, null, isolated); 6959 mProcessNames.put(info.processName, app.uid, app); 6960 if (isolated) { 6961 mIsolatedProcesses.put(app.uid, app); 6962 } 6963 updateLruProcessLocked(app, true, true); 6964 } 6965 6966 // This package really, really can not be stopped. 6967 try { 6968 AppGlobals.getPackageManager().setPackageStoppedState( 6969 info.packageName, false, UserHandle.getUserId(app.uid)); 6970 } catch (RemoteException e) { 6971 } catch (IllegalArgumentException e) { 6972 Slog.w(TAG, "Failed trying to unstop package " 6973 + info.packageName + ": " + e); 6974 } 6975 6976 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6977 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6978 app.persistent = true; 6979 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6980 } 6981 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6982 mPersistentStartingProcesses.add(app); 6983 startProcessLocked(app, "added application", app.processName); 6984 } 6985 6986 return app; 6987 } 6988 6989 public void unhandledBack() { 6990 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6991 "unhandledBack()"); 6992 6993 synchronized(this) { 6994 int count = mMainStack.mHistory.size(); 6995 if (DEBUG_SWITCH) Slog.d( 6996 TAG, "Performing unhandledBack(): stack size = " + count); 6997 if (count > 1) { 6998 final long origId = Binder.clearCallingIdentity(); 6999 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7000 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7001 Binder.restoreCallingIdentity(origId); 7002 } 7003 } 7004 } 7005 7006 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7007 enforceNotIsolatedCaller("openContentUri"); 7008 final int userId = UserHandle.getCallingUserId(); 7009 String name = uri.getAuthority(); 7010 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7011 ParcelFileDescriptor pfd = null; 7012 if (cph != null) { 7013 // We record the binder invoker's uid in thread-local storage before 7014 // going to the content provider to open the file. Later, in the code 7015 // that handles all permissions checks, we look for this uid and use 7016 // that rather than the Activity Manager's own uid. The effect is that 7017 // we do the check against the caller's permissions even though it looks 7018 // to the content provider like the Activity Manager itself is making 7019 // the request. 7020 sCallerIdentity.set(new Identity( 7021 Binder.getCallingPid(), Binder.getCallingUid())); 7022 try { 7023 pfd = cph.provider.openFile(uri, "r"); 7024 } catch (FileNotFoundException e) { 7025 // do nothing; pfd will be returned null 7026 } finally { 7027 // Ensure that whatever happens, we clean up the identity state 7028 sCallerIdentity.remove(); 7029 } 7030 7031 // We've got the fd now, so we're done with the provider. 7032 removeContentProviderExternalUnchecked(name, null, userId); 7033 } else { 7034 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7035 } 7036 return pfd; 7037 } 7038 7039 // Actually is sleeping or shutting down or whatever else in the future 7040 // is an inactive state. 7041 public boolean isSleeping() { 7042 return mSleeping || mShuttingDown; 7043 } 7044 7045 public void goingToSleep() { 7046 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7047 != PackageManager.PERMISSION_GRANTED) { 7048 throw new SecurityException("Requires permission " 7049 + android.Manifest.permission.DEVICE_POWER); 7050 } 7051 7052 synchronized(this) { 7053 mWentToSleep = true; 7054 updateEventDispatchingLocked(); 7055 7056 if (!mSleeping) { 7057 mSleeping = true; 7058 mMainStack.stopIfSleepingLocked(); 7059 7060 // Initialize the wake times of all processes. 7061 checkExcessivePowerUsageLocked(false); 7062 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7063 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7064 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7065 } 7066 } 7067 } 7068 7069 public boolean shutdown(int timeout) { 7070 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7071 != PackageManager.PERMISSION_GRANTED) { 7072 throw new SecurityException("Requires permission " 7073 + android.Manifest.permission.SHUTDOWN); 7074 } 7075 7076 boolean timedout = false; 7077 7078 synchronized(this) { 7079 mShuttingDown = true; 7080 updateEventDispatchingLocked(); 7081 7082 if (mMainStack.mResumedActivity != null) { 7083 mMainStack.stopIfSleepingLocked(); 7084 final long endTime = System.currentTimeMillis() + timeout; 7085 while (mMainStack.mResumedActivity != null 7086 || mMainStack.mPausingActivity != null) { 7087 long delay = endTime - System.currentTimeMillis(); 7088 if (delay <= 0) { 7089 Slog.w(TAG, "Activity manager shutdown timed out"); 7090 timedout = true; 7091 break; 7092 } 7093 try { 7094 this.wait(); 7095 } catch (InterruptedException e) { 7096 } 7097 } 7098 } 7099 } 7100 7101 mUsageStatsService.shutdown(); 7102 mBatteryStatsService.shutdown(); 7103 7104 return timedout; 7105 } 7106 7107 public final void activitySlept(IBinder token) { 7108 if (localLOGV) Slog.v( 7109 TAG, "Activity slept: token=" + token); 7110 7111 ActivityRecord r = null; 7112 7113 final long origId = Binder.clearCallingIdentity(); 7114 7115 synchronized (this) { 7116 r = mMainStack.isInStackLocked(token); 7117 if (r != null) { 7118 mMainStack.activitySleptLocked(r); 7119 } 7120 } 7121 7122 Binder.restoreCallingIdentity(origId); 7123 } 7124 7125 private void comeOutOfSleepIfNeededLocked() { 7126 if (!mWentToSleep && !mLockScreenShown) { 7127 if (mSleeping) { 7128 mSleeping = false; 7129 mMainStack.awakeFromSleepingLocked(); 7130 mMainStack.resumeTopActivityLocked(null); 7131 } 7132 } 7133 } 7134 7135 public void wakingUp() { 7136 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7137 != PackageManager.PERMISSION_GRANTED) { 7138 throw new SecurityException("Requires permission " 7139 + android.Manifest.permission.DEVICE_POWER); 7140 } 7141 7142 synchronized(this) { 7143 mWentToSleep = false; 7144 updateEventDispatchingLocked(); 7145 comeOutOfSleepIfNeededLocked(); 7146 } 7147 } 7148 7149 private void updateEventDispatchingLocked() { 7150 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7151 } 7152 7153 public void setLockScreenShown(boolean shown) { 7154 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7155 != PackageManager.PERMISSION_GRANTED) { 7156 throw new SecurityException("Requires permission " 7157 + android.Manifest.permission.DEVICE_POWER); 7158 } 7159 7160 synchronized(this) { 7161 mLockScreenShown = shown; 7162 comeOutOfSleepIfNeededLocked(); 7163 } 7164 } 7165 7166 public void stopAppSwitches() { 7167 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7168 != PackageManager.PERMISSION_GRANTED) { 7169 throw new SecurityException("Requires permission " 7170 + android.Manifest.permission.STOP_APP_SWITCHES); 7171 } 7172 7173 synchronized(this) { 7174 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7175 + APP_SWITCH_DELAY_TIME; 7176 mDidAppSwitch = false; 7177 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7178 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7179 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7180 } 7181 } 7182 7183 public void resumeAppSwitches() { 7184 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7185 != PackageManager.PERMISSION_GRANTED) { 7186 throw new SecurityException("Requires permission " 7187 + android.Manifest.permission.STOP_APP_SWITCHES); 7188 } 7189 7190 synchronized(this) { 7191 // Note that we don't execute any pending app switches... we will 7192 // let those wait until either the timeout, or the next start 7193 // activity request. 7194 mAppSwitchesAllowedTime = 0; 7195 } 7196 } 7197 7198 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7199 String name) { 7200 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7201 return true; 7202 } 7203 7204 final int perm = checkComponentPermission( 7205 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7206 callingUid, -1, true); 7207 if (perm == PackageManager.PERMISSION_GRANTED) { 7208 return true; 7209 } 7210 7211 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7212 return false; 7213 } 7214 7215 public void setDebugApp(String packageName, boolean waitForDebugger, 7216 boolean persistent) { 7217 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7218 "setDebugApp()"); 7219 7220 // Note that this is not really thread safe if there are multiple 7221 // callers into it at the same time, but that's not a situation we 7222 // care about. 7223 if (persistent) { 7224 final ContentResolver resolver = mContext.getContentResolver(); 7225 Settings.System.putString( 7226 resolver, Settings.System.DEBUG_APP, 7227 packageName); 7228 Settings.System.putInt( 7229 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7230 waitForDebugger ? 1 : 0); 7231 } 7232 7233 synchronized (this) { 7234 if (!persistent) { 7235 mOrigDebugApp = mDebugApp; 7236 mOrigWaitForDebugger = mWaitForDebugger; 7237 } 7238 mDebugApp = packageName; 7239 mWaitForDebugger = waitForDebugger; 7240 mDebugTransient = !persistent; 7241 if (packageName != null) { 7242 final long origId = Binder.clearCallingIdentity(); 7243 forceStopPackageLocked(packageName, -1, false, false, true, true, 7244 UserHandle.USER_ALL); 7245 Binder.restoreCallingIdentity(origId); 7246 } 7247 } 7248 } 7249 7250 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7251 synchronized (this) { 7252 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7253 if (!isDebuggable) { 7254 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7255 throw new SecurityException("Process not debuggable: " + app.packageName); 7256 } 7257 } 7258 7259 mOpenGlTraceApp = processName; 7260 } 7261 } 7262 7263 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7264 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7265 synchronized (this) { 7266 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7267 if (!isDebuggable) { 7268 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7269 throw new SecurityException("Process not debuggable: " + app.packageName); 7270 } 7271 } 7272 mProfileApp = processName; 7273 mProfileFile = profileFile; 7274 if (mProfileFd != null) { 7275 try { 7276 mProfileFd.close(); 7277 } catch (IOException e) { 7278 } 7279 mProfileFd = null; 7280 } 7281 mProfileFd = profileFd; 7282 mProfileType = 0; 7283 mAutoStopProfiler = autoStopProfiler; 7284 } 7285 } 7286 7287 public void setAlwaysFinish(boolean enabled) { 7288 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7289 "setAlwaysFinish()"); 7290 7291 Settings.System.putInt( 7292 mContext.getContentResolver(), 7293 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7294 7295 synchronized (this) { 7296 mAlwaysFinishActivities = enabled; 7297 } 7298 } 7299 7300 public void setActivityController(IActivityController controller) { 7301 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7302 "setActivityController()"); 7303 synchronized (this) { 7304 mController = controller; 7305 } 7306 } 7307 7308 public boolean isUserAMonkey() { 7309 // For now the fact that there is a controller implies 7310 // we have a monkey. 7311 synchronized (this) { 7312 return mController != null; 7313 } 7314 } 7315 7316 public void registerProcessObserver(IProcessObserver observer) { 7317 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7318 "registerProcessObserver()"); 7319 synchronized (this) { 7320 mProcessObservers.register(observer); 7321 } 7322 } 7323 7324 public void unregisterProcessObserver(IProcessObserver observer) { 7325 synchronized (this) { 7326 mProcessObservers.unregister(observer); 7327 } 7328 } 7329 7330 public void setImmersive(IBinder token, boolean immersive) { 7331 synchronized(this) { 7332 ActivityRecord r = mMainStack.isInStackLocked(token); 7333 if (r == null) { 7334 throw new IllegalArgumentException(); 7335 } 7336 r.immersive = immersive; 7337 } 7338 } 7339 7340 public boolean isImmersive(IBinder token) { 7341 synchronized (this) { 7342 ActivityRecord r = mMainStack.isInStackLocked(token); 7343 if (r == null) { 7344 throw new IllegalArgumentException(); 7345 } 7346 return r.immersive; 7347 } 7348 } 7349 7350 public boolean isTopActivityImmersive() { 7351 enforceNotIsolatedCaller("startActivity"); 7352 synchronized (this) { 7353 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7354 return (r != null) ? r.immersive : false; 7355 } 7356 } 7357 7358 public final void enterSafeMode() { 7359 synchronized(this) { 7360 // It only makes sense to do this before the system is ready 7361 // and started launching other packages. 7362 if (!mSystemReady) { 7363 try { 7364 AppGlobals.getPackageManager().enterSafeMode(); 7365 } catch (RemoteException e) { 7366 } 7367 } 7368 } 7369 } 7370 7371 public final void showSafeModeOverlay() { 7372 View v = LayoutInflater.from(mContext).inflate( 7373 com.android.internal.R.layout.safe_mode, null); 7374 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7375 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7376 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7377 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7378 lp.gravity = Gravity.BOTTOM | Gravity.START; 7379 lp.format = v.getBackground().getOpacity(); 7380 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7381 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7382 ((WindowManager)mContext.getSystemService( 7383 Context.WINDOW_SERVICE)).addView(v, lp); 7384 } 7385 7386 public void noteWakeupAlarm(IIntentSender sender) { 7387 if (!(sender instanceof PendingIntentRecord)) { 7388 return; 7389 } 7390 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7391 synchronized (stats) { 7392 if (mBatteryStatsService.isOnBattery()) { 7393 mBatteryStatsService.enforceCallingPermission(); 7394 PendingIntentRecord rec = (PendingIntentRecord)sender; 7395 int MY_UID = Binder.getCallingUid(); 7396 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7397 BatteryStatsImpl.Uid.Pkg pkg = 7398 stats.getPackageStatsLocked(uid, rec.key.packageName); 7399 pkg.incWakeupsLocked(); 7400 } 7401 } 7402 } 7403 7404 public boolean killPids(int[] pids, String pReason, boolean secure) { 7405 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7406 throw new SecurityException("killPids only available to the system"); 7407 } 7408 String reason = (pReason == null) ? "Unknown" : pReason; 7409 // XXX Note: don't acquire main activity lock here, because the window 7410 // manager calls in with its locks held. 7411 7412 boolean killed = false; 7413 synchronized (mPidsSelfLocked) { 7414 int[] types = new int[pids.length]; 7415 int worstType = 0; 7416 for (int i=0; i<pids.length; i++) { 7417 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7418 if (proc != null) { 7419 int type = proc.setAdj; 7420 types[i] = type; 7421 if (type > worstType) { 7422 worstType = type; 7423 } 7424 } 7425 } 7426 7427 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7428 // then constrain it so we will kill all hidden procs. 7429 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7430 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7431 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7432 } 7433 7434 // If this is not a secure call, don't let it kill processes that 7435 // are important. 7436 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7437 worstType = ProcessList.SERVICE_ADJ; 7438 } 7439 7440 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7441 for (int i=0; i<pids.length; i++) { 7442 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7443 if (proc == null) { 7444 continue; 7445 } 7446 int adj = proc.setAdj; 7447 if (adj >= worstType && !proc.killedBackground) { 7448 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7449 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7450 proc.processName, adj, reason); 7451 killed = true; 7452 proc.killedBackground = true; 7453 Process.killProcessQuiet(pids[i]); 7454 } 7455 } 7456 } 7457 return killed; 7458 } 7459 7460 @Override 7461 public boolean killProcessesBelowForeground(String reason) { 7462 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7463 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7464 } 7465 7466 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7467 } 7468 7469 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7470 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7471 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7472 } 7473 7474 boolean killed = false; 7475 synchronized (mPidsSelfLocked) { 7476 final int size = mPidsSelfLocked.size(); 7477 for (int i = 0; i < size; i++) { 7478 final int pid = mPidsSelfLocked.keyAt(i); 7479 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7480 if (proc == null) continue; 7481 7482 final int adj = proc.setAdj; 7483 if (adj > belowAdj && !proc.killedBackground) { 7484 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7485 EventLog.writeEvent( 7486 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7487 killed = true; 7488 proc.killedBackground = true; 7489 Process.killProcessQuiet(pid); 7490 } 7491 } 7492 } 7493 return killed; 7494 } 7495 7496 public final void startRunning(String pkg, String cls, String action, 7497 String data) { 7498 synchronized(this) { 7499 if (mStartRunning) { 7500 return; 7501 } 7502 mStartRunning = true; 7503 mTopComponent = pkg != null && cls != null 7504 ? new ComponentName(pkg, cls) : null; 7505 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7506 mTopData = data; 7507 if (!mSystemReady) { 7508 return; 7509 } 7510 } 7511 7512 systemReady(null); 7513 } 7514 7515 private void retrieveSettings() { 7516 final ContentResolver resolver = mContext.getContentResolver(); 7517 String debugApp = Settings.System.getString( 7518 resolver, Settings.System.DEBUG_APP); 7519 boolean waitForDebugger = Settings.System.getInt( 7520 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7521 boolean alwaysFinishActivities = Settings.System.getInt( 7522 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7523 7524 Configuration configuration = new Configuration(); 7525 Settings.System.getConfiguration(resolver, configuration); 7526 7527 synchronized (this) { 7528 mDebugApp = mOrigDebugApp = debugApp; 7529 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7530 mAlwaysFinishActivities = alwaysFinishActivities; 7531 // This happens before any activities are started, so we can 7532 // change mConfiguration in-place. 7533 updateConfigurationLocked(configuration, null, false, true); 7534 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7535 } 7536 } 7537 7538 public boolean testIsSystemReady() { 7539 // no need to synchronize(this) just to read & return the value 7540 return mSystemReady; 7541 } 7542 7543 private static File getCalledPreBootReceiversFile() { 7544 File dataDir = Environment.getDataDirectory(); 7545 File systemDir = new File(dataDir, "system"); 7546 File fname = new File(systemDir, "called_pre_boots.dat"); 7547 return fname; 7548 } 7549 7550 static final int LAST_DONE_VERSION = 10000; 7551 7552 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7553 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7554 File file = getCalledPreBootReceiversFile(); 7555 FileInputStream fis = null; 7556 try { 7557 fis = new FileInputStream(file); 7558 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7559 int fvers = dis.readInt(); 7560 if (fvers == LAST_DONE_VERSION) { 7561 String vers = dis.readUTF(); 7562 String codename = dis.readUTF(); 7563 String build = dis.readUTF(); 7564 if (android.os.Build.VERSION.RELEASE.equals(vers) 7565 && android.os.Build.VERSION.CODENAME.equals(codename) 7566 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7567 int num = dis.readInt(); 7568 while (num > 0) { 7569 num--; 7570 String pkg = dis.readUTF(); 7571 String cls = dis.readUTF(); 7572 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7573 } 7574 } 7575 } 7576 } catch (FileNotFoundException e) { 7577 } catch (IOException e) { 7578 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7579 } finally { 7580 if (fis != null) { 7581 try { 7582 fis.close(); 7583 } catch (IOException e) { 7584 } 7585 } 7586 } 7587 return lastDoneReceivers; 7588 } 7589 7590 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7591 File file = getCalledPreBootReceiversFile(); 7592 FileOutputStream fos = null; 7593 DataOutputStream dos = null; 7594 try { 7595 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7596 fos = new FileOutputStream(file); 7597 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7598 dos.writeInt(LAST_DONE_VERSION); 7599 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7600 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7601 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7602 dos.writeInt(list.size()); 7603 for (int i=0; i<list.size(); i++) { 7604 dos.writeUTF(list.get(i).getPackageName()); 7605 dos.writeUTF(list.get(i).getClassName()); 7606 } 7607 } catch (IOException e) { 7608 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7609 file.delete(); 7610 } finally { 7611 FileUtils.sync(fos); 7612 if (dos != null) { 7613 try { 7614 dos.close(); 7615 } catch (IOException e) { 7616 // TODO Auto-generated catch block 7617 e.printStackTrace(); 7618 } 7619 } 7620 } 7621 } 7622 7623 public void systemReady(final Runnable goingCallback) { 7624 synchronized(this) { 7625 if (mSystemReady) { 7626 if (goingCallback != null) goingCallback.run(); 7627 return; 7628 } 7629 7630 // Check to see if there are any update receivers to run. 7631 if (!mDidUpdate) { 7632 if (mWaitingUpdate) { 7633 return; 7634 } 7635 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7636 List<ResolveInfo> ris = null; 7637 try { 7638 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7639 intent, null, 0, 0); 7640 } catch (RemoteException e) { 7641 } 7642 if (ris != null) { 7643 for (int i=ris.size()-1; i>=0; i--) { 7644 if ((ris.get(i).activityInfo.applicationInfo.flags 7645 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7646 ris.remove(i); 7647 } 7648 } 7649 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7650 7651 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7652 7653 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7654 for (int i=0; i<ris.size(); i++) { 7655 ActivityInfo ai = ris.get(i).activityInfo; 7656 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7657 if (lastDoneReceivers.contains(comp)) { 7658 ris.remove(i); 7659 i--; 7660 } 7661 } 7662 7663 for (int i=0; i<ris.size(); i++) { 7664 ActivityInfo ai = ris.get(i).activityInfo; 7665 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7666 doneReceivers.add(comp); 7667 intent.setComponent(comp); 7668 IIntentReceiver finisher = null; 7669 if (i == ris.size()-1) { 7670 finisher = new IIntentReceiver.Stub() { 7671 public void performReceive(Intent intent, int resultCode, 7672 String data, Bundle extras, boolean ordered, 7673 boolean sticky, int sendingUser) { 7674 // The raw IIntentReceiver interface is called 7675 // with the AM lock held, so redispatch to 7676 // execute our code without the lock. 7677 mHandler.post(new Runnable() { 7678 public void run() { 7679 synchronized (ActivityManagerService.this) { 7680 mDidUpdate = true; 7681 } 7682 writeLastDonePreBootReceivers(doneReceivers); 7683 showBootMessage(mContext.getText( 7684 R.string.android_upgrading_complete), 7685 false); 7686 systemReady(goingCallback); 7687 } 7688 }); 7689 } 7690 }; 7691 } 7692 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7693 // XXX also need to send this to stopped users(!!!) 7694 broadcastIntentLocked(null, null, intent, null, finisher, 7695 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7696 UserHandle.USER_ALL); 7697 if (finisher != null) { 7698 mWaitingUpdate = true; 7699 } 7700 } 7701 } 7702 if (mWaitingUpdate) { 7703 return; 7704 } 7705 mDidUpdate = true; 7706 } 7707 7708 mSystemReady = true; 7709 if (!mStartRunning) { 7710 return; 7711 } 7712 } 7713 7714 ArrayList<ProcessRecord> procsToKill = null; 7715 synchronized(mPidsSelfLocked) { 7716 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7717 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7718 if (!isAllowedWhileBooting(proc.info)){ 7719 if (procsToKill == null) { 7720 procsToKill = new ArrayList<ProcessRecord>(); 7721 } 7722 procsToKill.add(proc); 7723 } 7724 } 7725 } 7726 7727 synchronized(this) { 7728 if (procsToKill != null) { 7729 for (int i=procsToKill.size()-1; i>=0; i--) { 7730 ProcessRecord proc = procsToKill.get(i); 7731 Slog.i(TAG, "Removing system update proc: " + proc); 7732 removeProcessLocked(proc, true, false, "system update done"); 7733 } 7734 } 7735 7736 // Now that we have cleaned up any update processes, we 7737 // are ready to start launching real processes and know that 7738 // we won't trample on them any more. 7739 mProcessesReady = true; 7740 } 7741 7742 Slog.i(TAG, "System now ready"); 7743 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7744 SystemClock.uptimeMillis()); 7745 7746 synchronized(this) { 7747 // Make sure we have no pre-ready processes sitting around. 7748 7749 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7750 ResolveInfo ri = mContext.getPackageManager() 7751 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7752 STOCK_PM_FLAGS); 7753 CharSequence errorMsg = null; 7754 if (ri != null) { 7755 ActivityInfo ai = ri.activityInfo; 7756 ApplicationInfo app = ai.applicationInfo; 7757 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7758 mTopAction = Intent.ACTION_FACTORY_TEST; 7759 mTopData = null; 7760 mTopComponent = new ComponentName(app.packageName, 7761 ai.name); 7762 } else { 7763 errorMsg = mContext.getResources().getText( 7764 com.android.internal.R.string.factorytest_not_system); 7765 } 7766 } else { 7767 errorMsg = mContext.getResources().getText( 7768 com.android.internal.R.string.factorytest_no_action); 7769 } 7770 if (errorMsg != null) { 7771 mTopAction = null; 7772 mTopData = null; 7773 mTopComponent = null; 7774 Message msg = Message.obtain(); 7775 msg.what = SHOW_FACTORY_ERROR_MSG; 7776 msg.getData().putCharSequence("msg", errorMsg); 7777 mHandler.sendMessage(msg); 7778 } 7779 } 7780 } 7781 7782 retrieveSettings(); 7783 7784 if (goingCallback != null) goingCallback.run(); 7785 7786 synchronized (this) { 7787 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7788 try { 7789 List apps = AppGlobals.getPackageManager(). 7790 getPersistentApplications(STOCK_PM_FLAGS); 7791 if (apps != null) { 7792 int N = apps.size(); 7793 int i; 7794 for (i=0; i<N; i++) { 7795 ApplicationInfo info 7796 = (ApplicationInfo)apps.get(i); 7797 if (info != null && 7798 !info.packageName.equals("android")) { 7799 addAppLocked(info, false); 7800 } 7801 } 7802 } 7803 } catch (RemoteException ex) { 7804 // pm is in same process, this will never happen. 7805 } 7806 } 7807 7808 // Start up initial activity. 7809 mBooting = true; 7810 7811 try { 7812 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7813 Message msg = Message.obtain(); 7814 msg.what = SHOW_UID_ERROR_MSG; 7815 mHandler.sendMessage(msg); 7816 } 7817 } catch (RemoteException e) { 7818 } 7819 7820 mMainStack.resumeTopActivityLocked(null); 7821 } 7822 } 7823 7824 private boolean makeAppCrashingLocked(ProcessRecord app, 7825 String shortMsg, String longMsg, String stackTrace) { 7826 app.crashing = true; 7827 app.crashingReport = generateProcessError(app, 7828 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7829 startAppProblemLocked(app); 7830 app.stopFreezingAllLocked(); 7831 return handleAppCrashLocked(app); 7832 } 7833 7834 private void makeAppNotRespondingLocked(ProcessRecord app, 7835 String activity, String shortMsg, String longMsg) { 7836 app.notResponding = true; 7837 app.notRespondingReport = generateProcessError(app, 7838 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7839 activity, shortMsg, longMsg, null); 7840 startAppProblemLocked(app); 7841 app.stopFreezingAllLocked(); 7842 } 7843 7844 /** 7845 * Generate a process error record, suitable for attachment to a ProcessRecord. 7846 * 7847 * @param app The ProcessRecord in which the error occurred. 7848 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7849 * ActivityManager.AppErrorStateInfo 7850 * @param activity The activity associated with the crash, if known. 7851 * @param shortMsg Short message describing the crash. 7852 * @param longMsg Long message describing the crash. 7853 * @param stackTrace Full crash stack trace, may be null. 7854 * 7855 * @return Returns a fully-formed AppErrorStateInfo record. 7856 */ 7857 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7858 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7859 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7860 7861 report.condition = condition; 7862 report.processName = app.processName; 7863 report.pid = app.pid; 7864 report.uid = app.info.uid; 7865 report.tag = activity; 7866 report.shortMsg = shortMsg; 7867 report.longMsg = longMsg; 7868 report.stackTrace = stackTrace; 7869 7870 return report; 7871 } 7872 7873 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7874 synchronized (this) { 7875 app.crashing = false; 7876 app.crashingReport = null; 7877 app.notResponding = false; 7878 app.notRespondingReport = null; 7879 if (app.anrDialog == fromDialog) { 7880 app.anrDialog = null; 7881 } 7882 if (app.waitDialog == fromDialog) { 7883 app.waitDialog = null; 7884 } 7885 if (app.pid > 0 && app.pid != MY_PID) { 7886 handleAppCrashLocked(app); 7887 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7888 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7889 app.processName, app.setAdj, "user's request after error"); 7890 Process.killProcessQuiet(app.pid); 7891 } 7892 } 7893 } 7894 7895 private boolean handleAppCrashLocked(ProcessRecord app) { 7896 if (mHeadless) { 7897 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7898 return false; 7899 } 7900 long now = SystemClock.uptimeMillis(); 7901 7902 Long crashTime; 7903 if (!app.isolated) { 7904 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7905 } else { 7906 crashTime = null; 7907 } 7908 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7909 // This process loses! 7910 Slog.w(TAG, "Process " + app.info.processName 7911 + " has crashed too many times: killing!"); 7912 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7913 app.info.processName, app.uid); 7914 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7915 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7916 if (r.app == app) { 7917 Slog.w(TAG, " Force finishing activity " 7918 + r.intent.getComponent().flattenToShortString()); 7919 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7920 null, "crashed", false); 7921 } 7922 } 7923 if (!app.persistent) { 7924 // We don't want to start this process again until the user 7925 // explicitly does so... but for persistent process, we really 7926 // need to keep it running. If a persistent process is actually 7927 // repeatedly crashing, then badness for everyone. 7928 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7929 app.info.processName); 7930 if (!app.isolated) { 7931 // XXX We don't have a way to mark isolated processes 7932 // as bad, since they don't have a peristent identity. 7933 mBadProcesses.put(app.info.processName, app.uid, now); 7934 mProcessCrashTimes.remove(app.info.processName, app.uid); 7935 } 7936 app.bad = true; 7937 app.removed = true; 7938 // Don't let services in this process be restarted and potentially 7939 // annoy the user repeatedly. Unless it is persistent, since those 7940 // processes run critical code. 7941 removeProcessLocked(app, false, false, "crash"); 7942 mMainStack.resumeTopActivityLocked(null); 7943 return false; 7944 } 7945 mMainStack.resumeTopActivityLocked(null); 7946 } else { 7947 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7948 if (r != null && r.app == app) { 7949 // If the top running activity is from this crashing 7950 // process, then terminate it to avoid getting in a loop. 7951 Slog.w(TAG, " Force finishing activity " 7952 + r.intent.getComponent().flattenToShortString()); 7953 int index = mMainStack.indexOfActivityLocked(r); 7954 r.stack.finishActivityLocked(r, index, 7955 Activity.RESULT_CANCELED, null, "crashed", false); 7956 // Also terminate any activities below it that aren't yet 7957 // stopped, to avoid a situation where one will get 7958 // re-start our crashing activity once it gets resumed again. 7959 index--; 7960 if (index >= 0) { 7961 r = (ActivityRecord)mMainStack.mHistory.get(index); 7962 if (r.state == ActivityState.RESUMED 7963 || r.state == ActivityState.PAUSING 7964 || r.state == ActivityState.PAUSED) { 7965 if (!r.isHomeActivity || mHomeProcess != r.app) { 7966 Slog.w(TAG, " Force finishing activity " 7967 + r.intent.getComponent().flattenToShortString()); 7968 r.stack.finishActivityLocked(r, index, 7969 Activity.RESULT_CANCELED, null, "crashed", false); 7970 } 7971 } 7972 } 7973 } 7974 } 7975 7976 // Bump up the crash count of any services currently running in the proc. 7977 if (app.services.size() != 0) { 7978 // Any services running in the application need to be placed 7979 // back in the pending list. 7980 Iterator<ServiceRecord> it = app.services.iterator(); 7981 while (it.hasNext()) { 7982 ServiceRecord sr = it.next(); 7983 sr.crashCount++; 7984 } 7985 } 7986 7987 // If the crashing process is what we consider to be the "home process" and it has been 7988 // replaced by a third-party app, clear the package preferred activities from packages 7989 // with a home activity running in the process to prevent a repeatedly crashing app 7990 // from blocking the user to manually clear the list. 7991 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7992 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7993 Iterator it = mHomeProcess.activities.iterator(); 7994 while (it.hasNext()) { 7995 ActivityRecord r = (ActivityRecord)it.next(); 7996 if (r.isHomeActivity) { 7997 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7998 try { 7999 ActivityThread.getPackageManager() 8000 .clearPackagePreferredActivities(r.packageName); 8001 } catch (RemoteException c) { 8002 // pm is in same process, this will never happen. 8003 } 8004 } 8005 } 8006 } 8007 8008 if (!app.isolated) { 8009 // XXX Can't keep track of crash times for isolated processes, 8010 // because they don't have a perisistent identity. 8011 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8012 } 8013 8014 return true; 8015 } 8016 8017 void startAppProblemLocked(ProcessRecord app) { 8018 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8019 mContext, app.info.packageName, app.info.flags); 8020 skipCurrentReceiverLocked(app); 8021 } 8022 8023 void skipCurrentReceiverLocked(ProcessRecord app) { 8024 for (BroadcastQueue queue : mBroadcastQueues) { 8025 queue.skipCurrentReceiverLocked(app); 8026 } 8027 } 8028 8029 /** 8030 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8031 * The application process will exit immediately after this call returns. 8032 * @param app object of the crashing app, null for the system server 8033 * @param crashInfo describing the exception 8034 */ 8035 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8036 ProcessRecord r = findAppProcess(app, "Crash"); 8037 final String processName = app == null ? "system_server" 8038 : (r == null ? "unknown" : r.processName); 8039 8040 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8041 processName, 8042 r == null ? -1 : r.info.flags, 8043 crashInfo.exceptionClassName, 8044 crashInfo.exceptionMessage, 8045 crashInfo.throwFileName, 8046 crashInfo.throwLineNumber); 8047 8048 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8049 8050 crashApplication(r, crashInfo); 8051 } 8052 8053 public void handleApplicationStrictModeViolation( 8054 IBinder app, 8055 int violationMask, 8056 StrictMode.ViolationInfo info) { 8057 ProcessRecord r = findAppProcess(app, "StrictMode"); 8058 if (r == null) { 8059 return; 8060 } 8061 8062 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8063 Integer stackFingerprint = info.hashCode(); 8064 boolean logIt = true; 8065 synchronized (mAlreadyLoggedViolatedStacks) { 8066 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8067 logIt = false; 8068 // TODO: sub-sample into EventLog for these, with 8069 // the info.durationMillis? Then we'd get 8070 // the relative pain numbers, without logging all 8071 // the stack traces repeatedly. We'd want to do 8072 // likewise in the client code, which also does 8073 // dup suppression, before the Binder call. 8074 } else { 8075 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8076 mAlreadyLoggedViolatedStacks.clear(); 8077 } 8078 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8079 } 8080 } 8081 if (logIt) { 8082 logStrictModeViolationToDropBox(r, info); 8083 } 8084 } 8085 8086 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8087 AppErrorResult result = new AppErrorResult(); 8088 synchronized (this) { 8089 final long origId = Binder.clearCallingIdentity(); 8090 8091 Message msg = Message.obtain(); 8092 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8093 HashMap<String, Object> data = new HashMap<String, Object>(); 8094 data.put("result", result); 8095 data.put("app", r); 8096 data.put("violationMask", violationMask); 8097 data.put("info", info); 8098 msg.obj = data; 8099 mHandler.sendMessage(msg); 8100 8101 Binder.restoreCallingIdentity(origId); 8102 } 8103 int res = result.get(); 8104 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8105 } 8106 } 8107 8108 // Depending on the policy in effect, there could be a bunch of 8109 // these in quick succession so we try to batch these together to 8110 // minimize disk writes, number of dropbox entries, and maximize 8111 // compression, by having more fewer, larger records. 8112 private void logStrictModeViolationToDropBox( 8113 ProcessRecord process, 8114 StrictMode.ViolationInfo info) { 8115 if (info == null) { 8116 return; 8117 } 8118 final boolean isSystemApp = process == null || 8119 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8120 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8121 final String processName = process == null ? "unknown" : process.processName; 8122 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8123 final DropBoxManager dbox = (DropBoxManager) 8124 mContext.getSystemService(Context.DROPBOX_SERVICE); 8125 8126 // Exit early if the dropbox isn't configured to accept this report type. 8127 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8128 8129 boolean bufferWasEmpty; 8130 boolean needsFlush; 8131 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8132 synchronized (sb) { 8133 bufferWasEmpty = sb.length() == 0; 8134 appendDropBoxProcessHeaders(process, processName, sb); 8135 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8136 sb.append("System-App: ").append(isSystemApp).append("\n"); 8137 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8138 if (info.violationNumThisLoop != 0) { 8139 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8140 } 8141 if (info.numAnimationsRunning != 0) { 8142 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8143 } 8144 if (info.broadcastIntentAction != null) { 8145 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8146 } 8147 if (info.durationMillis != -1) { 8148 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8149 } 8150 if (info.numInstances != -1) { 8151 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8152 } 8153 if (info.tags != null) { 8154 for (String tag : info.tags) { 8155 sb.append("Span-Tag: ").append(tag).append("\n"); 8156 } 8157 } 8158 sb.append("\n"); 8159 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8160 sb.append(info.crashInfo.stackTrace); 8161 } 8162 sb.append("\n"); 8163 8164 // Only buffer up to ~64k. Various logging bits truncate 8165 // things at 128k. 8166 needsFlush = (sb.length() > 64 * 1024); 8167 } 8168 8169 // Flush immediately if the buffer's grown too large, or this 8170 // is a non-system app. Non-system apps are isolated with a 8171 // different tag & policy and not batched. 8172 // 8173 // Batching is useful during internal testing with 8174 // StrictMode settings turned up high. Without batching, 8175 // thousands of separate files could be created on boot. 8176 if (!isSystemApp || needsFlush) { 8177 new Thread("Error dump: " + dropboxTag) { 8178 @Override 8179 public void run() { 8180 String report; 8181 synchronized (sb) { 8182 report = sb.toString(); 8183 sb.delete(0, sb.length()); 8184 sb.trimToSize(); 8185 } 8186 if (report.length() != 0) { 8187 dbox.addText(dropboxTag, report); 8188 } 8189 } 8190 }.start(); 8191 return; 8192 } 8193 8194 // System app batching: 8195 if (!bufferWasEmpty) { 8196 // An existing dropbox-writing thread is outstanding, so 8197 // we don't need to start it up. The existing thread will 8198 // catch the buffer appends we just did. 8199 return; 8200 } 8201 8202 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8203 // (After this point, we shouldn't access AMS internal data structures.) 8204 new Thread("Error dump: " + dropboxTag) { 8205 @Override 8206 public void run() { 8207 // 5 second sleep to let stacks arrive and be batched together 8208 try { 8209 Thread.sleep(5000); // 5 seconds 8210 } catch (InterruptedException e) {} 8211 8212 String errorReport; 8213 synchronized (mStrictModeBuffer) { 8214 errorReport = mStrictModeBuffer.toString(); 8215 if (errorReport.length() == 0) { 8216 return; 8217 } 8218 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8219 mStrictModeBuffer.trimToSize(); 8220 } 8221 dbox.addText(dropboxTag, errorReport); 8222 } 8223 }.start(); 8224 } 8225 8226 /** 8227 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8228 * @param app object of the crashing app, null for the system server 8229 * @param tag reported by the caller 8230 * @param crashInfo describing the context of the error 8231 * @return true if the process should exit immediately (WTF is fatal) 8232 */ 8233 public boolean handleApplicationWtf(IBinder app, String tag, 8234 ApplicationErrorReport.CrashInfo crashInfo) { 8235 ProcessRecord r = findAppProcess(app, "WTF"); 8236 final String processName = app == null ? "system_server" 8237 : (r == null ? "unknown" : r.processName); 8238 8239 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8240 processName, 8241 r == null ? -1 : r.info.flags, 8242 tag, crashInfo.exceptionMessage); 8243 8244 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8245 8246 if (r != null && r.pid != Process.myPid() && 8247 Settings.Secure.getInt(mContext.getContentResolver(), 8248 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8249 crashApplication(r, crashInfo); 8250 return true; 8251 } else { 8252 return false; 8253 } 8254 } 8255 8256 /** 8257 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8258 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8259 */ 8260 private ProcessRecord findAppProcess(IBinder app, String reason) { 8261 if (app == null) { 8262 return null; 8263 } 8264 8265 synchronized (this) { 8266 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8267 final int NA = apps.size(); 8268 for (int ia=0; ia<NA; ia++) { 8269 ProcessRecord p = apps.valueAt(ia); 8270 if (p.thread != null && p.thread.asBinder() == app) { 8271 return p; 8272 } 8273 } 8274 } 8275 8276 Slog.w(TAG, "Can't find mystery application for " + reason 8277 + " from pid=" + Binder.getCallingPid() 8278 + " uid=" + Binder.getCallingUid() + ": " + app); 8279 return null; 8280 } 8281 } 8282 8283 /** 8284 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8285 * to append various headers to the dropbox log text. 8286 */ 8287 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8288 StringBuilder sb) { 8289 // Watchdog thread ends up invoking this function (with 8290 // a null ProcessRecord) to add the stack file to dropbox. 8291 // Do not acquire a lock on this (am) in such cases, as it 8292 // could cause a potential deadlock, if and when watchdog 8293 // is invoked due to unavailability of lock on am and it 8294 // would prevent watchdog from killing system_server. 8295 if (process == null) { 8296 sb.append("Process: ").append(processName).append("\n"); 8297 return; 8298 } 8299 // Note: ProcessRecord 'process' is guarded by the service 8300 // instance. (notably process.pkgList, which could otherwise change 8301 // concurrently during execution of this method) 8302 synchronized (this) { 8303 sb.append("Process: ").append(processName).append("\n"); 8304 int flags = process.info.flags; 8305 IPackageManager pm = AppGlobals.getPackageManager(); 8306 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8307 for (String pkg : process.pkgList) { 8308 sb.append("Package: ").append(pkg); 8309 try { 8310 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8311 if (pi != null) { 8312 sb.append(" v").append(pi.versionCode); 8313 if (pi.versionName != null) { 8314 sb.append(" (").append(pi.versionName).append(")"); 8315 } 8316 } 8317 } catch (RemoteException e) { 8318 Slog.e(TAG, "Error getting package info: " + pkg, e); 8319 } 8320 sb.append("\n"); 8321 } 8322 } 8323 } 8324 8325 private static String processClass(ProcessRecord process) { 8326 if (process == null || process.pid == MY_PID) { 8327 return "system_server"; 8328 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8329 return "system_app"; 8330 } else { 8331 return "data_app"; 8332 } 8333 } 8334 8335 /** 8336 * Write a description of an error (crash, WTF, ANR) to the drop box. 8337 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8338 * @param process which caused the error, null means the system server 8339 * @param activity which triggered the error, null if unknown 8340 * @param parent activity related to the error, null if unknown 8341 * @param subject line related to the error, null if absent 8342 * @param report in long form describing the error, null if absent 8343 * @param logFile to include in the report, null if none 8344 * @param crashInfo giving an application stack trace, null if absent 8345 */ 8346 public void addErrorToDropBox(String eventType, 8347 ProcessRecord process, String processName, ActivityRecord activity, 8348 ActivityRecord parent, String subject, 8349 final String report, final File logFile, 8350 final ApplicationErrorReport.CrashInfo crashInfo) { 8351 // NOTE -- this must never acquire the ActivityManagerService lock, 8352 // otherwise the watchdog may be prevented from resetting the system. 8353 8354 final String dropboxTag = processClass(process) + "_" + eventType; 8355 final DropBoxManager dbox = (DropBoxManager) 8356 mContext.getSystemService(Context.DROPBOX_SERVICE); 8357 8358 // Exit early if the dropbox isn't configured to accept this report type. 8359 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8360 8361 final StringBuilder sb = new StringBuilder(1024); 8362 appendDropBoxProcessHeaders(process, processName, sb); 8363 if (activity != null) { 8364 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8365 } 8366 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8367 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8368 } 8369 if (parent != null && parent != activity) { 8370 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8371 } 8372 if (subject != null) { 8373 sb.append("Subject: ").append(subject).append("\n"); 8374 } 8375 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8376 if (Debug.isDebuggerConnected()) { 8377 sb.append("Debugger: Connected\n"); 8378 } 8379 sb.append("\n"); 8380 8381 // Do the rest in a worker thread to avoid blocking the caller on I/O 8382 // (After this point, we shouldn't access AMS internal data structures.) 8383 Thread worker = new Thread("Error dump: " + dropboxTag) { 8384 @Override 8385 public void run() { 8386 if (report != null) { 8387 sb.append(report); 8388 } 8389 if (logFile != null) { 8390 try { 8391 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8392 } catch (IOException e) { 8393 Slog.e(TAG, "Error reading " + logFile, e); 8394 } 8395 } 8396 if (crashInfo != null && crashInfo.stackTrace != null) { 8397 sb.append(crashInfo.stackTrace); 8398 } 8399 8400 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8401 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8402 if (lines > 0) { 8403 sb.append("\n"); 8404 8405 // Merge several logcat streams, and take the last N lines 8406 InputStreamReader input = null; 8407 try { 8408 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8409 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8410 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8411 8412 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8413 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8414 input = new InputStreamReader(logcat.getInputStream()); 8415 8416 int num; 8417 char[] buf = new char[8192]; 8418 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8419 } catch (IOException e) { 8420 Slog.e(TAG, "Error running logcat", e); 8421 } finally { 8422 if (input != null) try { input.close(); } catch (IOException e) {} 8423 } 8424 } 8425 8426 dbox.addText(dropboxTag, sb.toString()); 8427 } 8428 }; 8429 8430 if (process == null) { 8431 // If process is null, we are being called from some internal code 8432 // and may be about to die -- run this synchronously. 8433 worker.run(); 8434 } else { 8435 worker.start(); 8436 } 8437 } 8438 8439 /** 8440 * Bring up the "unexpected error" dialog box for a crashing app. 8441 * Deal with edge cases (intercepts from instrumented applications, 8442 * ActivityController, error intent receivers, that sort of thing). 8443 * @param r the application crashing 8444 * @param crashInfo describing the failure 8445 */ 8446 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8447 long timeMillis = System.currentTimeMillis(); 8448 String shortMsg = crashInfo.exceptionClassName; 8449 String longMsg = crashInfo.exceptionMessage; 8450 String stackTrace = crashInfo.stackTrace; 8451 if (shortMsg != null && longMsg != null) { 8452 longMsg = shortMsg + ": " + longMsg; 8453 } else if (shortMsg != null) { 8454 longMsg = shortMsg; 8455 } 8456 8457 AppErrorResult result = new AppErrorResult(); 8458 synchronized (this) { 8459 if (mController != null) { 8460 try { 8461 String name = r != null ? r.processName : null; 8462 int pid = r != null ? r.pid : Binder.getCallingPid(); 8463 if (!mController.appCrashed(name, pid, 8464 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8465 Slog.w(TAG, "Force-killing crashed app " + name 8466 + " at watcher's request"); 8467 Process.killProcess(pid); 8468 return; 8469 } 8470 } catch (RemoteException e) { 8471 mController = null; 8472 } 8473 } 8474 8475 final long origId = Binder.clearCallingIdentity(); 8476 8477 // If this process is running instrumentation, finish it. 8478 if (r != null && r.instrumentationClass != null) { 8479 Slog.w(TAG, "Error in app " + r.processName 8480 + " running instrumentation " + r.instrumentationClass + ":"); 8481 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8482 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8483 Bundle info = new Bundle(); 8484 info.putString("shortMsg", shortMsg); 8485 info.putString("longMsg", longMsg); 8486 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8487 Binder.restoreCallingIdentity(origId); 8488 return; 8489 } 8490 8491 // If we can't identify the process or it's already exceeded its crash quota, 8492 // quit right away without showing a crash dialog. 8493 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8494 Binder.restoreCallingIdentity(origId); 8495 return; 8496 } 8497 8498 Message msg = Message.obtain(); 8499 msg.what = SHOW_ERROR_MSG; 8500 HashMap data = new HashMap(); 8501 data.put("result", result); 8502 data.put("app", r); 8503 msg.obj = data; 8504 mHandler.sendMessage(msg); 8505 8506 Binder.restoreCallingIdentity(origId); 8507 } 8508 8509 int res = result.get(); 8510 8511 Intent appErrorIntent = null; 8512 synchronized (this) { 8513 if (r != null && !r.isolated) { 8514 // XXX Can't keep track of crash time for isolated processes, 8515 // since they don't have a persistent identity. 8516 mProcessCrashTimes.put(r.info.processName, r.uid, 8517 SystemClock.uptimeMillis()); 8518 } 8519 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8520 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8521 } 8522 } 8523 8524 if (appErrorIntent != null) { 8525 try { 8526 mContext.startActivity(appErrorIntent); 8527 } catch (ActivityNotFoundException e) { 8528 Slog.w(TAG, "bug report receiver dissappeared", e); 8529 } 8530 } 8531 } 8532 8533 Intent createAppErrorIntentLocked(ProcessRecord r, 8534 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8535 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8536 if (report == null) { 8537 return null; 8538 } 8539 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8540 result.setComponent(r.errorReportReceiver); 8541 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8542 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8543 return result; 8544 } 8545 8546 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8547 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8548 if (r.errorReportReceiver == null) { 8549 return null; 8550 } 8551 8552 if (!r.crashing && !r.notResponding) { 8553 return null; 8554 } 8555 8556 ApplicationErrorReport report = new ApplicationErrorReport(); 8557 report.packageName = r.info.packageName; 8558 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8559 report.processName = r.processName; 8560 report.time = timeMillis; 8561 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8562 8563 if (r.crashing) { 8564 report.type = ApplicationErrorReport.TYPE_CRASH; 8565 report.crashInfo = crashInfo; 8566 } else if (r.notResponding) { 8567 report.type = ApplicationErrorReport.TYPE_ANR; 8568 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8569 8570 report.anrInfo.activity = r.notRespondingReport.tag; 8571 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8572 report.anrInfo.info = r.notRespondingReport.longMsg; 8573 } 8574 8575 return report; 8576 } 8577 8578 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8579 enforceNotIsolatedCaller("getProcessesInErrorState"); 8580 // assume our apps are happy - lazy create the list 8581 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8582 8583 final boolean allUsers = ActivityManager.checkUidPermission( 8584 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8585 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8586 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8587 8588 synchronized (this) { 8589 8590 // iterate across all processes 8591 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8592 ProcessRecord app = mLruProcesses.get(i); 8593 if (!allUsers && app.userId != userId) { 8594 continue; 8595 } 8596 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8597 // This one's in trouble, so we'll generate a report for it 8598 // crashes are higher priority (in case there's a crash *and* an anr) 8599 ActivityManager.ProcessErrorStateInfo report = null; 8600 if (app.crashing) { 8601 report = app.crashingReport; 8602 } else if (app.notResponding) { 8603 report = app.notRespondingReport; 8604 } 8605 8606 if (report != null) { 8607 if (errList == null) { 8608 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8609 } 8610 errList.add(report); 8611 } else { 8612 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8613 " crashing = " + app.crashing + 8614 " notResponding = " + app.notResponding); 8615 } 8616 } 8617 } 8618 } 8619 8620 return errList; 8621 } 8622 8623 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8624 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8625 if (currApp != null) { 8626 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8627 } 8628 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8629 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8630 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8631 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8632 if (currApp != null) { 8633 currApp.lru = 0; 8634 } 8635 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8636 } else if (adj >= ProcessList.SERVICE_ADJ) { 8637 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8638 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8639 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8640 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8641 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8642 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8643 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8644 } else { 8645 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8646 } 8647 } 8648 8649 private void fillInProcMemInfo(ProcessRecord app, 8650 ActivityManager.RunningAppProcessInfo outInfo) { 8651 outInfo.pid = app.pid; 8652 outInfo.uid = app.info.uid; 8653 if (mHeavyWeightProcess == app) { 8654 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8655 } 8656 if (app.persistent) { 8657 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8658 } 8659 if (app.hasActivities) { 8660 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8661 } 8662 outInfo.lastTrimLevel = app.trimMemoryLevel; 8663 int adj = app.curAdj; 8664 outInfo.importance = oomAdjToImportance(adj, outInfo); 8665 outInfo.importanceReasonCode = app.adjTypeCode; 8666 } 8667 8668 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8669 enforceNotIsolatedCaller("getRunningAppProcesses"); 8670 // Lazy instantiation of list 8671 List<ActivityManager.RunningAppProcessInfo> runList = null; 8672 final boolean allUsers = ActivityManager.checkUidPermission( 8673 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8674 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8675 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8676 synchronized (this) { 8677 // Iterate across all processes 8678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8679 ProcessRecord app = mLruProcesses.get(i); 8680 if (!allUsers && app.userId != userId) { 8681 continue; 8682 } 8683 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8684 // Generate process state info for running application 8685 ActivityManager.RunningAppProcessInfo currApp = 8686 new ActivityManager.RunningAppProcessInfo(app.processName, 8687 app.pid, app.getPackageList()); 8688 fillInProcMemInfo(app, currApp); 8689 if (app.adjSource instanceof ProcessRecord) { 8690 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8691 currApp.importanceReasonImportance = oomAdjToImportance( 8692 app.adjSourceOom, null); 8693 } else if (app.adjSource instanceof ActivityRecord) { 8694 ActivityRecord r = (ActivityRecord)app.adjSource; 8695 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8696 } 8697 if (app.adjTarget instanceof ComponentName) { 8698 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8699 } 8700 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8701 // + " lru=" + currApp.lru); 8702 if (runList == null) { 8703 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8704 } 8705 runList.add(currApp); 8706 } 8707 } 8708 } 8709 return runList; 8710 } 8711 8712 public List<ApplicationInfo> getRunningExternalApplications() { 8713 enforceNotIsolatedCaller("getRunningExternalApplications"); 8714 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8715 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8716 if (runningApps != null && runningApps.size() > 0) { 8717 Set<String> extList = new HashSet<String>(); 8718 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8719 if (app.pkgList != null) { 8720 for (String pkg : app.pkgList) { 8721 extList.add(pkg); 8722 } 8723 } 8724 } 8725 IPackageManager pm = AppGlobals.getPackageManager(); 8726 for (String pkg : extList) { 8727 try { 8728 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8729 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8730 retList.add(info); 8731 } 8732 } catch (RemoteException e) { 8733 } 8734 } 8735 } 8736 return retList; 8737 } 8738 8739 @Override 8740 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8741 enforceNotIsolatedCaller("getMyMemoryState"); 8742 synchronized (this) { 8743 ProcessRecord proc; 8744 synchronized (mPidsSelfLocked) { 8745 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8746 } 8747 fillInProcMemInfo(proc, outInfo); 8748 } 8749 } 8750 8751 @Override 8752 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8753 if (checkCallingPermission(android.Manifest.permission.DUMP) 8754 != PackageManager.PERMISSION_GRANTED) { 8755 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8756 + Binder.getCallingPid() 8757 + ", uid=" + Binder.getCallingUid() 8758 + " without permission " 8759 + android.Manifest.permission.DUMP); 8760 return; 8761 } 8762 8763 boolean dumpAll = false; 8764 boolean dumpClient = false; 8765 String dumpPackage = null; 8766 8767 int opti = 0; 8768 while (opti < args.length) { 8769 String opt = args[opti]; 8770 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8771 break; 8772 } 8773 opti++; 8774 if ("-a".equals(opt)) { 8775 dumpAll = true; 8776 } else if ("-c".equals(opt)) { 8777 dumpClient = true; 8778 } else if ("-h".equals(opt)) { 8779 pw.println("Activity manager dump options:"); 8780 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8781 pw.println(" cmd may be one of:"); 8782 pw.println(" a[ctivities]: activity stack state"); 8783 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8784 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8785 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8786 pw.println(" o[om]: out of memory management"); 8787 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8788 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8789 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8790 pw.println(" service [COMP_SPEC]: service client-side state"); 8791 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8792 pw.println(" all: dump all activities"); 8793 pw.println(" top: dump the top activity"); 8794 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8795 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8796 pw.println(" a partial substring in a component name, a"); 8797 pw.println(" hex object identifier."); 8798 pw.println(" -a: include all available server state."); 8799 pw.println(" -c: include client state."); 8800 return; 8801 } else { 8802 pw.println("Unknown argument: " + opt + "; use -h for help"); 8803 } 8804 } 8805 8806 long origId = Binder.clearCallingIdentity(); 8807 boolean more = false; 8808 // Is the caller requesting to dump a particular piece of data? 8809 if (opti < args.length) { 8810 String cmd = args[opti]; 8811 opti++; 8812 if ("activities".equals(cmd) || "a".equals(cmd)) { 8813 synchronized (this) { 8814 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8815 } 8816 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8817 String[] newArgs; 8818 String name; 8819 if (opti >= args.length) { 8820 name = null; 8821 newArgs = EMPTY_STRING_ARRAY; 8822 } else { 8823 name = args[opti]; 8824 opti++; 8825 newArgs = new String[args.length - opti]; 8826 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8827 args.length - opti); 8828 } 8829 synchronized (this) { 8830 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8831 } 8832 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8833 String[] newArgs; 8834 String name; 8835 if (opti >= args.length) { 8836 name = null; 8837 newArgs = EMPTY_STRING_ARRAY; 8838 } else { 8839 name = args[opti]; 8840 opti++; 8841 newArgs = new String[args.length - opti]; 8842 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8843 args.length - opti); 8844 } 8845 synchronized (this) { 8846 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8847 } 8848 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8849 String[] newArgs; 8850 String name; 8851 if (opti >= args.length) { 8852 name = null; 8853 newArgs = EMPTY_STRING_ARRAY; 8854 } else { 8855 name = args[opti]; 8856 opti++; 8857 newArgs = new String[args.length - opti]; 8858 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8859 args.length - opti); 8860 } 8861 synchronized (this) { 8862 dumpProcessesLocked(fd, pw, args, opti, true, name); 8863 } 8864 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8865 synchronized (this) { 8866 dumpOomLocked(fd, pw, args, opti, true); 8867 } 8868 } else if ("provider".equals(cmd)) { 8869 String[] newArgs; 8870 String name; 8871 if (opti >= args.length) { 8872 name = null; 8873 newArgs = EMPTY_STRING_ARRAY; 8874 } else { 8875 name = args[opti]; 8876 opti++; 8877 newArgs = new String[args.length - opti]; 8878 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8879 } 8880 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8881 pw.println("No providers match: " + name); 8882 pw.println("Use -h for help."); 8883 } 8884 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8885 synchronized (this) { 8886 dumpProvidersLocked(fd, pw, args, opti, true, null); 8887 } 8888 } else if ("service".equals(cmd)) { 8889 String[] newArgs; 8890 String name; 8891 if (opti >= args.length) { 8892 name = null; 8893 newArgs = EMPTY_STRING_ARRAY; 8894 } else { 8895 name = args[opti]; 8896 opti++; 8897 newArgs = new String[args.length - opti]; 8898 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8899 args.length - opti); 8900 } 8901 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8902 pw.println("No services match: " + name); 8903 pw.println("Use -h for help."); 8904 } 8905 } else if ("package".equals(cmd)) { 8906 String[] newArgs; 8907 if (opti >= args.length) { 8908 pw.println("package: no package name specified"); 8909 pw.println("Use -h for help."); 8910 } else { 8911 dumpPackage = args[opti]; 8912 opti++; 8913 newArgs = new String[args.length - opti]; 8914 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8915 args.length - opti); 8916 args = newArgs; 8917 opti = 0; 8918 more = true; 8919 } 8920 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8921 synchronized (this) { 8922 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8923 } 8924 } else { 8925 // Dumping a single activity? 8926 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8927 pw.println("Bad activity command, or no activities match: " + cmd); 8928 pw.println("Use -h for help."); 8929 } 8930 } 8931 if (!more) { 8932 Binder.restoreCallingIdentity(origId); 8933 return; 8934 } 8935 } 8936 8937 // No piece of data specified, dump everything. 8938 synchronized (this) { 8939 boolean needSep; 8940 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8941 if (needSep) { 8942 pw.println(" "); 8943 } 8944 if (dumpAll) { 8945 pw.println("-------------------------------------------------------------------------------"); 8946 } 8947 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8948 if (needSep) { 8949 pw.println(" "); 8950 } 8951 if (dumpAll) { 8952 pw.println("-------------------------------------------------------------------------------"); 8953 } 8954 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8955 if (needSep) { 8956 pw.println(" "); 8957 } 8958 if (dumpAll) { 8959 pw.println("-------------------------------------------------------------------------------"); 8960 } 8961 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8962 if (needSep) { 8963 pw.println(" "); 8964 } 8965 if (dumpAll) { 8966 pw.println("-------------------------------------------------------------------------------"); 8967 } 8968 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8969 if (needSep) { 8970 pw.println(" "); 8971 } 8972 if (dumpAll) { 8973 pw.println("-------------------------------------------------------------------------------"); 8974 } 8975 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8976 } 8977 Binder.restoreCallingIdentity(origId); 8978 } 8979 8980 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8981 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8982 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8983 pw.println(" Main stack:"); 8984 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8985 dumpPackage); 8986 pw.println(" "); 8987 pw.println(" Running activities (most recent first):"); 8988 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8989 dumpPackage); 8990 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8991 pw.println(" "); 8992 pw.println(" Activities waiting for another to become visible:"); 8993 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8994 !dumpAll, false, dumpPackage); 8995 } 8996 if (mMainStack.mStoppingActivities.size() > 0) { 8997 pw.println(" "); 8998 pw.println(" Activities waiting to stop:"); 8999 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9000 !dumpAll, false, dumpPackage); 9001 } 9002 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9003 pw.println(" "); 9004 pw.println(" Activities waiting to sleep:"); 9005 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9006 !dumpAll, false, dumpPackage); 9007 } 9008 if (mMainStack.mFinishingActivities.size() > 0) { 9009 pw.println(" "); 9010 pw.println(" Activities waiting to finish:"); 9011 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9012 !dumpAll, false, dumpPackage); 9013 } 9014 9015 pw.println(" "); 9016 if (mMainStack.mPausingActivity != null) { 9017 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9018 } 9019 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9020 pw.println(" mFocusedActivity: " + mFocusedActivity); 9021 if (dumpAll) { 9022 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9023 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9024 pw.println(" mDismissKeyguardOnNextActivity: " 9025 + mMainStack.mDismissKeyguardOnNextActivity); 9026 } 9027 9028 if (mRecentTasks.size() > 0) { 9029 pw.println(); 9030 pw.println(" Recent tasks:"); 9031 9032 final int N = mRecentTasks.size(); 9033 for (int i=0; i<N; i++) { 9034 TaskRecord tr = mRecentTasks.get(i); 9035 if (dumpPackage != null) { 9036 if (tr.realActivity == null || 9037 !dumpPackage.equals(tr.realActivity)) { 9038 continue; 9039 } 9040 } 9041 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9042 pw.println(tr); 9043 if (dumpAll) { 9044 mRecentTasks.get(i).dump(pw, " "); 9045 } 9046 } 9047 } 9048 9049 if (dumpAll) { 9050 pw.println(" "); 9051 pw.println(" mCurTask: " + mCurTask); 9052 } 9053 9054 return true; 9055 } 9056 9057 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9058 int opti, boolean dumpAll, String dumpPackage) { 9059 boolean needSep = false; 9060 int numPers = 0; 9061 9062 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9063 9064 if (dumpAll) { 9065 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9066 final int NA = procs.size(); 9067 for (int ia=0; ia<NA; ia++) { 9068 ProcessRecord r = procs.valueAt(ia); 9069 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9070 continue; 9071 } 9072 if (!needSep) { 9073 pw.println(" All known processes:"); 9074 needSep = true; 9075 } 9076 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9077 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9078 pw.print(" "); pw.println(r); 9079 r.dump(pw, " "); 9080 if (r.persistent) { 9081 numPers++; 9082 } 9083 } 9084 } 9085 } 9086 9087 if (mIsolatedProcesses.size() > 0) { 9088 if (needSep) pw.println(" "); 9089 needSep = true; 9090 pw.println(" Isolated process list (sorted by uid):"); 9091 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9092 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9093 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9094 continue; 9095 } 9096 pw.println(String.format("%sIsolated #%2d: %s", 9097 " ", i, r.toString())); 9098 } 9099 } 9100 9101 if (mLruProcesses.size() > 0) { 9102 if (needSep) pw.println(" "); 9103 needSep = true; 9104 pw.println(" Process LRU list (sorted by oom_adj):"); 9105 dumpProcessOomList(pw, this, mLruProcesses, " ", 9106 "Proc", "PERS", false, dumpPackage); 9107 needSep = true; 9108 } 9109 9110 if (dumpAll) { 9111 synchronized (mPidsSelfLocked) { 9112 boolean printed = false; 9113 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9114 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9115 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9116 continue; 9117 } 9118 if (!printed) { 9119 if (needSep) pw.println(" "); 9120 needSep = true; 9121 pw.println(" PID mappings:"); 9122 printed = true; 9123 } 9124 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9125 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9126 } 9127 } 9128 } 9129 9130 if (mForegroundProcesses.size() > 0) { 9131 synchronized (mPidsSelfLocked) { 9132 boolean printed = false; 9133 for (int i=0; i<mForegroundProcesses.size(); i++) { 9134 ProcessRecord r = mPidsSelfLocked.get( 9135 mForegroundProcesses.valueAt(i).pid); 9136 if (dumpPackage != null && (r == null 9137 || !dumpPackage.equals(r.info.packageName))) { 9138 continue; 9139 } 9140 if (!printed) { 9141 if (needSep) pw.println(" "); 9142 needSep = true; 9143 pw.println(" Foreground Processes:"); 9144 printed = true; 9145 } 9146 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9147 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9148 } 9149 } 9150 } 9151 9152 if (mPersistentStartingProcesses.size() > 0) { 9153 if (needSep) pw.println(" "); 9154 needSep = true; 9155 pw.println(" Persisent processes that are starting:"); 9156 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9157 "Starting Norm", "Restarting PERS", dumpPackage); 9158 } 9159 9160 if (mRemovedProcesses.size() > 0) { 9161 if (needSep) pw.println(" "); 9162 needSep = true; 9163 pw.println(" Processes that are being removed:"); 9164 dumpProcessList(pw, this, mRemovedProcesses, " ", 9165 "Removed Norm", "Removed PERS", dumpPackage); 9166 } 9167 9168 if (mProcessesOnHold.size() > 0) { 9169 if (needSep) pw.println(" "); 9170 needSep = true; 9171 pw.println(" Processes that are on old until the system is ready:"); 9172 dumpProcessList(pw, this, mProcessesOnHold, " ", 9173 "OnHold Norm", "OnHold PERS", dumpPackage); 9174 } 9175 9176 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9177 9178 if (mProcessCrashTimes.getMap().size() > 0) { 9179 boolean printed = false; 9180 long now = SystemClock.uptimeMillis(); 9181 for (Map.Entry<String, SparseArray<Long>> procs 9182 : mProcessCrashTimes.getMap().entrySet()) { 9183 String pname = procs.getKey(); 9184 SparseArray<Long> uids = procs.getValue(); 9185 final int N = uids.size(); 9186 for (int i=0; i<N; i++) { 9187 int puid = uids.keyAt(i); 9188 ProcessRecord r = mProcessNames.get(pname, puid); 9189 if (dumpPackage != null && (r == null 9190 || !dumpPackage.equals(r.info.packageName))) { 9191 continue; 9192 } 9193 if (!printed) { 9194 if (needSep) pw.println(" "); 9195 needSep = true; 9196 pw.println(" Time since processes crashed:"); 9197 printed = true; 9198 } 9199 pw.print(" Process "); pw.print(pname); 9200 pw.print(" uid "); pw.print(puid); 9201 pw.print(": last crashed "); 9202 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9203 pw.println(" ago"); 9204 } 9205 } 9206 } 9207 9208 if (mBadProcesses.getMap().size() > 0) { 9209 boolean printed = false; 9210 for (Map.Entry<String, SparseArray<Long>> procs 9211 : mBadProcesses.getMap().entrySet()) { 9212 String pname = procs.getKey(); 9213 SparseArray<Long> uids = procs.getValue(); 9214 final int N = uids.size(); 9215 for (int i=0; i<N; i++) { 9216 int puid = uids.keyAt(i); 9217 ProcessRecord r = mProcessNames.get(pname, puid); 9218 if (dumpPackage != null && (r == null 9219 || !dumpPackage.equals(r.info.packageName))) { 9220 continue; 9221 } 9222 if (!printed) { 9223 if (needSep) pw.println(" "); 9224 needSep = true; 9225 pw.println(" Bad processes:"); 9226 } 9227 pw.print(" Bad process "); pw.print(pname); 9228 pw.print(" uid "); pw.print(puid); 9229 pw.print(": crashed at time "); 9230 pw.println(uids.valueAt(i)); 9231 } 9232 } 9233 } 9234 9235 pw.println(); 9236 pw.println(" mStartedUsers:"); 9237 for (int i=0; i<mStartedUsers.size(); i++) { 9238 UserStartedState uss = mStartedUsers.valueAt(i); 9239 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9240 pw.print(": "); uss.dump("", pw); 9241 } 9242 pw.print(" mUserLru: ["); 9243 for (int i=0; i<mUserLru.size(); i++) { 9244 if (i > 0) pw.print(", "); 9245 pw.print(mUserLru.get(i)); 9246 } 9247 pw.println("]"); 9248 pw.println(" mHomeProcess: " + mHomeProcess); 9249 pw.println(" mPreviousProcess: " + mPreviousProcess); 9250 if (dumpAll) { 9251 StringBuilder sb = new StringBuilder(128); 9252 sb.append(" mPreviousProcessVisibleTime: "); 9253 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9254 pw.println(sb); 9255 } 9256 if (mHeavyWeightProcess != null) { 9257 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9258 } 9259 pw.println(" mConfiguration: " + mConfiguration); 9260 if (dumpAll) { 9261 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9262 if (mCompatModePackages.getPackages().size() > 0) { 9263 boolean printed = false; 9264 for (Map.Entry<String, Integer> entry 9265 : mCompatModePackages.getPackages().entrySet()) { 9266 String pkg = entry.getKey(); 9267 int mode = entry.getValue(); 9268 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9269 continue; 9270 } 9271 if (!printed) { 9272 pw.println(" mScreenCompatPackages:"); 9273 printed = true; 9274 } 9275 pw.print(" "); pw.print(pkg); pw.print(": "); 9276 pw.print(mode); pw.println(); 9277 } 9278 } 9279 } 9280 if (mSleeping || mWentToSleep || mLockScreenShown) { 9281 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9282 + " mLockScreenShown " + mLockScreenShown); 9283 } 9284 if (mShuttingDown) { 9285 pw.println(" mShuttingDown=" + mShuttingDown); 9286 } 9287 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9288 || mOrigWaitForDebugger) { 9289 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9290 + " mDebugTransient=" + mDebugTransient 9291 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9292 } 9293 if (mOpenGlTraceApp != null) { 9294 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9295 } 9296 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9297 || mProfileFd != null) { 9298 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9299 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9300 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9301 + mAutoStopProfiler); 9302 } 9303 if (mAlwaysFinishActivities || mController != null) { 9304 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9305 + " mController=" + mController); 9306 } 9307 if (dumpAll) { 9308 pw.println(" Total persistent processes: " + numPers); 9309 pw.println(" mStartRunning=" + mStartRunning 9310 + " mProcessesReady=" + mProcessesReady 9311 + " mSystemReady=" + mSystemReady); 9312 pw.println(" mBooting=" + mBooting 9313 + " mBooted=" + mBooted 9314 + " mFactoryTest=" + mFactoryTest); 9315 pw.print(" mLastPowerCheckRealtime="); 9316 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9317 pw.println(""); 9318 pw.print(" mLastPowerCheckUptime="); 9319 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9320 pw.println(""); 9321 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9322 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9323 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9324 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9325 + " mNumHiddenProcs=" + mNumHiddenProcs 9326 + " mNumServiceProcs=" + mNumServiceProcs 9327 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9328 } 9329 9330 return true; 9331 } 9332 9333 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9334 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9335 if (mProcessesToGc.size() > 0) { 9336 boolean printed = false; 9337 long now = SystemClock.uptimeMillis(); 9338 for (int i=0; i<mProcessesToGc.size(); i++) { 9339 ProcessRecord proc = mProcessesToGc.get(i); 9340 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9341 continue; 9342 } 9343 if (!printed) { 9344 if (needSep) pw.println(" "); 9345 needSep = true; 9346 pw.println(" Processes that are waiting to GC:"); 9347 printed = true; 9348 } 9349 pw.print(" Process "); pw.println(proc); 9350 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9351 pw.print(", last gced="); 9352 pw.print(now-proc.lastRequestedGc); 9353 pw.print(" ms ago, last lowMem="); 9354 pw.print(now-proc.lastLowMemory); 9355 pw.println(" ms ago"); 9356 9357 } 9358 } 9359 return needSep; 9360 } 9361 9362 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9363 int opti, boolean dumpAll) { 9364 boolean needSep = false; 9365 9366 if (mLruProcesses.size() > 0) { 9367 if (needSep) pw.println(" "); 9368 needSep = true; 9369 pw.println(" OOM levels:"); 9370 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9371 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9372 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9373 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9374 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9375 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9376 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9377 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9378 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9379 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9380 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9381 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9382 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9383 9384 if (needSep) pw.println(" "); 9385 needSep = true; 9386 pw.println(" Process OOM control:"); 9387 dumpProcessOomList(pw, this, mLruProcesses, " ", 9388 "Proc", "PERS", true, null); 9389 needSep = true; 9390 } 9391 9392 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9393 9394 pw.println(); 9395 pw.println(" mHomeProcess: " + mHomeProcess); 9396 pw.println(" mPreviousProcess: " + mPreviousProcess); 9397 if (mHeavyWeightProcess != null) { 9398 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9399 } 9400 9401 return true; 9402 } 9403 9404 /** 9405 * There are three ways to call this: 9406 * - no provider specified: dump all the providers 9407 * - a flattened component name that matched an existing provider was specified as the 9408 * first arg: dump that one provider 9409 * - the first arg isn't the flattened component name of an existing provider: 9410 * dump all providers whose component contains the first arg as a substring 9411 */ 9412 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9413 int opti, boolean dumpAll) { 9414 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9415 } 9416 9417 static class ItemMatcher { 9418 ArrayList<ComponentName> components; 9419 ArrayList<String> strings; 9420 ArrayList<Integer> objects; 9421 boolean all; 9422 9423 ItemMatcher() { 9424 all = true; 9425 } 9426 9427 void build(String name) { 9428 ComponentName componentName = ComponentName.unflattenFromString(name); 9429 if (componentName != null) { 9430 if (components == null) { 9431 components = new ArrayList<ComponentName>(); 9432 } 9433 components.add(componentName); 9434 all = false; 9435 } else { 9436 int objectId = 0; 9437 // Not a '/' separated full component name; maybe an object ID? 9438 try { 9439 objectId = Integer.parseInt(name, 16); 9440 if (objects == null) { 9441 objects = new ArrayList<Integer>(); 9442 } 9443 objects.add(objectId); 9444 all = false; 9445 } catch (RuntimeException e) { 9446 // Not an integer; just do string match. 9447 if (strings == null) { 9448 strings = new ArrayList<String>(); 9449 } 9450 strings.add(name); 9451 all = false; 9452 } 9453 } 9454 } 9455 9456 int build(String[] args, int opti) { 9457 for (; opti<args.length; opti++) { 9458 String name = args[opti]; 9459 if ("--".equals(name)) { 9460 return opti+1; 9461 } 9462 build(name); 9463 } 9464 return opti; 9465 } 9466 9467 boolean match(Object object, ComponentName comp) { 9468 if (all) { 9469 return true; 9470 } 9471 if (components != null) { 9472 for (int i=0; i<components.size(); i++) { 9473 if (components.get(i).equals(comp)) { 9474 return true; 9475 } 9476 } 9477 } 9478 if (objects != null) { 9479 for (int i=0; i<objects.size(); i++) { 9480 if (System.identityHashCode(object) == objects.get(i)) { 9481 return true; 9482 } 9483 } 9484 } 9485 if (strings != null) { 9486 String flat = comp.flattenToString(); 9487 for (int i=0; i<strings.size(); i++) { 9488 if (flat.contains(strings.get(i))) { 9489 return true; 9490 } 9491 } 9492 } 9493 return false; 9494 } 9495 } 9496 9497 /** 9498 * There are three things that cmd can be: 9499 * - a flattened component name that matches an existing activity 9500 * - the cmd arg isn't the flattened component name of an existing activity: 9501 * dump all activity whose component contains the cmd as a substring 9502 * - A hex number of the ActivityRecord object instance. 9503 */ 9504 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9505 int opti, boolean dumpAll) { 9506 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9507 9508 if ("all".equals(name)) { 9509 synchronized (this) { 9510 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9511 activities.add(r1); 9512 } 9513 } 9514 } else if ("top".equals(name)) { 9515 synchronized (this) { 9516 final int N = mMainStack.mHistory.size(); 9517 if (N > 0) { 9518 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9519 } 9520 } 9521 } else { 9522 ItemMatcher matcher = new ItemMatcher(); 9523 matcher.build(name); 9524 9525 synchronized (this) { 9526 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9527 if (matcher.match(r1, r1.intent.getComponent())) { 9528 activities.add(r1); 9529 } 9530 } 9531 } 9532 } 9533 9534 if (activities.size() <= 0) { 9535 return false; 9536 } 9537 9538 String[] newArgs = new String[args.length - opti]; 9539 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9540 9541 TaskRecord lastTask = null; 9542 boolean needSep = false; 9543 for (int i=activities.size()-1; i>=0; i--) { 9544 ActivityRecord r = (ActivityRecord)activities.get(i); 9545 if (needSep) { 9546 pw.println(); 9547 } 9548 needSep = true; 9549 synchronized (this) { 9550 if (lastTask != r.task) { 9551 lastTask = r.task; 9552 pw.print("TASK "); pw.print(lastTask.affinity); 9553 pw.print(" id="); pw.println(lastTask.taskId); 9554 if (dumpAll) { 9555 lastTask.dump(pw, " "); 9556 } 9557 } 9558 } 9559 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9560 } 9561 return true; 9562 } 9563 9564 /** 9565 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9566 * there is a thread associated with the activity. 9567 */ 9568 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9569 final ActivityRecord r, String[] args, boolean dumpAll) { 9570 String innerPrefix = prefix + " "; 9571 synchronized (this) { 9572 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9573 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9574 pw.print(" pid="); 9575 if (r.app != null) pw.println(r.app.pid); 9576 else pw.println("(not running)"); 9577 if (dumpAll) { 9578 r.dump(pw, innerPrefix); 9579 } 9580 } 9581 if (r.app != null && r.app.thread != null) { 9582 // flush anything that is already in the PrintWriter since the thread is going 9583 // to write to the file descriptor directly 9584 pw.flush(); 9585 try { 9586 TransferPipe tp = new TransferPipe(); 9587 try { 9588 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9589 r.appToken, innerPrefix, args); 9590 tp.go(fd); 9591 } finally { 9592 tp.kill(); 9593 } 9594 } catch (IOException e) { 9595 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9596 } catch (RemoteException e) { 9597 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9598 } 9599 } 9600 } 9601 9602 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9603 int opti, boolean dumpAll, String dumpPackage) { 9604 boolean needSep = false; 9605 boolean onlyHistory = false; 9606 9607 if ("history".equals(dumpPackage)) { 9608 onlyHistory = true; 9609 dumpPackage = null; 9610 } 9611 9612 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9613 if (!onlyHistory && dumpAll) { 9614 if (mRegisteredReceivers.size() > 0) { 9615 boolean printed = false; 9616 Iterator it = mRegisteredReceivers.values().iterator(); 9617 while (it.hasNext()) { 9618 ReceiverList r = (ReceiverList)it.next(); 9619 if (dumpPackage != null && (r.app == null || 9620 !dumpPackage.equals(r.app.info.packageName))) { 9621 continue; 9622 } 9623 if (!printed) { 9624 pw.println(" Registered Receivers:"); 9625 needSep = true; 9626 printed = true; 9627 } 9628 pw.print(" * "); pw.println(r); 9629 r.dump(pw, " "); 9630 } 9631 } 9632 9633 if (mReceiverResolver.dump(pw, needSep ? 9634 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9635 " ", dumpPackage, false)) { 9636 needSep = true; 9637 } 9638 } 9639 9640 for (BroadcastQueue q : mBroadcastQueues) { 9641 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9642 } 9643 9644 needSep = true; 9645 9646 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9647 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9648 if (needSep) { 9649 pw.println(); 9650 } 9651 needSep = true; 9652 pw.print(" Sticky broadcasts for user "); 9653 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9654 StringBuilder sb = new StringBuilder(128); 9655 for (Map.Entry<String, ArrayList<Intent>> ent 9656 : mStickyBroadcasts.valueAt(user).entrySet()) { 9657 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9658 if (dumpAll) { 9659 pw.println(":"); 9660 ArrayList<Intent> intents = ent.getValue(); 9661 final int N = intents.size(); 9662 for (int i=0; i<N; i++) { 9663 sb.setLength(0); 9664 sb.append(" Intent: "); 9665 intents.get(i).toShortString(sb, false, true, false, false); 9666 pw.println(sb.toString()); 9667 Bundle bundle = intents.get(i).getExtras(); 9668 if (bundle != null) { 9669 pw.print(" "); 9670 pw.println(bundle.toString()); 9671 } 9672 } 9673 } else { 9674 pw.println(""); 9675 } 9676 } 9677 } 9678 } 9679 9680 if (!onlyHistory && dumpAll) { 9681 pw.println(); 9682 for (BroadcastQueue queue : mBroadcastQueues) { 9683 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9684 + queue.mBroadcastsScheduled); 9685 } 9686 pw.println(" mHandler:"); 9687 mHandler.dump(new PrintWriterPrinter(pw), " "); 9688 needSep = true; 9689 } 9690 9691 return needSep; 9692 } 9693 9694 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9695 int opti, boolean dumpAll, String dumpPackage) { 9696 boolean needSep = true; 9697 9698 ItemMatcher matcher = new ItemMatcher(); 9699 matcher.build(args, opti); 9700 9701 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9702 9703 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9704 9705 if (mLaunchingProviders.size() > 0) { 9706 boolean printed = false; 9707 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9708 ContentProviderRecord r = mLaunchingProviders.get(i); 9709 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9710 continue; 9711 } 9712 if (!printed) { 9713 if (needSep) pw.println(" "); 9714 needSep = true; 9715 pw.println(" Launching content providers:"); 9716 printed = true; 9717 } 9718 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9719 pw.println(r); 9720 } 9721 } 9722 9723 if (mGrantedUriPermissions.size() > 0) { 9724 if (needSep) pw.println(); 9725 needSep = true; 9726 pw.println("Granted Uri Permissions:"); 9727 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9728 int uid = mGrantedUriPermissions.keyAt(i); 9729 HashMap<Uri, UriPermission> perms 9730 = mGrantedUriPermissions.valueAt(i); 9731 pw.print(" * UID "); pw.print(uid); 9732 pw.println(" holds:"); 9733 for (UriPermission perm : perms.values()) { 9734 pw.print(" "); pw.println(perm); 9735 if (dumpAll) { 9736 perm.dump(pw, " "); 9737 } 9738 } 9739 } 9740 needSep = true; 9741 } 9742 9743 return needSep; 9744 } 9745 9746 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9747 int opti, boolean dumpAll, String dumpPackage) { 9748 boolean needSep = false; 9749 9750 if (mIntentSenderRecords.size() > 0) { 9751 boolean printed = false; 9752 Iterator<WeakReference<PendingIntentRecord>> it 9753 = mIntentSenderRecords.values().iterator(); 9754 while (it.hasNext()) { 9755 WeakReference<PendingIntentRecord> ref = it.next(); 9756 PendingIntentRecord rec = ref != null ? ref.get(): null; 9757 if (dumpPackage != null && (rec == null 9758 || !dumpPackage.equals(rec.key.packageName))) { 9759 continue; 9760 } 9761 if (!printed) { 9762 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9763 printed = true; 9764 } 9765 needSep = true; 9766 if (rec != null) { 9767 pw.print(" * "); pw.println(rec); 9768 if (dumpAll) { 9769 rec.dump(pw, " "); 9770 } 9771 } else { 9772 pw.print(" * "); pw.println(ref); 9773 } 9774 } 9775 } 9776 9777 return needSep; 9778 } 9779 9780 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9781 String prefix, String label, boolean complete, boolean brief, boolean client, 9782 String dumpPackage) { 9783 TaskRecord lastTask = null; 9784 boolean needNL = false; 9785 final String innerPrefix = prefix + " "; 9786 final String[] args = new String[0]; 9787 for (int i=list.size()-1; i>=0; i--) { 9788 final ActivityRecord r = (ActivityRecord)list.get(i); 9789 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9790 continue; 9791 } 9792 final boolean full = !brief && (complete || !r.isInHistory()); 9793 if (needNL) { 9794 pw.println(" "); 9795 needNL = false; 9796 } 9797 if (lastTask != r.task) { 9798 lastTask = r.task; 9799 pw.print(prefix); 9800 pw.print(full ? "* " : " "); 9801 pw.println(lastTask); 9802 if (full) { 9803 lastTask.dump(pw, prefix + " "); 9804 } else if (complete) { 9805 // Complete + brief == give a summary. Isn't that obvious?!? 9806 if (lastTask.intent != null) { 9807 pw.print(prefix); pw.print(" "); 9808 pw.println(lastTask.intent.toInsecureStringWithClip()); 9809 } 9810 } 9811 } 9812 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9813 pw.print(" #"); pw.print(i); pw.print(": "); 9814 pw.println(r); 9815 if (full) { 9816 r.dump(pw, innerPrefix); 9817 } else if (complete) { 9818 // Complete + brief == give a summary. Isn't that obvious?!? 9819 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9820 if (r.app != null) { 9821 pw.print(innerPrefix); pw.println(r.app); 9822 } 9823 } 9824 if (client && r.app != null && r.app.thread != null) { 9825 // flush anything that is already in the PrintWriter since the thread is going 9826 // to write to the file descriptor directly 9827 pw.flush(); 9828 try { 9829 TransferPipe tp = new TransferPipe(); 9830 try { 9831 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9832 r.appToken, innerPrefix, args); 9833 // Short timeout, since blocking here can 9834 // deadlock with the application. 9835 tp.go(fd, 2000); 9836 } finally { 9837 tp.kill(); 9838 } 9839 } catch (IOException e) { 9840 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9841 } catch (RemoteException e) { 9842 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9843 } 9844 needNL = true; 9845 } 9846 } 9847 } 9848 9849 private static String buildOomTag(String prefix, String space, int val, int base) { 9850 if (val == base) { 9851 if (space == null) return prefix; 9852 return prefix + " "; 9853 } 9854 return prefix + "+" + Integer.toString(val-base); 9855 } 9856 9857 private static final int dumpProcessList(PrintWriter pw, 9858 ActivityManagerService service, List list, 9859 String prefix, String normalLabel, String persistentLabel, 9860 String dumpPackage) { 9861 int numPers = 0; 9862 final int N = list.size()-1; 9863 for (int i=N; i>=0; i--) { 9864 ProcessRecord r = (ProcessRecord)list.get(i); 9865 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9866 continue; 9867 } 9868 pw.println(String.format("%s%s #%2d: %s", 9869 prefix, (r.persistent ? persistentLabel : normalLabel), 9870 i, r.toString())); 9871 if (r.persistent) { 9872 numPers++; 9873 } 9874 } 9875 return numPers; 9876 } 9877 9878 private static final boolean dumpProcessOomList(PrintWriter pw, 9879 ActivityManagerService service, List<ProcessRecord> origList, 9880 String prefix, String normalLabel, String persistentLabel, 9881 boolean inclDetails, String dumpPackage) { 9882 9883 ArrayList<Pair<ProcessRecord, Integer>> list 9884 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9885 for (int i=0; i<origList.size(); i++) { 9886 ProcessRecord r = origList.get(i); 9887 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9888 continue; 9889 } 9890 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9891 } 9892 9893 if (list.size() <= 0) { 9894 return false; 9895 } 9896 9897 Comparator<Pair<ProcessRecord, Integer>> comparator 9898 = new Comparator<Pair<ProcessRecord, Integer>>() { 9899 @Override 9900 public int compare(Pair<ProcessRecord, Integer> object1, 9901 Pair<ProcessRecord, Integer> object2) { 9902 if (object1.first.setAdj != object2.first.setAdj) { 9903 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9904 } 9905 if (object1.second.intValue() != object2.second.intValue()) { 9906 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9907 } 9908 return 0; 9909 } 9910 }; 9911 9912 Collections.sort(list, comparator); 9913 9914 final long curRealtime = SystemClock.elapsedRealtime(); 9915 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9916 final long curUptime = SystemClock.uptimeMillis(); 9917 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9918 9919 for (int i=list.size()-1; i>=0; i--) { 9920 ProcessRecord r = list.get(i).first; 9921 String oomAdj; 9922 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9923 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9924 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9925 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9926 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9927 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9928 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9929 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9930 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9931 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9932 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9933 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9934 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9935 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9936 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9937 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9938 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9939 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9940 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9941 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9942 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9943 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9944 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9945 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9946 } else { 9947 oomAdj = Integer.toString(r.setAdj); 9948 } 9949 String schedGroup; 9950 switch (r.setSchedGroup) { 9951 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9952 schedGroup = "B"; 9953 break; 9954 case Process.THREAD_GROUP_DEFAULT: 9955 schedGroup = "F"; 9956 break; 9957 default: 9958 schedGroup = Integer.toString(r.setSchedGroup); 9959 break; 9960 } 9961 String foreground; 9962 if (r.foregroundActivities) { 9963 foreground = "A"; 9964 } else if (r.foregroundServices) { 9965 foreground = "S"; 9966 } else { 9967 foreground = " "; 9968 } 9969 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9970 prefix, (r.persistent ? persistentLabel : normalLabel), 9971 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9972 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9973 if (r.adjSource != null || r.adjTarget != null) { 9974 pw.print(prefix); 9975 pw.print(" "); 9976 if (r.adjTarget instanceof ComponentName) { 9977 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9978 } else if (r.adjTarget != null) { 9979 pw.print(r.adjTarget.toString()); 9980 } else { 9981 pw.print("{null}"); 9982 } 9983 pw.print("<="); 9984 if (r.adjSource instanceof ProcessRecord) { 9985 pw.print("Proc{"); 9986 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9987 pw.println("}"); 9988 } else if (r.adjSource != null) { 9989 pw.println(r.adjSource.toString()); 9990 } else { 9991 pw.println("{null}"); 9992 } 9993 } 9994 if (inclDetails) { 9995 pw.print(prefix); 9996 pw.print(" "); 9997 pw.print("oom: max="); pw.print(r.maxAdj); 9998 pw.print(" hidden="); pw.print(r.hiddenAdj); 9999 pw.print(" empty="); pw.print(r.emptyAdj); 10000 pw.print(" curRaw="); pw.print(r.curRawAdj); 10001 pw.print(" setRaw="); pw.print(r.setRawAdj); 10002 pw.print(" cur="); pw.print(r.curAdj); 10003 pw.print(" set="); pw.println(r.setAdj); 10004 pw.print(prefix); 10005 pw.print(" "); 10006 pw.print("keeping="); pw.print(r.keeping); 10007 pw.print(" hidden="); pw.print(r.hidden); 10008 pw.print(" empty="); pw.print(r.empty); 10009 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10010 10011 if (!r.keeping) { 10012 if (r.lastWakeTime != 0) { 10013 long wtime; 10014 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10015 synchronized (stats) { 10016 wtime = stats.getProcessWakeTime(r.info.uid, 10017 r.pid, curRealtime); 10018 } 10019 long timeUsed = wtime - r.lastWakeTime; 10020 pw.print(prefix); 10021 pw.print(" "); 10022 pw.print("keep awake over "); 10023 TimeUtils.formatDuration(realtimeSince, pw); 10024 pw.print(" used "); 10025 TimeUtils.formatDuration(timeUsed, pw); 10026 pw.print(" ("); 10027 pw.print((timeUsed*100)/realtimeSince); 10028 pw.println("%)"); 10029 } 10030 if (r.lastCpuTime != 0) { 10031 long timeUsed = r.curCpuTime - r.lastCpuTime; 10032 pw.print(prefix); 10033 pw.print(" "); 10034 pw.print("run cpu over "); 10035 TimeUtils.formatDuration(uptimeSince, pw); 10036 pw.print(" used "); 10037 TimeUtils.formatDuration(timeUsed, pw); 10038 pw.print(" ("); 10039 pw.print((timeUsed*100)/uptimeSince); 10040 pw.println("%)"); 10041 } 10042 } 10043 } 10044 } 10045 return true; 10046 } 10047 10048 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10049 ArrayList<ProcessRecord> procs; 10050 synchronized (this) { 10051 if (args != null && args.length > start 10052 && args[start].charAt(0) != '-') { 10053 procs = new ArrayList<ProcessRecord>(); 10054 int pid = -1; 10055 try { 10056 pid = Integer.parseInt(args[start]); 10057 } catch (NumberFormatException e) { 10058 10059 } 10060 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10061 ProcessRecord proc = mLruProcesses.get(i); 10062 if (proc.pid == pid) { 10063 procs.add(proc); 10064 } else if (proc.processName.equals(args[start])) { 10065 procs.add(proc); 10066 } 10067 } 10068 if (procs.size() <= 0) { 10069 pw.println("No process found for: " + args[start]); 10070 return null; 10071 } 10072 } else { 10073 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10074 } 10075 } 10076 return procs; 10077 } 10078 10079 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10080 PrintWriter pw, String[] args) { 10081 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10082 if (procs == null) { 10083 return; 10084 } 10085 10086 long uptime = SystemClock.uptimeMillis(); 10087 long realtime = SystemClock.elapsedRealtime(); 10088 pw.println("Applications Graphics Acceleration Info:"); 10089 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10090 10091 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10092 ProcessRecord r = procs.get(i); 10093 if (r.thread != null) { 10094 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10095 pw.flush(); 10096 try { 10097 TransferPipe tp = new TransferPipe(); 10098 try { 10099 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10100 tp.go(fd); 10101 } finally { 10102 tp.kill(); 10103 } 10104 } catch (IOException e) { 10105 pw.println("Failure while dumping the app: " + r); 10106 pw.flush(); 10107 } catch (RemoteException e) { 10108 pw.println("Got a RemoteException while dumping the app " + r); 10109 pw.flush(); 10110 } 10111 } 10112 } 10113 } 10114 10115 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10116 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10117 if (procs == null) { 10118 return; 10119 } 10120 10121 pw.println("Applications Database Info:"); 10122 10123 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10124 ProcessRecord r = procs.get(i); 10125 if (r.thread != null) { 10126 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10127 pw.flush(); 10128 try { 10129 TransferPipe tp = new TransferPipe(); 10130 try { 10131 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10132 tp.go(fd); 10133 } finally { 10134 tp.kill(); 10135 } 10136 } catch (IOException e) { 10137 pw.println("Failure while dumping the app: " + r); 10138 pw.flush(); 10139 } catch (RemoteException e) { 10140 pw.println("Got a RemoteException while dumping the app " + r); 10141 pw.flush(); 10142 } 10143 } 10144 } 10145 } 10146 10147 final static class MemItem { 10148 final String label; 10149 final String shortLabel; 10150 final long pss; 10151 final int id; 10152 ArrayList<MemItem> subitems; 10153 10154 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10155 label = _label; 10156 shortLabel = _shortLabel; 10157 pss = _pss; 10158 id = _id; 10159 } 10160 } 10161 10162 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10163 boolean sort) { 10164 if (sort) { 10165 Collections.sort(items, new Comparator<MemItem>() { 10166 @Override 10167 public int compare(MemItem lhs, MemItem rhs) { 10168 if (lhs.pss < rhs.pss) { 10169 return 1; 10170 } else if (lhs.pss > rhs.pss) { 10171 return -1; 10172 } 10173 return 0; 10174 } 10175 }); 10176 } 10177 10178 for (int i=0; i<items.size(); i++) { 10179 MemItem mi = items.get(i); 10180 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10181 if (mi.subitems != null) { 10182 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10183 } 10184 } 10185 } 10186 10187 // These are in KB. 10188 static final long[] DUMP_MEM_BUCKETS = new long[] { 10189 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10190 120*1024, 160*1024, 200*1024, 10191 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10192 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10193 }; 10194 10195 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10196 boolean stackLike) { 10197 int start = label.lastIndexOf('.'); 10198 if (start >= 0) start++; 10199 else start = 0; 10200 int end = label.length(); 10201 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10202 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10203 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10204 out.append(bucket); 10205 out.append(stackLike ? "MB." : "MB "); 10206 out.append(label, start, end); 10207 return; 10208 } 10209 } 10210 out.append(memKB/1024); 10211 out.append(stackLike ? "MB." : "MB "); 10212 out.append(label, start, end); 10213 } 10214 10215 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10216 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10217 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10218 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10219 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10220 }; 10221 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10222 "System", "Persistent", "Foreground", 10223 "Visible", "Perceptible", "Heavy Weight", 10224 "Backup", "A Services", "Home", "Previous", 10225 "B Services", "Background" 10226 }; 10227 10228 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10229 PrintWriter pw, String prefix, String[] args, boolean brief, 10230 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10231 boolean dumpAll = false; 10232 boolean oomOnly = false; 10233 10234 int opti = 0; 10235 while (opti < args.length) { 10236 String opt = args[opti]; 10237 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10238 break; 10239 } 10240 opti++; 10241 if ("-a".equals(opt)) { 10242 dumpAll = true; 10243 } else if ("--oom".equals(opt)) { 10244 oomOnly = true; 10245 } else if ("-h".equals(opt)) { 10246 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10247 pw.println(" -a: include all available information for each process."); 10248 pw.println(" --oom: only show processes organized by oom adj."); 10249 pw.println("If [process] is specified it can be the name or "); 10250 pw.println("pid of a specific process to dump."); 10251 return; 10252 } else { 10253 pw.println("Unknown argument: " + opt + "; use -h for help"); 10254 } 10255 } 10256 10257 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10258 if (procs == null) { 10259 return; 10260 } 10261 10262 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10263 long uptime = SystemClock.uptimeMillis(); 10264 long realtime = SystemClock.elapsedRealtime(); 10265 10266 if (procs.size() == 1 || isCheckinRequest) { 10267 dumpAll = true; 10268 } 10269 10270 if (isCheckinRequest) { 10271 // short checkin version 10272 pw.println(uptime + "," + realtime); 10273 pw.flush(); 10274 } else { 10275 pw.println("Applications Memory Usage (kB):"); 10276 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10277 } 10278 10279 String[] innerArgs = new String[args.length-opti]; 10280 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10281 10282 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10283 long nativePss=0, dalvikPss=0, otherPss=0; 10284 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10285 10286 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10287 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10288 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10289 10290 long totalPss = 0; 10291 10292 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10293 ProcessRecord r = procs.get(i); 10294 if (r.thread != null) { 10295 if (!isCheckinRequest && dumpAll) { 10296 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10297 pw.flush(); 10298 } 10299 Debug.MemoryInfo mi = null; 10300 if (dumpAll) { 10301 try { 10302 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10303 } catch (RemoteException e) { 10304 if (!isCheckinRequest) { 10305 pw.println("Got RemoteException!"); 10306 pw.flush(); 10307 } 10308 } 10309 } else { 10310 mi = new Debug.MemoryInfo(); 10311 Debug.getMemoryInfo(r.pid, mi); 10312 } 10313 10314 if (!isCheckinRequest && mi != null) { 10315 long myTotalPss = mi.getTotalPss(); 10316 totalPss += myTotalPss; 10317 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10318 r.processName, myTotalPss, 0); 10319 procMems.add(pssItem); 10320 10321 nativePss += mi.nativePss; 10322 dalvikPss += mi.dalvikPss; 10323 otherPss += mi.otherPss; 10324 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10325 long mem = mi.getOtherPss(j); 10326 miscPss[j] += mem; 10327 otherPss -= mem; 10328 } 10329 10330 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10331 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10332 || oomIndex == (oomPss.length-1)) { 10333 oomPss[oomIndex] += myTotalPss; 10334 if (oomProcs[oomIndex] == null) { 10335 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10336 } 10337 oomProcs[oomIndex].add(pssItem); 10338 break; 10339 } 10340 } 10341 } 10342 } 10343 } 10344 10345 if (!isCheckinRequest && procs.size() > 1) { 10346 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10347 10348 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10349 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10350 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10351 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10352 String label = Debug.MemoryInfo.getOtherLabel(j); 10353 catMems.add(new MemItem(label, label, miscPss[j], j)); 10354 } 10355 10356 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10357 for (int j=0; j<oomPss.length; j++) { 10358 if (oomPss[j] != 0) { 10359 String label = DUMP_MEM_OOM_LABEL[j]; 10360 MemItem item = new MemItem(label, label, oomPss[j], 10361 DUMP_MEM_OOM_ADJ[j]); 10362 item.subitems = oomProcs[j]; 10363 oomMems.add(item); 10364 } 10365 } 10366 10367 if (outTag != null || outStack != null) { 10368 if (outTag != null) { 10369 appendMemBucket(outTag, totalPss, "total", false); 10370 } 10371 if (outStack != null) { 10372 appendMemBucket(outStack, totalPss, "total", true); 10373 } 10374 boolean firstLine = true; 10375 for (int i=0; i<oomMems.size(); i++) { 10376 MemItem miCat = oomMems.get(i); 10377 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10378 continue; 10379 } 10380 if (miCat.id < ProcessList.SERVICE_ADJ 10381 || miCat.id == ProcessList.HOME_APP_ADJ 10382 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10383 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10384 outTag.append(" / "); 10385 } 10386 if (outStack != null) { 10387 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10388 if (firstLine) { 10389 outStack.append(":"); 10390 firstLine = false; 10391 } 10392 outStack.append("\n\t at "); 10393 } else { 10394 outStack.append("$"); 10395 } 10396 } 10397 for (int j=0; j<miCat.subitems.size(); j++) { 10398 MemItem mi = miCat.subitems.get(j); 10399 if (j > 0) { 10400 if (outTag != null) { 10401 outTag.append(" "); 10402 } 10403 if (outStack != null) { 10404 outStack.append("$"); 10405 } 10406 } 10407 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10408 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10409 } 10410 if (outStack != null) { 10411 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10412 } 10413 } 10414 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10415 outStack.append("("); 10416 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10417 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10418 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10419 outStack.append(":"); 10420 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10421 } 10422 } 10423 outStack.append(")"); 10424 } 10425 } 10426 } 10427 } 10428 10429 if (!brief && !oomOnly) { 10430 pw.println(); 10431 pw.println("Total PSS by process:"); 10432 dumpMemItems(pw, " ", procMems, true); 10433 pw.println(); 10434 } 10435 pw.println("Total PSS by OOM adjustment:"); 10436 dumpMemItems(pw, " ", oomMems, false); 10437 if (!oomOnly) { 10438 PrintWriter out = categoryPw != null ? categoryPw : pw; 10439 out.println(); 10440 out.println("Total PSS by category:"); 10441 dumpMemItems(out, " ", catMems, true); 10442 } 10443 pw.println(); 10444 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10445 final int[] SINGLE_LONG_FORMAT = new int[] { 10446 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10447 }; 10448 long[] longOut = new long[1]; 10449 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10450 SINGLE_LONG_FORMAT, null, longOut, null); 10451 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10452 longOut[0] = 0; 10453 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10454 SINGLE_LONG_FORMAT, null, longOut, null); 10455 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10456 longOut[0] = 0; 10457 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10458 SINGLE_LONG_FORMAT, null, longOut, null); 10459 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10460 longOut[0] = 0; 10461 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10462 SINGLE_LONG_FORMAT, null, longOut, null); 10463 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10464 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10465 pw.print(shared); pw.println(" kB"); 10466 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10467 pw.print(voltile); pw.println(" kB volatile"); 10468 } 10469 } 10470 10471 /** 10472 * Searches array of arguments for the specified string 10473 * @param args array of argument strings 10474 * @param value value to search for 10475 * @return true if the value is contained in the array 10476 */ 10477 private static boolean scanArgs(String[] args, String value) { 10478 if (args != null) { 10479 for (String arg : args) { 10480 if (value.equals(arg)) { 10481 return true; 10482 } 10483 } 10484 } 10485 return false; 10486 } 10487 10488 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10489 ContentProviderRecord cpr, boolean always) { 10490 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10491 10492 if (!inLaunching || always) { 10493 synchronized (cpr) { 10494 cpr.launchingApp = null; 10495 cpr.notifyAll(); 10496 } 10497 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10498 String names[] = cpr.info.authority.split(";"); 10499 for (int j = 0; j < names.length; j++) { 10500 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10501 } 10502 } 10503 10504 for (int i=0; i<cpr.connections.size(); i++) { 10505 ContentProviderConnection conn = cpr.connections.get(i); 10506 if (conn.waiting) { 10507 // If this connection is waiting for the provider, then we don't 10508 // need to mess with its process unless we are always removing 10509 // or for some reason the provider is not currently launching. 10510 if (inLaunching && !always) { 10511 continue; 10512 } 10513 } 10514 ProcessRecord capp = conn.client; 10515 conn.dead = true; 10516 if (conn.stableCount > 0) { 10517 if (!capp.persistent && capp.thread != null 10518 && capp.pid != 0 10519 && capp.pid != MY_PID) { 10520 Slog.i(TAG, "Kill " + capp.processName 10521 + " (pid " + capp.pid + "): provider " + cpr.info.name 10522 + " in dying process " + (proc != null ? proc.processName : "??")); 10523 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10524 capp.processName, capp.setAdj, "dying provider " 10525 + cpr.name.toShortString()); 10526 Process.killProcessQuiet(capp.pid); 10527 } 10528 } else if (capp.thread != null && conn.provider.provider != null) { 10529 try { 10530 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10531 } catch (RemoteException e) { 10532 } 10533 // In the protocol here, we don't expect the client to correctly 10534 // clean up this connection, we'll just remove it. 10535 cpr.connections.remove(i); 10536 conn.client.conProviders.remove(conn); 10537 } 10538 } 10539 10540 if (inLaunching && always) { 10541 mLaunchingProviders.remove(cpr); 10542 } 10543 return inLaunching; 10544 } 10545 10546 /** 10547 * Main code for cleaning up a process when it has gone away. This is 10548 * called both as a result of the process dying, or directly when stopping 10549 * a process when running in single process mode. 10550 */ 10551 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10552 boolean restarting, boolean allowRestart, int index) { 10553 if (index >= 0) { 10554 mLruProcesses.remove(index); 10555 } 10556 10557 mProcessesToGc.remove(app); 10558 10559 // Dismiss any open dialogs. 10560 if (app.crashDialog != null) { 10561 app.crashDialog.dismiss(); 10562 app.crashDialog = null; 10563 } 10564 if (app.anrDialog != null) { 10565 app.anrDialog.dismiss(); 10566 app.anrDialog = null; 10567 } 10568 if (app.waitDialog != null) { 10569 app.waitDialog.dismiss(); 10570 app.waitDialog = null; 10571 } 10572 10573 app.crashing = false; 10574 app.notResponding = false; 10575 10576 app.resetPackageList(); 10577 app.unlinkDeathRecipient(); 10578 app.thread = null; 10579 app.forcingToForeground = null; 10580 app.foregroundServices = false; 10581 app.foregroundActivities = false; 10582 app.hasShownUi = false; 10583 app.hasAboveClient = false; 10584 10585 mServices.killServicesLocked(app, allowRestart); 10586 10587 boolean restart = false; 10588 10589 // Remove published content providers. 10590 if (!app.pubProviders.isEmpty()) { 10591 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10592 while (it.hasNext()) { 10593 ContentProviderRecord cpr = it.next(); 10594 10595 final boolean always = app.bad || !allowRestart; 10596 if (removeDyingProviderLocked(app, cpr, always) || always) { 10597 // We left the provider in the launching list, need to 10598 // restart it. 10599 restart = true; 10600 } 10601 10602 cpr.provider = null; 10603 cpr.proc = null; 10604 } 10605 app.pubProviders.clear(); 10606 } 10607 10608 // Take care of any launching providers waiting for this process. 10609 if (checkAppInLaunchingProvidersLocked(app, false)) { 10610 restart = true; 10611 } 10612 10613 // Unregister from connected content providers. 10614 if (!app.conProviders.isEmpty()) { 10615 for (int i=0; i<app.conProviders.size(); i++) { 10616 ContentProviderConnection conn = app.conProviders.get(i); 10617 conn.provider.connections.remove(conn); 10618 } 10619 app.conProviders.clear(); 10620 } 10621 10622 // At this point there may be remaining entries in mLaunchingProviders 10623 // where we were the only one waiting, so they are no longer of use. 10624 // Look for these and clean up if found. 10625 // XXX Commented out for now. Trying to figure out a way to reproduce 10626 // the actual situation to identify what is actually going on. 10627 if (false) { 10628 for (int i=0; i<mLaunchingProviders.size(); i++) { 10629 ContentProviderRecord cpr = (ContentProviderRecord) 10630 mLaunchingProviders.get(i); 10631 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10632 synchronized (cpr) { 10633 cpr.launchingApp = null; 10634 cpr.notifyAll(); 10635 } 10636 } 10637 } 10638 } 10639 10640 skipCurrentReceiverLocked(app); 10641 10642 // Unregister any receivers. 10643 if (app.receivers.size() > 0) { 10644 Iterator<ReceiverList> it = app.receivers.iterator(); 10645 while (it.hasNext()) { 10646 removeReceiverLocked(it.next()); 10647 } 10648 app.receivers.clear(); 10649 } 10650 10651 // If the app is undergoing backup, tell the backup manager about it 10652 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10653 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10654 try { 10655 IBackupManager bm = IBackupManager.Stub.asInterface( 10656 ServiceManager.getService(Context.BACKUP_SERVICE)); 10657 bm.agentDisconnected(app.info.packageName); 10658 } catch (RemoteException e) { 10659 // can't happen; backup manager is local 10660 } 10661 } 10662 10663 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10664 ProcessChangeItem item = mPendingProcessChanges.get(i); 10665 if (item.pid == app.pid) { 10666 mPendingProcessChanges.remove(i); 10667 mAvailProcessChanges.add(item); 10668 } 10669 } 10670 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10671 10672 // If the caller is restarting this app, then leave it in its 10673 // current lists and let the caller take care of it. 10674 if (restarting) { 10675 return; 10676 } 10677 10678 if (!app.persistent || app.isolated) { 10679 if (DEBUG_PROCESSES) Slog.v(TAG, 10680 "Removing non-persistent process during cleanup: " + app); 10681 mProcessNames.remove(app.processName, app.uid); 10682 mIsolatedProcesses.remove(app.uid); 10683 if (mHeavyWeightProcess == app) { 10684 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10685 mHeavyWeightProcess.userId, 0)); 10686 mHeavyWeightProcess = null; 10687 } 10688 } else if (!app.removed) { 10689 // This app is persistent, so we need to keep its record around. 10690 // If it is not already on the pending app list, add it there 10691 // and start a new process for it. 10692 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10693 mPersistentStartingProcesses.add(app); 10694 restart = true; 10695 } 10696 } 10697 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10698 "Clean-up removing on hold: " + app); 10699 mProcessesOnHold.remove(app); 10700 10701 if (app == mHomeProcess) { 10702 mHomeProcess = null; 10703 } 10704 if (app == mPreviousProcess) { 10705 mPreviousProcess = null; 10706 } 10707 10708 if (restart && !app.isolated) { 10709 // We have components that still need to be running in the 10710 // process, so re-launch it. 10711 mProcessNames.put(app.processName, app.uid, app); 10712 startProcessLocked(app, "restart", app.processName); 10713 } else if (app.pid > 0 && app.pid != MY_PID) { 10714 // Goodbye! 10715 synchronized (mPidsSelfLocked) { 10716 mPidsSelfLocked.remove(app.pid); 10717 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10718 } 10719 app.setPid(0); 10720 } 10721 } 10722 10723 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10724 // Look through the content providers we are waiting to have launched, 10725 // and if any run in this process then either schedule a restart of 10726 // the process or kill the client waiting for it if this process has 10727 // gone bad. 10728 int NL = mLaunchingProviders.size(); 10729 boolean restart = false; 10730 for (int i=0; i<NL; i++) { 10731 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10732 if (cpr.launchingApp == app) { 10733 if (!alwaysBad && !app.bad) { 10734 restart = true; 10735 } else { 10736 removeDyingProviderLocked(app, cpr, true); 10737 // cpr should have been removed from mLaunchingProviders 10738 NL = mLaunchingProviders.size(); 10739 i--; 10740 } 10741 } 10742 } 10743 return restart; 10744 } 10745 10746 // ========================================================= 10747 // SERVICES 10748 // ========================================================= 10749 10750 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10751 int flags) { 10752 enforceNotIsolatedCaller("getServices"); 10753 synchronized (this) { 10754 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10755 } 10756 } 10757 10758 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10759 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10760 synchronized (this) { 10761 return mServices.getRunningServiceControlPanelLocked(name); 10762 } 10763 } 10764 10765 public ComponentName startService(IApplicationThread caller, Intent service, 10766 String resolvedType, int userId) { 10767 enforceNotIsolatedCaller("startService"); 10768 // Refuse possible leaked file descriptors 10769 if (service != null && service.hasFileDescriptors() == true) { 10770 throw new IllegalArgumentException("File descriptors passed in Intent"); 10771 } 10772 10773 if (DEBUG_SERVICE) 10774 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10775 synchronized(this) { 10776 final int callingPid = Binder.getCallingPid(); 10777 final int callingUid = Binder.getCallingUid(); 10778 checkValidCaller(callingUid, userId); 10779 final long origId = Binder.clearCallingIdentity(); 10780 ComponentName res = mServices.startServiceLocked(caller, service, 10781 resolvedType, callingPid, callingUid, userId); 10782 Binder.restoreCallingIdentity(origId); 10783 return res; 10784 } 10785 } 10786 10787 ComponentName startServiceInPackage(int uid, 10788 Intent service, String resolvedType, int userId) { 10789 synchronized(this) { 10790 if (DEBUG_SERVICE) 10791 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10792 final long origId = Binder.clearCallingIdentity(); 10793 ComponentName res = mServices.startServiceLocked(null, service, 10794 resolvedType, -1, uid, userId); 10795 Binder.restoreCallingIdentity(origId); 10796 return res; 10797 } 10798 } 10799 10800 public int stopService(IApplicationThread caller, Intent service, 10801 String resolvedType, int userId) { 10802 enforceNotIsolatedCaller("stopService"); 10803 // Refuse possible leaked file descriptors 10804 if (service != null && service.hasFileDescriptors() == true) { 10805 throw new IllegalArgumentException("File descriptors passed in Intent"); 10806 } 10807 10808 checkValidCaller(Binder.getCallingUid(), userId); 10809 10810 synchronized(this) { 10811 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10812 } 10813 } 10814 10815 public IBinder peekService(Intent service, String resolvedType) { 10816 enforceNotIsolatedCaller("peekService"); 10817 // Refuse possible leaked file descriptors 10818 if (service != null && service.hasFileDescriptors() == true) { 10819 throw new IllegalArgumentException("File descriptors passed in Intent"); 10820 } 10821 synchronized(this) { 10822 return mServices.peekServiceLocked(service, resolvedType); 10823 } 10824 } 10825 10826 public boolean stopServiceToken(ComponentName className, IBinder token, 10827 int startId) { 10828 synchronized(this) { 10829 return mServices.stopServiceTokenLocked(className, token, startId); 10830 } 10831 } 10832 10833 public void setServiceForeground(ComponentName className, IBinder token, 10834 int id, Notification notification, boolean removeNotification) { 10835 synchronized(this) { 10836 mServices.setServiceForegroundLocked(className, token, id, notification, 10837 removeNotification); 10838 } 10839 } 10840 10841 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10842 boolean requireFull, String name, String callerPackage) { 10843 synchronized(this) { 10844 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10845 requireFull, name, callerPackage); 10846 } 10847 } 10848 10849 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10850 boolean requireFull, String name, String callerPackage) { 10851 final int callingUserId = UserHandle.getUserId(callingUid); 10852 if (callingUserId != userId) { 10853 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10854 if ((requireFull || checkComponentPermission( 10855 android.Manifest.permission.INTERACT_ACROSS_USERS, 10856 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10857 && checkComponentPermission( 10858 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10859 callingPid, callingUid, -1, true) 10860 != PackageManager.PERMISSION_GRANTED) { 10861 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10862 // In this case, they would like to just execute as their 10863 // owner user instead of failing. 10864 userId = callingUserId; 10865 } else { 10866 StringBuilder builder = new StringBuilder(128); 10867 builder.append("Permission Denial: "); 10868 builder.append(name); 10869 if (callerPackage != null) { 10870 builder.append(" from "); 10871 builder.append(callerPackage); 10872 } 10873 builder.append(" asks to run as user "); 10874 builder.append(userId); 10875 builder.append(" but is calling from user "); 10876 builder.append(UserHandle.getUserId(callingUid)); 10877 builder.append("; this requires "); 10878 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10879 if (!requireFull) { 10880 builder.append(" or "); 10881 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10882 } 10883 String msg = builder.toString(); 10884 Slog.w(TAG, msg); 10885 throw new SecurityException(msg); 10886 } 10887 } 10888 } 10889 if (userId == UserHandle.USER_CURRENT 10890 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10891 userId = mCurrentUserId; 10892 } 10893 if (!allowAll && userId < 0) { 10894 throw new IllegalArgumentException( 10895 "Call does not support special user #" + userId); 10896 } 10897 } 10898 return userId; 10899 } 10900 10901 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10902 String className, int flags) { 10903 boolean result = false; 10904 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10905 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10906 if (ActivityManager.checkUidPermission( 10907 android.Manifest.permission.INTERACT_ACROSS_USERS, 10908 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10909 ComponentName comp = new ComponentName(aInfo.packageName, className); 10910 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10911 + " requests FLAG_SINGLE_USER, but app does not hold " 10912 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10913 Slog.w(TAG, msg); 10914 throw new SecurityException(msg); 10915 } 10916 result = true; 10917 } 10918 } else if (componentProcessName == aInfo.packageName) { 10919 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10920 } else if ("system".equals(componentProcessName)) { 10921 result = true; 10922 } 10923 if (DEBUG_MU) { 10924 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10925 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10926 } 10927 return result; 10928 } 10929 10930 public int bindService(IApplicationThread caller, IBinder token, 10931 Intent service, String resolvedType, 10932 IServiceConnection connection, int flags, int userId) { 10933 enforceNotIsolatedCaller("bindService"); 10934 // Refuse possible leaked file descriptors 10935 if (service != null && service.hasFileDescriptors() == true) { 10936 throw new IllegalArgumentException("File descriptors passed in Intent"); 10937 } 10938 10939 synchronized(this) { 10940 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10941 connection, flags, userId); 10942 } 10943 } 10944 10945 public boolean unbindService(IServiceConnection connection) { 10946 synchronized (this) { 10947 return mServices.unbindServiceLocked(connection); 10948 } 10949 } 10950 10951 public void publishService(IBinder token, Intent intent, IBinder service) { 10952 // Refuse possible leaked file descriptors 10953 if (intent != null && intent.hasFileDescriptors() == true) { 10954 throw new IllegalArgumentException("File descriptors passed in Intent"); 10955 } 10956 10957 synchronized(this) { 10958 if (!(token instanceof ServiceRecord)) { 10959 throw new IllegalArgumentException("Invalid service token"); 10960 } 10961 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10962 } 10963 } 10964 10965 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10966 // Refuse possible leaked file descriptors 10967 if (intent != null && intent.hasFileDescriptors() == true) { 10968 throw new IllegalArgumentException("File descriptors passed in Intent"); 10969 } 10970 10971 synchronized(this) { 10972 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10973 } 10974 } 10975 10976 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10977 synchronized(this) { 10978 if (!(token instanceof ServiceRecord)) { 10979 throw new IllegalArgumentException("Invalid service token"); 10980 } 10981 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10982 } 10983 } 10984 10985 // ========================================================= 10986 // BACKUP AND RESTORE 10987 // ========================================================= 10988 10989 // Cause the target app to be launched if necessary and its backup agent 10990 // instantiated. The backup agent will invoke backupAgentCreated() on the 10991 // activity manager to announce its creation. 10992 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10993 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10994 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10995 10996 synchronized(this) { 10997 // !!! TODO: currently no check here that we're already bound 10998 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10999 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11000 synchronized (stats) { 11001 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11002 } 11003 11004 // Backup agent is now in use, its package can't be stopped. 11005 try { 11006 AppGlobals.getPackageManager().setPackageStoppedState( 11007 app.packageName, false, UserHandle.getUserId(app.uid)); 11008 } catch (RemoteException e) { 11009 } catch (IllegalArgumentException e) { 11010 Slog.w(TAG, "Failed trying to unstop package " 11011 + app.packageName + ": " + e); 11012 } 11013 11014 BackupRecord r = new BackupRecord(ss, app, backupMode); 11015 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11016 ? new ComponentName(app.packageName, app.backupAgentName) 11017 : new ComponentName("android", "FullBackupAgent"); 11018 // startProcessLocked() returns existing proc's record if it's already running 11019 ProcessRecord proc = startProcessLocked(app.processName, app, 11020 false, 0, "backup", hostingName, false, false); 11021 if (proc == null) { 11022 Slog.e(TAG, "Unable to start backup agent process " + r); 11023 return false; 11024 } 11025 11026 r.app = proc; 11027 mBackupTarget = r; 11028 mBackupAppName = app.packageName; 11029 11030 // Try not to kill the process during backup 11031 updateOomAdjLocked(proc); 11032 11033 // If the process is already attached, schedule the creation of the backup agent now. 11034 // If it is not yet live, this will be done when it attaches to the framework. 11035 if (proc.thread != null) { 11036 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11037 try { 11038 proc.thread.scheduleCreateBackupAgent(app, 11039 compatibilityInfoForPackageLocked(app), backupMode); 11040 } catch (RemoteException e) { 11041 // Will time out on the backup manager side 11042 } 11043 } else { 11044 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11045 } 11046 // Invariants: at this point, the target app process exists and the application 11047 // is either already running or in the process of coming up. mBackupTarget and 11048 // mBackupAppName describe the app, so that when it binds back to the AM we 11049 // know that it's scheduled for a backup-agent operation. 11050 } 11051 11052 return true; 11053 } 11054 11055 // A backup agent has just come up 11056 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11057 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11058 + " = " + agent); 11059 11060 synchronized(this) { 11061 if (!agentPackageName.equals(mBackupAppName)) { 11062 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11063 return; 11064 } 11065 } 11066 11067 long oldIdent = Binder.clearCallingIdentity(); 11068 try { 11069 IBackupManager bm = IBackupManager.Stub.asInterface( 11070 ServiceManager.getService(Context.BACKUP_SERVICE)); 11071 bm.agentConnected(agentPackageName, agent); 11072 } catch (RemoteException e) { 11073 // can't happen; the backup manager service is local 11074 } catch (Exception e) { 11075 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11076 e.printStackTrace(); 11077 } finally { 11078 Binder.restoreCallingIdentity(oldIdent); 11079 } 11080 } 11081 11082 // done with this agent 11083 public void unbindBackupAgent(ApplicationInfo appInfo) { 11084 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11085 if (appInfo == null) { 11086 Slog.w(TAG, "unbind backup agent for null app"); 11087 return; 11088 } 11089 11090 synchronized(this) { 11091 if (mBackupAppName == null) { 11092 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11093 return; 11094 } 11095 11096 if (!mBackupAppName.equals(appInfo.packageName)) { 11097 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11098 return; 11099 } 11100 11101 ProcessRecord proc = mBackupTarget.app; 11102 mBackupTarget = null; 11103 mBackupAppName = null; 11104 11105 // Not backing this app up any more; reset its OOM adjustment 11106 updateOomAdjLocked(proc); 11107 11108 // If the app crashed during backup, 'thread' will be null here 11109 if (proc.thread != null) { 11110 try { 11111 proc.thread.scheduleDestroyBackupAgent(appInfo, 11112 compatibilityInfoForPackageLocked(appInfo)); 11113 } catch (Exception e) { 11114 Slog.e(TAG, "Exception when unbinding backup agent:"); 11115 e.printStackTrace(); 11116 } 11117 } 11118 } 11119 } 11120 // ========================================================= 11121 // BROADCASTS 11122 // ========================================================= 11123 11124 private final List getStickiesLocked(String action, IntentFilter filter, 11125 List cur, int userId) { 11126 final ContentResolver resolver = mContext.getContentResolver(); 11127 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11128 if (stickies == null) { 11129 return cur; 11130 } 11131 final ArrayList<Intent> list = stickies.get(action); 11132 if (list == null) { 11133 return cur; 11134 } 11135 int N = list.size(); 11136 for (int i=0; i<N; i++) { 11137 Intent intent = list.get(i); 11138 if (filter.match(resolver, intent, true, TAG) >= 0) { 11139 if (cur == null) { 11140 cur = new ArrayList<Intent>(); 11141 } 11142 cur.add(intent); 11143 } 11144 } 11145 return cur; 11146 } 11147 11148 boolean isPendingBroadcastProcessLocked(int pid) { 11149 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11150 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11151 } 11152 11153 void skipPendingBroadcastLocked(int pid) { 11154 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11155 for (BroadcastQueue queue : mBroadcastQueues) { 11156 queue.skipPendingBroadcastLocked(pid); 11157 } 11158 } 11159 11160 // The app just attached; send any pending broadcasts that it should receive 11161 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11162 boolean didSomething = false; 11163 for (BroadcastQueue queue : mBroadcastQueues) { 11164 didSomething |= queue.sendPendingBroadcastsLocked(app); 11165 } 11166 return didSomething; 11167 } 11168 11169 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11170 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11171 enforceNotIsolatedCaller("registerReceiver"); 11172 int callingUid; 11173 int callingPid; 11174 synchronized(this) { 11175 ProcessRecord callerApp = null; 11176 if (caller != null) { 11177 callerApp = getRecordForAppLocked(caller); 11178 if (callerApp == null) { 11179 throw new SecurityException( 11180 "Unable to find app for caller " + caller 11181 + " (pid=" + Binder.getCallingPid() 11182 + ") when registering receiver " + receiver); 11183 } 11184 if (callerApp.info.uid != Process.SYSTEM_UID && 11185 !callerApp.pkgList.contains(callerPackage)) { 11186 throw new SecurityException("Given caller package " + callerPackage 11187 + " is not running in process " + callerApp); 11188 } 11189 callingUid = callerApp.info.uid; 11190 callingPid = callerApp.pid; 11191 } else { 11192 callerPackage = null; 11193 callingUid = Binder.getCallingUid(); 11194 callingPid = Binder.getCallingPid(); 11195 } 11196 11197 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11198 true, true, "registerReceiver", callerPackage); 11199 11200 List allSticky = null; 11201 11202 // Look for any matching sticky broadcasts... 11203 Iterator actions = filter.actionsIterator(); 11204 if (actions != null) { 11205 while (actions.hasNext()) { 11206 String action = (String)actions.next(); 11207 allSticky = getStickiesLocked(action, filter, allSticky, 11208 UserHandle.USER_ALL); 11209 allSticky = getStickiesLocked(action, filter, allSticky, 11210 UserHandle.getUserId(callingUid)); 11211 } 11212 } else { 11213 allSticky = getStickiesLocked(null, filter, allSticky, 11214 UserHandle.USER_ALL); 11215 allSticky = getStickiesLocked(null, filter, allSticky, 11216 UserHandle.getUserId(callingUid)); 11217 } 11218 11219 // The first sticky in the list is returned directly back to 11220 // the client. 11221 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11222 11223 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11224 + ": " + sticky); 11225 11226 if (receiver == null) { 11227 return sticky; 11228 } 11229 11230 ReceiverList rl 11231 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11232 if (rl == null) { 11233 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11234 userId, receiver); 11235 if (rl.app != null) { 11236 rl.app.receivers.add(rl); 11237 } else { 11238 try { 11239 receiver.asBinder().linkToDeath(rl, 0); 11240 } catch (RemoteException e) { 11241 return sticky; 11242 } 11243 rl.linkedToDeath = true; 11244 } 11245 mRegisteredReceivers.put(receiver.asBinder(), rl); 11246 } else if (rl.uid != callingUid) { 11247 throw new IllegalArgumentException( 11248 "Receiver requested to register for uid " + callingUid 11249 + " was previously registered for uid " + rl.uid); 11250 } else if (rl.pid != callingPid) { 11251 throw new IllegalArgumentException( 11252 "Receiver requested to register for pid " + callingPid 11253 + " was previously registered for pid " + rl.pid); 11254 } else if (rl.userId != userId) { 11255 throw new IllegalArgumentException( 11256 "Receiver requested to register for user " + userId 11257 + " was previously registered for user " + rl.userId); 11258 } 11259 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11260 permission, callingUid, userId); 11261 rl.add(bf); 11262 if (!bf.debugCheck()) { 11263 Slog.w(TAG, "==> For Dynamic broadast"); 11264 } 11265 mReceiverResolver.addFilter(bf); 11266 11267 // Enqueue broadcasts for all existing stickies that match 11268 // this filter. 11269 if (allSticky != null) { 11270 ArrayList receivers = new ArrayList(); 11271 receivers.add(bf); 11272 11273 int N = allSticky.size(); 11274 for (int i=0; i<N; i++) { 11275 Intent intent = (Intent)allSticky.get(i); 11276 BroadcastQueue queue = broadcastQueueForIntent(intent); 11277 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11278 null, -1, -1, null, receivers, null, 0, null, null, 11279 false, true, true, -1); 11280 queue.enqueueParallelBroadcastLocked(r); 11281 queue.scheduleBroadcastsLocked(); 11282 } 11283 } 11284 11285 return sticky; 11286 } 11287 } 11288 11289 public void unregisterReceiver(IIntentReceiver receiver) { 11290 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11291 11292 final long origId = Binder.clearCallingIdentity(); 11293 try { 11294 boolean doTrim = false; 11295 11296 synchronized(this) { 11297 ReceiverList rl 11298 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11299 if (rl != null) { 11300 if (rl.curBroadcast != null) { 11301 BroadcastRecord r = rl.curBroadcast; 11302 final boolean doNext = finishReceiverLocked( 11303 receiver.asBinder(), r.resultCode, r.resultData, 11304 r.resultExtras, r.resultAbort, true); 11305 if (doNext) { 11306 doTrim = true; 11307 r.queue.processNextBroadcast(false); 11308 } 11309 } 11310 11311 if (rl.app != null) { 11312 rl.app.receivers.remove(rl); 11313 } 11314 removeReceiverLocked(rl); 11315 if (rl.linkedToDeath) { 11316 rl.linkedToDeath = false; 11317 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11318 } 11319 } 11320 } 11321 11322 // If we actually concluded any broadcasts, we might now be able 11323 // to trim the recipients' apps from our working set 11324 if (doTrim) { 11325 trimApplications(); 11326 return; 11327 } 11328 11329 } finally { 11330 Binder.restoreCallingIdentity(origId); 11331 } 11332 } 11333 11334 void removeReceiverLocked(ReceiverList rl) { 11335 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11336 int N = rl.size(); 11337 for (int i=0; i<N; i++) { 11338 mReceiverResolver.removeFilter(rl.get(i)); 11339 } 11340 } 11341 11342 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11343 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11344 ProcessRecord r = mLruProcesses.get(i); 11345 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11346 try { 11347 r.thread.dispatchPackageBroadcast(cmd, packages); 11348 } catch (RemoteException ex) { 11349 } 11350 } 11351 } 11352 } 11353 11354 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11355 int[] users) { 11356 List<ResolveInfo> receivers = null; 11357 try { 11358 HashSet<ComponentName> singleUserReceivers = null; 11359 boolean scannedFirstReceivers = false; 11360 for (int user : users) { 11361 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11362 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11363 if (newReceivers != null && newReceivers.size() == 0) { 11364 newReceivers = null; 11365 } 11366 if (receivers == null) { 11367 receivers = newReceivers; 11368 } else if (newReceivers != null) { 11369 // We need to concatenate the additional receivers 11370 // found with what we have do far. This would be easy, 11371 // but we also need to de-dup any receivers that are 11372 // singleUser. 11373 if (!scannedFirstReceivers) { 11374 // Collect any single user receivers we had already retrieved. 11375 scannedFirstReceivers = true; 11376 for (int i=0; i<receivers.size(); i++) { 11377 ResolveInfo ri = receivers.get(i); 11378 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11379 ComponentName cn = new ComponentName( 11380 ri.activityInfo.packageName, ri.activityInfo.name); 11381 if (singleUserReceivers == null) { 11382 singleUserReceivers = new HashSet<ComponentName>(); 11383 } 11384 singleUserReceivers.add(cn); 11385 } 11386 } 11387 } 11388 // Add the new results to the existing results, tracking 11389 // and de-dupping single user receivers. 11390 for (int i=0; i<newReceivers.size(); i++) { 11391 ResolveInfo ri = receivers.get(i); 11392 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11393 ComponentName cn = new ComponentName( 11394 ri.activityInfo.packageName, ri.activityInfo.name); 11395 if (singleUserReceivers == null) { 11396 singleUserReceivers = new HashSet<ComponentName>(); 11397 } 11398 if (!singleUserReceivers.contains(cn)) { 11399 singleUserReceivers.add(cn); 11400 receivers.add(ri); 11401 } 11402 } else { 11403 receivers.add(ri); 11404 } 11405 } 11406 } 11407 } 11408 } catch (RemoteException ex) { 11409 // pm is in same process, this will never happen. 11410 } 11411 return receivers; 11412 } 11413 11414 private final int broadcastIntentLocked(ProcessRecord callerApp, 11415 String callerPackage, Intent intent, String resolvedType, 11416 IIntentReceiver resultTo, int resultCode, String resultData, 11417 Bundle map, String requiredPermission, 11418 boolean ordered, boolean sticky, int callingPid, int callingUid, 11419 int userId) { 11420 intent = new Intent(intent); 11421 11422 // By default broadcasts do not go to stopped apps. 11423 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11424 11425 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11426 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11427 + " ordered=" + ordered + " userid=" + userId); 11428 if ((resultTo != null) && !ordered) { 11429 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11430 } 11431 11432 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11433 true, false, "broadcast", callerPackage); 11434 11435 // Make sure that the user who is receiving this broadcast is started 11436 // If not, we will just skip it. 11437 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11438 Slog.w(TAG, "Skipping broadcast of " + intent 11439 + ": user " + userId + " is stopped"); 11440 return ActivityManager.BROADCAST_SUCCESS; 11441 } 11442 11443 /* 11444 * Prevent non-system code (defined here to be non-persistent 11445 * processes) from sending protected broadcasts. 11446 */ 11447 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11448 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11449 callingUid == 0) { 11450 // Always okay. 11451 } else if (callerApp == null || !callerApp.persistent) { 11452 try { 11453 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11454 intent.getAction())) { 11455 String msg = "Permission Denial: not allowed to send broadcast " 11456 + intent.getAction() + " from pid=" 11457 + callingPid + ", uid=" + callingUid; 11458 Slog.w(TAG, msg); 11459 throw new SecurityException(msg); 11460 } 11461 } catch (RemoteException e) { 11462 Slog.w(TAG, "Remote exception", e); 11463 return ActivityManager.BROADCAST_SUCCESS; 11464 } 11465 } 11466 11467 // Handle special intents: if this broadcast is from the package 11468 // manager about a package being removed, we need to remove all of 11469 // its activities from the history stack. 11470 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11471 intent.getAction()); 11472 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11473 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11474 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11475 || uidRemoved) { 11476 if (checkComponentPermission( 11477 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11478 callingPid, callingUid, -1, true) 11479 == PackageManager.PERMISSION_GRANTED) { 11480 if (uidRemoved) { 11481 final Bundle intentExtras = intent.getExtras(); 11482 final int uid = intentExtras != null 11483 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11484 if (uid >= 0) { 11485 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11486 synchronized (bs) { 11487 bs.removeUidStatsLocked(uid); 11488 } 11489 } 11490 } else { 11491 // If resources are unavailable just force stop all 11492 // those packages and flush the attribute cache as well. 11493 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11494 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11495 if (list != null && (list.length > 0)) { 11496 for (String pkg : list) { 11497 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11498 } 11499 sendPackageBroadcastLocked( 11500 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11501 } 11502 } else { 11503 Uri data = intent.getData(); 11504 String ssp; 11505 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11506 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11507 forceStopPackageLocked(ssp, 11508 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11509 false, userId); 11510 } 11511 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11512 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11513 new String[] {ssp}, userId); 11514 } 11515 } 11516 } 11517 } 11518 } else { 11519 String msg = "Permission Denial: " + intent.getAction() 11520 + " broadcast from " + callerPackage + " (pid=" + callingPid 11521 + ", uid=" + callingUid + ")" 11522 + " requires " 11523 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11524 Slog.w(TAG, msg); 11525 throw new SecurityException(msg); 11526 } 11527 11528 // Special case for adding a package: by default turn on compatibility 11529 // mode. 11530 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11531 Uri data = intent.getData(); 11532 String ssp; 11533 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11534 mCompatModePackages.handlePackageAddedLocked(ssp, 11535 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11536 } 11537 } 11538 11539 /* 11540 * If this is the time zone changed action, queue up a message that will reset the timezone 11541 * of all currently running processes. This message will get queued up before the broadcast 11542 * happens. 11543 */ 11544 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11545 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11546 } 11547 11548 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11549 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11550 } 11551 11552 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11553 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11554 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11555 } 11556 11557 // Add to the sticky list if requested. 11558 if (sticky) { 11559 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11560 callingPid, callingUid) 11561 != PackageManager.PERMISSION_GRANTED) { 11562 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11563 + callingPid + ", uid=" + callingUid 11564 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11565 Slog.w(TAG, msg); 11566 throw new SecurityException(msg); 11567 } 11568 if (requiredPermission != null) { 11569 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11570 + " and enforce permission " + requiredPermission); 11571 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11572 } 11573 if (intent.getComponent() != null) { 11574 throw new SecurityException( 11575 "Sticky broadcasts can't target a specific component"); 11576 } 11577 // We use userId directly here, since the "all" target is maintained 11578 // as a separate set of sticky broadcasts. 11579 if (userId != UserHandle.USER_ALL) { 11580 // But first, if this is not a broadcast to all users, then 11581 // make sure it doesn't conflict with an existing broadcast to 11582 // all users. 11583 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11584 UserHandle.USER_ALL); 11585 if (stickies != null) { 11586 ArrayList<Intent> list = stickies.get(intent.getAction()); 11587 if (list != null) { 11588 int N = list.size(); 11589 int i; 11590 for (i=0; i<N; i++) { 11591 if (intent.filterEquals(list.get(i))) { 11592 throw new IllegalArgumentException( 11593 "Sticky broadcast " + intent + " for user " 11594 + userId + " conflicts with existing global broadcast"); 11595 } 11596 } 11597 } 11598 } 11599 } 11600 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11601 if (stickies == null) { 11602 stickies = new HashMap<String, ArrayList<Intent>>(); 11603 mStickyBroadcasts.put(userId, stickies); 11604 } 11605 ArrayList<Intent> list = stickies.get(intent.getAction()); 11606 if (list == null) { 11607 list = new ArrayList<Intent>(); 11608 stickies.put(intent.getAction(), list); 11609 } 11610 int N = list.size(); 11611 int i; 11612 for (i=0; i<N; i++) { 11613 if (intent.filterEquals(list.get(i))) { 11614 // This sticky already exists, replace it. 11615 list.set(i, new Intent(intent)); 11616 break; 11617 } 11618 } 11619 if (i >= N) { 11620 list.add(new Intent(intent)); 11621 } 11622 } 11623 11624 int[] users; 11625 if (userId == UserHandle.USER_ALL) { 11626 // Caller wants broadcast to go to all started users. 11627 users = new int[mStartedUsers.size()]; 11628 for (int i=0; i<mStartedUsers.size(); i++) { 11629 users[i] = mStartedUsers.keyAt(i); 11630 } 11631 } else { 11632 // Caller wants broadcast to go to one specific user. 11633 users = new int[] {userId}; 11634 } 11635 11636 // Figure out who all will receive this broadcast. 11637 List receivers = null; 11638 List<BroadcastFilter> registeredReceivers = null; 11639 // Need to resolve the intent to interested receivers... 11640 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11641 == 0) { 11642 receivers = collectReceiverComponents(intent, resolvedType, users); 11643 } 11644 if (intent.getComponent() == null) { 11645 registeredReceivers = mReceiverResolver.queryIntent(intent, 11646 resolvedType, false, userId); 11647 } 11648 11649 final boolean replacePending = 11650 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11651 11652 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11653 + " replacePending=" + replacePending); 11654 11655 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11656 if (!ordered && NR > 0) { 11657 // If we are not serializing this broadcast, then send the 11658 // registered receivers separately so they don't wait for the 11659 // components to be launched. 11660 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11661 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11662 callerPackage, callingPid, callingUid, requiredPermission, 11663 registeredReceivers, resultTo, resultCode, resultData, map, 11664 ordered, sticky, false, userId); 11665 if (DEBUG_BROADCAST) Slog.v( 11666 TAG, "Enqueueing parallel broadcast " + r); 11667 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11668 if (!replaced) { 11669 queue.enqueueParallelBroadcastLocked(r); 11670 queue.scheduleBroadcastsLocked(); 11671 } 11672 registeredReceivers = null; 11673 NR = 0; 11674 } 11675 11676 // Merge into one list. 11677 int ir = 0; 11678 if (receivers != null) { 11679 // A special case for PACKAGE_ADDED: do not allow the package 11680 // being added to see this broadcast. This prevents them from 11681 // using this as a back door to get run as soon as they are 11682 // installed. Maybe in the future we want to have a special install 11683 // broadcast or such for apps, but we'd like to deliberately make 11684 // this decision. 11685 String skipPackages[] = null; 11686 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11687 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11688 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11689 Uri data = intent.getData(); 11690 if (data != null) { 11691 String pkgName = data.getSchemeSpecificPart(); 11692 if (pkgName != null) { 11693 skipPackages = new String[] { pkgName }; 11694 } 11695 } 11696 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11697 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11698 } 11699 if (skipPackages != null && (skipPackages.length > 0)) { 11700 for (String skipPackage : skipPackages) { 11701 if (skipPackage != null) { 11702 int NT = receivers.size(); 11703 for (int it=0; it<NT; it++) { 11704 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11705 if (curt.activityInfo.packageName.equals(skipPackage)) { 11706 receivers.remove(it); 11707 it--; 11708 NT--; 11709 } 11710 } 11711 } 11712 } 11713 } 11714 11715 int NT = receivers != null ? receivers.size() : 0; 11716 int it = 0; 11717 ResolveInfo curt = null; 11718 BroadcastFilter curr = null; 11719 while (it < NT && ir < NR) { 11720 if (curt == null) { 11721 curt = (ResolveInfo)receivers.get(it); 11722 } 11723 if (curr == null) { 11724 curr = registeredReceivers.get(ir); 11725 } 11726 if (curr.getPriority() >= curt.priority) { 11727 // Insert this broadcast record into the final list. 11728 receivers.add(it, curr); 11729 ir++; 11730 curr = null; 11731 it++; 11732 NT++; 11733 } else { 11734 // Skip to the next ResolveInfo in the final list. 11735 it++; 11736 curt = null; 11737 } 11738 } 11739 } 11740 while (ir < NR) { 11741 if (receivers == null) { 11742 receivers = new ArrayList(); 11743 } 11744 receivers.add(registeredReceivers.get(ir)); 11745 ir++; 11746 } 11747 11748 if ((receivers != null && receivers.size() > 0) 11749 || resultTo != null) { 11750 BroadcastQueue queue = broadcastQueueForIntent(intent); 11751 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11752 callerPackage, callingPid, callingUid, requiredPermission, 11753 receivers, resultTo, resultCode, resultData, map, ordered, 11754 sticky, false, userId); 11755 if (DEBUG_BROADCAST) Slog.v( 11756 TAG, "Enqueueing ordered broadcast " + r 11757 + ": prev had " + queue.mOrderedBroadcasts.size()); 11758 if (DEBUG_BROADCAST) { 11759 int seq = r.intent.getIntExtra("seq", -1); 11760 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11761 } 11762 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11763 if (!replaced) { 11764 queue.enqueueOrderedBroadcastLocked(r); 11765 queue.scheduleBroadcastsLocked(); 11766 } 11767 } 11768 11769 return ActivityManager.BROADCAST_SUCCESS; 11770 } 11771 11772 final Intent verifyBroadcastLocked(Intent intent) { 11773 // Refuse possible leaked file descriptors 11774 if (intent != null && intent.hasFileDescriptors() == true) { 11775 throw new IllegalArgumentException("File descriptors passed in Intent"); 11776 } 11777 11778 int flags = intent.getFlags(); 11779 11780 if (!mProcessesReady) { 11781 // if the caller really truly claims to know what they're doing, go 11782 // ahead and allow the broadcast without launching any receivers 11783 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11784 intent = new Intent(intent); 11785 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11786 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11787 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11788 + " before boot completion"); 11789 throw new IllegalStateException("Cannot broadcast before boot completed"); 11790 } 11791 } 11792 11793 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11794 throw new IllegalArgumentException( 11795 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11796 } 11797 11798 return intent; 11799 } 11800 11801 public final int broadcastIntent(IApplicationThread caller, 11802 Intent intent, String resolvedType, IIntentReceiver resultTo, 11803 int resultCode, String resultData, Bundle map, 11804 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11805 enforceNotIsolatedCaller("broadcastIntent"); 11806 synchronized(this) { 11807 intent = verifyBroadcastLocked(intent); 11808 11809 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11810 final int callingPid = Binder.getCallingPid(); 11811 final int callingUid = Binder.getCallingUid(); 11812 final long origId = Binder.clearCallingIdentity(); 11813 int res = broadcastIntentLocked(callerApp, 11814 callerApp != null ? callerApp.info.packageName : null, 11815 intent, resolvedType, resultTo, 11816 resultCode, resultData, map, requiredPermission, serialized, sticky, 11817 callingPid, callingUid, userId); 11818 Binder.restoreCallingIdentity(origId); 11819 return res; 11820 } 11821 } 11822 11823 int broadcastIntentInPackage(String packageName, int uid, 11824 Intent intent, String resolvedType, IIntentReceiver resultTo, 11825 int resultCode, String resultData, Bundle map, 11826 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11827 synchronized(this) { 11828 intent = verifyBroadcastLocked(intent); 11829 11830 final long origId = Binder.clearCallingIdentity(); 11831 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11832 resultTo, resultCode, resultData, map, requiredPermission, 11833 serialized, sticky, -1, uid, userId); 11834 Binder.restoreCallingIdentity(origId); 11835 return res; 11836 } 11837 } 11838 11839 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11840 // Refuse possible leaked file descriptors 11841 if (intent != null && intent.hasFileDescriptors() == true) { 11842 throw new IllegalArgumentException("File descriptors passed in Intent"); 11843 } 11844 11845 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11846 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11847 11848 synchronized(this) { 11849 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11850 != PackageManager.PERMISSION_GRANTED) { 11851 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11852 + Binder.getCallingPid() 11853 + ", uid=" + Binder.getCallingUid() 11854 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11855 Slog.w(TAG, msg); 11856 throw new SecurityException(msg); 11857 } 11858 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11859 if (stickies != null) { 11860 ArrayList<Intent> list = stickies.get(intent.getAction()); 11861 if (list != null) { 11862 int N = list.size(); 11863 int i; 11864 for (i=0; i<N; i++) { 11865 if (intent.filterEquals(list.get(i))) { 11866 list.remove(i); 11867 break; 11868 } 11869 } 11870 if (list.size() <= 0) { 11871 stickies.remove(intent.getAction()); 11872 } 11873 } 11874 if (stickies.size() <= 0) { 11875 mStickyBroadcasts.remove(userId); 11876 } 11877 } 11878 } 11879 } 11880 11881 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11882 String resultData, Bundle resultExtras, boolean resultAbort, 11883 boolean explicit) { 11884 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11885 if (r == null) { 11886 Slog.w(TAG, "finishReceiver called but not found on queue"); 11887 return false; 11888 } 11889 11890 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11891 explicit); 11892 } 11893 11894 public void finishReceiver(IBinder who, int resultCode, String resultData, 11895 Bundle resultExtras, boolean resultAbort) { 11896 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11897 11898 // Refuse possible leaked file descriptors 11899 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11900 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11901 } 11902 11903 final long origId = Binder.clearCallingIdentity(); 11904 try { 11905 boolean doNext = false; 11906 BroadcastRecord r = null; 11907 11908 synchronized(this) { 11909 r = broadcastRecordForReceiverLocked(who); 11910 if (r != null) { 11911 doNext = r.queue.finishReceiverLocked(r, resultCode, 11912 resultData, resultExtras, resultAbort, true); 11913 } 11914 } 11915 11916 if (doNext) { 11917 r.queue.processNextBroadcast(false); 11918 } 11919 trimApplications(); 11920 } finally { 11921 Binder.restoreCallingIdentity(origId); 11922 } 11923 } 11924 11925 // ========================================================= 11926 // INSTRUMENTATION 11927 // ========================================================= 11928 11929 public boolean startInstrumentation(ComponentName className, 11930 String profileFile, int flags, Bundle arguments, 11931 IInstrumentationWatcher watcher, int userId) { 11932 enforceNotIsolatedCaller("startInstrumentation"); 11933 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 11934 userId, false, true, "startInstrumentation", null); 11935 // Refuse possible leaked file descriptors 11936 if (arguments != null && arguments.hasFileDescriptors()) { 11937 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11938 } 11939 11940 synchronized(this) { 11941 InstrumentationInfo ii = null; 11942 ApplicationInfo ai = null; 11943 try { 11944 ii = mContext.getPackageManager().getInstrumentationInfo( 11945 className, STOCK_PM_FLAGS); 11946 ai = AppGlobals.getPackageManager().getApplicationInfo( 11947 ii.targetPackage, STOCK_PM_FLAGS, userId); 11948 } catch (PackageManager.NameNotFoundException e) { 11949 } catch (RemoteException e) { 11950 } 11951 if (ii == null) { 11952 reportStartInstrumentationFailure(watcher, className, 11953 "Unable to find instrumentation info for: " + className); 11954 return false; 11955 } 11956 if (ai == null) { 11957 reportStartInstrumentationFailure(watcher, className, 11958 "Unable to find instrumentation target package: " + ii.targetPackage); 11959 return false; 11960 } 11961 11962 int match = mContext.getPackageManager().checkSignatures( 11963 ii.targetPackage, ii.packageName); 11964 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11965 String msg = "Permission Denial: starting instrumentation " 11966 + className + " from pid=" 11967 + Binder.getCallingPid() 11968 + ", uid=" + Binder.getCallingPid() 11969 + " not allowed because package " + ii.packageName 11970 + " does not have a signature matching the target " 11971 + ii.targetPackage; 11972 reportStartInstrumentationFailure(watcher, className, msg); 11973 throw new SecurityException(msg); 11974 } 11975 11976 final long origId = Binder.clearCallingIdentity(); 11977 // Instrumentation can kill and relaunch even persistent processes 11978 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11979 ProcessRecord app = addAppLocked(ai, false); 11980 app.instrumentationClass = className; 11981 app.instrumentationInfo = ai; 11982 app.instrumentationProfileFile = profileFile; 11983 app.instrumentationArguments = arguments; 11984 app.instrumentationWatcher = watcher; 11985 app.instrumentationResultClass = className; 11986 Binder.restoreCallingIdentity(origId); 11987 } 11988 11989 return true; 11990 } 11991 11992 /** 11993 * Report errors that occur while attempting to start Instrumentation. Always writes the 11994 * error to the logs, but if somebody is watching, send the report there too. This enables 11995 * the "am" command to report errors with more information. 11996 * 11997 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11998 * @param cn The component name of the instrumentation. 11999 * @param report The error report. 12000 */ 12001 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12002 ComponentName cn, String report) { 12003 Slog.w(TAG, report); 12004 try { 12005 if (watcher != null) { 12006 Bundle results = new Bundle(); 12007 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12008 results.putString("Error", report); 12009 watcher.instrumentationStatus(cn, -1, results); 12010 } 12011 } catch (RemoteException e) { 12012 Slog.w(TAG, e); 12013 } 12014 } 12015 12016 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12017 if (app.instrumentationWatcher != null) { 12018 try { 12019 // NOTE: IInstrumentationWatcher *must* be oneway here 12020 app.instrumentationWatcher.instrumentationFinished( 12021 app.instrumentationClass, 12022 resultCode, 12023 results); 12024 } catch (RemoteException e) { 12025 } 12026 } 12027 app.instrumentationWatcher = null; 12028 app.instrumentationClass = null; 12029 app.instrumentationInfo = null; 12030 app.instrumentationProfileFile = null; 12031 app.instrumentationArguments = null; 12032 12033 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12034 } 12035 12036 public void finishInstrumentation(IApplicationThread target, 12037 int resultCode, Bundle results) { 12038 int userId = UserHandle.getCallingUserId(); 12039 // Refuse possible leaked file descriptors 12040 if (results != null && results.hasFileDescriptors()) { 12041 throw new IllegalArgumentException("File descriptors passed in Intent"); 12042 } 12043 12044 synchronized(this) { 12045 ProcessRecord app = getRecordForAppLocked(target); 12046 if (app == null) { 12047 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12048 return; 12049 } 12050 final long origId = Binder.clearCallingIdentity(); 12051 finishInstrumentationLocked(app, resultCode, results); 12052 Binder.restoreCallingIdentity(origId); 12053 } 12054 } 12055 12056 // ========================================================= 12057 // CONFIGURATION 12058 // ========================================================= 12059 12060 public ConfigurationInfo getDeviceConfigurationInfo() { 12061 ConfigurationInfo config = new ConfigurationInfo(); 12062 synchronized (this) { 12063 config.reqTouchScreen = mConfiguration.touchscreen; 12064 config.reqKeyboardType = mConfiguration.keyboard; 12065 config.reqNavigation = mConfiguration.navigation; 12066 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12067 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12068 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12069 } 12070 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12071 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12072 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12073 } 12074 config.reqGlEsVersion = GL_ES_VERSION; 12075 } 12076 return config; 12077 } 12078 12079 public Configuration getConfiguration() { 12080 Configuration ci; 12081 synchronized(this) { 12082 ci = new Configuration(mConfiguration); 12083 } 12084 return ci; 12085 } 12086 12087 public void updatePersistentConfiguration(Configuration values) { 12088 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12089 "updateConfiguration()"); 12090 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12091 "updateConfiguration()"); 12092 if (values == null) { 12093 throw new NullPointerException("Configuration must not be null"); 12094 } 12095 12096 synchronized(this) { 12097 final long origId = Binder.clearCallingIdentity(); 12098 updateConfigurationLocked(values, null, true, false); 12099 Binder.restoreCallingIdentity(origId); 12100 } 12101 } 12102 12103 public void updateConfiguration(Configuration values) { 12104 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12105 "updateConfiguration()"); 12106 12107 synchronized(this) { 12108 if (values == null && mWindowManager != null) { 12109 // sentinel: fetch the current configuration from the window manager 12110 values = mWindowManager.computeNewConfiguration(); 12111 } 12112 12113 if (mWindowManager != null) { 12114 mProcessList.applyDisplaySize(mWindowManager); 12115 } 12116 12117 final long origId = Binder.clearCallingIdentity(); 12118 if (values != null) { 12119 Settings.System.clearConfiguration(values); 12120 } 12121 updateConfigurationLocked(values, null, false, false); 12122 Binder.restoreCallingIdentity(origId); 12123 } 12124 } 12125 12126 /** 12127 * Do either or both things: (1) change the current configuration, and (2) 12128 * make sure the given activity is running with the (now) current 12129 * configuration. Returns true if the activity has been left running, or 12130 * false if <var>starting</var> is being destroyed to match the new 12131 * configuration. 12132 * @param persistent TODO 12133 */ 12134 boolean updateConfigurationLocked(Configuration values, 12135 ActivityRecord starting, boolean persistent, boolean initLocale) { 12136 // do nothing if we are headless 12137 if (mHeadless) return true; 12138 12139 int changes = 0; 12140 12141 boolean kept = true; 12142 12143 if (values != null) { 12144 Configuration newConfig = new Configuration(mConfiguration); 12145 changes = newConfig.updateFrom(values); 12146 if (changes != 0) { 12147 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12148 Slog.i(TAG, "Updating configuration to: " + values); 12149 } 12150 12151 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12152 12153 if (values.locale != null && !initLocale) { 12154 saveLocaleLocked(values.locale, 12155 !values.locale.equals(mConfiguration.locale), 12156 values.userSetLocale); 12157 } 12158 12159 mConfigurationSeq++; 12160 if (mConfigurationSeq <= 0) { 12161 mConfigurationSeq = 1; 12162 } 12163 newConfig.seq = mConfigurationSeq; 12164 mConfiguration = newConfig; 12165 Slog.i(TAG, "Config changed: " + newConfig); 12166 12167 final Configuration configCopy = new Configuration(mConfiguration); 12168 12169 // TODO: If our config changes, should we auto dismiss any currently 12170 // showing dialogs? 12171 mShowDialogs = shouldShowDialogs(newConfig); 12172 12173 AttributeCache ac = AttributeCache.instance(); 12174 if (ac != null) { 12175 ac.updateConfiguration(configCopy); 12176 } 12177 12178 // Make sure all resources in our process are updated 12179 // right now, so that anyone who is going to retrieve 12180 // resource values after we return will be sure to get 12181 // the new ones. This is especially important during 12182 // boot, where the first config change needs to guarantee 12183 // all resources have that config before following boot 12184 // code is executed. 12185 mSystemThread.applyConfigurationToResources(configCopy); 12186 12187 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12188 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12189 msg.obj = new Configuration(configCopy); 12190 mHandler.sendMessage(msg); 12191 } 12192 12193 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12194 ProcessRecord app = mLruProcesses.get(i); 12195 try { 12196 if (app.thread != null) { 12197 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12198 + app.processName + " new config " + mConfiguration); 12199 app.thread.scheduleConfigurationChanged(configCopy); 12200 } 12201 } catch (Exception e) { 12202 } 12203 } 12204 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12205 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12206 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12207 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12208 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12209 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12210 broadcastIntentLocked(null, null, 12211 new Intent(Intent.ACTION_LOCALE_CHANGED), 12212 null, null, 0, null, null, 12213 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12214 } 12215 } 12216 } 12217 12218 if (changes != 0 && starting == null) { 12219 // If the configuration changed, and the caller is not already 12220 // in the process of starting an activity, then find the top 12221 // activity to check if its configuration needs to change. 12222 starting = mMainStack.topRunningActivityLocked(null); 12223 } 12224 12225 if (starting != null) { 12226 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12227 // And we need to make sure at this point that all other activities 12228 // are made visible with the correct configuration. 12229 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12230 } 12231 12232 if (values != null && mWindowManager != null) { 12233 mWindowManager.setNewConfiguration(mConfiguration); 12234 } 12235 12236 return kept; 12237 } 12238 12239 /** 12240 * Decide based on the configuration whether we should shouw the ANR, 12241 * crash, etc dialogs. The idea is that if there is no affordnace to 12242 * press the on-screen buttons, we shouldn't show the dialog. 12243 * 12244 * A thought: SystemUI might also want to get told about this, the Power 12245 * dialog / global actions also might want different behaviors. 12246 */ 12247 private static final boolean shouldShowDialogs(Configuration config) { 12248 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12249 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12250 } 12251 12252 /** 12253 * Save the locale. You must be inside a synchronized (this) block. 12254 */ 12255 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12256 if(isDiff) { 12257 SystemProperties.set("user.language", l.getLanguage()); 12258 SystemProperties.set("user.region", l.getCountry()); 12259 } 12260 12261 if(isPersist) { 12262 SystemProperties.set("persist.sys.language", l.getLanguage()); 12263 SystemProperties.set("persist.sys.country", l.getCountry()); 12264 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12265 } 12266 } 12267 12268 @Override 12269 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12270 ActivityRecord srec = ActivityRecord.forToken(token); 12271 return srec != null && srec.task.affinity != null && 12272 srec.task.affinity.equals(destAffinity); 12273 } 12274 12275 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12276 Intent resultData) { 12277 ComponentName dest = destIntent.getComponent(); 12278 12279 synchronized (this) { 12280 ActivityRecord srec = ActivityRecord.forToken(token); 12281 if (srec == null) { 12282 return false; 12283 } 12284 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12285 final int start = history.indexOf(srec); 12286 if (start < 0) { 12287 // Current activity is not in history stack; do nothing. 12288 return false; 12289 } 12290 int finishTo = start - 1; 12291 ActivityRecord parent = null; 12292 boolean foundParentInTask = false; 12293 if (dest != null) { 12294 TaskRecord tr = srec.task; 12295 for (int i = start - 1; i >= 0; i--) { 12296 ActivityRecord r = history.get(i); 12297 if (tr != r.task) { 12298 // Couldn't find parent in the same task; stop at the one above this. 12299 // (Root of current task; in-app "home" behavior) 12300 // Always at least finish the current activity. 12301 finishTo = Math.min(start - 1, i + 1); 12302 parent = history.get(finishTo); 12303 break; 12304 } else if (r.info.packageName.equals(dest.getPackageName()) && 12305 r.info.name.equals(dest.getClassName())) { 12306 finishTo = i; 12307 parent = r; 12308 foundParentInTask = true; 12309 break; 12310 } 12311 } 12312 } 12313 12314 if (mController != null) { 12315 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12316 if (next != null) { 12317 // ask watcher if this is allowed 12318 boolean resumeOK = true; 12319 try { 12320 resumeOK = mController.activityResuming(next.packageName); 12321 } catch (RemoteException e) { 12322 mController = null; 12323 } 12324 12325 if (!resumeOK) { 12326 return false; 12327 } 12328 } 12329 } 12330 final long origId = Binder.clearCallingIdentity(); 12331 for (int i = start; i > finishTo; i--) { 12332 ActivityRecord r = history.get(i); 12333 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12334 "navigate-up", true); 12335 // Only return the supplied result for the first activity finished 12336 resultCode = Activity.RESULT_CANCELED; 12337 resultData = null; 12338 } 12339 12340 if (parent != null && foundParentInTask) { 12341 final int parentLaunchMode = parent.info.launchMode; 12342 final int destIntentFlags = destIntent.getFlags(); 12343 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12344 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12345 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12346 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12347 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12348 } else { 12349 try { 12350 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12351 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12352 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12353 null, aInfo, parent.appToken, null, 12354 0, -1, parent.launchedFromUid, 0, null, true, null); 12355 foundParentInTask = res == ActivityManager.START_SUCCESS; 12356 } catch (RemoteException e) { 12357 foundParentInTask = false; 12358 } 12359 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12360 resultData, "navigate-up", true); 12361 } 12362 } 12363 Binder.restoreCallingIdentity(origId); 12364 return foundParentInTask; 12365 } 12366 } 12367 12368 public int getLaunchedFromUid(IBinder activityToken) { 12369 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12370 if (srec == null) { 12371 return -1; 12372 } 12373 return srec.launchedFromUid; 12374 } 12375 12376 // ========================================================= 12377 // LIFETIME MANAGEMENT 12378 // ========================================================= 12379 12380 // Returns which broadcast queue the app is the current [or imminent] receiver 12381 // on, or 'null' if the app is not an active broadcast recipient. 12382 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12383 BroadcastRecord r = app.curReceiver; 12384 if (r != null) { 12385 return r.queue; 12386 } 12387 12388 // It's not the current receiver, but it might be starting up to become one 12389 synchronized (this) { 12390 for (BroadcastQueue queue : mBroadcastQueues) { 12391 r = queue.mPendingBroadcast; 12392 if (r != null && r.curApp == app) { 12393 // found it; report which queue it's in 12394 return queue; 12395 } 12396 } 12397 } 12398 12399 return null; 12400 } 12401 12402 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12403 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12404 if (mAdjSeq == app.adjSeq) { 12405 // This adjustment has already been computed. If we are calling 12406 // from the top, we may have already computed our adjustment with 12407 // an earlier hidden adjustment that isn't really for us... if 12408 // so, use the new hidden adjustment. 12409 if (!recursed && app.hidden) { 12410 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12411 app.hasActivities ? hiddenAdj : emptyAdj; 12412 } 12413 return app.curRawAdj; 12414 } 12415 12416 if (app.thread == null) { 12417 app.adjSeq = mAdjSeq; 12418 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12419 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12420 } 12421 12422 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12423 app.adjSource = null; 12424 app.adjTarget = null; 12425 app.empty = false; 12426 app.hidden = false; 12427 12428 final int activitiesSize = app.activities.size(); 12429 12430 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12431 // The max adjustment doesn't allow this app to be anything 12432 // below foreground, so it is not worth doing work for it. 12433 app.adjType = "fixed"; 12434 app.adjSeq = mAdjSeq; 12435 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12436 app.hasActivities = false; 12437 app.foregroundActivities = false; 12438 app.keeping = true; 12439 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12440 // System process can do UI, and when they do we want to have 12441 // them trim their memory after the user leaves the UI. To 12442 // facilitate this, here we need to determine whether or not it 12443 // is currently showing UI. 12444 app.systemNoUi = true; 12445 if (app == TOP_APP) { 12446 app.systemNoUi = false; 12447 app.hasActivities = true; 12448 } else if (activitiesSize > 0) { 12449 for (int j = 0; j < activitiesSize; j++) { 12450 final ActivityRecord r = app.activities.get(j); 12451 if (r.visible) { 12452 app.systemNoUi = false; 12453 } 12454 if (r.app == app) { 12455 app.hasActivities = true; 12456 } 12457 } 12458 } 12459 return (app.curAdj=app.maxAdj); 12460 } 12461 12462 app.keeping = false; 12463 app.systemNoUi = false; 12464 app.hasActivities = false; 12465 12466 // Determine the importance of the process, starting with most 12467 // important to least, and assign an appropriate OOM adjustment. 12468 int adj; 12469 int schedGroup; 12470 boolean foregroundActivities = false; 12471 boolean interesting = false; 12472 BroadcastQueue queue; 12473 if (app == TOP_APP) { 12474 // The last app on the list is the foreground app. 12475 adj = ProcessList.FOREGROUND_APP_ADJ; 12476 schedGroup = Process.THREAD_GROUP_DEFAULT; 12477 app.adjType = "top-activity"; 12478 foregroundActivities = true; 12479 interesting = true; 12480 app.hasActivities = true; 12481 } else if (app.instrumentationClass != null) { 12482 // Don't want to kill running instrumentation. 12483 adj = ProcessList.FOREGROUND_APP_ADJ; 12484 schedGroup = Process.THREAD_GROUP_DEFAULT; 12485 app.adjType = "instrumentation"; 12486 interesting = true; 12487 } else if ((queue = isReceivingBroadcast(app)) != null) { 12488 // An app that is currently receiving a broadcast also 12489 // counts as being in the foreground for OOM killer purposes. 12490 // It's placed in a sched group based on the nature of the 12491 // broadcast as reflected by which queue it's active in. 12492 adj = ProcessList.FOREGROUND_APP_ADJ; 12493 schedGroup = (queue == mFgBroadcastQueue) 12494 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12495 app.adjType = "broadcast"; 12496 } else if (app.executingServices.size() > 0) { 12497 // An app that is currently executing a service callback also 12498 // counts as being in the foreground. 12499 adj = ProcessList.FOREGROUND_APP_ADJ; 12500 schedGroup = Process.THREAD_GROUP_DEFAULT; 12501 app.adjType = "exec-service"; 12502 } else { 12503 // Assume process is hidden (has activities); we will correct 12504 // later if this is not the case. 12505 adj = hiddenAdj; 12506 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12507 app.hidden = true; 12508 app.adjType = "bg-activities"; 12509 } 12510 12511 boolean hasStoppingActivities = false; 12512 12513 // Examine all activities if not already foreground. 12514 if (!foregroundActivities && activitiesSize > 0) { 12515 for (int j = 0; j < activitiesSize; j++) { 12516 final ActivityRecord r = app.activities.get(j); 12517 if (r.visible) { 12518 // App has a visible activity; only upgrade adjustment. 12519 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12520 adj = ProcessList.VISIBLE_APP_ADJ; 12521 app.adjType = "visible"; 12522 } 12523 schedGroup = Process.THREAD_GROUP_DEFAULT; 12524 app.hidden = false; 12525 app.hasActivities = true; 12526 foregroundActivities = true; 12527 break; 12528 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12529 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12530 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12531 app.adjType = "pausing"; 12532 } 12533 app.hidden = false; 12534 foregroundActivities = true; 12535 } else if (r.state == ActivityState.STOPPING) { 12536 // We will apply the actual adjustment later, because 12537 // we want to allow this process to immediately go through 12538 // any memory trimming that is in effect. 12539 app.hidden = false; 12540 foregroundActivities = true; 12541 hasStoppingActivities = true; 12542 } 12543 if (r.app == app) { 12544 app.hasActivities = true; 12545 } 12546 } 12547 } 12548 12549 if (adj == hiddenAdj && !app.hasActivities) { 12550 // Whoops, this process is completely empty as far as we know 12551 // at this point. 12552 adj = emptyAdj; 12553 app.empty = true; 12554 app.adjType = "bg-empty"; 12555 } 12556 12557 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12558 if (app.foregroundServices) { 12559 // The user is aware of this app, so make it visible. 12560 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12561 app.hidden = false; 12562 app.adjType = "foreground-service"; 12563 schedGroup = Process.THREAD_GROUP_DEFAULT; 12564 } else if (app.forcingToForeground != null) { 12565 // The user is aware of this app, so make it visible. 12566 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12567 app.hidden = false; 12568 app.adjType = "force-foreground"; 12569 app.adjSource = app.forcingToForeground; 12570 schedGroup = Process.THREAD_GROUP_DEFAULT; 12571 } 12572 } 12573 12574 if (app.foregroundServices) { 12575 interesting = true; 12576 } 12577 12578 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12579 // We don't want to kill the current heavy-weight process. 12580 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12581 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12582 app.hidden = false; 12583 app.adjType = "heavy"; 12584 } 12585 12586 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12587 // This process is hosting what we currently consider to be the 12588 // home app, so we don't want to let it go into the background. 12589 adj = ProcessList.HOME_APP_ADJ; 12590 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12591 app.hidden = false; 12592 app.adjType = "home"; 12593 } 12594 12595 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12596 && app.activities.size() > 0) { 12597 // This was the previous process that showed UI to the user. 12598 // We want to try to keep it around more aggressively, to give 12599 // a good experience around switching between two apps. 12600 adj = ProcessList.PREVIOUS_APP_ADJ; 12601 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12602 app.hidden = false; 12603 app.adjType = "previous"; 12604 } 12605 12606 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12607 + " reason=" + app.adjType); 12608 12609 // By default, we use the computed adjustment. It may be changed if 12610 // there are applications dependent on our services or providers, but 12611 // this gives us a baseline and makes sure we don't get into an 12612 // infinite recursion. 12613 app.adjSeq = mAdjSeq; 12614 app.curRawAdj = app.nonStoppingAdj = adj; 12615 12616 if (mBackupTarget != null && app == mBackupTarget.app) { 12617 // If possible we want to avoid killing apps while they're being backed up 12618 if (adj > ProcessList.BACKUP_APP_ADJ) { 12619 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12620 adj = ProcessList.BACKUP_APP_ADJ; 12621 app.adjType = "backup"; 12622 app.hidden = false; 12623 } 12624 } 12625 12626 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12627 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12628 final long now = SystemClock.uptimeMillis(); 12629 // This process is more important if the top activity is 12630 // bound to the service. 12631 Iterator<ServiceRecord> jt = app.services.iterator(); 12632 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12633 ServiceRecord s = jt.next(); 12634 if (s.startRequested) { 12635 if (app.hasShownUi && app != mHomeProcess) { 12636 // If this process has shown some UI, let it immediately 12637 // go to the LRU list because it may be pretty heavy with 12638 // UI stuff. We'll tag it with a label just to help 12639 // debug and understand what is going on. 12640 if (adj > ProcessList.SERVICE_ADJ) { 12641 app.adjType = "started-bg-ui-services"; 12642 } 12643 } else { 12644 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12645 // This service has seen some activity within 12646 // recent memory, so we will keep its process ahead 12647 // of the background processes. 12648 if (adj > ProcessList.SERVICE_ADJ) { 12649 adj = ProcessList.SERVICE_ADJ; 12650 app.adjType = "started-services"; 12651 app.hidden = false; 12652 } 12653 } 12654 // If we have let the service slide into the background 12655 // state, still have some text describing what it is doing 12656 // even though the service no longer has an impact. 12657 if (adj > ProcessList.SERVICE_ADJ) { 12658 app.adjType = "started-bg-services"; 12659 } 12660 } 12661 // Don't kill this process because it is doing work; it 12662 // has said it is doing work. 12663 app.keeping = true; 12664 } 12665 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12666 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12667 Iterator<ArrayList<ConnectionRecord>> kt 12668 = s.connections.values().iterator(); 12669 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12670 ArrayList<ConnectionRecord> clist = kt.next(); 12671 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12672 // XXX should compute this based on the max of 12673 // all connected clients. 12674 ConnectionRecord cr = clist.get(i); 12675 if (cr.binding.client == app) { 12676 // Binding to ourself is not interesting. 12677 continue; 12678 } 12679 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12680 ProcessRecord client = cr.binding.client; 12681 int clientAdj = adj; 12682 int myHiddenAdj = hiddenAdj; 12683 if (myHiddenAdj > client.hiddenAdj) { 12684 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12685 myHiddenAdj = client.hiddenAdj; 12686 } else { 12687 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12688 } 12689 } 12690 int myEmptyAdj = emptyAdj; 12691 if (myEmptyAdj > client.emptyAdj) { 12692 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12693 myEmptyAdj = client.emptyAdj; 12694 } else { 12695 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12696 } 12697 } 12698 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12699 myEmptyAdj, TOP_APP, true, doingAll); 12700 String adjType = null; 12701 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12702 // Not doing bind OOM management, so treat 12703 // this guy more like a started service. 12704 if (app.hasShownUi && app != mHomeProcess) { 12705 // If this process has shown some UI, let it immediately 12706 // go to the LRU list because it may be pretty heavy with 12707 // UI stuff. We'll tag it with a label just to help 12708 // debug and understand what is going on. 12709 if (adj > clientAdj) { 12710 adjType = "bound-bg-ui-services"; 12711 } 12712 app.hidden = false; 12713 clientAdj = adj; 12714 } else { 12715 if (now >= (s.lastActivity 12716 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12717 // This service has not seen activity within 12718 // recent memory, so allow it to drop to the 12719 // LRU list if there is no other reason to keep 12720 // it around. We'll also tag it with a label just 12721 // to help debug and undertand what is going on. 12722 if (adj > clientAdj) { 12723 adjType = "bound-bg-services"; 12724 } 12725 clientAdj = adj; 12726 } 12727 } 12728 } 12729 if (adj > clientAdj) { 12730 // If this process has recently shown UI, and 12731 // the process that is binding to it is less 12732 // important than being visible, then we don't 12733 // care about the binding as much as we care 12734 // about letting this process get into the LRU 12735 // list to be killed and restarted if needed for 12736 // memory. 12737 if (app.hasShownUi && app != mHomeProcess 12738 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12739 adjType = "bound-bg-ui-services"; 12740 } else { 12741 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12742 |Context.BIND_IMPORTANT)) != 0) { 12743 adj = clientAdj; 12744 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12745 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12746 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12747 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12748 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12749 adj = clientAdj; 12750 } else { 12751 app.pendingUiClean = true; 12752 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12753 adj = ProcessList.VISIBLE_APP_ADJ; 12754 } 12755 } 12756 if (!client.hidden) { 12757 app.hidden = false; 12758 } 12759 if (client.keeping) { 12760 app.keeping = true; 12761 } 12762 adjType = "service"; 12763 } 12764 } 12765 if (adjType != null) { 12766 app.adjType = adjType; 12767 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12768 .REASON_SERVICE_IN_USE; 12769 app.adjSource = cr.binding.client; 12770 app.adjSourceOom = clientAdj; 12771 app.adjTarget = s.name; 12772 } 12773 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12774 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12775 schedGroup = Process.THREAD_GROUP_DEFAULT; 12776 } 12777 } 12778 } 12779 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12780 ActivityRecord a = cr.activity; 12781 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12782 (a.visible || a.state == ActivityState.RESUMED 12783 || a.state == ActivityState.PAUSING)) { 12784 adj = ProcessList.FOREGROUND_APP_ADJ; 12785 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12786 schedGroup = Process.THREAD_GROUP_DEFAULT; 12787 } 12788 app.hidden = false; 12789 app.adjType = "service"; 12790 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12791 .REASON_SERVICE_IN_USE; 12792 app.adjSource = a; 12793 app.adjSourceOom = adj; 12794 app.adjTarget = s.name; 12795 } 12796 } 12797 } 12798 } 12799 } 12800 } 12801 12802 // Finally, if this process has active services running in it, we 12803 // would like to avoid killing it unless it would prevent the current 12804 // application from running. By default we put the process in 12805 // with the rest of the background processes; as we scan through 12806 // its services we may bump it up from there. 12807 if (adj > hiddenAdj) { 12808 adj = hiddenAdj; 12809 app.hidden = false; 12810 app.adjType = "bg-services"; 12811 } 12812 } 12813 12814 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12815 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12816 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12817 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12818 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12819 ContentProviderRecord cpr = jt.next(); 12820 for (int i = cpr.connections.size()-1; 12821 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12822 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12823 i--) { 12824 ContentProviderConnection conn = cpr.connections.get(i); 12825 ProcessRecord client = conn.client; 12826 if (client == app) { 12827 // Being our own client is not interesting. 12828 continue; 12829 } 12830 int myHiddenAdj = hiddenAdj; 12831 if (myHiddenAdj > client.hiddenAdj) { 12832 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12833 myHiddenAdj = client.hiddenAdj; 12834 } else { 12835 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12836 } 12837 } 12838 int myEmptyAdj = emptyAdj; 12839 if (myEmptyAdj > client.emptyAdj) { 12840 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12841 myEmptyAdj = client.emptyAdj; 12842 } else { 12843 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12844 } 12845 } 12846 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12847 myEmptyAdj, TOP_APP, true, doingAll); 12848 if (adj > clientAdj) { 12849 if (app.hasShownUi && app != mHomeProcess 12850 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12851 app.adjType = "bg-ui-provider"; 12852 } else { 12853 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12854 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12855 app.adjType = "provider"; 12856 } 12857 if (!client.hidden) { 12858 app.hidden = false; 12859 } 12860 if (client.keeping) { 12861 app.keeping = true; 12862 } 12863 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12864 .REASON_PROVIDER_IN_USE; 12865 app.adjSource = client; 12866 app.adjSourceOom = clientAdj; 12867 app.adjTarget = cpr.name; 12868 } 12869 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12870 schedGroup = Process.THREAD_GROUP_DEFAULT; 12871 } 12872 } 12873 // If the provider has external (non-framework) process 12874 // dependencies, ensure that its adjustment is at least 12875 // FOREGROUND_APP_ADJ. 12876 if (cpr.hasExternalProcessHandles()) { 12877 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12878 adj = ProcessList.FOREGROUND_APP_ADJ; 12879 schedGroup = Process.THREAD_GROUP_DEFAULT; 12880 app.hidden = false; 12881 app.keeping = true; 12882 app.adjType = "provider"; 12883 app.adjTarget = cpr.name; 12884 } 12885 } 12886 } 12887 } 12888 12889 if (adj == ProcessList.SERVICE_ADJ) { 12890 if (doingAll) { 12891 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12892 mNewNumServiceProcs++; 12893 } 12894 if (app.serviceb) { 12895 adj = ProcessList.SERVICE_B_ADJ; 12896 } 12897 } else { 12898 app.serviceb = false; 12899 } 12900 12901 app.nonStoppingAdj = adj; 12902 12903 if (hasStoppingActivities) { 12904 // Only upgrade adjustment. 12905 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12906 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12907 app.adjType = "stopping"; 12908 } 12909 } 12910 12911 app.curRawAdj = adj; 12912 12913 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12914 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12915 if (adj > app.maxAdj) { 12916 adj = app.maxAdj; 12917 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12918 schedGroup = Process.THREAD_GROUP_DEFAULT; 12919 } 12920 } 12921 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12922 app.keeping = true; 12923 } 12924 12925 if (app.hasAboveClient) { 12926 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12927 // then we need to drop its adjustment to be lower than the service's 12928 // in order to honor the request. We want to drop it by one adjustment 12929 // level... but there is special meaning applied to various levels so 12930 // we will skip some of them. 12931 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12932 // System process will not get dropped, ever 12933 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12934 adj = ProcessList.VISIBLE_APP_ADJ; 12935 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12936 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12937 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12938 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12939 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12940 adj++; 12941 } 12942 } 12943 12944 int importance = app.memImportance; 12945 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12946 app.curAdj = adj; 12947 app.curSchedGroup = schedGroup; 12948 if (!interesting) { 12949 // For this reporting, if there is not something explicitly 12950 // interesting in this process then we will push it to the 12951 // background importance. 12952 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12953 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12954 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12955 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12956 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12957 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12958 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12959 } else if (adj >= ProcessList.SERVICE_ADJ) { 12960 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12961 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12962 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12963 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12964 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12965 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12966 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12967 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12968 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12969 } else { 12970 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12971 } 12972 } 12973 12974 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12975 if (foregroundActivities != app.foregroundActivities) { 12976 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12977 } 12978 if (changes != 0) { 12979 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12980 app.memImportance = importance; 12981 app.foregroundActivities = foregroundActivities; 12982 int i = mPendingProcessChanges.size()-1; 12983 ProcessChangeItem item = null; 12984 while (i >= 0) { 12985 item = mPendingProcessChanges.get(i); 12986 if (item.pid == app.pid) { 12987 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12988 break; 12989 } 12990 i--; 12991 } 12992 if (i < 0) { 12993 // No existing item in pending changes; need a new one. 12994 final int NA = mAvailProcessChanges.size(); 12995 if (NA > 0) { 12996 item = mAvailProcessChanges.remove(NA-1); 12997 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12998 } else { 12999 item = new ProcessChangeItem(); 13000 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13001 } 13002 item.changes = 0; 13003 item.pid = app.pid; 13004 item.uid = app.info.uid; 13005 if (mPendingProcessChanges.size() == 0) { 13006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13007 "*** Enqueueing dispatch processes changed!"); 13008 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13009 } 13010 mPendingProcessChanges.add(item); 13011 } 13012 item.changes |= changes; 13013 item.importance = importance; 13014 item.foregroundActivities = foregroundActivities; 13015 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13016 + Integer.toHexString(System.identityHashCode(item)) 13017 + " " + app.toShortString() + ": changes=" + item.changes 13018 + " importance=" + item.importance 13019 + " foreground=" + item.foregroundActivities 13020 + " type=" + app.adjType + " source=" + app.adjSource 13021 + " target=" + app.adjTarget); 13022 } 13023 13024 return app.curRawAdj; 13025 } 13026 13027 /** 13028 * Ask a given process to GC right now. 13029 */ 13030 final void performAppGcLocked(ProcessRecord app) { 13031 try { 13032 app.lastRequestedGc = SystemClock.uptimeMillis(); 13033 if (app.thread != null) { 13034 if (app.reportLowMemory) { 13035 app.reportLowMemory = false; 13036 app.thread.scheduleLowMemory(); 13037 } else { 13038 app.thread.processInBackground(); 13039 } 13040 } 13041 } catch (Exception e) { 13042 // whatever. 13043 } 13044 } 13045 13046 /** 13047 * Returns true if things are idle enough to perform GCs. 13048 */ 13049 private final boolean canGcNowLocked() { 13050 boolean processingBroadcasts = false; 13051 for (BroadcastQueue q : mBroadcastQueues) { 13052 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13053 processingBroadcasts = true; 13054 } 13055 } 13056 return !processingBroadcasts 13057 && (mSleeping || (mMainStack.mResumedActivity != null && 13058 mMainStack.mResumedActivity.idle)); 13059 } 13060 13061 /** 13062 * Perform GCs on all processes that are waiting for it, but only 13063 * if things are idle. 13064 */ 13065 final void performAppGcsLocked() { 13066 final int N = mProcessesToGc.size(); 13067 if (N <= 0) { 13068 return; 13069 } 13070 if (canGcNowLocked()) { 13071 while (mProcessesToGc.size() > 0) { 13072 ProcessRecord proc = mProcessesToGc.remove(0); 13073 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13074 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13075 <= SystemClock.uptimeMillis()) { 13076 // To avoid spamming the system, we will GC processes one 13077 // at a time, waiting a few seconds between each. 13078 performAppGcLocked(proc); 13079 scheduleAppGcsLocked(); 13080 return; 13081 } else { 13082 // It hasn't been long enough since we last GCed this 13083 // process... put it in the list to wait for its time. 13084 addProcessToGcListLocked(proc); 13085 break; 13086 } 13087 } 13088 } 13089 13090 scheduleAppGcsLocked(); 13091 } 13092 } 13093 13094 /** 13095 * If all looks good, perform GCs on all processes waiting for them. 13096 */ 13097 final void performAppGcsIfAppropriateLocked() { 13098 if (canGcNowLocked()) { 13099 performAppGcsLocked(); 13100 return; 13101 } 13102 // Still not idle, wait some more. 13103 scheduleAppGcsLocked(); 13104 } 13105 13106 /** 13107 * Schedule the execution of all pending app GCs. 13108 */ 13109 final void scheduleAppGcsLocked() { 13110 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13111 13112 if (mProcessesToGc.size() > 0) { 13113 // Schedule a GC for the time to the next process. 13114 ProcessRecord proc = mProcessesToGc.get(0); 13115 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13116 13117 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13118 long now = SystemClock.uptimeMillis(); 13119 if (when < (now+GC_TIMEOUT)) { 13120 when = now + GC_TIMEOUT; 13121 } 13122 mHandler.sendMessageAtTime(msg, when); 13123 } 13124 } 13125 13126 /** 13127 * Add a process to the array of processes waiting to be GCed. Keeps the 13128 * list in sorted order by the last GC time. The process can't already be 13129 * on the list. 13130 */ 13131 final void addProcessToGcListLocked(ProcessRecord proc) { 13132 boolean added = false; 13133 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13134 if (mProcessesToGc.get(i).lastRequestedGc < 13135 proc.lastRequestedGc) { 13136 added = true; 13137 mProcessesToGc.add(i+1, proc); 13138 break; 13139 } 13140 } 13141 if (!added) { 13142 mProcessesToGc.add(0, proc); 13143 } 13144 } 13145 13146 /** 13147 * Set up to ask a process to GC itself. This will either do it 13148 * immediately, or put it on the list of processes to gc the next 13149 * time things are idle. 13150 */ 13151 final void scheduleAppGcLocked(ProcessRecord app) { 13152 long now = SystemClock.uptimeMillis(); 13153 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13154 return; 13155 } 13156 if (!mProcessesToGc.contains(app)) { 13157 addProcessToGcListLocked(app); 13158 scheduleAppGcsLocked(); 13159 } 13160 } 13161 13162 final void checkExcessivePowerUsageLocked(boolean doKills) { 13163 updateCpuStatsNow(); 13164 13165 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13166 boolean doWakeKills = doKills; 13167 boolean doCpuKills = doKills; 13168 if (mLastPowerCheckRealtime == 0) { 13169 doWakeKills = false; 13170 } 13171 if (mLastPowerCheckUptime == 0) { 13172 doCpuKills = false; 13173 } 13174 if (stats.isScreenOn()) { 13175 doWakeKills = false; 13176 } 13177 final long curRealtime = SystemClock.elapsedRealtime(); 13178 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13179 final long curUptime = SystemClock.uptimeMillis(); 13180 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13181 mLastPowerCheckRealtime = curRealtime; 13182 mLastPowerCheckUptime = curUptime; 13183 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13184 doWakeKills = false; 13185 } 13186 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13187 doCpuKills = false; 13188 } 13189 int i = mLruProcesses.size(); 13190 while (i > 0) { 13191 i--; 13192 ProcessRecord app = mLruProcesses.get(i); 13193 if (!app.keeping) { 13194 long wtime; 13195 synchronized (stats) { 13196 wtime = stats.getProcessWakeTime(app.info.uid, 13197 app.pid, curRealtime); 13198 } 13199 long wtimeUsed = wtime - app.lastWakeTime; 13200 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13201 if (DEBUG_POWER) { 13202 StringBuilder sb = new StringBuilder(128); 13203 sb.append("Wake for "); 13204 app.toShortString(sb); 13205 sb.append(": over "); 13206 TimeUtils.formatDuration(realtimeSince, sb); 13207 sb.append(" used "); 13208 TimeUtils.formatDuration(wtimeUsed, sb); 13209 sb.append(" ("); 13210 sb.append((wtimeUsed*100)/realtimeSince); 13211 sb.append("%)"); 13212 Slog.i(TAG, sb.toString()); 13213 sb.setLength(0); 13214 sb.append("CPU for "); 13215 app.toShortString(sb); 13216 sb.append(": over "); 13217 TimeUtils.formatDuration(uptimeSince, sb); 13218 sb.append(" used "); 13219 TimeUtils.formatDuration(cputimeUsed, sb); 13220 sb.append(" ("); 13221 sb.append((cputimeUsed*100)/uptimeSince); 13222 sb.append("%)"); 13223 Slog.i(TAG, sb.toString()); 13224 } 13225 // If a process has held a wake lock for more 13226 // than 50% of the time during this period, 13227 // that sounds bad. Kill! 13228 if (doWakeKills && realtimeSince > 0 13229 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13230 synchronized (stats) { 13231 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13232 realtimeSince, wtimeUsed); 13233 } 13234 Slog.w(TAG, "Excessive wake lock in " + app.processName 13235 + " (pid " + app.pid + "): held " + wtimeUsed 13236 + " during " + realtimeSince); 13237 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13238 app.processName, app.setAdj, "excessive wake lock"); 13239 Process.killProcessQuiet(app.pid); 13240 } else if (doCpuKills && uptimeSince > 0 13241 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13242 synchronized (stats) { 13243 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13244 uptimeSince, cputimeUsed); 13245 } 13246 Slog.w(TAG, "Excessive CPU in " + app.processName 13247 + " (pid " + app.pid + "): used " + cputimeUsed 13248 + " during " + uptimeSince); 13249 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13250 app.processName, app.setAdj, "excessive cpu"); 13251 Process.killProcessQuiet(app.pid); 13252 } else { 13253 app.lastWakeTime = wtime; 13254 app.lastCpuTime = app.curCpuTime; 13255 } 13256 } 13257 } 13258 } 13259 13260 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13261 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13262 app.hiddenAdj = hiddenAdj; 13263 app.emptyAdj = emptyAdj; 13264 13265 if (app.thread == null) { 13266 return false; 13267 } 13268 13269 final boolean wasKeeping = app.keeping; 13270 13271 boolean success = true; 13272 13273 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13274 13275 if (app.curRawAdj != app.setRawAdj) { 13276 if (wasKeeping && !app.keeping) { 13277 // This app is no longer something we want to keep. Note 13278 // its current wake lock time to later know to kill it if 13279 // it is not behaving well. 13280 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13281 synchronized (stats) { 13282 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13283 app.pid, SystemClock.elapsedRealtime()); 13284 } 13285 app.lastCpuTime = app.curCpuTime; 13286 } 13287 13288 app.setRawAdj = app.curRawAdj; 13289 } 13290 13291 if (app.curAdj != app.setAdj) { 13292 if (Process.setOomAdj(app.pid, app.curAdj)) { 13293 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13294 TAG, "Set " + app.pid + " " + app.processName + 13295 " adj " + app.curAdj + ": " + app.adjType); 13296 app.setAdj = app.curAdj; 13297 } else { 13298 success = false; 13299 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13300 } 13301 } 13302 if (app.setSchedGroup != app.curSchedGroup) { 13303 app.setSchedGroup = app.curSchedGroup; 13304 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13305 "Setting process group of " + app.processName 13306 + " to " + app.curSchedGroup); 13307 if (app.waitingToKill != null && 13308 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13309 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13310 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13311 app.processName, app.setAdj, app.waitingToKill); 13312 app.killedBackground = true; 13313 Process.killProcessQuiet(app.pid); 13314 success = false; 13315 } else { 13316 if (true) { 13317 long oldId = Binder.clearCallingIdentity(); 13318 try { 13319 Process.setProcessGroup(app.pid, app.curSchedGroup); 13320 } catch (Exception e) { 13321 Slog.w(TAG, "Failed setting process group of " + app.pid 13322 + " to " + app.curSchedGroup); 13323 e.printStackTrace(); 13324 } finally { 13325 Binder.restoreCallingIdentity(oldId); 13326 } 13327 } else { 13328 if (app.thread != null) { 13329 try { 13330 app.thread.setSchedulingGroup(app.curSchedGroup); 13331 } catch (RemoteException e) { 13332 } 13333 } 13334 } 13335 } 13336 } 13337 return success; 13338 } 13339 13340 private final ActivityRecord resumedAppLocked() { 13341 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13342 if (resumedActivity == null || resumedActivity.app == null) { 13343 resumedActivity = mMainStack.mPausingActivity; 13344 if (resumedActivity == null || resumedActivity.app == null) { 13345 resumedActivity = mMainStack.topRunningActivityLocked(null); 13346 } 13347 } 13348 return resumedActivity; 13349 } 13350 13351 final boolean updateOomAdjLocked(ProcessRecord app) { 13352 final ActivityRecord TOP_ACT = resumedAppLocked(); 13353 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13354 int curAdj = app.curAdj; 13355 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13356 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13357 13358 mAdjSeq++; 13359 13360 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13361 TOP_APP, false); 13362 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13363 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13364 if (nowHidden != wasHidden) { 13365 // Changed to/from hidden state, so apps after it in the LRU 13366 // list may also be changed. 13367 updateOomAdjLocked(); 13368 } 13369 return success; 13370 } 13371 13372 final void updateOomAdjLocked() { 13373 final ActivityRecord TOP_ACT = resumedAppLocked(); 13374 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13375 13376 if (false) { 13377 RuntimeException e = new RuntimeException(); 13378 e.fillInStackTrace(); 13379 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13380 } 13381 13382 mAdjSeq++; 13383 mNewNumServiceProcs = 0; 13384 13385 // Let's determine how many processes we have running vs. 13386 // how many slots we have for background processes; we may want 13387 // to put multiple processes in a slot of there are enough of 13388 // them. 13389 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13390 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13391 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13392 if (emptyFactor < 1) emptyFactor = 1; 13393 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13394 if (hiddenFactor < 1) hiddenFactor = 1; 13395 int stepHidden = 0; 13396 int stepEmpty = 0; 13397 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13398 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13399 int numHidden = 0; 13400 int numEmpty = 0; 13401 int numTrimming = 0; 13402 13403 mNumNonHiddenProcs = 0; 13404 mNumHiddenProcs = 0; 13405 13406 // First update the OOM adjustment for each of the 13407 // application processes based on their current state. 13408 int i = mLruProcesses.size(); 13409 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13410 int nextHiddenAdj = curHiddenAdj+1; 13411 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13412 int nextEmptyAdj = curEmptyAdj+2; 13413 while (i > 0) { 13414 i--; 13415 ProcessRecord app = mLruProcesses.get(i); 13416 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13417 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13418 if (!app.killedBackground) { 13419 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13420 // This process was assigned as a hidden process... step the 13421 // hidden level. 13422 mNumHiddenProcs++; 13423 if (curHiddenAdj != nextHiddenAdj) { 13424 stepHidden++; 13425 if (stepHidden >= hiddenFactor) { 13426 stepHidden = 0; 13427 curHiddenAdj = nextHiddenAdj; 13428 nextHiddenAdj += 2; 13429 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13430 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13431 } 13432 } 13433 } 13434 numHidden++; 13435 if (numHidden > hiddenProcessLimit) { 13436 Slog.i(TAG, "No longer want " + app.processName 13437 + " (pid " + app.pid + "): hidden #" + numHidden); 13438 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13439 app.processName, app.setAdj, "too many background"); 13440 app.killedBackground = true; 13441 Process.killProcessQuiet(app.pid); 13442 } 13443 } else { 13444 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13445 // This process was assigned as an empty process... step the 13446 // empty level. 13447 if (curEmptyAdj != nextEmptyAdj) { 13448 stepEmpty++; 13449 if (stepEmpty >= emptyFactor) { 13450 stepEmpty = 0; 13451 curEmptyAdj = nextEmptyAdj; 13452 nextEmptyAdj += 2; 13453 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13454 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13455 } 13456 } 13457 } 13458 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13459 mNumNonHiddenProcs++; 13460 } 13461 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13462 numEmpty++; 13463 if (numEmpty > emptyProcessLimit) { 13464 Slog.i(TAG, "No longer want " + app.processName 13465 + " (pid " + app.pid + "): empty #" + numEmpty); 13466 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13467 app.processName, app.setAdj, "too many background"); 13468 app.killedBackground = true; 13469 Process.killProcessQuiet(app.pid); 13470 } 13471 } 13472 } 13473 if (app.isolated && app.services.size() <= 0) { 13474 // If this is an isolated process, and there are no 13475 // services running in it, then the process is no longer 13476 // needed. We agressively kill these because we can by 13477 // definition not re-use the same process again, and it is 13478 // good to avoid having whatever code was running in them 13479 // left sitting around after no longer needed. 13480 Slog.i(TAG, "Isolated process " + app.processName 13481 + " (pid " + app.pid + ") no longer needed"); 13482 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13483 app.processName, app.setAdj, "isolated not needed"); 13484 app.killedBackground = true; 13485 Process.killProcessQuiet(app.pid); 13486 } 13487 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13488 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13489 && !app.killedBackground) { 13490 numTrimming++; 13491 } 13492 } 13493 } 13494 13495 mNumServiceProcs = mNewNumServiceProcs; 13496 13497 // Now determine the memory trimming level of background processes. 13498 // Unfortunately we need to start at the back of the list to do this 13499 // properly. We only do this if the number of background apps we 13500 // are managing to keep around is less than half the maximum we desire; 13501 // if we are keeping a good number around, we'll let them use whatever 13502 // memory they want. 13503 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13504 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13505 final int numHiddenAndEmpty = numHidden + numEmpty; 13506 final int N = mLruProcesses.size(); 13507 int factor = numTrimming/3; 13508 int minFactor = 2; 13509 if (mHomeProcess != null) minFactor++; 13510 if (mPreviousProcess != null) minFactor++; 13511 if (factor < minFactor) factor = minFactor; 13512 int step = 0; 13513 int fgTrimLevel; 13514 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13515 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13516 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13517 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13518 } else { 13519 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13520 } 13521 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13522 for (i=0; i<N; i++) { 13523 ProcessRecord app = mLruProcesses.get(i); 13524 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13525 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13526 && !app.killedBackground) { 13527 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13528 try { 13529 app.thread.scheduleTrimMemory(curLevel); 13530 } catch (RemoteException e) { 13531 } 13532 if (false) { 13533 // For now we won't do this; our memory trimming seems 13534 // to be good enough at this point that destroying 13535 // activities causes more harm than good. 13536 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13537 && app != mHomeProcess && app != mPreviousProcess) { 13538 // Need to do this on its own message because the stack may not 13539 // be in a consistent state at this point. 13540 // For these apps we will also finish their activities 13541 // to help them free memory. 13542 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13543 } 13544 } 13545 } 13546 app.trimMemoryLevel = curLevel; 13547 step++; 13548 if (step >= factor) { 13549 step = 0; 13550 switch (curLevel) { 13551 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13552 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13553 break; 13554 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13555 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13556 break; 13557 } 13558 } 13559 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13560 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13561 && app.thread != null) { 13562 try { 13563 app.thread.scheduleTrimMemory( 13564 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13565 } catch (RemoteException e) { 13566 } 13567 } 13568 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13569 } else { 13570 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13571 && app.pendingUiClean) { 13572 // If this application is now in the background and it 13573 // had done UI, then give it the special trim level to 13574 // have it free UI resources. 13575 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13576 if (app.trimMemoryLevel < level && app.thread != null) { 13577 try { 13578 app.thread.scheduleTrimMemory(level); 13579 } catch (RemoteException e) { 13580 } 13581 } 13582 app.pendingUiClean = false; 13583 } 13584 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13585 try { 13586 app.thread.scheduleTrimMemory(fgTrimLevel); 13587 } catch (RemoteException e) { 13588 } 13589 } 13590 app.trimMemoryLevel = fgTrimLevel; 13591 } 13592 } 13593 } else { 13594 final int N = mLruProcesses.size(); 13595 for (i=0; i<N; i++) { 13596 ProcessRecord app = mLruProcesses.get(i); 13597 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13598 && app.pendingUiClean) { 13599 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13600 && app.thread != null) { 13601 try { 13602 app.thread.scheduleTrimMemory( 13603 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13604 } catch (RemoteException e) { 13605 } 13606 } 13607 app.pendingUiClean = false; 13608 } 13609 app.trimMemoryLevel = 0; 13610 } 13611 } 13612 13613 if (mAlwaysFinishActivities) { 13614 // Need to do this on its own message because the stack may not 13615 // be in a consistent state at this point. 13616 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13617 } 13618 } 13619 13620 final void trimApplications() { 13621 synchronized (this) { 13622 int i; 13623 13624 // First remove any unused application processes whose package 13625 // has been removed. 13626 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13627 final ProcessRecord app = mRemovedProcesses.get(i); 13628 if (app.activities.size() == 0 13629 && app.curReceiver == null && app.services.size() == 0) { 13630 Slog.i( 13631 TAG, "Exiting empty application process " 13632 + app.processName + " (" 13633 + (app.thread != null ? app.thread.asBinder() : null) 13634 + ")\n"); 13635 if (app.pid > 0 && app.pid != MY_PID) { 13636 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13637 app.processName, app.setAdj, "empty"); 13638 Process.killProcessQuiet(app.pid); 13639 } else { 13640 try { 13641 app.thread.scheduleExit(); 13642 } catch (Exception e) { 13643 // Ignore exceptions. 13644 } 13645 } 13646 cleanUpApplicationRecordLocked(app, false, true, -1); 13647 mRemovedProcesses.remove(i); 13648 13649 if (app.persistent) { 13650 if (app.persistent) { 13651 addAppLocked(app.info, false); 13652 } 13653 } 13654 } 13655 } 13656 13657 // Now update the oom adj for all processes. 13658 updateOomAdjLocked(); 13659 } 13660 } 13661 13662 /** This method sends the specified signal to each of the persistent apps */ 13663 public void signalPersistentProcesses(int sig) throws RemoteException { 13664 if (sig != Process.SIGNAL_USR1) { 13665 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13666 } 13667 13668 synchronized (this) { 13669 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13670 != PackageManager.PERMISSION_GRANTED) { 13671 throw new SecurityException("Requires permission " 13672 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13673 } 13674 13675 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13676 ProcessRecord r = mLruProcesses.get(i); 13677 if (r.thread != null && r.persistent) { 13678 Process.sendSignal(r.pid, sig); 13679 } 13680 } 13681 } 13682 } 13683 13684 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13685 if (proc == null || proc == mProfileProc) { 13686 proc = mProfileProc; 13687 path = mProfileFile; 13688 profileType = mProfileType; 13689 clearProfilerLocked(); 13690 } 13691 if (proc == null) { 13692 return; 13693 } 13694 try { 13695 proc.thread.profilerControl(false, path, null, profileType); 13696 } catch (RemoteException e) { 13697 throw new IllegalStateException("Process disappeared"); 13698 } 13699 } 13700 13701 private void clearProfilerLocked() { 13702 if (mProfileFd != null) { 13703 try { 13704 mProfileFd.close(); 13705 } catch (IOException e) { 13706 } 13707 } 13708 mProfileApp = null; 13709 mProfileProc = null; 13710 mProfileFile = null; 13711 mProfileType = 0; 13712 mAutoStopProfiler = false; 13713 } 13714 13715 public boolean profileControl(String process, int userId, boolean start, 13716 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13717 13718 try { 13719 synchronized (this) { 13720 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13721 // its own permission. 13722 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13723 != PackageManager.PERMISSION_GRANTED) { 13724 throw new SecurityException("Requires permission " 13725 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13726 } 13727 13728 if (start && fd == null) { 13729 throw new IllegalArgumentException("null fd"); 13730 } 13731 13732 ProcessRecord proc = null; 13733 if (process != null) { 13734 proc = findProcessLocked(process, userId, "profileControl"); 13735 } 13736 13737 if (start && (proc == null || proc.thread == null)) { 13738 throw new IllegalArgumentException("Unknown process: " + process); 13739 } 13740 13741 if (start) { 13742 stopProfilerLocked(null, null, 0); 13743 setProfileApp(proc.info, proc.processName, path, fd, false); 13744 mProfileProc = proc; 13745 mProfileType = profileType; 13746 try { 13747 fd = fd.dup(); 13748 } catch (IOException e) { 13749 fd = null; 13750 } 13751 proc.thread.profilerControl(start, path, fd, profileType); 13752 fd = null; 13753 mProfileFd = null; 13754 } else { 13755 stopProfilerLocked(proc, path, profileType); 13756 if (fd != null) { 13757 try { 13758 fd.close(); 13759 } catch (IOException e) { 13760 } 13761 } 13762 } 13763 13764 return true; 13765 } 13766 } catch (RemoteException e) { 13767 throw new IllegalStateException("Process disappeared"); 13768 } finally { 13769 if (fd != null) { 13770 try { 13771 fd.close(); 13772 } catch (IOException e) { 13773 } 13774 } 13775 } 13776 } 13777 13778 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13779 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13780 userId, true, true, callName, null); 13781 ProcessRecord proc = null; 13782 try { 13783 int pid = Integer.parseInt(process); 13784 synchronized (mPidsSelfLocked) { 13785 proc = mPidsSelfLocked.get(pid); 13786 } 13787 } catch (NumberFormatException e) { 13788 } 13789 13790 if (proc == null) { 13791 HashMap<String, SparseArray<ProcessRecord>> all 13792 = mProcessNames.getMap(); 13793 SparseArray<ProcessRecord> procs = all.get(process); 13794 if (procs != null && procs.size() > 0) { 13795 proc = procs.valueAt(0); 13796 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13797 for (int i=1; i<procs.size(); i++) { 13798 ProcessRecord thisProc = procs.valueAt(i); 13799 if (thisProc.userId == userId) { 13800 proc = thisProc; 13801 break; 13802 } 13803 } 13804 } 13805 } 13806 } 13807 13808 return proc; 13809 } 13810 13811 public boolean dumpHeap(String process, int userId, boolean managed, 13812 String path, ParcelFileDescriptor fd) throws RemoteException { 13813 13814 try { 13815 synchronized (this) { 13816 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13817 // its own permission (same as profileControl). 13818 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13819 != PackageManager.PERMISSION_GRANTED) { 13820 throw new SecurityException("Requires permission " 13821 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13822 } 13823 13824 if (fd == null) { 13825 throw new IllegalArgumentException("null fd"); 13826 } 13827 13828 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13829 if (proc == null || proc.thread == null) { 13830 throw new IllegalArgumentException("Unknown process: " + process); 13831 } 13832 13833 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13834 if (!isDebuggable) { 13835 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13836 throw new SecurityException("Process not debuggable: " + proc); 13837 } 13838 } 13839 13840 proc.thread.dumpHeap(managed, path, fd); 13841 fd = null; 13842 return true; 13843 } 13844 } catch (RemoteException e) { 13845 throw new IllegalStateException("Process disappeared"); 13846 } finally { 13847 if (fd != null) { 13848 try { 13849 fd.close(); 13850 } catch (IOException e) { 13851 } 13852 } 13853 } 13854 } 13855 13856 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13857 public void monitor() { 13858 synchronized (this) { } 13859 } 13860 13861 void onCoreSettingsChange(Bundle settings) { 13862 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13863 ProcessRecord processRecord = mLruProcesses.get(i); 13864 try { 13865 if (processRecord.thread != null) { 13866 processRecord.thread.setCoreSettings(settings); 13867 } 13868 } catch (RemoteException re) { 13869 /* ignore */ 13870 } 13871 } 13872 } 13873 13874 // Multi-user methods 13875 13876 @Override 13877 public boolean switchUser(int userId) { 13878 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13879 != PackageManager.PERMISSION_GRANTED) { 13880 String msg = "Permission Denial: switchUser() from pid=" 13881 + Binder.getCallingPid() 13882 + ", uid=" + Binder.getCallingUid() 13883 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13884 Slog.w(TAG, msg); 13885 throw new SecurityException(msg); 13886 } 13887 synchronized (this) { 13888 if (mCurrentUserId == userId) { 13889 return true; 13890 } 13891 13892 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13893 R.anim.screen_user_enter); 13894 13895 // If the user we are switching to is not currently started, then 13896 // we need to start it now. 13897 if (mStartedUsers.get(userId) == null) { 13898 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13899 } 13900 13901 mCurrentUserId = userId; 13902 Integer userIdInt = Integer.valueOf(userId); 13903 mUserLru.remove(userIdInt); 13904 mUserLru.add(userIdInt); 13905 boolean haveActivities = mMainStack.switchUser(userId); 13906 if (!haveActivities) { 13907 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13908 } else { 13909 mMainStack.addStartingUserLocked(mStartedUsers.get(userId)); 13910 } 13911 } 13912 13913 long ident = Binder.clearCallingIdentity(); 13914 try { 13915 // Inform of user switch 13916 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13917 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13918 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 13919 android.Manifest.permission.MANAGE_USERS); 13920 } finally { 13921 Binder.restoreCallingIdentity(ident); 13922 } 13923 13924 return true; 13925 } 13926 13927 void finishUserSwitch(UserStartedState uss) { 13928 synchronized (this) { 13929 if (uss.mState == UserStartedState.STATE_BOOTING 13930 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13931 uss.mState = UserStartedState.STATE_RUNNING; 13932 final int userId = uss.mHandle.getIdentifier(); 13933 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 13934 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13935 broadcastIntentLocked(null, null, intent, 13936 null, null, 0, null, null, 13937 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13938 false, false, MY_PID, Process.SYSTEM_UID, userId); 13939 } 13940 mWindowManager.stopFreezingScreen(); 13941 } 13942 } 13943 13944 @Override 13945 public int stopUser(final int userId, final IStopUserCallback callback) { 13946 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13947 != PackageManager.PERMISSION_GRANTED) { 13948 String msg = "Permission Denial: switchUser() from pid=" 13949 + Binder.getCallingPid() 13950 + ", uid=" + Binder.getCallingUid() 13951 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13952 Slog.w(TAG, msg); 13953 throw new SecurityException(msg); 13954 } 13955 if (userId <= 0) { 13956 throw new IllegalArgumentException("Can't stop primary user " + userId); 13957 } 13958 synchronized (this) { 13959 if (mCurrentUserId == userId) { 13960 return ActivityManager.USER_OP_IS_CURRENT; 13961 } 13962 13963 final UserStartedState uss = mStartedUsers.get(userId); 13964 if (uss == null) { 13965 // User is not started, nothing to do... but we do need to 13966 // callback if requested. 13967 if (callback != null) { 13968 mHandler.post(new Runnable() { 13969 @Override 13970 public void run() { 13971 try { 13972 callback.userStopped(userId); 13973 } catch (RemoteException e) { 13974 } 13975 } 13976 }); 13977 } 13978 return ActivityManager.USER_OP_SUCCESS; 13979 } 13980 13981 if (callback != null) { 13982 uss.mStopCallbacks.add(callback); 13983 } 13984 13985 if (uss.mState != UserStartedState.STATE_STOPPING) { 13986 uss.mState = UserStartedState.STATE_STOPPING; 13987 13988 long ident = Binder.clearCallingIdentity(); 13989 try { 13990 // Inform of user switch 13991 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13992 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13993 @Override 13994 public void performReceive(Intent intent, int resultCode, String data, 13995 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 13996 finishUserStop(uss); 13997 } 13998 }; 13999 broadcastIntentLocked(null, null, intent, 14000 null, resultReceiver, 0, null, null, null, 14001 true, false, MY_PID, Process.SYSTEM_UID, userId); 14002 } finally { 14003 Binder.restoreCallingIdentity(ident); 14004 } 14005 } 14006 } 14007 14008 return ActivityManager.USER_OP_SUCCESS; 14009 } 14010 14011 void finishUserStop(UserStartedState uss) { 14012 final int userId = uss.mHandle.getIdentifier(); 14013 boolean stopped; 14014 ArrayList<IStopUserCallback> callbacks; 14015 synchronized (this) { 14016 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14017 if (uss.mState != UserStartedState.STATE_STOPPING 14018 || mStartedUsers.get(userId) != uss) { 14019 stopped = false; 14020 } else { 14021 stopped = true; 14022 // User can no longer run. 14023 mStartedUsers.remove(userId); 14024 14025 // Clean up all state and processes associated with the user. 14026 // Kill all the processes for the user. 14027 forceStopUserLocked(userId); 14028 } 14029 } 14030 14031 for (int i=0; i<callbacks.size(); i++) { 14032 try { 14033 if (stopped) callbacks.get(i).userStopped(userId); 14034 else callbacks.get(i).userStopAborted(userId); 14035 } catch (RemoteException e) { 14036 } 14037 } 14038 } 14039 14040 @Override 14041 public UserInfo getCurrentUser() { 14042 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14043 != PackageManager.PERMISSION_GRANTED) { 14044 String msg = "Permission Denial: getCurrentUser() from pid=" 14045 + Binder.getCallingPid() 14046 + ", uid=" + Binder.getCallingUid() 14047 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14048 Slog.w(TAG, msg); 14049 throw new SecurityException(msg); 14050 } 14051 synchronized (this) { 14052 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14053 } 14054 } 14055 14056 @Override 14057 public boolean isUserRunning(int userId) { 14058 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14059 != PackageManager.PERMISSION_GRANTED) { 14060 String msg = "Permission Denial: isUserRunning() from pid=" 14061 + Binder.getCallingPid() 14062 + ", uid=" + Binder.getCallingUid() 14063 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14064 Slog.w(TAG, msg); 14065 throw new SecurityException(msg); 14066 } 14067 synchronized (this) { 14068 return isUserRunningLocked(userId); 14069 } 14070 } 14071 14072 boolean isUserRunningLocked(int userId) { 14073 UserStartedState state = mStartedUsers.get(userId); 14074 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14075 } 14076 14077 private boolean userExists(int userId) { 14078 if (userId == 0) { 14079 return true; 14080 } 14081 UserManagerService ums = getUserManagerLocked(); 14082 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14083 } 14084 14085 int[] getUsersLocked() { 14086 UserManagerService ums = getUserManagerLocked(); 14087 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14088 } 14089 14090 UserManagerService getUserManagerLocked() { 14091 if (mUserManager == null) { 14092 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14093 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14094 } 14095 return mUserManager; 14096 } 14097 14098 private void checkValidCaller(int uid, int userId) { 14099 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14100 14101 throw new SecurityException("Caller uid=" + uid 14102 + " is not privileged to communicate with user=" + userId); 14103 } 14104 14105 private int applyUserId(int uid, int userId) { 14106 return UserHandle.getUid(userId, uid); 14107 } 14108 14109 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14110 if (info == null) return null; 14111 ApplicationInfo newInfo = new ApplicationInfo(info); 14112 newInfo.uid = applyUserId(info.uid, userId); 14113 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14114 + info.packageName; 14115 return newInfo; 14116 } 14117 14118 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14119 if (aInfo == null 14120 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14121 return aInfo; 14122 } 14123 14124 ActivityInfo info = new ActivityInfo(aInfo); 14125 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14126 return info; 14127 } 14128} 14129