ActivityManagerService.java revision 20e809870d8ac1e5b848f2daf51b2272ef89bdfc
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.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IStopUserCallback; 50import android.app.IThumbnailReceiver; 51import android.app.Instrumentation; 52import android.app.Notification; 53import android.app.NotificationManager; 54import android.app.PendingIntent; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 79import android.content.pm.UserInfo; 80import android.content.pm.PackageManager.NameNotFoundException; 81import android.content.pm.PathPermission; 82import android.content.pm.ProviderInfo; 83import android.content.pm.ResolveInfo; 84import android.content.pm.ServiceInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.SELinux; 110import android.os.ServiceManager; 111import android.os.StrictMode; 112import android.os.SystemClock; 113import android.os.SystemProperties; 114import android.os.UserHandle; 115import android.os.UserManager; 116import android.provider.Settings; 117import android.text.format.Time; 118import android.util.EventLog; 119import android.util.Log; 120import android.util.Pair; 121import android.util.PrintWriterPrinter; 122import android.util.Slog; 123import android.util.SparseArray; 124import android.util.SparseIntArray; 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.Map.Entry; 157import java.util.Set; 158import java.util.concurrent.atomic.AtomicBoolean; 159import java.util.concurrent.atomic.AtomicLong; 160 161public final class ActivityManagerService extends ActivityManagerNative 162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 163 private static final String USER_DATA_DIR = "/data/user/"; 164 static final String TAG = "ActivityManager"; 165 static final String TAG_MU = "ActivityManagerServiceMU"; 166 static final boolean DEBUG = false; 167 static final boolean localLOGV = DEBUG; 168 static final boolean DEBUG_SWITCH = localLOGV || false; 169 static final boolean DEBUG_TASKS = localLOGV || false; 170 static final boolean DEBUG_PAUSE = localLOGV || false; 171 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 172 static final boolean DEBUG_TRANSITION = localLOGV || false; 173 static final boolean DEBUG_BROADCAST = localLOGV || false; 174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_SERVICE = localLOGV || false; 177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 178 static final boolean DEBUG_VISBILITY = localLOGV || false; 179 static final boolean DEBUG_PROCESSES = localLOGV || false; 180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 181 static final boolean DEBUG_PROVIDER = localLOGV || false; 182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 183 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 184 static final boolean DEBUG_RESULTS = localLOGV || false; 185 static final boolean DEBUG_BACKUP = localLOGV || false; 186 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 187 static final boolean DEBUG_POWER = localLOGV || false; 188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 189 static final boolean DEBUG_MU = localLOGV || false; 190 static final boolean VALIDATE_TOKENS = false; 191 static final boolean SHOW_ACTIVITY_START_TIME = true; 192 193 // Control over CPU and battery monitoring. 194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 195 static final boolean MONITOR_CPU_USAGE = true; 196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 198 static final boolean MONITOR_THREAD_CPU_USAGE = false; 199 200 // The flags that are set for all calls we make to the package manager. 201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 202 203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 204 205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 206 207 // Maximum number of recent tasks that we can remember. 208 static final int MAX_RECENT_TASKS = 20; 209 210 // Amount of time after a call to stopAppSwitches() during which we will 211 // prevent further untrusted switches from happening. 212 static final long APP_SWITCH_DELAY_TIME = 5*1000; 213 214 // How long we wait for a launched process to attach to the activity manager 215 // before we decide it's never going to come up for real. 216 static final int PROC_START_TIMEOUT = 10*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real, when the process was 220 // started with a wrapper for instrumentation (such as Valgrind) because it 221 // could take much longer than usual. 222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 223 224 // How long to wait after going idle before forcing apps to GC. 225 static final int GC_TIMEOUT = 5*1000; 226 227 // The minimum amount of time between successive GC requests for a process. 228 static final int GC_MIN_INTERVAL = 60*1000; 229 230 // The rate at which we check for apps using excessive power -- 15 mins. 231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 232 233 // The minimum sample duration we will allow before deciding we have 234 // enough data on wake locks to start killing things. 235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on CPU usage to start killing things. 239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // How long we allow a receiver to run before giving up on it. 242 static final int BROADCAST_FG_TIMEOUT = 10*1000; 243 static final int BROADCAST_BG_TIMEOUT = 60*1000; 244 245 // How long we wait until we timeout on key dispatching. 246 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 247 248 // How long we wait until we timeout on key dispatching during instrumentation. 249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 250 251 static final int MY_PID = Process.myPid(); 252 253 static final String[] EMPTY_STRING_ARRAY = new String[0]; 254 255 public ActivityStack mMainStack; 256 257 private final boolean mHeadless; 258 259 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 260 // default actuion automatically. Important for devices without direct input 261 // devices. 262 private boolean mShowDialogs = true; 263 264 /** 265 * Description of a request to start a new activity, which has been held 266 * due to app switches being disabled. 267 */ 268 static class PendingActivityLaunch { 269 ActivityRecord r; 270 ActivityRecord sourceRecord; 271 int startFlags; 272 } 273 274 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 275 = new ArrayList<PendingActivityLaunch>(); 276 277 278 BroadcastQueue mFgBroadcastQueue; 279 BroadcastQueue mBgBroadcastQueue; 280 // Convenient for easy iteration over the queues. Foreground is first 281 // so that dispatch of foreground broadcasts gets precedence. 282 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 283 284 BroadcastQueue broadcastQueueForIntent(Intent intent) { 285 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 286 if (DEBUG_BACKGROUND_BROADCAST) { 287 Slog.i(TAG, "Broadcast intent " + intent + " on " 288 + (isFg ? "foreground" : "background") 289 + " queue"); 290 } 291 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 292 } 293 294 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 295 for (BroadcastQueue queue : mBroadcastQueues) { 296 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 297 if (r != null) { 298 return r; 299 } 300 } 301 return null; 302 } 303 304 /** 305 * Activity we have told the window manager to have key focus. 306 */ 307 ActivityRecord mFocusedActivity = null; 308 /** 309 * List of intents that were used to start the most recent tasks. 310 */ 311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 312 313 /** 314 * Process management. 315 */ 316 final ProcessList mProcessList = new ProcessList(); 317 318 /** 319 * All of the applications we currently have running organized by name. 320 * The keys are strings of the application package name (as 321 * returned by the package manager), and the keys are ApplicationRecord 322 * objects. 323 */ 324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 325 326 /** 327 * The currently running isolated processes. 328 */ 329 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 330 331 /** 332 * Counter for assigning isolated process uids, to avoid frequently reusing the 333 * same ones. 334 */ 335 int mNextIsolatedProcessUid = 0; 336 337 /** 338 * The currently running heavy-weight process, if any. 339 */ 340 ProcessRecord mHeavyWeightProcess = null; 341 342 /** 343 * The last time that various processes have crashed. 344 */ 345 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 346 347 /** 348 * Set of applications that we consider to be bad, and will reject 349 * incoming broadcasts from (which the user has no control over). 350 * Processes are added to this set when they have crashed twice within 351 * a minimum amount of time; they are removed from it when they are 352 * later restarted (hopefully due to some user action). The value is the 353 * time it was added to the list. 354 */ 355 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 356 357 /** 358 * All of the processes we currently have running organized by pid. 359 * The keys are the pid running the application. 360 * 361 * <p>NOTE: This object is protected by its own lock, NOT the global 362 * activity manager lock! 363 */ 364 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 365 366 /** 367 * All of the processes that have been forced to be foreground. The key 368 * is the pid of the caller who requested it (we hold a death 369 * link on it). 370 */ 371 abstract class ForegroundToken implements IBinder.DeathRecipient { 372 int pid; 373 IBinder token; 374 } 375 final SparseArray<ForegroundToken> mForegroundProcesses 376 = new SparseArray<ForegroundToken>(); 377 378 /** 379 * List of records for processes that someone had tried to start before the 380 * system was ready. We don't start them at that point, but ensure they 381 * are started by the time booting is complete. 382 */ 383 final ArrayList<ProcessRecord> mProcessesOnHold 384 = new ArrayList<ProcessRecord>(); 385 386 /** 387 * List of persistent applications that are in the process 388 * of being started. 389 */ 390 final ArrayList<ProcessRecord> mPersistentStartingProcesses 391 = new ArrayList<ProcessRecord>(); 392 393 /** 394 * Processes that are being forcibly torn down. 395 */ 396 final ArrayList<ProcessRecord> mRemovedProcesses 397 = new ArrayList<ProcessRecord>(); 398 399 /** 400 * List of running applications, sorted by recent usage. 401 * The first entry in the list is the least recently used. 402 * It contains ApplicationRecord objects. This list does NOT include 403 * any persistent application records (since we never want to exit them). 404 */ 405 final ArrayList<ProcessRecord> mLruProcesses 406 = new ArrayList<ProcessRecord>(); 407 408 /** 409 * List of processes that should gc as soon as things are idle. 410 */ 411 final ArrayList<ProcessRecord> mProcessesToGc 412 = new ArrayList<ProcessRecord>(); 413 414 /** 415 * This is the process holding what we currently consider to be 416 * the "home" activity. 417 */ 418 ProcessRecord mHomeProcess; 419 420 /** 421 * This is the process holding the activity the user last visited that 422 * is in a different process from the one they are currently in. 423 */ 424 ProcessRecord mPreviousProcess; 425 426 /** 427 * The time at which the previous process was last visible. 428 */ 429 long mPreviousProcessVisibleTime; 430 431 /** 432 * Which uses have been started, so are allowed to run code. 433 */ 434 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 435 436 /** 437 * Packages that the user has asked to have run in screen size 438 * compatibility mode instead of filling the screen. 439 */ 440 final CompatModePackages mCompatModePackages; 441 442 /** 443 * Set of PendingResultRecord objects that are currently active. 444 */ 445 final HashSet mPendingResultRecords = new HashSet(); 446 447 /** 448 * Set of IntentSenderRecord objects that are currently active. 449 */ 450 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 451 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 452 453 /** 454 * Fingerprints (hashCode()) of stack traces that we've 455 * already logged DropBox entries for. Guarded by itself. If 456 * something (rogue user app) forces this over 457 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 458 */ 459 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 460 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 461 462 /** 463 * Strict Mode background batched logging state. 464 * 465 * The string buffer is guarded by itself, and its lock is also 466 * used to determine if another batched write is already 467 * in-flight. 468 */ 469 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 470 471 /** 472 * Keeps track of all IIntentReceivers that have been registered for 473 * broadcasts. Hash keys are the receiver IBinder, hash value is 474 * a ReceiverList. 475 */ 476 final HashMap mRegisteredReceivers = new HashMap(); 477 478 /** 479 * Resolver for broadcast intents to registered receivers. 480 * Holds BroadcastFilter (subclass of IntentFilter). 481 */ 482 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 483 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 484 @Override 485 protected boolean allowFilterResult( 486 BroadcastFilter filter, List<BroadcastFilter> dest) { 487 IBinder target = filter.receiverList.receiver.asBinder(); 488 for (int i=dest.size()-1; i>=0; i--) { 489 if (dest.get(i).receiverList.receiver.asBinder() == target) { 490 return false; 491 } 492 } 493 return true; 494 } 495 496 @Override 497 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 498 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 499 || userId == filter.owningUserId) { 500 return super.newResult(filter, match, userId); 501 } 502 return null; 503 } 504 505 @Override 506 protected BroadcastFilter[] newArray(int size) { 507 return new BroadcastFilter[size]; 508 } 509 510 @Override 511 protected String packageForFilter(BroadcastFilter filter) { 512 return filter.packageName; 513 } 514 }; 515 516 /** 517 * State of all active sticky broadcasts per user. Keys are the action of the 518 * sticky Intent, values are an ArrayList of all broadcasted intents with 519 * that action (which should usually be one). The SparseArray is keyed 520 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 521 * for stickies that are sent to all users. 522 */ 523 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 524 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 525 526 final ActiveServices mServices; 527 528 /** 529 * Backup/restore process management 530 */ 531 String mBackupAppName = null; 532 BackupRecord mBackupTarget = null; 533 534 /** 535 * List of PendingThumbnailsRecord objects of clients who are still 536 * waiting to receive all of the thumbnails for a task. 537 */ 538 final ArrayList mPendingThumbnails = new ArrayList(); 539 540 /** 541 * List of HistoryRecord objects that have been finished and must 542 * still report back to a pending thumbnail receiver. 543 */ 544 final ArrayList mCancelledThumbnails = new ArrayList(); 545 546 final ProviderMap mProviderMap = new ProviderMap(); 547 548 /** 549 * List of content providers who have clients waiting for them. The 550 * application is currently being launched and the provider will be 551 * removed from this list once it is published. 552 */ 553 final ArrayList<ContentProviderRecord> mLaunchingProviders 554 = new ArrayList<ContentProviderRecord>(); 555 556 /** 557 * Global set of specific Uri permissions that have been granted. 558 */ 559 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 560 = new SparseArray<HashMap<Uri, UriPermission>>(); 561 562 CoreSettingsObserver mCoreSettingsObserver; 563 564 /** 565 * Thread-local storage used to carry caller permissions over through 566 * indirect content-provider access. 567 * @see #ActivityManagerService.openContentUri() 568 */ 569 private class Identity { 570 public int pid; 571 public int uid; 572 573 Identity(int _pid, int _uid) { 574 pid = _pid; 575 uid = _uid; 576 } 577 } 578 579 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 580 581 /** 582 * All information we have collected about the runtime performance of 583 * any user id that can impact battery performance. 584 */ 585 final BatteryStatsService mBatteryStatsService; 586 587 /** 588 * information about component usage 589 */ 590 final UsageStatsService mUsageStatsService; 591 592 /** 593 * Current configuration information. HistoryRecord objects are given 594 * a reference to this object to indicate which configuration they are 595 * currently running in, so this object must be kept immutable. 596 */ 597 Configuration mConfiguration = new Configuration(); 598 599 /** 600 * Current sequencing integer of the configuration, for skipping old 601 * configurations. 602 */ 603 int mConfigurationSeq = 0; 604 605 /** 606 * Hardware-reported OpenGLES version. 607 */ 608 final int GL_ES_VERSION; 609 610 /** 611 * List of initialization arguments to pass to all processes when binding applications to them. 612 * For example, references to the commonly used services. 613 */ 614 HashMap<String, IBinder> mAppBindArgs; 615 616 /** 617 * Temporary to avoid allocations. Protected by main lock. 618 */ 619 final StringBuilder mStringBuilder = new StringBuilder(256); 620 621 /** 622 * Used to control how we initialize the service. 623 */ 624 boolean mStartRunning = false; 625 ComponentName mTopComponent; 626 String mTopAction; 627 String mTopData; 628 boolean mProcessesReady = false; 629 boolean mSystemReady = false; 630 boolean mBooting = false; 631 boolean mWaitingUpdate = false; 632 boolean mDidUpdate = false; 633 boolean mOnBattery = false; 634 boolean mLaunchWarningShown = false; 635 636 Context mContext; 637 638 int mFactoryTest; 639 640 boolean mCheckedForSetup; 641 642 /** 643 * The time at which we will allow normal application switches again, 644 * after a call to {@link #stopAppSwitches()}. 645 */ 646 long mAppSwitchesAllowedTime; 647 648 /** 649 * This is set to true after the first switch after mAppSwitchesAllowedTime 650 * is set; any switches after that will clear the time. 651 */ 652 boolean mDidAppSwitch; 653 654 /** 655 * Last time (in realtime) at which we checked for power usage. 656 */ 657 long mLastPowerCheckRealtime; 658 659 /** 660 * Last time (in uptime) at which we checked for power usage. 661 */ 662 long mLastPowerCheckUptime; 663 664 /** 665 * Set while we are wanting to sleep, to prevent any 666 * activities from being started/resumed. 667 */ 668 boolean mSleeping = false; 669 670 /** 671 * State of external calls telling us if the device is asleep. 672 */ 673 boolean mWentToSleep = false; 674 675 /** 676 * State of external call telling us if the lock screen is shown. 677 */ 678 boolean mLockScreenShown = false; 679 680 /** 681 * Set if we are shutting down the system, similar to sleeping. 682 */ 683 boolean mShuttingDown = false; 684 685 /** 686 * Task identifier that activities are currently being started 687 * in. Incremented each time a new task is created. 688 * todo: Replace this with a TokenSpace class that generates non-repeating 689 * integers that won't wrap. 690 */ 691 int mCurTask = 1; 692 693 /** 694 * Current sequence id for oom_adj computation traversal. 695 */ 696 int mAdjSeq = 0; 697 698 /** 699 * Current sequence id for process LRU updating. 700 */ 701 int mLruSeq = 0; 702 703 /** 704 * Keep track of the non-hidden/empty process we last found, to help 705 * determine how to distribute hidden/empty processes next time. 706 */ 707 int mNumNonHiddenProcs = 0; 708 709 /** 710 * Keep track of the number of hidden procs, to balance oom adj 711 * distribution between those and empty procs. 712 */ 713 int mNumHiddenProcs = 0; 714 715 /** 716 * Keep track of the number of service processes we last found, to 717 * determine on the next iteration which should be B services. 718 */ 719 int mNumServiceProcs = 0; 720 int mNewNumServiceProcs = 0; 721 722 /** 723 * System monitoring: number of processes that died since the last 724 * N procs were started. 725 */ 726 int[] mProcDeaths = new int[20]; 727 728 /** 729 * This is set if we had to do a delayed dexopt of an app before launching 730 * it, to increasing the ANR timeouts in that case. 731 */ 732 boolean mDidDexOpt; 733 734 String mDebugApp = null; 735 boolean mWaitForDebugger = false; 736 boolean mDebugTransient = false; 737 String mOrigDebugApp = null; 738 boolean mOrigWaitForDebugger = false; 739 boolean mAlwaysFinishActivities = false; 740 IActivityController mController = null; 741 String mProfileApp = null; 742 ProcessRecord mProfileProc = null; 743 String mProfileFile; 744 ParcelFileDescriptor mProfileFd; 745 int mProfileType = 0; 746 boolean mAutoStopProfiler = false; 747 String mOpenGlTraceApp = null; 748 749 static class ProcessChangeItem { 750 static final int CHANGE_ACTIVITIES = 1<<0; 751 static final int CHANGE_IMPORTANCE= 1<<1; 752 int changes; 753 int uid; 754 int pid; 755 int importance; 756 boolean foregroundActivities; 757 } 758 759 final RemoteCallbackList<IProcessObserver> mProcessObservers 760 = new RemoteCallbackList<IProcessObserver>(); 761 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 762 763 final ArrayList<ProcessChangeItem> mPendingProcessChanges 764 = new ArrayList<ProcessChangeItem>(); 765 final ArrayList<ProcessChangeItem> mAvailProcessChanges 766 = new ArrayList<ProcessChangeItem>(); 767 768 /** 769 * Callback of last caller to {@link #requestPss}. 770 */ 771 Runnable mRequestPssCallback; 772 773 /** 774 * Remaining processes for which we are waiting results from the last 775 * call to {@link #requestPss}. 776 */ 777 final ArrayList<ProcessRecord> mRequestPssList 778 = new ArrayList<ProcessRecord>(); 779 780 /** 781 * Runtime statistics collection thread. This object's lock is used to 782 * protect all related state. 783 */ 784 final Thread mProcessStatsThread; 785 786 /** 787 * Used to collect process stats when showing not responding dialog. 788 * Protected by mProcessStatsThread. 789 */ 790 final ProcessStats mProcessStats = new ProcessStats( 791 MONITOR_THREAD_CPU_USAGE); 792 final AtomicLong mLastCpuTime = new AtomicLong(0); 793 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 794 795 long mLastWriteTime = 0; 796 797 /** 798 * Set to true after the system has finished booting. 799 */ 800 boolean mBooted = false; 801 802 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 803 int mProcessLimitOverride = -1; 804 805 WindowManagerService mWindowManager; 806 807 static ActivityManagerService mSelf; 808 static ActivityThread mSystemThread; 809 810 private int mCurrentUserId; 811 private UserManager mUserManager; 812 813 private final class AppDeathRecipient implements IBinder.DeathRecipient { 814 final ProcessRecord mApp; 815 final int mPid; 816 final IApplicationThread mAppThread; 817 818 AppDeathRecipient(ProcessRecord app, int pid, 819 IApplicationThread thread) { 820 if (localLOGV) Slog.v( 821 TAG, "New death recipient " + this 822 + " for thread " + thread.asBinder()); 823 mApp = app; 824 mPid = pid; 825 mAppThread = thread; 826 } 827 828 public void binderDied() { 829 if (localLOGV) Slog.v( 830 TAG, "Death received in " + this 831 + " for thread " + mAppThread.asBinder()); 832 synchronized(ActivityManagerService.this) { 833 appDiedLocked(mApp, mPid, mAppThread); 834 } 835 } 836 } 837 838 static final int SHOW_ERROR_MSG = 1; 839 static final int SHOW_NOT_RESPONDING_MSG = 2; 840 static final int SHOW_FACTORY_ERROR_MSG = 3; 841 static final int UPDATE_CONFIGURATION_MSG = 4; 842 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 843 static final int WAIT_FOR_DEBUGGER_MSG = 6; 844 static final int SERVICE_TIMEOUT_MSG = 12; 845 static final int UPDATE_TIME_ZONE = 13; 846 static final int SHOW_UID_ERROR_MSG = 14; 847 static final int IM_FEELING_LUCKY_MSG = 15; 848 static final int PROC_START_TIMEOUT_MSG = 20; 849 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 850 static final int KILL_APPLICATION_MSG = 22; 851 static final int FINALIZE_PENDING_INTENT_MSG = 23; 852 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 853 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 854 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 855 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 856 static final int CLEAR_DNS_CACHE = 28; 857 static final int UPDATE_HTTP_PROXY = 29; 858 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 859 static final int DISPATCH_PROCESSES_CHANGED = 31; 860 static final int DISPATCH_PROCESS_DIED = 32; 861 static final int REPORT_MEM_USAGE = 33; 862 863 static final int FIRST_ACTIVITY_STACK_MSG = 100; 864 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 865 static final int FIRST_COMPAT_MODE_MSG = 300; 866 867 AlertDialog mUidAlert; 868 CompatModeDialog mCompatModeDialog; 869 long mLastMemUsageReportTime = 0; 870 871 final Handler mHandler = new Handler() { 872 //public Handler() { 873 // if (localLOGV) Slog.v(TAG, "Handler started!"); 874 //} 875 876 public void handleMessage(Message msg) { 877 switch (msg.what) { 878 case SHOW_ERROR_MSG: { 879 HashMap data = (HashMap) msg.obj; 880 synchronized (ActivityManagerService.this) { 881 ProcessRecord proc = (ProcessRecord)data.get("app"); 882 if (proc != null && proc.crashDialog != null) { 883 Slog.e(TAG, "App already has crash dialog: " + proc); 884 return; 885 } 886 AppErrorResult res = (AppErrorResult) data.get("result"); 887 if (mShowDialogs && !mSleeping && !mShuttingDown) { 888 Dialog d = new AppErrorDialog(mContext, res, proc); 889 d.show(); 890 proc.crashDialog = d; 891 } else { 892 // The device is asleep, so just pretend that the user 893 // saw a crash dialog and hit "force quit". 894 res.set(0); 895 } 896 } 897 898 ensureBootCompleted(); 899 } break; 900 case SHOW_NOT_RESPONDING_MSG: { 901 synchronized (ActivityManagerService.this) { 902 HashMap data = (HashMap) msg.obj; 903 ProcessRecord proc = (ProcessRecord)data.get("app"); 904 if (proc != null && proc.anrDialog != null) { 905 Slog.e(TAG, "App already has anr dialog: " + proc); 906 return; 907 } 908 909 Intent intent = new Intent("android.intent.action.ANR"); 910 if (!mProcessesReady) { 911 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 912 | Intent.FLAG_RECEIVER_FOREGROUND); 913 } 914 broadcastIntentLocked(null, null, intent, 915 null, null, 0, null, null, null, 916 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 917 918 if (mShowDialogs) { 919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 920 mContext, proc, (ActivityRecord)data.get("activity")); 921 d.show(); 922 proc.anrDialog = d; 923 } else { 924 // Just kill the app if there is no dialog to be shown. 925 killAppAtUsersRequest(proc, null); 926 } 927 } 928 929 ensureBootCompleted(); 930 } break; 931 case SHOW_STRICT_MODE_VIOLATION_MSG: { 932 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 933 synchronized (ActivityManagerService.this) { 934 ProcessRecord proc = (ProcessRecord) data.get("app"); 935 if (proc == null) { 936 Slog.e(TAG, "App not found when showing strict mode dialog."); 937 break; 938 } 939 if (proc.crashDialog != null) { 940 Slog.e(TAG, "App already has strict mode dialog: " + proc); 941 return; 942 } 943 AppErrorResult res = (AppErrorResult) data.get("result"); 944 if (mShowDialogs && !mSleeping && !mShuttingDown) { 945 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 946 d.show(); 947 proc.crashDialog = d; 948 } else { 949 // The device is asleep, so just pretend that the user 950 // saw a crash dialog and hit "force quit". 951 res.set(0); 952 } 953 } 954 ensureBootCompleted(); 955 } break; 956 case SHOW_FACTORY_ERROR_MSG: { 957 Dialog d = new FactoryErrorDialog( 958 mContext, msg.getData().getCharSequence("msg")); 959 d.show(); 960 ensureBootCompleted(); 961 } break; 962 case UPDATE_CONFIGURATION_MSG: { 963 final ContentResolver resolver = mContext.getContentResolver(); 964 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 965 } break; 966 case GC_BACKGROUND_PROCESSES_MSG: { 967 synchronized (ActivityManagerService.this) { 968 performAppGcsIfAppropriateLocked(); 969 } 970 } break; 971 case WAIT_FOR_DEBUGGER_MSG: { 972 synchronized (ActivityManagerService.this) { 973 ProcessRecord app = (ProcessRecord)msg.obj; 974 if (msg.arg1 != 0) { 975 if (!app.waitedForDebugger) { 976 Dialog d = new AppWaitingForDebuggerDialog( 977 ActivityManagerService.this, 978 mContext, app); 979 app.waitDialog = d; 980 app.waitedForDebugger = true; 981 d.show(); 982 } 983 } else { 984 if (app.waitDialog != null) { 985 app.waitDialog.dismiss(); 986 app.waitDialog = null; 987 } 988 } 989 } 990 } break; 991 case SERVICE_TIMEOUT_MSG: { 992 if (mDidDexOpt) { 993 mDidDexOpt = false; 994 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 995 nmsg.obj = msg.obj; 996 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 997 return; 998 } 999 mServices.serviceTimeout((ProcessRecord)msg.obj); 1000 } break; 1001 case UPDATE_TIME_ZONE: { 1002 synchronized (ActivityManagerService.this) { 1003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1004 ProcessRecord r = mLruProcesses.get(i); 1005 if (r.thread != null) { 1006 try { 1007 r.thread.updateTimeZone(); 1008 } catch (RemoteException ex) { 1009 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1010 } 1011 } 1012 } 1013 } 1014 } break; 1015 case CLEAR_DNS_CACHE: { 1016 synchronized (ActivityManagerService.this) { 1017 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1018 ProcessRecord r = mLruProcesses.get(i); 1019 if (r.thread != null) { 1020 try { 1021 r.thread.clearDnsCache(); 1022 } catch (RemoteException ex) { 1023 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1024 } 1025 } 1026 } 1027 } 1028 } break; 1029 case UPDATE_HTTP_PROXY: { 1030 ProxyProperties proxy = (ProxyProperties)msg.obj; 1031 String host = ""; 1032 String port = ""; 1033 String exclList = ""; 1034 if (proxy != null) { 1035 host = proxy.getHost(); 1036 port = Integer.toString(proxy.getPort()); 1037 exclList = proxy.getExclusionList(); 1038 } 1039 synchronized (ActivityManagerService.this) { 1040 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1041 ProcessRecord r = mLruProcesses.get(i); 1042 if (r.thread != null) { 1043 try { 1044 r.thread.setHttpProxy(host, port, exclList); 1045 } catch (RemoteException ex) { 1046 Slog.w(TAG, "Failed to update http proxy for: " + 1047 r.info.processName); 1048 } 1049 } 1050 } 1051 } 1052 } break; 1053 case SHOW_UID_ERROR_MSG: { 1054 String title = "System UIDs Inconsistent"; 1055 String text = "UIDs on the system are inconsistent, you need to wipe your" 1056 + " data partition or your device will be unstable."; 1057 Log.e(TAG, title + ": " + text); 1058 if (mShowDialogs) { 1059 // XXX This is a temporary dialog, no need to localize. 1060 AlertDialog d = new BaseErrorDialog(mContext); 1061 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1062 d.setCancelable(false); 1063 d.setTitle(title); 1064 d.setMessage(text); 1065 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1066 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1067 mUidAlert = d; 1068 d.show(); 1069 } 1070 } break; 1071 case IM_FEELING_LUCKY_MSG: { 1072 if (mUidAlert != null) { 1073 mUidAlert.dismiss(); 1074 mUidAlert = null; 1075 } 1076 } break; 1077 case PROC_START_TIMEOUT_MSG: { 1078 if (mDidDexOpt) { 1079 mDidDexOpt = false; 1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1081 nmsg.obj = msg.obj; 1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1083 return; 1084 } 1085 ProcessRecord app = (ProcessRecord)msg.obj; 1086 synchronized (ActivityManagerService.this) { 1087 processStartTimedOutLocked(app); 1088 } 1089 } break; 1090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1091 synchronized (ActivityManagerService.this) { 1092 doPendingActivityLaunchesLocked(true); 1093 } 1094 } break; 1095 case KILL_APPLICATION_MSG: { 1096 synchronized (ActivityManagerService.this) { 1097 int uid = msg.arg1; 1098 boolean restart = (msg.arg2 == 1); 1099 String pkg = (String) msg.obj; 1100 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1101 UserHandle.getUserId(uid)); 1102 } 1103 } break; 1104 case FINALIZE_PENDING_INTENT_MSG: { 1105 ((PendingIntentRecord)msg.obj).completeFinalize(); 1106 } break; 1107 case POST_HEAVY_NOTIFICATION_MSG: { 1108 INotificationManager inm = NotificationManager.getService(); 1109 if (inm == null) { 1110 return; 1111 } 1112 1113 ActivityRecord root = (ActivityRecord)msg.obj; 1114 ProcessRecord process = root.app; 1115 if (process == null) { 1116 return; 1117 } 1118 1119 try { 1120 Context context = mContext.createPackageContext(process.info.packageName, 0); 1121 String text = mContext.getString(R.string.heavy_weight_notification, 1122 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1123 Notification notification = new Notification(); 1124 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1125 notification.when = 0; 1126 notification.flags = Notification.FLAG_ONGOING_EVENT; 1127 notification.tickerText = text; 1128 notification.defaults = 0; // please be quiet 1129 notification.sound = null; 1130 notification.vibrate = null; 1131 notification.setLatestEventInfo(context, text, 1132 mContext.getText(R.string.heavy_weight_notification_detail), 1133 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1134 PendingIntent.FLAG_CANCEL_CURRENT, null, 1135 new UserHandle(root.userId))); 1136 1137 try { 1138 int[] outId = new int[1]; 1139 inm.enqueueNotificationWithTag("android", null, 1140 R.string.heavy_weight_notification, 1141 notification, outId, root.userId); 1142 } catch (RuntimeException e) { 1143 Slog.w(ActivityManagerService.TAG, 1144 "Error showing notification for heavy-weight app", e); 1145 } catch (RemoteException e) { 1146 } 1147 } catch (NameNotFoundException e) { 1148 Slog.w(TAG, "Unable to create context for heavy notification", e); 1149 } 1150 } break; 1151 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1152 INotificationManager inm = NotificationManager.getService(); 1153 if (inm == null) { 1154 return; 1155 } 1156 try { 1157 inm.cancelNotificationWithTag("android", null, 1158 R.string.heavy_weight_notification, msg.arg1); 1159 } catch (RuntimeException e) { 1160 Slog.w(ActivityManagerService.TAG, 1161 "Error canceling notification for service", e); 1162 } catch (RemoteException e) { 1163 } 1164 } break; 1165 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1166 synchronized (ActivityManagerService.this) { 1167 checkExcessivePowerUsageLocked(true); 1168 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1169 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1170 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1171 } 1172 } break; 1173 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1174 synchronized (ActivityManagerService.this) { 1175 ActivityRecord ar = (ActivityRecord)msg.obj; 1176 if (mCompatModeDialog != null) { 1177 if (mCompatModeDialog.mAppInfo.packageName.equals( 1178 ar.info.applicationInfo.packageName)) { 1179 return; 1180 } 1181 mCompatModeDialog.dismiss(); 1182 mCompatModeDialog = null; 1183 } 1184 if (ar != null && false) { 1185 if (mCompatModePackages.getPackageAskCompatModeLocked( 1186 ar.packageName)) { 1187 int mode = mCompatModePackages.computeCompatModeLocked( 1188 ar.info.applicationInfo); 1189 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1190 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1191 mCompatModeDialog = new CompatModeDialog( 1192 ActivityManagerService.this, mContext, 1193 ar.info.applicationInfo); 1194 mCompatModeDialog.show(); 1195 } 1196 } 1197 } 1198 } 1199 break; 1200 } 1201 case DISPATCH_PROCESSES_CHANGED: { 1202 dispatchProcessesChanged(); 1203 break; 1204 } 1205 case DISPATCH_PROCESS_DIED: { 1206 final int pid = msg.arg1; 1207 final int uid = msg.arg2; 1208 dispatchProcessDied(pid, uid); 1209 break; 1210 } 1211 case REPORT_MEM_USAGE: { 1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1213 if (!isDebuggable) { 1214 return; 1215 } 1216 synchronized (ActivityManagerService.this) { 1217 long now = SystemClock.uptimeMillis(); 1218 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1219 // Don't report more than every 5 minutes to somewhat 1220 // avoid spamming. 1221 return; 1222 } 1223 mLastMemUsageReportTime = now; 1224 } 1225 Thread thread = new Thread() { 1226 @Override public void run() { 1227 StringBuilder dropBuilder = new StringBuilder(1024); 1228 StringBuilder logBuilder = new StringBuilder(1024); 1229 StringWriter oomSw = new StringWriter(); 1230 PrintWriter oomPw = new PrintWriter(oomSw); 1231 StringWriter catSw = new StringWriter(); 1232 PrintWriter catPw = new PrintWriter(catSw); 1233 String[] emptyArgs = new String[] { }; 1234 StringBuilder tag = new StringBuilder(128); 1235 StringBuilder stack = new StringBuilder(128); 1236 tag.append("Low on memory -- "); 1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1238 tag, stack); 1239 dropBuilder.append(stack); 1240 dropBuilder.append('\n'); 1241 dropBuilder.append('\n'); 1242 String oomString = oomSw.toString(); 1243 dropBuilder.append(oomString); 1244 dropBuilder.append('\n'); 1245 logBuilder.append(oomString); 1246 try { 1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1248 "procrank", }); 1249 final InputStreamReader converter = new InputStreamReader( 1250 proc.getInputStream()); 1251 BufferedReader in = new BufferedReader(converter); 1252 String line; 1253 while (true) { 1254 line = in.readLine(); 1255 if (line == null) { 1256 break; 1257 } 1258 if (line.length() > 0) { 1259 logBuilder.append(line); 1260 logBuilder.append('\n'); 1261 } 1262 dropBuilder.append(line); 1263 dropBuilder.append('\n'); 1264 } 1265 converter.close(); 1266 } catch (IOException e) { 1267 } 1268 synchronized (ActivityManagerService.this) { 1269 catPw.println(); 1270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1271 catPw.println(); 1272 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1273 false, false, null); 1274 catPw.println(); 1275 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1276 } 1277 dropBuilder.append(catSw.toString()); 1278 addErrorToDropBox("lowmem", null, "system_server", null, 1279 null, tag.toString(), dropBuilder.toString(), null, null); 1280 Slog.i(TAG, logBuilder.toString()); 1281 synchronized (ActivityManagerService.this) { 1282 long now = SystemClock.uptimeMillis(); 1283 if (mLastMemUsageReportTime < now) { 1284 mLastMemUsageReportTime = now; 1285 } 1286 } 1287 } 1288 }; 1289 thread.start(); 1290 break; 1291 } 1292 } 1293 } 1294 }; 1295 1296 public static void setSystemProcess() { 1297 try { 1298 ActivityManagerService m = mSelf; 1299 1300 ServiceManager.addService("activity", m, true); 1301 ServiceManager.addService("meminfo", new MemBinder(m)); 1302 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1303 ServiceManager.addService("dbinfo", new DbBinder(m)); 1304 if (MONITOR_CPU_USAGE) { 1305 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1306 } 1307 ServiceManager.addService("permission", new PermissionController(m)); 1308 1309 ApplicationInfo info = 1310 mSelf.mContext.getPackageManager().getApplicationInfo( 1311 "android", STOCK_PM_FLAGS); 1312 mSystemThread.installSystemApplicationInfo(info); 1313 1314 synchronized (mSelf) { 1315 ProcessRecord app = mSelf.newProcessRecordLocked( 1316 mSystemThread.getApplicationThread(), info, 1317 info.processName, false); 1318 app.persistent = true; 1319 app.pid = MY_PID; 1320 app.maxAdj = ProcessList.SYSTEM_ADJ; 1321 mSelf.mProcessNames.put(app.processName, app.uid, app); 1322 synchronized (mSelf.mPidsSelfLocked) { 1323 mSelf.mPidsSelfLocked.put(app.pid, app); 1324 } 1325 mSelf.updateLruProcessLocked(app, true, true); 1326 } 1327 } catch (PackageManager.NameNotFoundException e) { 1328 throw new RuntimeException( 1329 "Unable to find android system package", e); 1330 } 1331 } 1332 1333 public void setWindowManager(WindowManagerService wm) { 1334 mWindowManager = wm; 1335 } 1336 1337 public static final Context main(int factoryTest) { 1338 AThread thr = new AThread(); 1339 thr.start(); 1340 1341 synchronized (thr) { 1342 while (thr.mService == null) { 1343 try { 1344 thr.wait(); 1345 } catch (InterruptedException e) { 1346 } 1347 } 1348 } 1349 1350 ActivityManagerService m = thr.mService; 1351 mSelf = m; 1352 ActivityThread at = ActivityThread.systemMain(); 1353 mSystemThread = at; 1354 Context context = at.getSystemContext(); 1355 context.setTheme(android.R.style.Theme_Holo); 1356 m.mContext = context; 1357 m.mFactoryTest = factoryTest; 1358 m.mMainStack = new ActivityStack(m, context, true); 1359 1360 m.mBatteryStatsService.publish(context); 1361 m.mUsageStatsService.publish(context); 1362 1363 synchronized (thr) { 1364 thr.mReady = true; 1365 thr.notifyAll(); 1366 } 1367 1368 m.startRunning(null, null, null, null); 1369 1370 return context; 1371 } 1372 1373 public static ActivityManagerService self() { 1374 return mSelf; 1375 } 1376 1377 static class AThread extends Thread { 1378 ActivityManagerService mService; 1379 boolean mReady = false; 1380 1381 public AThread() { 1382 super("ActivityManager"); 1383 } 1384 1385 public void run() { 1386 Looper.prepare(); 1387 1388 android.os.Process.setThreadPriority( 1389 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1390 android.os.Process.setCanSelfBackground(false); 1391 1392 ActivityManagerService m = new ActivityManagerService(); 1393 1394 synchronized (this) { 1395 mService = m; 1396 notifyAll(); 1397 } 1398 1399 synchronized (this) { 1400 while (!mReady) { 1401 try { 1402 wait(); 1403 } catch (InterruptedException e) { 1404 } 1405 } 1406 } 1407 1408 // For debug builds, log event loop stalls to dropbox for analysis. 1409 if (StrictMode.conditionallyEnableDebugLogging()) { 1410 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1411 } 1412 1413 Looper.loop(); 1414 } 1415 } 1416 1417 static class MemBinder extends Binder { 1418 ActivityManagerService mActivityManagerService; 1419 MemBinder(ActivityManagerService activityManagerService) { 1420 mActivityManagerService = activityManagerService; 1421 } 1422 1423 @Override 1424 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1425 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1426 != PackageManager.PERMISSION_GRANTED) { 1427 pw.println("Permission Denial: can't dump meminfo from from pid=" 1428 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1429 + " without permission " + android.Manifest.permission.DUMP); 1430 return; 1431 } 1432 1433 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1434 false, null, null, null); 1435 } 1436 } 1437 1438 static class GraphicsBinder extends Binder { 1439 ActivityManagerService mActivityManagerService; 1440 GraphicsBinder(ActivityManagerService activityManagerService) { 1441 mActivityManagerService = activityManagerService; 1442 } 1443 1444 @Override 1445 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1446 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1447 != PackageManager.PERMISSION_GRANTED) { 1448 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1449 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1450 + " without permission " + android.Manifest.permission.DUMP); 1451 return; 1452 } 1453 1454 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1455 } 1456 } 1457 1458 static class DbBinder extends Binder { 1459 ActivityManagerService mActivityManagerService; 1460 DbBinder(ActivityManagerService activityManagerService) { 1461 mActivityManagerService = activityManagerService; 1462 } 1463 1464 @Override 1465 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1466 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1467 != PackageManager.PERMISSION_GRANTED) { 1468 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1469 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1470 + " without permission " + android.Manifest.permission.DUMP); 1471 return; 1472 } 1473 1474 mActivityManagerService.dumpDbInfo(fd, pw, args); 1475 } 1476 } 1477 1478 static class CpuBinder extends Binder { 1479 ActivityManagerService mActivityManagerService; 1480 CpuBinder(ActivityManagerService activityManagerService) { 1481 mActivityManagerService = activityManagerService; 1482 } 1483 1484 @Override 1485 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1486 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1487 != PackageManager.PERMISSION_GRANTED) { 1488 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1489 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1490 + " without permission " + android.Manifest.permission.DUMP); 1491 return; 1492 } 1493 1494 synchronized (mActivityManagerService.mProcessStatsThread) { 1495 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1496 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1497 SystemClock.uptimeMillis())); 1498 } 1499 } 1500 } 1501 1502 private ActivityManagerService() { 1503 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1504 1505 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1506 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1507 mBroadcastQueues[0] = mFgBroadcastQueue; 1508 mBroadcastQueues[1] = mBgBroadcastQueue; 1509 1510 mServices = new ActiveServices(this); 1511 1512 File dataDir = Environment.getDataDirectory(); 1513 File systemDir = new File(dataDir, "system"); 1514 systemDir.mkdirs(); 1515 mBatteryStatsService = new BatteryStatsService(new File( 1516 systemDir, "batterystats.bin").toString()); 1517 mBatteryStatsService.getActiveStatistics().readLocked(); 1518 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1519 mOnBattery = DEBUG_POWER ? true 1520 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1521 mBatteryStatsService.getActiveStatistics().setCallback(this); 1522 1523 mUsageStatsService = new UsageStatsService(new File( 1524 systemDir, "usagestats").toString()); 1525 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1526 1527 // User 0 is the first and only user that runs at boot. 1528 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1529 1530 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1531 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1532 1533 mConfiguration.setToDefaults(); 1534 mConfiguration.locale = Locale.getDefault(); 1535 mConfigurationSeq = mConfiguration.seq = 1; 1536 mProcessStats.init(); 1537 1538 mCompatModePackages = new CompatModePackages(this, systemDir); 1539 1540 // Add ourself to the Watchdog monitors. 1541 Watchdog.getInstance().addMonitor(this); 1542 1543 mProcessStatsThread = new Thread("ProcessStats") { 1544 public void run() { 1545 while (true) { 1546 try { 1547 try { 1548 synchronized(this) { 1549 final long now = SystemClock.uptimeMillis(); 1550 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1551 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1552 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1553 // + ", write delay=" + nextWriteDelay); 1554 if (nextWriteDelay < nextCpuDelay) { 1555 nextCpuDelay = nextWriteDelay; 1556 } 1557 if (nextCpuDelay > 0) { 1558 mProcessStatsMutexFree.set(true); 1559 this.wait(nextCpuDelay); 1560 } 1561 } 1562 } catch (InterruptedException e) { 1563 } 1564 updateCpuStatsNow(); 1565 } catch (Exception e) { 1566 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1567 } 1568 } 1569 } 1570 }; 1571 mProcessStatsThread.start(); 1572 } 1573 1574 @Override 1575 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1576 throws RemoteException { 1577 if (code == SYSPROPS_TRANSACTION) { 1578 // We need to tell all apps about the system property change. 1579 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1580 synchronized(this) { 1581 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1582 final int NA = apps.size(); 1583 for (int ia=0; ia<NA; ia++) { 1584 ProcessRecord app = apps.valueAt(ia); 1585 if (app.thread != null) { 1586 procs.add(app.thread.asBinder()); 1587 } 1588 } 1589 } 1590 } 1591 1592 int N = procs.size(); 1593 for (int i=0; i<N; i++) { 1594 Parcel data2 = Parcel.obtain(); 1595 try { 1596 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1597 } catch (RemoteException e) { 1598 } 1599 data2.recycle(); 1600 } 1601 } 1602 try { 1603 return super.onTransact(code, data, reply, flags); 1604 } catch (RuntimeException e) { 1605 // The activity manager only throws security exceptions, so let's 1606 // log all others. 1607 if (!(e instanceof SecurityException)) { 1608 Slog.e(TAG, "Activity Manager Crash", e); 1609 } 1610 throw e; 1611 } 1612 } 1613 1614 void updateCpuStats() { 1615 final long now = SystemClock.uptimeMillis(); 1616 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1617 return; 1618 } 1619 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1620 synchronized (mProcessStatsThread) { 1621 mProcessStatsThread.notify(); 1622 } 1623 } 1624 } 1625 1626 void updateCpuStatsNow() { 1627 synchronized (mProcessStatsThread) { 1628 mProcessStatsMutexFree.set(false); 1629 final long now = SystemClock.uptimeMillis(); 1630 boolean haveNewCpuStats = false; 1631 1632 if (MONITOR_CPU_USAGE && 1633 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1634 mLastCpuTime.set(now); 1635 haveNewCpuStats = true; 1636 mProcessStats.update(); 1637 //Slog.i(TAG, mProcessStats.printCurrentState()); 1638 //Slog.i(TAG, "Total CPU usage: " 1639 // + mProcessStats.getTotalCpuPercent() + "%"); 1640 1641 // Slog the cpu usage if the property is set. 1642 if ("true".equals(SystemProperties.get("events.cpu"))) { 1643 int user = mProcessStats.getLastUserTime(); 1644 int system = mProcessStats.getLastSystemTime(); 1645 int iowait = mProcessStats.getLastIoWaitTime(); 1646 int irq = mProcessStats.getLastIrqTime(); 1647 int softIrq = mProcessStats.getLastSoftIrqTime(); 1648 int idle = mProcessStats.getLastIdleTime(); 1649 1650 int total = user + system + iowait + irq + softIrq + idle; 1651 if (total == 0) total = 1; 1652 1653 EventLog.writeEvent(EventLogTags.CPU, 1654 ((user+system+iowait+irq+softIrq) * 100) / total, 1655 (user * 100) / total, 1656 (system * 100) / total, 1657 (iowait * 100) / total, 1658 (irq * 100) / total, 1659 (softIrq * 100) / total); 1660 } 1661 } 1662 1663 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1664 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1665 synchronized(bstats) { 1666 synchronized(mPidsSelfLocked) { 1667 if (haveNewCpuStats) { 1668 if (mOnBattery) { 1669 int perc = bstats.startAddingCpuLocked(); 1670 int totalUTime = 0; 1671 int totalSTime = 0; 1672 final int N = mProcessStats.countStats(); 1673 for (int i=0; i<N; i++) { 1674 ProcessStats.Stats st = mProcessStats.getStats(i); 1675 if (!st.working) { 1676 continue; 1677 } 1678 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1679 int otherUTime = (st.rel_utime*perc)/100; 1680 int otherSTime = (st.rel_stime*perc)/100; 1681 totalUTime += otherUTime; 1682 totalSTime += otherSTime; 1683 if (pr != null) { 1684 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1685 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1686 st.rel_stime-otherSTime); 1687 ps.addSpeedStepTimes(cpuSpeedTimes); 1688 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1689 } else { 1690 BatteryStatsImpl.Uid.Proc ps = 1691 bstats.getProcessStatsLocked(st.name, st.pid); 1692 if (ps != null) { 1693 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1694 st.rel_stime-otherSTime); 1695 ps.addSpeedStepTimes(cpuSpeedTimes); 1696 } 1697 } 1698 } 1699 bstats.finishAddingCpuLocked(perc, totalUTime, 1700 totalSTime, cpuSpeedTimes); 1701 } 1702 } 1703 } 1704 1705 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1706 mLastWriteTime = now; 1707 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1708 } 1709 } 1710 } 1711 } 1712 1713 @Override 1714 public void batteryNeedsCpuUpdate() { 1715 updateCpuStatsNow(); 1716 } 1717 1718 @Override 1719 public void batteryPowerChanged(boolean onBattery) { 1720 // When plugging in, update the CPU stats first before changing 1721 // the plug state. 1722 updateCpuStatsNow(); 1723 synchronized (this) { 1724 synchronized(mPidsSelfLocked) { 1725 mOnBattery = DEBUG_POWER ? true : onBattery; 1726 } 1727 } 1728 } 1729 1730 /** 1731 * Initialize the application bind args. These are passed to each 1732 * process when the bindApplication() IPC is sent to the process. They're 1733 * lazily setup to make sure the services are running when they're asked for. 1734 */ 1735 private HashMap<String, IBinder> getCommonServicesLocked() { 1736 if (mAppBindArgs == null) { 1737 mAppBindArgs = new HashMap<String, IBinder>(); 1738 1739 // Setup the application init args 1740 mAppBindArgs.put("package", ServiceManager.getService("package")); 1741 mAppBindArgs.put("window", ServiceManager.getService("window")); 1742 mAppBindArgs.put(Context.ALARM_SERVICE, 1743 ServiceManager.getService(Context.ALARM_SERVICE)); 1744 } 1745 return mAppBindArgs; 1746 } 1747 1748 final void setFocusedActivityLocked(ActivityRecord r) { 1749 if (mFocusedActivity != r) { 1750 mFocusedActivity = r; 1751 if (r != null) { 1752 mWindowManager.setFocusedApp(r.appToken, true); 1753 } 1754 } 1755 } 1756 1757 private final void updateLruProcessInternalLocked(ProcessRecord app, 1758 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1759 // put it on the LRU to keep track of when it should be exited. 1760 int lrui = mLruProcesses.indexOf(app); 1761 if (lrui >= 0) mLruProcesses.remove(lrui); 1762 1763 int i = mLruProcesses.size()-1; 1764 int skipTop = 0; 1765 1766 app.lruSeq = mLruSeq; 1767 1768 // compute the new weight for this process. 1769 if (updateActivityTime) { 1770 app.lastActivityTime = SystemClock.uptimeMillis(); 1771 } 1772 if (app.activities.size() > 0) { 1773 // If this process has activities, we more strongly want to keep 1774 // it around. 1775 app.lruWeight = app.lastActivityTime; 1776 } else if (app.pubProviders.size() > 0) { 1777 // If this process contains content providers, we want to keep 1778 // it a little more strongly. 1779 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1780 // Also don't let it kick out the first few "real" hidden processes. 1781 skipTop = ProcessList.MIN_HIDDEN_APPS; 1782 } else { 1783 // If this process doesn't have activities, we less strongly 1784 // want to keep it around, and generally want to avoid getting 1785 // in front of any very recently used activities. 1786 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1787 // Also don't let it kick out the first few "real" hidden processes. 1788 skipTop = ProcessList.MIN_HIDDEN_APPS; 1789 } 1790 1791 while (i >= 0) { 1792 ProcessRecord p = mLruProcesses.get(i); 1793 // If this app shouldn't be in front of the first N background 1794 // apps, then skip over that many that are currently hidden. 1795 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1796 skipTop--; 1797 } 1798 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1799 mLruProcesses.add(i+1, app); 1800 break; 1801 } 1802 i--; 1803 } 1804 if (i < 0) { 1805 mLruProcesses.add(0, app); 1806 } 1807 1808 // If the app is currently using a content provider or service, 1809 // bump those processes as well. 1810 if (app.connections.size() > 0) { 1811 for (ConnectionRecord cr : app.connections) { 1812 if (cr.binding != null && cr.binding.service != null 1813 && cr.binding.service.app != null 1814 && cr.binding.service.app.lruSeq != mLruSeq) { 1815 updateLruProcessInternalLocked(cr.binding.service.app, false, 1816 updateActivityTime, i+1); 1817 } 1818 } 1819 } 1820 for (int j=app.conProviders.size()-1; j>=0; j--) { 1821 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1822 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1823 updateLruProcessInternalLocked(cpr.proc, false, 1824 updateActivityTime, i+1); 1825 } 1826 } 1827 1828 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1829 if (oomAdj) { 1830 updateOomAdjLocked(); 1831 } 1832 } 1833 1834 final void updateLruProcessLocked(ProcessRecord app, 1835 boolean oomAdj, boolean updateActivityTime) { 1836 mLruSeq++; 1837 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1838 } 1839 1840 final ProcessRecord getProcessRecordLocked( 1841 String processName, int uid) { 1842 if (uid == Process.SYSTEM_UID) { 1843 // The system gets to run in any process. If there are multiple 1844 // processes with the same uid, just pick the first (this 1845 // should never happen). 1846 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1847 processName); 1848 if (procs == null) return null; 1849 final int N = procs.size(); 1850 for (int i = 0; i < N; i++) { 1851 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1852 } 1853 } 1854 ProcessRecord proc = mProcessNames.get(processName, uid); 1855 return proc; 1856 } 1857 1858 void ensurePackageDexOpt(String packageName) { 1859 IPackageManager pm = AppGlobals.getPackageManager(); 1860 try { 1861 if (pm.performDexOpt(packageName)) { 1862 mDidDexOpt = true; 1863 } 1864 } catch (RemoteException e) { 1865 } 1866 } 1867 1868 boolean isNextTransitionForward() { 1869 int transit = mWindowManager.getPendingAppTransition(); 1870 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1871 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1872 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1873 } 1874 1875 final ProcessRecord startProcessLocked(String processName, 1876 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1877 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1878 boolean isolated) { 1879 ProcessRecord app; 1880 if (!isolated) { 1881 app = getProcessRecordLocked(processName, info.uid); 1882 } else { 1883 // If this is an isolated process, it can't re-use an existing process. 1884 app = null; 1885 } 1886 // We don't have to do anything more if: 1887 // (1) There is an existing application record; and 1888 // (2) The caller doesn't think it is dead, OR there is no thread 1889 // object attached to it so we know it couldn't have crashed; and 1890 // (3) There is a pid assigned to it, so it is either starting or 1891 // already running. 1892 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1893 + " app=" + app + " knownToBeDead=" + knownToBeDead 1894 + " thread=" + (app != null ? app.thread : null) 1895 + " pid=" + (app != null ? app.pid : -1)); 1896 if (app != null && app.pid > 0) { 1897 if (!knownToBeDead || app.thread == null) { 1898 // We already have the app running, or are waiting for it to 1899 // come up (we have a pid but not yet its thread), so keep it. 1900 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1901 // If this is a new package in the process, add the package to the list 1902 app.addPackage(info.packageName); 1903 return app; 1904 } else { 1905 // An application record is attached to a previous process, 1906 // clean it up now. 1907 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1908 handleAppDiedLocked(app, true, true); 1909 } 1910 } 1911 1912 String hostingNameStr = hostingName != null 1913 ? hostingName.flattenToShortString() : null; 1914 1915 if (!isolated) { 1916 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1917 // If we are in the background, then check to see if this process 1918 // is bad. If so, we will just silently fail. 1919 if (mBadProcesses.get(info.processName, info.uid) != null) { 1920 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1921 + "/" + info.processName); 1922 return null; 1923 } 1924 } else { 1925 // When the user is explicitly starting a process, then clear its 1926 // crash count so that we won't make it bad until they see at 1927 // least one crash dialog again, and make the process good again 1928 // if it had been bad. 1929 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1930 + "/" + info.processName); 1931 mProcessCrashTimes.remove(info.processName, info.uid); 1932 if (mBadProcesses.get(info.processName, info.uid) != null) { 1933 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1934 info.processName); 1935 mBadProcesses.remove(info.processName, info.uid); 1936 if (app != null) { 1937 app.bad = false; 1938 } 1939 } 1940 } 1941 } 1942 1943 if (app == null) { 1944 app = newProcessRecordLocked(null, info, processName, isolated); 1945 if (app == null) { 1946 Slog.w(TAG, "Failed making new process record for " 1947 + processName + "/" + info.uid + " isolated=" + isolated); 1948 return null; 1949 } 1950 mProcessNames.put(processName, app.uid, app); 1951 if (isolated) { 1952 mIsolatedProcesses.put(app.uid, app); 1953 } 1954 } else { 1955 // If this is a new package in the process, add the package to the list 1956 app.addPackage(info.packageName); 1957 } 1958 1959 // If the system is not ready yet, then hold off on starting this 1960 // process until it is. 1961 if (!mProcessesReady 1962 && !isAllowedWhileBooting(info) 1963 && !allowWhileBooting) { 1964 if (!mProcessesOnHold.contains(app)) { 1965 mProcessesOnHold.add(app); 1966 } 1967 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1968 return app; 1969 } 1970 1971 startProcessLocked(app, hostingType, hostingNameStr); 1972 return (app.pid != 0) ? app : null; 1973 } 1974 1975 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1976 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1977 } 1978 1979 private final void startProcessLocked(ProcessRecord app, 1980 String hostingType, String hostingNameStr) { 1981 if (app.pid > 0 && app.pid != MY_PID) { 1982 synchronized (mPidsSelfLocked) { 1983 mPidsSelfLocked.remove(app.pid); 1984 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1985 } 1986 app.setPid(0); 1987 } 1988 1989 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1990 "startProcessLocked removing on hold: " + app); 1991 mProcessesOnHold.remove(app); 1992 1993 updateCpuStats(); 1994 1995 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1996 mProcDeaths[0] = 0; 1997 1998 try { 1999 int uid = app.uid; 2000 2001 int[] gids = null; 2002 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2003 if (!app.isolated) { 2004 try { 2005 final PackageManager pm = mContext.getPackageManager(); 2006 gids = pm.getPackageGids(app.info.packageName); 2007 2008 if (Environment.isExternalStorageEmulated()) { 2009 if (pm.checkPermission( 2010 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2011 app.info.packageName) == PERMISSION_GRANTED) { 2012 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2013 } else { 2014 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2015 } 2016 } 2017 } catch (PackageManager.NameNotFoundException e) { 2018 Slog.w(TAG, "Unable to retrieve gids", e); 2019 } 2020 } 2021 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2022 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2023 && mTopComponent != null 2024 && app.processName.equals(mTopComponent.getPackageName())) { 2025 uid = 0; 2026 } 2027 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2028 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2029 uid = 0; 2030 } 2031 } 2032 int debugFlags = 0; 2033 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2034 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2035 // Also turn on CheckJNI for debuggable apps. It's quite 2036 // awkward to turn on otherwise. 2037 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2038 } 2039 // Run the app in safe mode if its manifest requests so or the 2040 // system is booted in safe mode. 2041 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2042 Zygote.systemInSafeMode == true) { 2043 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2044 } 2045 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2046 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2047 } 2048 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2049 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2050 } 2051 if ("1".equals(SystemProperties.get("debug.assert"))) { 2052 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2053 } 2054 2055 // Start the process. It will either succeed and return a result containing 2056 // the PID of the new process, or else throw a RuntimeException. 2057 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2058 app.processName, uid, uid, gids, debugFlags, mountExternal, 2059 app.info.targetSdkVersion, null, null); 2060 2061 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2062 synchronized (bs) { 2063 if (bs.isOnBattery()) { 2064 app.batteryStats.incStartsLocked(); 2065 } 2066 } 2067 2068 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2069 app.processName, hostingType, 2070 hostingNameStr != null ? hostingNameStr : ""); 2071 2072 if (app.persistent) { 2073 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2074 } 2075 2076 StringBuilder buf = mStringBuilder; 2077 buf.setLength(0); 2078 buf.append("Start proc "); 2079 buf.append(app.processName); 2080 buf.append(" for "); 2081 buf.append(hostingType); 2082 if (hostingNameStr != null) { 2083 buf.append(" "); 2084 buf.append(hostingNameStr); 2085 } 2086 buf.append(": pid="); 2087 buf.append(startResult.pid); 2088 buf.append(" uid="); 2089 buf.append(uid); 2090 buf.append(" gids={"); 2091 if (gids != null) { 2092 for (int gi=0; gi<gids.length; gi++) { 2093 if (gi != 0) buf.append(", "); 2094 buf.append(gids[gi]); 2095 2096 } 2097 } 2098 buf.append("}"); 2099 Slog.i(TAG, buf.toString()); 2100 app.setPid(startResult.pid); 2101 app.usingWrapper = startResult.usingWrapper; 2102 app.removed = false; 2103 synchronized (mPidsSelfLocked) { 2104 this.mPidsSelfLocked.put(startResult.pid, app); 2105 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2106 msg.obj = app; 2107 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2108 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2109 } 2110 } catch (RuntimeException e) { 2111 // XXX do better error recovery. 2112 app.setPid(0); 2113 Slog.e(TAG, "Failure starting process " + app.processName, e); 2114 } 2115 } 2116 2117 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2118 if (resumed) { 2119 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2120 } else { 2121 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2122 } 2123 } 2124 2125 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2126 if (mHeadless) { 2127 // Added because none of the other calls to ensureBootCompleted seem to fire 2128 // when running headless. 2129 ensureBootCompleted(); 2130 return false; 2131 } 2132 2133 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2134 && mTopAction == null) { 2135 // We are running in factory test mode, but unable to find 2136 // the factory test app, so just sit around displaying the 2137 // error message and don't try to start anything. 2138 return false; 2139 } 2140 Intent intent = new Intent( 2141 mTopAction, 2142 mTopData != null ? Uri.parse(mTopData) : null); 2143 intent.setComponent(mTopComponent); 2144 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2145 intent.addCategory(Intent.CATEGORY_HOME); 2146 } 2147 ActivityInfo aInfo = 2148 intent.resolveActivityInfo(mContext.getPackageManager(), 2149 STOCK_PM_FLAGS); 2150 if (aInfo != null) { 2151 intent.setComponent(new ComponentName( 2152 aInfo.applicationInfo.packageName, aInfo.name)); 2153 // Don't do this if the home app is currently being 2154 // instrumented. 2155 aInfo = new ActivityInfo(aInfo); 2156 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2157 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2158 aInfo.applicationInfo.uid); 2159 if (app == null || app.instrumentationClass == null) { 2160 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2161 mMainStack.startActivityLocked(null, intent, null, aInfo, 2162 null, null, 0, 0, 0, 0, null, false, null); 2163 } 2164 } 2165 if (startingUser != null) { 2166 mMainStack.addStartingUserLocked(startingUser); 2167 } 2168 2169 return true; 2170 } 2171 2172 /** 2173 * Starts the "new version setup screen" if appropriate. 2174 */ 2175 void startSetupActivityLocked() { 2176 // Only do this once per boot. 2177 if (mCheckedForSetup) { 2178 return; 2179 } 2180 2181 // We will show this screen if the current one is a different 2182 // version than the last one shown, and we are not running in 2183 // low-level factory test mode. 2184 final ContentResolver resolver = mContext.getContentResolver(); 2185 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2186 Settings.Secure.getInt(resolver, 2187 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2188 mCheckedForSetup = true; 2189 2190 // See if we should be showing the platform update setup UI. 2191 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2192 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2193 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2194 2195 // We don't allow third party apps to replace this. 2196 ResolveInfo ri = null; 2197 for (int i=0; ris != null && i<ris.size(); i++) { 2198 if ((ris.get(i).activityInfo.applicationInfo.flags 2199 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2200 ri = ris.get(i); 2201 break; 2202 } 2203 } 2204 2205 if (ri != null) { 2206 String vers = ri.activityInfo.metaData != null 2207 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2208 : null; 2209 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2210 vers = ri.activityInfo.applicationInfo.metaData.getString( 2211 Intent.METADATA_SETUP_VERSION); 2212 } 2213 String lastVers = Settings.Secure.getString( 2214 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2215 if (vers != null && !vers.equals(lastVers)) { 2216 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2217 intent.setComponent(new ComponentName( 2218 ri.activityInfo.packageName, ri.activityInfo.name)); 2219 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2220 null, null, 0, 0, 0, 0, null, false, null); 2221 } 2222 } 2223 } 2224 } 2225 2226 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2227 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2228 } 2229 2230 void enforceNotIsolatedCaller(String caller) { 2231 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2232 throw new SecurityException("Isolated process not allowed to call " + caller); 2233 } 2234 } 2235 2236 public int getFrontActivityScreenCompatMode() { 2237 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2238 synchronized (this) { 2239 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2240 } 2241 } 2242 2243 public void setFrontActivityScreenCompatMode(int mode) { 2244 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2245 "setFrontActivityScreenCompatMode"); 2246 synchronized (this) { 2247 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2248 } 2249 } 2250 2251 public int getPackageScreenCompatMode(String packageName) { 2252 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2253 synchronized (this) { 2254 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2255 } 2256 } 2257 2258 public void setPackageScreenCompatMode(String packageName, int mode) { 2259 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2260 "setPackageScreenCompatMode"); 2261 synchronized (this) { 2262 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2263 } 2264 } 2265 2266 public boolean getPackageAskScreenCompat(String packageName) { 2267 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2268 synchronized (this) { 2269 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2270 } 2271 } 2272 2273 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2274 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2275 "setPackageAskScreenCompat"); 2276 synchronized (this) { 2277 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2278 } 2279 } 2280 2281 void reportResumedActivityLocked(ActivityRecord r) { 2282 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2283 updateUsageStats(r, true); 2284 } 2285 2286 private void dispatchProcessesChanged() { 2287 int N; 2288 synchronized (this) { 2289 N = mPendingProcessChanges.size(); 2290 if (mActiveProcessChanges.length < N) { 2291 mActiveProcessChanges = new ProcessChangeItem[N]; 2292 } 2293 mPendingProcessChanges.toArray(mActiveProcessChanges); 2294 mAvailProcessChanges.addAll(mPendingProcessChanges); 2295 mPendingProcessChanges.clear(); 2296 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2297 } 2298 int i = mProcessObservers.beginBroadcast(); 2299 while (i > 0) { 2300 i--; 2301 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2302 if (observer != null) { 2303 try { 2304 for (int j=0; j<N; j++) { 2305 ProcessChangeItem item = mActiveProcessChanges[j]; 2306 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2308 + item.pid + " uid=" + item.uid + ": " 2309 + item.foregroundActivities); 2310 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2311 item.foregroundActivities); 2312 } 2313 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2314 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2315 + item.pid + " uid=" + item.uid + ": " + item.importance); 2316 observer.onImportanceChanged(item.pid, item.uid, 2317 item.importance); 2318 } 2319 } 2320 } catch (RemoteException e) { 2321 } 2322 } 2323 } 2324 mProcessObservers.finishBroadcast(); 2325 } 2326 2327 private void dispatchProcessDied(int pid, int uid) { 2328 int i = mProcessObservers.beginBroadcast(); 2329 while (i > 0) { 2330 i--; 2331 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2332 if (observer != null) { 2333 try { 2334 observer.onProcessDied(pid, uid); 2335 } catch (RemoteException e) { 2336 } 2337 } 2338 } 2339 mProcessObservers.finishBroadcast(); 2340 } 2341 2342 final void doPendingActivityLaunchesLocked(boolean doResume) { 2343 final int N = mPendingActivityLaunches.size(); 2344 if (N <= 0) { 2345 return; 2346 } 2347 for (int i=0; i<N; i++) { 2348 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2349 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2350 pal.startFlags, doResume && i == (N-1), null); 2351 } 2352 mPendingActivityLaunches.clear(); 2353 } 2354 2355 public final int startActivity(IApplicationThread caller, 2356 Intent intent, String resolvedType, IBinder resultTo, 2357 String resultWho, int requestCode, int startFlags, 2358 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2359 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2360 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2361 } 2362 2363 public final int startActivityAsUser(IApplicationThread caller, 2364 Intent intent, String resolvedType, IBinder resultTo, 2365 String resultWho, int requestCode, int startFlags, 2366 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2367 enforceNotIsolatedCaller("startActivity"); 2368 if (userId != UserHandle.getCallingUserId()) { 2369 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2370 false, true, "startActivity", null); 2371 } else { 2372 if (intent.getCategories() != null 2373 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2374 // Requesting home, set the identity to the current user 2375 // HACK! 2376 userId = mCurrentUserId; 2377 } 2378 } 2379 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2380 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2381 null, null, options, userId); 2382 } 2383 2384 public final WaitResult startActivityAndWait(IApplicationThread caller, 2385 Intent intent, String resolvedType, IBinder resultTo, 2386 String resultWho, int requestCode, int startFlags, String profileFile, 2387 ParcelFileDescriptor profileFd, Bundle options) { 2388 enforceNotIsolatedCaller("startActivityAndWait"); 2389 WaitResult res = new WaitResult(); 2390 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2391 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2392 res, null, options, UserHandle.getCallingUserId()); 2393 return res; 2394 } 2395 2396 public final int startActivityWithConfig(IApplicationThread caller, 2397 Intent intent, String resolvedType, IBinder resultTo, 2398 String resultWho, int requestCode, int startFlags, Configuration config, 2399 Bundle options, int userId) { 2400 enforceNotIsolatedCaller("startActivityWithConfig"); 2401 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2402 false, true, "startActivityWithConfig", null); 2403 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2404 resultTo, resultWho, requestCode, startFlags, 2405 null, null, null, config, options, userId); 2406 return ret; 2407 } 2408 2409 public int startActivityIntentSender(IApplicationThread caller, 2410 IntentSender intent, Intent fillInIntent, String resolvedType, 2411 IBinder resultTo, String resultWho, int requestCode, 2412 int flagsMask, int flagsValues, Bundle options) { 2413 enforceNotIsolatedCaller("startActivityIntentSender"); 2414 // Refuse possible leaked file descriptors 2415 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2416 throw new IllegalArgumentException("File descriptors passed in Intent"); 2417 } 2418 2419 IIntentSender sender = intent.getTarget(); 2420 if (!(sender instanceof PendingIntentRecord)) { 2421 throw new IllegalArgumentException("Bad PendingIntent object"); 2422 } 2423 2424 PendingIntentRecord pir = (PendingIntentRecord)sender; 2425 2426 synchronized (this) { 2427 // If this is coming from the currently resumed activity, it is 2428 // effectively saying that app switches are allowed at this point. 2429 if (mMainStack.mResumedActivity != null 2430 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2431 Binder.getCallingUid()) { 2432 mAppSwitchesAllowedTime = 0; 2433 } 2434 } 2435 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2436 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2437 return ret; 2438 } 2439 2440 public boolean startNextMatchingActivity(IBinder callingActivity, 2441 Intent intent, Bundle options) { 2442 // Refuse possible leaked file descriptors 2443 if (intent != null && intent.hasFileDescriptors() == true) { 2444 throw new IllegalArgumentException("File descriptors passed in Intent"); 2445 } 2446 2447 synchronized (this) { 2448 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2449 if (r == null) { 2450 ActivityOptions.abort(options); 2451 return false; 2452 } 2453 if (r.app == null || r.app.thread == null) { 2454 // The caller is not running... d'oh! 2455 ActivityOptions.abort(options); 2456 return false; 2457 } 2458 intent = new Intent(intent); 2459 // The caller is not allowed to change the data. 2460 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2461 // And we are resetting to find the next component... 2462 intent.setComponent(null); 2463 2464 ActivityInfo aInfo = null; 2465 try { 2466 List<ResolveInfo> resolves = 2467 AppGlobals.getPackageManager().queryIntentActivities( 2468 intent, r.resolvedType, 2469 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2470 UserHandle.getCallingUserId()); 2471 2472 // Look for the original activity in the list... 2473 final int N = resolves != null ? resolves.size() : 0; 2474 for (int i=0; i<N; i++) { 2475 ResolveInfo rInfo = resolves.get(i); 2476 if (rInfo.activityInfo.packageName.equals(r.packageName) 2477 && rInfo.activityInfo.name.equals(r.info.name)) { 2478 // We found the current one... the next matching is 2479 // after it. 2480 i++; 2481 if (i<N) { 2482 aInfo = resolves.get(i).activityInfo; 2483 } 2484 break; 2485 } 2486 } 2487 } catch (RemoteException e) { 2488 } 2489 2490 if (aInfo == null) { 2491 // Nobody who is next! 2492 ActivityOptions.abort(options); 2493 return false; 2494 } 2495 2496 intent.setComponent(new ComponentName( 2497 aInfo.applicationInfo.packageName, aInfo.name)); 2498 intent.setFlags(intent.getFlags()&~( 2499 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2500 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2501 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2502 Intent.FLAG_ACTIVITY_NEW_TASK)); 2503 2504 // Okay now we need to start the new activity, replacing the 2505 // currently running activity. This is a little tricky because 2506 // we want to start the new one as if the current one is finished, 2507 // but not finish the current one first so that there is no flicker. 2508 // And thus... 2509 final boolean wasFinishing = r.finishing; 2510 r.finishing = true; 2511 2512 // Propagate reply information over to the new activity. 2513 final ActivityRecord resultTo = r.resultTo; 2514 final String resultWho = r.resultWho; 2515 final int requestCode = r.requestCode; 2516 r.resultTo = null; 2517 if (resultTo != null) { 2518 resultTo.removeResultsLocked(r, resultWho, requestCode); 2519 } 2520 2521 final long origId = Binder.clearCallingIdentity(); 2522 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2523 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2524 resultWho, requestCode, -1, r.launchedFromUid, 0, 2525 options, false, null); 2526 Binder.restoreCallingIdentity(origId); 2527 2528 r.finishing = wasFinishing; 2529 if (res != ActivityManager.START_SUCCESS) { 2530 return false; 2531 } 2532 return true; 2533 } 2534 } 2535 2536 final int startActivityInPackage(int uid, 2537 Intent intent, String resolvedType, IBinder resultTo, 2538 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2539 2540 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2541 false, true, "startActivityInPackage", null); 2542 2543 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2544 resultTo, resultWho, requestCode, startFlags, 2545 null, null, null, null, options, userId); 2546 return ret; 2547 } 2548 2549 public final int startActivities(IApplicationThread caller, 2550 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2551 enforceNotIsolatedCaller("startActivities"); 2552 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2553 options, UserHandle.getCallingUserId()); 2554 return ret; 2555 } 2556 2557 final int startActivitiesInPackage(int uid, 2558 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2559 Bundle options, int userId) { 2560 2561 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2562 false, true, "startActivityInPackage", null); 2563 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2564 options, userId); 2565 return ret; 2566 } 2567 2568 final void addRecentTaskLocked(TaskRecord task) { 2569 int N = mRecentTasks.size(); 2570 // Quick case: check if the top-most recent task is the same. 2571 if (N > 0 && mRecentTasks.get(0) == task) { 2572 return; 2573 } 2574 // Remove any existing entries that are the same kind of task. 2575 for (int i=0; i<N; i++) { 2576 TaskRecord tr = mRecentTasks.get(i); 2577 if (task.userId == tr.userId 2578 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2579 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2580 mRecentTasks.remove(i); 2581 i--; 2582 N--; 2583 if (task.intent == null) { 2584 // If the new recent task we are adding is not fully 2585 // specified, then replace it with the existing recent task. 2586 task = tr; 2587 } 2588 } 2589 } 2590 if (N >= MAX_RECENT_TASKS) { 2591 mRecentTasks.remove(N-1); 2592 } 2593 mRecentTasks.add(0, task); 2594 } 2595 2596 public void setRequestedOrientation(IBinder token, 2597 int requestedOrientation) { 2598 synchronized (this) { 2599 ActivityRecord r = mMainStack.isInStackLocked(token); 2600 if (r == null) { 2601 return; 2602 } 2603 final long origId = Binder.clearCallingIdentity(); 2604 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2605 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2606 mConfiguration, 2607 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2608 if (config != null) { 2609 r.frozenBeforeDestroy = true; 2610 if (!updateConfigurationLocked(config, r, false, false)) { 2611 mMainStack.resumeTopActivityLocked(null); 2612 } 2613 } 2614 Binder.restoreCallingIdentity(origId); 2615 } 2616 } 2617 2618 public int getRequestedOrientation(IBinder token) { 2619 synchronized (this) { 2620 ActivityRecord r = mMainStack.isInStackLocked(token); 2621 if (r == null) { 2622 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2623 } 2624 return mWindowManager.getAppOrientation(r.appToken); 2625 } 2626 } 2627 2628 /** 2629 * This is the internal entry point for handling Activity.finish(). 2630 * 2631 * @param token The Binder token referencing the Activity we want to finish. 2632 * @param resultCode Result code, if any, from this Activity. 2633 * @param resultData Result data (Intent), if any, from this Activity. 2634 * 2635 * @return Returns true if the activity successfully finished, or false if it is still running. 2636 */ 2637 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2638 // Refuse possible leaked file descriptors 2639 if (resultData != null && resultData.hasFileDescriptors() == true) { 2640 throw new IllegalArgumentException("File descriptors passed in Intent"); 2641 } 2642 2643 synchronized(this) { 2644 if (mController != null) { 2645 // Find the first activity that is not finishing. 2646 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2647 if (next != null) { 2648 // ask watcher if this is allowed 2649 boolean resumeOK = true; 2650 try { 2651 resumeOK = mController.activityResuming(next.packageName); 2652 } catch (RemoteException e) { 2653 mController = null; 2654 } 2655 2656 if (!resumeOK) { 2657 return false; 2658 } 2659 } 2660 } 2661 final long origId = Binder.clearCallingIdentity(); 2662 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2663 resultData, "app-request"); 2664 Binder.restoreCallingIdentity(origId); 2665 return res; 2666 } 2667 } 2668 2669 public final void finishHeavyWeightApp() { 2670 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2671 != PackageManager.PERMISSION_GRANTED) { 2672 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2673 + Binder.getCallingPid() 2674 + ", uid=" + Binder.getCallingUid() 2675 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2676 Slog.w(TAG, msg); 2677 throw new SecurityException(msg); 2678 } 2679 2680 synchronized(this) { 2681 if (mHeavyWeightProcess == null) { 2682 return; 2683 } 2684 2685 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2686 mHeavyWeightProcess.activities); 2687 for (int i=0; i<activities.size(); i++) { 2688 ActivityRecord r = activities.get(i); 2689 if (!r.finishing) { 2690 int index = mMainStack.indexOfTokenLocked(r.appToken); 2691 if (index >= 0) { 2692 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2693 null, "finish-heavy"); 2694 } 2695 } 2696 } 2697 2698 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2699 mHeavyWeightProcess.userId, 0)); 2700 mHeavyWeightProcess = null; 2701 } 2702 } 2703 2704 public void crashApplication(int uid, int initialPid, String packageName, 2705 String message) { 2706 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2707 != PackageManager.PERMISSION_GRANTED) { 2708 String msg = "Permission Denial: crashApplication() from pid=" 2709 + Binder.getCallingPid() 2710 + ", uid=" + Binder.getCallingUid() 2711 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2712 Slog.w(TAG, msg); 2713 throw new SecurityException(msg); 2714 } 2715 2716 synchronized(this) { 2717 ProcessRecord proc = null; 2718 2719 // Figure out which process to kill. We don't trust that initialPid 2720 // still has any relation to current pids, so must scan through the 2721 // list. 2722 synchronized (mPidsSelfLocked) { 2723 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2724 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2725 if (p.uid != uid) { 2726 continue; 2727 } 2728 if (p.pid == initialPid) { 2729 proc = p; 2730 break; 2731 } 2732 for (String str : p.pkgList) { 2733 if (str.equals(packageName)) { 2734 proc = p; 2735 } 2736 } 2737 } 2738 } 2739 2740 if (proc == null) { 2741 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2742 + " initialPid=" + initialPid 2743 + " packageName=" + packageName); 2744 return; 2745 } 2746 2747 if (proc.thread != null) { 2748 if (proc.pid == Process.myPid()) { 2749 Log.w(TAG, "crashApplication: trying to crash self!"); 2750 return; 2751 } 2752 long ident = Binder.clearCallingIdentity(); 2753 try { 2754 proc.thread.scheduleCrash(message); 2755 } catch (RemoteException e) { 2756 } 2757 Binder.restoreCallingIdentity(ident); 2758 } 2759 } 2760 } 2761 2762 public final void finishSubActivity(IBinder token, String resultWho, 2763 int requestCode) { 2764 synchronized(this) { 2765 final long origId = Binder.clearCallingIdentity(); 2766 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2767 Binder.restoreCallingIdentity(origId); 2768 } 2769 } 2770 2771 public boolean finishActivityAffinity(IBinder token) { 2772 synchronized(this) { 2773 final long origId = Binder.clearCallingIdentity(); 2774 boolean res = mMainStack.finishActivityAffinityLocked(token); 2775 Binder.restoreCallingIdentity(origId); 2776 return res; 2777 } 2778 } 2779 2780 public boolean willActivityBeVisible(IBinder token) { 2781 synchronized(this) { 2782 int i; 2783 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2784 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2785 if (r.appToken == token) { 2786 return true; 2787 } 2788 if (r.fullscreen && !r.finishing) { 2789 return false; 2790 } 2791 } 2792 return true; 2793 } 2794 } 2795 2796 public void overridePendingTransition(IBinder token, String packageName, 2797 int enterAnim, int exitAnim) { 2798 synchronized(this) { 2799 ActivityRecord self = mMainStack.isInStackLocked(token); 2800 if (self == null) { 2801 return; 2802 } 2803 2804 final long origId = Binder.clearCallingIdentity(); 2805 2806 if (self.state == ActivityState.RESUMED 2807 || self.state == ActivityState.PAUSING) { 2808 mWindowManager.overridePendingAppTransition(packageName, 2809 enterAnim, exitAnim, null); 2810 } 2811 2812 Binder.restoreCallingIdentity(origId); 2813 } 2814 } 2815 2816 /** 2817 * Main function for removing an existing process from the activity manager 2818 * as a result of that process going away. Clears out all connections 2819 * to the process. 2820 */ 2821 private final void handleAppDiedLocked(ProcessRecord app, 2822 boolean restarting, boolean allowRestart) { 2823 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2824 if (!restarting) { 2825 mLruProcesses.remove(app); 2826 } 2827 2828 if (mProfileProc == app) { 2829 clearProfilerLocked(); 2830 } 2831 2832 // Just in case... 2833 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2834 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2835 mMainStack.mPausingActivity = null; 2836 } 2837 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2838 mMainStack.mLastPausedActivity = null; 2839 } 2840 2841 // Remove this application's activities from active lists. 2842 mMainStack.removeHistoryRecordsForAppLocked(app); 2843 2844 boolean atTop = true; 2845 boolean hasVisibleActivities = false; 2846 2847 // Clean out the history list. 2848 int i = mMainStack.mHistory.size(); 2849 if (localLOGV) Slog.v( 2850 TAG, "Removing app " + app + " from history with " + i + " entries"); 2851 while (i > 0) { 2852 i--; 2853 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2854 if (localLOGV) Slog.v( 2855 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2856 if (r.app == app) { 2857 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2858 if (ActivityStack.DEBUG_ADD_REMOVE) { 2859 RuntimeException here = new RuntimeException("here"); 2860 here.fillInStackTrace(); 2861 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2862 + ": haveState=" + r.haveState 2863 + " stateNotNeeded=" + r.stateNotNeeded 2864 + " finishing=" + r.finishing 2865 + " state=" + r.state, here); 2866 } 2867 if (!r.finishing) { 2868 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2869 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2870 System.identityHashCode(r), 2871 r.task.taskId, r.shortComponentName, 2872 "proc died without state saved"); 2873 } 2874 mMainStack.removeActivityFromHistoryLocked(r); 2875 2876 } else { 2877 // We have the current state for this activity, so 2878 // it can be restarted later when needed. 2879 if (localLOGV) Slog.v( 2880 TAG, "Keeping entry, setting app to null"); 2881 if (r.visible) { 2882 hasVisibleActivities = true; 2883 } 2884 r.app = null; 2885 r.nowVisible = false; 2886 if (!r.haveState) { 2887 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2888 "App died, clearing saved state of " + r); 2889 r.icicle = null; 2890 } 2891 } 2892 2893 r.stack.cleanUpActivityLocked(r, true, true); 2894 } 2895 atTop = false; 2896 } 2897 2898 app.activities.clear(); 2899 2900 if (app.instrumentationClass != null) { 2901 Slog.w(TAG, "Crash of app " + app.processName 2902 + " running instrumentation " + app.instrumentationClass); 2903 Bundle info = new Bundle(); 2904 info.putString("shortMsg", "Process crashed."); 2905 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2906 } 2907 2908 if (!restarting) { 2909 if (!mMainStack.resumeTopActivityLocked(null)) { 2910 // If there was nothing to resume, and we are not already 2911 // restarting this process, but there is a visible activity that 2912 // is hosted by the process... then make sure all visible 2913 // activities are running, taking care of restarting this 2914 // process. 2915 if (hasVisibleActivities) { 2916 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2917 } 2918 } 2919 } 2920 } 2921 2922 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2923 IBinder threadBinder = thread.asBinder(); 2924 // Find the application record. 2925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2926 ProcessRecord rec = mLruProcesses.get(i); 2927 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2928 return i; 2929 } 2930 } 2931 return -1; 2932 } 2933 2934 final ProcessRecord getRecordForAppLocked( 2935 IApplicationThread thread) { 2936 if (thread == null) { 2937 return null; 2938 } 2939 2940 int appIndex = getLRURecordIndexForAppLocked(thread); 2941 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2942 } 2943 2944 final void appDiedLocked(ProcessRecord app, int pid, 2945 IApplicationThread thread) { 2946 2947 mProcDeaths[0]++; 2948 2949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2950 synchronized (stats) { 2951 stats.noteProcessDiedLocked(app.info.uid, pid); 2952 } 2953 2954 // Clean up already done if the process has been re-started. 2955 if (app.pid == pid && app.thread != null && 2956 app.thread.asBinder() == thread.asBinder()) { 2957 if (!app.killedBackground) { 2958 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2959 + ") has died."); 2960 } 2961 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2962 if (localLOGV) Slog.v( 2963 TAG, "Dying app: " + app + ", pid: " + pid 2964 + ", thread: " + thread.asBinder()); 2965 boolean doLowMem = app.instrumentationClass == null; 2966 handleAppDiedLocked(app, false, true); 2967 2968 if (doLowMem) { 2969 // If there are no longer any background processes running, 2970 // and the app that died was not running instrumentation, 2971 // then tell everyone we are now low on memory. 2972 boolean haveBg = false; 2973 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2974 ProcessRecord rec = mLruProcesses.get(i); 2975 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2976 haveBg = true; 2977 break; 2978 } 2979 } 2980 2981 if (!haveBg) { 2982 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2983 long now = SystemClock.uptimeMillis(); 2984 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2985 ProcessRecord rec = mLruProcesses.get(i); 2986 if (rec != app && rec.thread != null && 2987 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2988 // The low memory report is overriding any current 2989 // state for a GC request. Make sure to do 2990 // heavy/important/visible/foreground processes first. 2991 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2992 rec.lastRequestedGc = 0; 2993 } else { 2994 rec.lastRequestedGc = rec.lastLowMemory; 2995 } 2996 rec.reportLowMemory = true; 2997 rec.lastLowMemory = now; 2998 mProcessesToGc.remove(rec); 2999 addProcessToGcListLocked(rec); 3000 } 3001 } 3002 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3003 scheduleAppGcsLocked(); 3004 } 3005 } 3006 } else if (app.pid != pid) { 3007 // A new process has already been started. 3008 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3009 + ") has died and restarted (pid " + app.pid + ")."); 3010 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3011 } else if (DEBUG_PROCESSES) { 3012 Slog.d(TAG, "Received spurious death notification for thread " 3013 + thread.asBinder()); 3014 } 3015 } 3016 3017 /** 3018 * If a stack trace dump file is configured, dump process stack traces. 3019 * @param clearTraces causes the dump file to be erased prior to the new 3020 * traces being written, if true; when false, the new traces will be 3021 * appended to any existing file content. 3022 * @param firstPids of dalvik VM processes to dump stack traces for first 3023 * @param lastPids of dalvik VM processes to dump stack traces for last 3024 * @param nativeProcs optional list of native process names to dump stack crawls 3025 * @return file containing stack traces, or null if no dump file is configured 3026 */ 3027 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3028 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3029 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3030 if (tracesPath == null || tracesPath.length() == 0) { 3031 return null; 3032 } 3033 3034 File tracesFile = new File(tracesPath); 3035 try { 3036 File tracesDir = tracesFile.getParentFile(); 3037 if (!tracesDir.exists()) { 3038 tracesFile.mkdirs(); 3039 if (!SELinux.restorecon(tracesDir)) { 3040 return null; 3041 } 3042 } 3043 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3044 3045 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3046 tracesFile.createNewFile(); 3047 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3048 } catch (IOException e) { 3049 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3050 return null; 3051 } 3052 3053 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3054 return tracesFile; 3055 } 3056 3057 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3058 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3059 // Use a FileObserver to detect when traces finish writing. 3060 // The order of traces is considered important to maintain for legibility. 3061 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3062 public synchronized void onEvent(int event, String path) { notify(); } 3063 }; 3064 3065 try { 3066 observer.startWatching(); 3067 3068 // First collect all of the stacks of the most important pids. 3069 if (firstPids != null) { 3070 try { 3071 int num = firstPids.size(); 3072 for (int i = 0; i < num; i++) { 3073 synchronized (observer) { 3074 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3075 observer.wait(200); // Wait for write-close, give up after 200msec 3076 } 3077 } 3078 } catch (InterruptedException e) { 3079 Log.wtf(TAG, e); 3080 } 3081 } 3082 3083 // Next measure CPU usage. 3084 if (processStats != null) { 3085 processStats.init(); 3086 System.gc(); 3087 processStats.update(); 3088 try { 3089 synchronized (processStats) { 3090 processStats.wait(500); // measure over 1/2 second. 3091 } 3092 } catch (InterruptedException e) { 3093 } 3094 processStats.update(); 3095 3096 // We'll take the stack crawls of just the top apps using CPU. 3097 final int N = processStats.countWorkingStats(); 3098 int numProcs = 0; 3099 for (int i=0; i<N && numProcs<5; i++) { 3100 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3101 if (lastPids.indexOfKey(stats.pid) >= 0) { 3102 numProcs++; 3103 try { 3104 synchronized (observer) { 3105 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3106 observer.wait(200); // Wait for write-close, give up after 200msec 3107 } 3108 } catch (InterruptedException e) { 3109 Log.wtf(TAG, e); 3110 } 3111 3112 } 3113 } 3114 } 3115 3116 } finally { 3117 observer.stopWatching(); 3118 } 3119 3120 if (nativeProcs != null) { 3121 int[] pids = Process.getPidsForCommands(nativeProcs); 3122 if (pids != null) { 3123 for (int pid : pids) { 3124 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3125 } 3126 } 3127 } 3128 } 3129 3130 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3131 if (true || IS_USER_BUILD) { 3132 return; 3133 } 3134 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3135 if (tracesPath == null || tracesPath.length() == 0) { 3136 return; 3137 } 3138 3139 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3140 StrictMode.allowThreadDiskWrites(); 3141 try { 3142 final File tracesFile = new File(tracesPath); 3143 final File tracesDir = tracesFile.getParentFile(); 3144 final File tracesTmp = new File(tracesDir, "__tmp__"); 3145 try { 3146 if (!tracesDir.exists()) { 3147 tracesFile.mkdirs(); 3148 if (!SELinux.restorecon(tracesDir.getPath())) { 3149 return; 3150 } 3151 } 3152 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3153 3154 if (tracesFile.exists()) { 3155 tracesTmp.delete(); 3156 tracesFile.renameTo(tracesTmp); 3157 } 3158 StringBuilder sb = new StringBuilder(); 3159 Time tobj = new Time(); 3160 tobj.set(System.currentTimeMillis()); 3161 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3162 sb.append(": "); 3163 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3164 sb.append(" since "); 3165 sb.append(msg); 3166 FileOutputStream fos = new FileOutputStream(tracesFile); 3167 fos.write(sb.toString().getBytes()); 3168 if (app == null) { 3169 fos.write("\n*** No application process!".getBytes()); 3170 } 3171 fos.close(); 3172 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3173 } catch (IOException e) { 3174 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3175 return; 3176 } 3177 3178 if (app != null) { 3179 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3180 firstPids.add(app.pid); 3181 dumpStackTraces(tracesPath, firstPids, null, null, null); 3182 } 3183 3184 File lastTracesFile = null; 3185 File curTracesFile = null; 3186 for (int i=9; i>=0; i--) { 3187 String name = String.format("slow%02d.txt", i); 3188 curTracesFile = new File(tracesDir, name); 3189 if (curTracesFile.exists()) { 3190 if (lastTracesFile != null) { 3191 curTracesFile.renameTo(lastTracesFile); 3192 } else { 3193 curTracesFile.delete(); 3194 } 3195 } 3196 lastTracesFile = curTracesFile; 3197 } 3198 tracesFile.renameTo(curTracesFile); 3199 if (tracesTmp.exists()) { 3200 tracesTmp.renameTo(tracesFile); 3201 } 3202 } finally { 3203 StrictMode.setThreadPolicy(oldPolicy); 3204 } 3205 } 3206 3207 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3208 ActivityRecord parent, final String annotation) { 3209 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3210 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3211 3212 if (mController != null) { 3213 try { 3214 // 0 == continue, -1 = kill process immediately 3215 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3216 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3217 } catch (RemoteException e) { 3218 mController = null; 3219 } 3220 } 3221 3222 long anrTime = SystemClock.uptimeMillis(); 3223 if (MONITOR_CPU_USAGE) { 3224 updateCpuStatsNow(); 3225 } 3226 3227 synchronized (this) { 3228 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3229 if (mShuttingDown) { 3230 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3231 return; 3232 } else if (app.notResponding) { 3233 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3234 return; 3235 } else if (app.crashing) { 3236 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3237 return; 3238 } 3239 3240 // In case we come through here for the same app before completing 3241 // this one, mark as anring now so we will bail out. 3242 app.notResponding = true; 3243 3244 // Log the ANR to the event log. 3245 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3246 annotation); 3247 3248 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3249 firstPids.add(app.pid); 3250 3251 int parentPid = app.pid; 3252 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3253 if (parentPid != app.pid) firstPids.add(parentPid); 3254 3255 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3256 3257 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3258 ProcessRecord r = mLruProcesses.get(i); 3259 if (r != null && r.thread != null) { 3260 int pid = r.pid; 3261 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3262 if (r.persistent) { 3263 firstPids.add(pid); 3264 } else { 3265 lastPids.put(pid, Boolean.TRUE); 3266 } 3267 } 3268 } 3269 } 3270 } 3271 3272 // Log the ANR to the main log. 3273 StringBuilder info = new StringBuilder(); 3274 info.setLength(0); 3275 info.append("ANR in ").append(app.processName); 3276 if (activity != null && activity.shortComponentName != null) { 3277 info.append(" (").append(activity.shortComponentName).append(")"); 3278 } 3279 info.append("\n"); 3280 if (annotation != null) { 3281 info.append("Reason: ").append(annotation).append("\n"); 3282 } 3283 if (parent != null && parent != activity) { 3284 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3285 } 3286 3287 final ProcessStats processStats = new ProcessStats(true); 3288 3289 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3290 3291 String cpuInfo = null; 3292 if (MONITOR_CPU_USAGE) { 3293 updateCpuStatsNow(); 3294 synchronized (mProcessStatsThread) { 3295 cpuInfo = mProcessStats.printCurrentState(anrTime); 3296 } 3297 info.append(processStats.printCurrentLoad()); 3298 info.append(cpuInfo); 3299 } 3300 3301 info.append(processStats.printCurrentState(anrTime)); 3302 3303 Slog.e(TAG, info.toString()); 3304 if (tracesFile == null) { 3305 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3306 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3307 } 3308 3309 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3310 cpuInfo, tracesFile, null); 3311 3312 if (mController != null) { 3313 try { 3314 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3315 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3316 if (res != 0) { 3317 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3318 return; 3319 } 3320 } catch (RemoteException e) { 3321 mController = null; 3322 } 3323 } 3324 3325 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3326 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3327 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3328 3329 synchronized (this) { 3330 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3331 Slog.w(TAG, "Killing " + app + ": background ANR"); 3332 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3333 app.processName, app.setAdj, "background ANR"); 3334 Process.killProcessQuiet(app.pid); 3335 return; 3336 } 3337 3338 // Set the app's notResponding state, and look up the errorReportReceiver 3339 makeAppNotRespondingLocked(app, 3340 activity != null ? activity.shortComponentName : null, 3341 annotation != null ? "ANR " + annotation : "ANR", 3342 info.toString()); 3343 3344 // Bring up the infamous App Not Responding dialog 3345 Message msg = Message.obtain(); 3346 HashMap map = new HashMap(); 3347 msg.what = SHOW_NOT_RESPONDING_MSG; 3348 msg.obj = map; 3349 map.put("app", app); 3350 if (activity != null) { 3351 map.put("activity", activity); 3352 } 3353 3354 mHandler.sendMessage(msg); 3355 } 3356 } 3357 3358 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3359 if (!mLaunchWarningShown) { 3360 mLaunchWarningShown = true; 3361 mHandler.post(new Runnable() { 3362 @Override 3363 public void run() { 3364 synchronized (ActivityManagerService.this) { 3365 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3366 d.show(); 3367 mHandler.postDelayed(new Runnable() { 3368 @Override 3369 public void run() { 3370 synchronized (ActivityManagerService.this) { 3371 d.dismiss(); 3372 mLaunchWarningShown = false; 3373 } 3374 } 3375 }, 4000); 3376 } 3377 } 3378 }); 3379 } 3380 } 3381 3382 public boolean clearApplicationUserData(final String packageName, 3383 final IPackageDataObserver observer, final int userId) { 3384 enforceNotIsolatedCaller("clearApplicationUserData"); 3385 int uid = Binder.getCallingUid(); 3386 int pid = Binder.getCallingPid(); 3387 long callingId = Binder.clearCallingIdentity(); 3388 try { 3389 IPackageManager pm = AppGlobals.getPackageManager(); 3390 int pkgUid = -1; 3391 synchronized(this) { 3392 try { 3393 pkgUid = pm.getPackageUid(packageName, userId); 3394 } catch (RemoteException e) { 3395 } 3396 if (pkgUid == -1) { 3397 Slog.w(TAG, "Invalid packageName:" + packageName); 3398 return false; 3399 } 3400 if (uid == pkgUid || checkComponentPermission( 3401 android.Manifest.permission.CLEAR_APP_USER_DATA, 3402 pid, uid, -1, true) 3403 == PackageManager.PERMISSION_GRANTED) { 3404 forceStopPackageLocked(packageName, pkgUid); 3405 } else { 3406 throw new SecurityException(pid+" does not have permission:"+ 3407 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3408 "for process:"+packageName); 3409 } 3410 } 3411 3412 try { 3413 //clear application user data 3414 pm.clearApplicationUserData(packageName, observer, userId); 3415 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3416 Uri.fromParts("package", packageName, null)); 3417 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3418 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3419 null, null, 0, null, null, null, false, false, userId); 3420 } catch (RemoteException e) { 3421 } 3422 } finally { 3423 Binder.restoreCallingIdentity(callingId); 3424 } 3425 return true; 3426 } 3427 3428 public void killBackgroundProcesses(final String packageName) { 3429 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3430 != PackageManager.PERMISSION_GRANTED && 3431 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3432 != PackageManager.PERMISSION_GRANTED) { 3433 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3434 + Binder.getCallingPid() 3435 + ", uid=" + Binder.getCallingUid() 3436 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3437 Slog.w(TAG, msg); 3438 throw new SecurityException(msg); 3439 } 3440 3441 int userId = UserHandle.getCallingUserId(); 3442 long callingId = Binder.clearCallingIdentity(); 3443 try { 3444 IPackageManager pm = AppGlobals.getPackageManager(); 3445 int pkgUid = -1; 3446 synchronized(this) { 3447 try { 3448 pkgUid = pm.getPackageUid(packageName, userId); 3449 } catch (RemoteException e) { 3450 } 3451 if (pkgUid == -1) { 3452 Slog.w(TAG, "Invalid packageName: " + packageName); 3453 return; 3454 } 3455 killPackageProcessesLocked(packageName, pkgUid, -1, 3456 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3457 } 3458 } finally { 3459 Binder.restoreCallingIdentity(callingId); 3460 } 3461 } 3462 3463 public void killAllBackgroundProcesses() { 3464 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3465 != PackageManager.PERMISSION_GRANTED) { 3466 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3467 + Binder.getCallingPid() 3468 + ", uid=" + Binder.getCallingUid() 3469 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3470 Slog.w(TAG, msg); 3471 throw new SecurityException(msg); 3472 } 3473 3474 long callingId = Binder.clearCallingIdentity(); 3475 try { 3476 synchronized(this) { 3477 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3478 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3479 final int NA = apps.size(); 3480 for (int ia=0; ia<NA; ia++) { 3481 ProcessRecord app = apps.valueAt(ia); 3482 if (app.persistent) { 3483 // we don't kill persistent processes 3484 continue; 3485 } 3486 if (app.removed) { 3487 procs.add(app); 3488 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3489 app.removed = true; 3490 procs.add(app); 3491 } 3492 } 3493 } 3494 3495 int N = procs.size(); 3496 for (int i=0; i<N; i++) { 3497 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3498 } 3499 } 3500 } finally { 3501 Binder.restoreCallingIdentity(callingId); 3502 } 3503 } 3504 3505 public void forceStopPackage(final String packageName) { 3506 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3507 != PackageManager.PERMISSION_GRANTED) { 3508 String msg = "Permission Denial: forceStopPackage() from pid=" 3509 + Binder.getCallingPid() 3510 + ", uid=" + Binder.getCallingUid() 3511 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3512 Slog.w(TAG, msg); 3513 throw new SecurityException(msg); 3514 } 3515 final int userId = UserHandle.getCallingUserId(); 3516 long callingId = Binder.clearCallingIdentity(); 3517 try { 3518 IPackageManager pm = AppGlobals.getPackageManager(); 3519 int pkgUid = -1; 3520 synchronized(this) { 3521 try { 3522 pkgUid = pm.getPackageUid(packageName, userId); 3523 } catch (RemoteException e) { 3524 } 3525 if (pkgUid == -1) { 3526 Slog.w(TAG, "Invalid packageName: " + packageName); 3527 return; 3528 } 3529 forceStopPackageLocked(packageName, pkgUid); 3530 try { 3531 pm.setPackageStoppedState(packageName, true, userId); 3532 } catch (RemoteException e) { 3533 } catch (IllegalArgumentException e) { 3534 Slog.w(TAG, "Failed trying to unstop package " 3535 + packageName + ": " + e); 3536 } 3537 } 3538 } finally { 3539 Binder.restoreCallingIdentity(callingId); 3540 } 3541 } 3542 3543 /* 3544 * The pkg name and uid have to be specified. 3545 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3546 */ 3547 public void killApplicationWithUid(String pkg, int uid) { 3548 if (pkg == null) { 3549 return; 3550 } 3551 // Make sure the uid is valid. 3552 if (uid < 0) { 3553 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3554 return; 3555 } 3556 int callerUid = Binder.getCallingUid(); 3557 // Only the system server can kill an application 3558 if (callerUid == Process.SYSTEM_UID) { 3559 // Post an aysnc message to kill the application 3560 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3561 msg.arg1 = uid; 3562 msg.arg2 = 0; 3563 msg.obj = pkg; 3564 mHandler.sendMessage(msg); 3565 } else { 3566 throw new SecurityException(callerUid + " cannot kill pkg: " + 3567 pkg); 3568 } 3569 } 3570 3571 public void closeSystemDialogs(String reason) { 3572 enforceNotIsolatedCaller("closeSystemDialogs"); 3573 3574 final int uid = Binder.getCallingUid(); 3575 final long origId = Binder.clearCallingIdentity(); 3576 synchronized (this) { 3577 closeSystemDialogsLocked(uid, reason); 3578 } 3579 Binder.restoreCallingIdentity(origId); 3580 } 3581 3582 void closeSystemDialogsLocked(int callingUid, String reason) { 3583 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3585 if (reason != null) { 3586 intent.putExtra("reason", reason); 3587 } 3588 mWindowManager.closeSystemDialogs(reason); 3589 3590 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3591 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3592 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3593 r.stack.finishActivityLocked(r, i, 3594 Activity.RESULT_CANCELED, null, "close-sys"); 3595 } 3596 } 3597 3598 final long origId = Binder.clearCallingIdentity(); 3599 try { 3600 broadcastIntentLocked(null, null, intent, null, 3601 null, 0, null, null, null, false, false, -1, 3602 callingUid, UserHandle.USER_ALL); 3603 } finally { 3604 Binder.restoreCallingIdentity(origId); 3605 } 3606 } 3607 3608 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3609 throws RemoteException { 3610 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3611 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3612 for (int i=pids.length-1; i>=0; i--) { 3613 infos[i] = new Debug.MemoryInfo(); 3614 Debug.getMemoryInfo(pids[i], infos[i]); 3615 } 3616 return infos; 3617 } 3618 3619 public long[] getProcessPss(int[] pids) throws RemoteException { 3620 enforceNotIsolatedCaller("getProcessPss"); 3621 long[] pss = new long[pids.length]; 3622 for (int i=pids.length-1; i>=0; i--) { 3623 pss[i] = Debug.getPss(pids[i]); 3624 } 3625 return pss; 3626 } 3627 3628 public void killApplicationProcess(String processName, int uid) { 3629 if (processName == null) { 3630 return; 3631 } 3632 3633 int callerUid = Binder.getCallingUid(); 3634 // Only the system server can kill an application 3635 if (callerUid == Process.SYSTEM_UID) { 3636 synchronized (this) { 3637 ProcessRecord app = getProcessRecordLocked(processName, uid); 3638 if (app != null && app.thread != null) { 3639 try { 3640 app.thread.scheduleSuicide(); 3641 } catch (RemoteException e) { 3642 // If the other end already died, then our work here is done. 3643 } 3644 } else { 3645 Slog.w(TAG, "Process/uid not found attempting kill of " 3646 + processName + " / " + uid); 3647 } 3648 } 3649 } else { 3650 throw new SecurityException(callerUid + " cannot kill app process: " + 3651 processName); 3652 } 3653 } 3654 3655 private void forceStopPackageLocked(final String packageName, int uid) { 3656 forceStopPackageLocked(packageName, uid, false, false, true, false, 3657 UserHandle.getUserId(uid)); 3658 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3659 Uri.fromParts("package", packageName, null)); 3660 if (!mProcessesReady) { 3661 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3662 } 3663 intent.putExtra(Intent.EXTRA_UID, uid); 3664 broadcastIntentLocked(null, null, intent, 3665 null, null, 0, null, null, null, 3666 false, false, 3667 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3668 } 3669 3670 private void forceStopUserLocked(int userId) { 3671 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3672 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3673 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3674 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3675 broadcastIntentLocked(null, null, intent, 3676 null, null, 0, null, null, null, 3677 false, false, 3678 MY_PID, Process.SYSTEM_UID, userId); 3679 } 3680 3681 private final boolean killPackageProcessesLocked(String packageName, int uid, 3682 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3683 boolean doit, boolean evenPersistent, String reason) { 3684 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3685 3686 // Remove all processes this package may have touched: all with the 3687 // same UID (except for the system or root user), and all whose name 3688 // matches the package name. 3689 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3690 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3691 final int NA = apps.size(); 3692 for (int ia=0; ia<NA; ia++) { 3693 ProcessRecord app = apps.valueAt(ia); 3694 if (app.persistent && !evenPersistent) { 3695 // we don't kill persistent processes 3696 continue; 3697 } 3698 if (app.removed) { 3699 if (doit) { 3700 procs.add(app); 3701 } 3702 // If no package is specified, we call all processes under the 3703 // give user id. 3704 } else if (packageName == null) { 3705 if (app.userId == userId) { 3706 if (app.setAdj >= minOomAdj) { 3707 if (!doit) { 3708 return true; 3709 } 3710 app.removed = true; 3711 procs.add(app); 3712 } 3713 } 3714 // If uid is specified and the uid and process name match 3715 // Or, the uid is not specified and the process name matches 3716 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3717 || ((app.processName.equals(packageName) 3718 || app.processName.startsWith(procNamePrefix)) 3719 && uid < 0))) { 3720 if (app.setAdj >= minOomAdj) { 3721 if (!doit) { 3722 return true; 3723 } 3724 app.removed = true; 3725 procs.add(app); 3726 } 3727 } 3728 } 3729 } 3730 3731 int N = procs.size(); 3732 for (int i=0; i<N; i++) { 3733 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3734 } 3735 return N > 0; 3736 } 3737 3738 private final boolean forceStopPackageLocked(String name, int uid, 3739 boolean callerWillRestart, boolean purgeCache, boolean doit, 3740 boolean evenPersistent, int userId) { 3741 int i; 3742 int N; 3743 3744 if (uid < 0 && name != null) { 3745 try { 3746 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3747 } catch (RemoteException e) { 3748 } 3749 } 3750 3751 if (doit) { 3752 if (name != null) { 3753 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3754 } else { 3755 Slog.i(TAG, "Force stopping user " + userId); 3756 } 3757 3758 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3759 while (badApps.hasNext()) { 3760 SparseArray<Long> ba = badApps.next(); 3761 for (i=ba.size()-1; i>=0; i--) { 3762 boolean remove = false; 3763 final int entUid = ba.keyAt(i); 3764 if (name != null) { 3765 if (entUid == uid) { 3766 remove = true; 3767 } 3768 } else if (UserHandle.getUserId(entUid) == userId) { 3769 remove = true; 3770 } 3771 if (remove) { 3772 ba.removeAt(i); 3773 } 3774 } 3775 if (ba.size() == 0) { 3776 badApps.remove(); 3777 } 3778 } 3779 } 3780 3781 boolean didSomething = killPackageProcessesLocked(name, uid, 3782 name == null ? userId : -1 , -100, callerWillRestart, false, 3783 doit, evenPersistent, 3784 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3785 3786 TaskRecord lastTask = null; 3787 for (i=0; i<mMainStack.mHistory.size(); i++) { 3788 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3789 final boolean samePackage = r.packageName.equals(name) 3790 || (name == null && r.userId == userId); 3791 if (r.userId == userId 3792 && (samePackage || r.task == lastTask) 3793 && (r.app == null || evenPersistent || !r.app.persistent)) { 3794 if (!doit) { 3795 if (r.finishing) { 3796 // If this activity is just finishing, then it is not 3797 // interesting as far as something to stop. 3798 continue; 3799 } 3800 return true; 3801 } 3802 didSomething = true; 3803 Slog.i(TAG, " Force finishing activity " + r); 3804 if (samePackage) { 3805 if (r.app != null) { 3806 r.app.removed = true; 3807 } 3808 r.app = null; 3809 } 3810 lastTask = r.task; 3811 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3812 null, "force-stop", true)) { 3813 i--; 3814 } 3815 } 3816 } 3817 3818 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3819 if (!doit) { 3820 return true; 3821 } 3822 didSomething = true; 3823 } 3824 3825 if (name == null) { 3826 // Remove all sticky broadcasts from this user. 3827 mStickyBroadcasts.remove(userId); 3828 } 3829 3830 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3831 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3832 if ((name == null || provider.info.packageName.equals(name)) 3833 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3834 if (!doit) { 3835 return true; 3836 } 3837 didSomething = true; 3838 providers.add(provider); 3839 } 3840 } 3841 3842 N = providers.size(); 3843 for (i=0; i<N; i++) { 3844 removeDyingProviderLocked(null, providers.get(i), true); 3845 } 3846 3847 if (doit) { 3848 if (purgeCache && name != null) { 3849 AttributeCache ac = AttributeCache.instance(); 3850 if (ac != null) { 3851 ac.removePackage(name); 3852 } 3853 } 3854 if (mBooted) { 3855 mMainStack.resumeTopActivityLocked(null); 3856 mMainStack.scheduleIdleLocked(); 3857 } 3858 } 3859 3860 return didSomething; 3861 } 3862 3863 private final boolean removeProcessLocked(ProcessRecord app, 3864 boolean callerWillRestart, boolean allowRestart, String reason) { 3865 final String name = app.processName; 3866 final int uid = app.uid; 3867 if (DEBUG_PROCESSES) Slog.d( 3868 TAG, "Force removing proc " + app.toShortString() + " (" + name 3869 + "/" + uid + ")"); 3870 3871 mProcessNames.remove(name, uid); 3872 mIsolatedProcesses.remove(app.uid); 3873 if (mHeavyWeightProcess == app) { 3874 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3875 mHeavyWeightProcess.userId, 0)); 3876 mHeavyWeightProcess = null; 3877 } 3878 boolean needRestart = false; 3879 if (app.pid > 0 && app.pid != MY_PID) { 3880 int pid = app.pid; 3881 synchronized (mPidsSelfLocked) { 3882 mPidsSelfLocked.remove(pid); 3883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3884 } 3885 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3886 handleAppDiedLocked(app, true, allowRestart); 3887 mLruProcesses.remove(app); 3888 Process.killProcessQuiet(pid); 3889 3890 if (app.persistent && !app.isolated) { 3891 if (!callerWillRestart) { 3892 addAppLocked(app.info, false); 3893 } else { 3894 needRestart = true; 3895 } 3896 } 3897 } else { 3898 mRemovedProcesses.add(app); 3899 } 3900 3901 return needRestart; 3902 } 3903 3904 private final void processStartTimedOutLocked(ProcessRecord app) { 3905 final int pid = app.pid; 3906 boolean gone = false; 3907 synchronized (mPidsSelfLocked) { 3908 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3909 if (knownApp != null && knownApp.thread == null) { 3910 mPidsSelfLocked.remove(pid); 3911 gone = true; 3912 } 3913 } 3914 3915 if (gone) { 3916 Slog.w(TAG, "Process " + app + " failed to attach"); 3917 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3918 app.processName); 3919 mProcessNames.remove(app.processName, app.uid); 3920 mIsolatedProcesses.remove(app.uid); 3921 if (mHeavyWeightProcess == app) { 3922 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3923 mHeavyWeightProcess.userId, 0)); 3924 mHeavyWeightProcess = null; 3925 } 3926 // Take care of any launching providers waiting for this process. 3927 checkAppInLaunchingProvidersLocked(app, true); 3928 // Take care of any services that are waiting for the process. 3929 mServices.processStartTimedOutLocked(app); 3930 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3931 app.processName, app.setAdj, "start timeout"); 3932 Process.killProcessQuiet(pid); 3933 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3934 Slog.w(TAG, "Unattached app died before backup, skipping"); 3935 try { 3936 IBackupManager bm = IBackupManager.Stub.asInterface( 3937 ServiceManager.getService(Context.BACKUP_SERVICE)); 3938 bm.agentDisconnected(app.info.packageName); 3939 } catch (RemoteException e) { 3940 // Can't happen; the backup manager is local 3941 } 3942 } 3943 if (isPendingBroadcastProcessLocked(pid)) { 3944 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3945 skipPendingBroadcastLocked(pid); 3946 } 3947 } else { 3948 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3949 } 3950 } 3951 3952 private final boolean attachApplicationLocked(IApplicationThread thread, 3953 int pid) { 3954 3955 // Find the application record that is being attached... either via 3956 // the pid if we are running in multiple processes, or just pull the 3957 // next app record if we are emulating process with anonymous threads. 3958 ProcessRecord app; 3959 if (pid != MY_PID && pid >= 0) { 3960 synchronized (mPidsSelfLocked) { 3961 app = mPidsSelfLocked.get(pid); 3962 } 3963 } else { 3964 app = null; 3965 } 3966 3967 if (app == null) { 3968 Slog.w(TAG, "No pending application record for pid " + pid 3969 + " (IApplicationThread " + thread + "); dropping process"); 3970 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3971 if (pid > 0 && pid != MY_PID) { 3972 Process.killProcessQuiet(pid); 3973 } else { 3974 try { 3975 thread.scheduleExit(); 3976 } catch (Exception e) { 3977 // Ignore exceptions. 3978 } 3979 } 3980 return false; 3981 } 3982 3983 // If this application record is still attached to a previous 3984 // process, clean it up now. 3985 if (app.thread != null) { 3986 handleAppDiedLocked(app, true, true); 3987 } 3988 3989 // Tell the process all about itself. 3990 3991 if (localLOGV) Slog.v( 3992 TAG, "Binding process pid " + pid + " to record " + app); 3993 3994 String processName = app.processName; 3995 try { 3996 AppDeathRecipient adr = new AppDeathRecipient( 3997 app, pid, thread); 3998 thread.asBinder().linkToDeath(adr, 0); 3999 app.deathRecipient = adr; 4000 } catch (RemoteException e) { 4001 app.resetPackageList(); 4002 startProcessLocked(app, "link fail", processName); 4003 return false; 4004 } 4005 4006 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4007 4008 app.thread = thread; 4009 app.curAdj = app.setAdj = -100; 4010 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4011 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4012 app.forcingToForeground = null; 4013 app.foregroundServices = false; 4014 app.hasShownUi = false; 4015 app.debugging = false; 4016 4017 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4018 4019 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4020 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4021 4022 if (!normalMode) { 4023 Slog.i(TAG, "Launching preboot mode app: " + app); 4024 } 4025 4026 if (localLOGV) Slog.v( 4027 TAG, "New app record " + app 4028 + " thread=" + thread.asBinder() + " pid=" + pid); 4029 try { 4030 int testMode = IApplicationThread.DEBUG_OFF; 4031 if (mDebugApp != null && mDebugApp.equals(processName)) { 4032 testMode = mWaitForDebugger 4033 ? IApplicationThread.DEBUG_WAIT 4034 : IApplicationThread.DEBUG_ON; 4035 app.debugging = true; 4036 if (mDebugTransient) { 4037 mDebugApp = mOrigDebugApp; 4038 mWaitForDebugger = mOrigWaitForDebugger; 4039 } 4040 } 4041 String profileFile = app.instrumentationProfileFile; 4042 ParcelFileDescriptor profileFd = null; 4043 boolean profileAutoStop = false; 4044 if (mProfileApp != null && mProfileApp.equals(processName)) { 4045 mProfileProc = app; 4046 profileFile = mProfileFile; 4047 profileFd = mProfileFd; 4048 profileAutoStop = mAutoStopProfiler; 4049 } 4050 boolean enableOpenGlTrace = false; 4051 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4052 enableOpenGlTrace = true; 4053 mOpenGlTraceApp = null; 4054 } 4055 4056 // If the app is being launched for restore or full backup, set it up specially 4057 boolean isRestrictedBackupMode = false; 4058 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4059 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4060 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4061 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4062 } 4063 4064 ensurePackageDexOpt(app.instrumentationInfo != null 4065 ? app.instrumentationInfo.packageName 4066 : app.info.packageName); 4067 if (app.instrumentationClass != null) { 4068 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4069 } 4070 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4071 + processName + " with config " + mConfiguration); 4072 ApplicationInfo appInfo = app.instrumentationInfo != null 4073 ? app.instrumentationInfo : app.info; 4074 app.compat = compatibilityInfoForPackageLocked(appInfo); 4075 if (profileFd != null) { 4076 profileFd = profileFd.dup(); 4077 } 4078 thread.bindApplication(processName, appInfo, providers, 4079 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4080 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4081 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4082 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4083 mCoreSettingsObserver.getCoreSettingsLocked()); 4084 updateLruProcessLocked(app, false, true); 4085 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4086 } catch (Exception e) { 4087 // todo: Yikes! What should we do? For now we will try to 4088 // start another process, but that could easily get us in 4089 // an infinite loop of restarting processes... 4090 Slog.w(TAG, "Exception thrown during bind!", e); 4091 4092 app.resetPackageList(); 4093 app.unlinkDeathRecipient(); 4094 startProcessLocked(app, "bind fail", processName); 4095 return false; 4096 } 4097 4098 // Remove this record from the list of starting applications. 4099 mPersistentStartingProcesses.remove(app); 4100 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4101 "Attach application locked removing on hold: " + app); 4102 mProcessesOnHold.remove(app); 4103 4104 boolean badApp = false; 4105 boolean didSomething = false; 4106 4107 // See if the top visible activity is waiting to run in this process... 4108 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4109 if (hr != null && normalMode) { 4110 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4111 && processName.equals(hr.processName)) { 4112 try { 4113 if (mHeadless) { 4114 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4115 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4116 didSomething = true; 4117 } 4118 } catch (Exception e) { 4119 Slog.w(TAG, "Exception in new application when starting activity " 4120 + hr.intent.getComponent().flattenToShortString(), e); 4121 badApp = true; 4122 } 4123 } else { 4124 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4125 } 4126 } 4127 4128 // Find any services that should be running in this process... 4129 if (!badApp) { 4130 try { 4131 didSomething |= mServices.attachApplicationLocked(app, processName); 4132 } catch (Exception e) { 4133 badApp = true; 4134 } 4135 } 4136 4137 // Check if a next-broadcast receiver is in this process... 4138 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4139 try { 4140 didSomething = sendPendingBroadcastsLocked(app); 4141 } catch (Exception e) { 4142 // If the app died trying to launch the receiver we declare it 'bad' 4143 badApp = true; 4144 } 4145 } 4146 4147 // Check whether the next backup agent is in this process... 4148 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4149 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4150 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4151 try { 4152 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4153 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4154 mBackupTarget.backupMode); 4155 } catch (Exception e) { 4156 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4157 e.printStackTrace(); 4158 } 4159 } 4160 4161 if (badApp) { 4162 // todo: Also need to kill application to deal with all 4163 // kinds of exceptions. 4164 handleAppDiedLocked(app, false, true); 4165 return false; 4166 } 4167 4168 if (!didSomething) { 4169 updateOomAdjLocked(); 4170 } 4171 4172 return true; 4173 } 4174 4175 public final void attachApplication(IApplicationThread thread) { 4176 synchronized (this) { 4177 int callingPid = Binder.getCallingPid(); 4178 final long origId = Binder.clearCallingIdentity(); 4179 attachApplicationLocked(thread, callingPid); 4180 Binder.restoreCallingIdentity(origId); 4181 } 4182 } 4183 4184 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4185 final long origId = Binder.clearCallingIdentity(); 4186 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4187 if (stopProfiling) { 4188 synchronized (this) { 4189 if (mProfileProc == r.app) { 4190 if (mProfileFd != null) { 4191 try { 4192 mProfileFd.close(); 4193 } catch (IOException e) { 4194 } 4195 clearProfilerLocked(); 4196 } 4197 } 4198 } 4199 } 4200 Binder.restoreCallingIdentity(origId); 4201 } 4202 4203 void enableScreenAfterBoot() { 4204 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4205 SystemClock.uptimeMillis()); 4206 mWindowManager.enableScreenAfterBoot(); 4207 4208 synchronized (this) { 4209 updateEventDispatchingLocked(); 4210 } 4211 } 4212 4213 public void showBootMessage(final CharSequence msg, final boolean always) { 4214 enforceNotIsolatedCaller("showBootMessage"); 4215 mWindowManager.showBootMessage(msg, always); 4216 } 4217 4218 public void dismissKeyguardOnNextActivity() { 4219 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4220 final long token = Binder.clearCallingIdentity(); 4221 try { 4222 synchronized (this) { 4223 if (mLockScreenShown) { 4224 mLockScreenShown = false; 4225 comeOutOfSleepIfNeededLocked(); 4226 } 4227 mMainStack.dismissKeyguardOnNextActivityLocked(); 4228 } 4229 } finally { 4230 Binder.restoreCallingIdentity(token); 4231 } 4232 } 4233 4234 final void finishBooting() { 4235 IntentFilter pkgFilter = new IntentFilter(); 4236 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4237 pkgFilter.addDataScheme("package"); 4238 mContext.registerReceiver(new BroadcastReceiver() { 4239 @Override 4240 public void onReceive(Context context, Intent intent) { 4241 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4242 if (pkgs != null) { 4243 for (String pkg : pkgs) { 4244 synchronized (ActivityManagerService.this) { 4245 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4246 setResultCode(Activity.RESULT_OK); 4247 return; 4248 } 4249 } 4250 } 4251 } 4252 } 4253 }, pkgFilter); 4254 4255 synchronized (this) { 4256 // Ensure that any processes we had put on hold are now started 4257 // up. 4258 final int NP = mProcessesOnHold.size(); 4259 if (NP > 0) { 4260 ArrayList<ProcessRecord> procs = 4261 new ArrayList<ProcessRecord>(mProcessesOnHold); 4262 for (int ip=0; ip<NP; ip++) { 4263 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4264 + procs.get(ip)); 4265 startProcessLocked(procs.get(ip), "on-hold", null); 4266 } 4267 } 4268 4269 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4270 // Start looking for apps that are abusing wake locks. 4271 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4272 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4273 // Tell anyone interested that we are done booting! 4274 SystemProperties.set("sys.boot_completed", "1"); 4275 SystemProperties.set("dev.bootcomplete", "1"); 4276 for (int i=0; i<mStartedUsers.size(); i++) { 4277 UserStartedState uss = mStartedUsers.valueAt(i); 4278 if (uss.mState == UserStartedState.STATE_BOOTING) { 4279 uss.mState = UserStartedState.STATE_RUNNING; 4280 final int userId = mStartedUsers.keyAt(i); 4281 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4282 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4283 broadcastIntentLocked(null, null, intent, 4284 null, null, 0, null, null, 4285 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4286 false, false, MY_PID, Process.SYSTEM_UID, userId); 4287 } 4288 } 4289 } 4290 } 4291 } 4292 4293 final void ensureBootCompleted() { 4294 boolean booting; 4295 boolean enableScreen; 4296 synchronized (this) { 4297 booting = mBooting; 4298 mBooting = false; 4299 enableScreen = !mBooted; 4300 mBooted = true; 4301 } 4302 4303 if (booting) { 4304 finishBooting(); 4305 } 4306 4307 if (enableScreen) { 4308 enableScreenAfterBoot(); 4309 } 4310 } 4311 4312 public final void activityPaused(IBinder token) { 4313 final long origId = Binder.clearCallingIdentity(); 4314 mMainStack.activityPaused(token, false); 4315 Binder.restoreCallingIdentity(origId); 4316 } 4317 4318 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4319 CharSequence description) { 4320 if (localLOGV) Slog.v( 4321 TAG, "Activity stopped: token=" + token); 4322 4323 // Refuse possible leaked file descriptors 4324 if (icicle != null && icicle.hasFileDescriptors()) { 4325 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4326 } 4327 4328 ActivityRecord r = null; 4329 4330 final long origId = Binder.clearCallingIdentity(); 4331 4332 synchronized (this) { 4333 r = mMainStack.isInStackLocked(token); 4334 if (r != null) { 4335 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4336 } 4337 } 4338 4339 if (r != null) { 4340 sendPendingThumbnail(r, null, null, null, false); 4341 } 4342 4343 trimApplications(); 4344 4345 Binder.restoreCallingIdentity(origId); 4346 } 4347 4348 public final void activityDestroyed(IBinder token) { 4349 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4350 mMainStack.activityDestroyed(token); 4351 } 4352 4353 public String getCallingPackage(IBinder token) { 4354 synchronized (this) { 4355 ActivityRecord r = getCallingRecordLocked(token); 4356 return r != null && r.app != null ? r.info.packageName : null; 4357 } 4358 } 4359 4360 public ComponentName getCallingActivity(IBinder token) { 4361 synchronized (this) { 4362 ActivityRecord r = getCallingRecordLocked(token); 4363 return r != null ? r.intent.getComponent() : null; 4364 } 4365 } 4366 4367 private ActivityRecord getCallingRecordLocked(IBinder token) { 4368 ActivityRecord r = mMainStack.isInStackLocked(token); 4369 if (r == null) { 4370 return null; 4371 } 4372 return r.resultTo; 4373 } 4374 4375 public ComponentName getActivityClassForToken(IBinder token) { 4376 synchronized(this) { 4377 ActivityRecord r = mMainStack.isInStackLocked(token); 4378 if (r == null) { 4379 return null; 4380 } 4381 return r.intent.getComponent(); 4382 } 4383 } 4384 4385 public String getPackageForToken(IBinder token) { 4386 synchronized(this) { 4387 ActivityRecord r = mMainStack.isInStackLocked(token); 4388 if (r == null) { 4389 return null; 4390 } 4391 return r.packageName; 4392 } 4393 } 4394 4395 public IIntentSender getIntentSender(int type, 4396 String packageName, IBinder token, String resultWho, 4397 int requestCode, Intent[] intents, String[] resolvedTypes, 4398 int flags, Bundle options, int userId) { 4399 enforceNotIsolatedCaller("getIntentSender"); 4400 // Refuse possible leaked file descriptors 4401 if (intents != null) { 4402 if (intents.length < 1) { 4403 throw new IllegalArgumentException("Intents array length must be >= 1"); 4404 } 4405 for (int i=0; i<intents.length; i++) { 4406 Intent intent = intents[i]; 4407 if (intent != null) { 4408 if (intent.hasFileDescriptors()) { 4409 throw new IllegalArgumentException("File descriptors passed in Intent"); 4410 } 4411 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4412 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4413 throw new IllegalArgumentException( 4414 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4415 } 4416 intents[i] = new Intent(intent); 4417 } 4418 } 4419 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4420 throw new IllegalArgumentException( 4421 "Intent array length does not match resolvedTypes length"); 4422 } 4423 } 4424 if (options != null) { 4425 if (options.hasFileDescriptors()) { 4426 throw new IllegalArgumentException("File descriptors passed in options"); 4427 } 4428 } 4429 4430 synchronized(this) { 4431 int callingUid = Binder.getCallingUid(); 4432 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4433 false, true, "getIntentSender", null); 4434 try { 4435 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4436 int uid = AppGlobals.getPackageManager() 4437 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4438 if (!UserHandle.isSameApp(callingUid, uid)) { 4439 String msg = "Permission Denial: getIntentSender() from pid=" 4440 + Binder.getCallingPid() 4441 + ", uid=" + Binder.getCallingUid() 4442 + ", (need uid=" + uid + ")" 4443 + " is not allowed to send as package " + packageName; 4444 Slog.w(TAG, msg); 4445 throw new SecurityException(msg); 4446 } 4447 } 4448 4449 return getIntentSenderLocked(type, packageName, callingUid, userId, 4450 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4451 4452 } catch (RemoteException e) { 4453 throw new SecurityException(e); 4454 } 4455 } 4456 } 4457 4458 IIntentSender getIntentSenderLocked(int type, String packageName, 4459 int callingUid, int userId, IBinder token, String resultWho, 4460 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4461 Bundle options) { 4462 if (DEBUG_MU) 4463 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4464 ActivityRecord activity = null; 4465 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4466 activity = mMainStack.isInStackLocked(token); 4467 if (activity == null) { 4468 return null; 4469 } 4470 if (activity.finishing) { 4471 return null; 4472 } 4473 } 4474 4475 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4476 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4477 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4478 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4479 |PendingIntent.FLAG_UPDATE_CURRENT); 4480 4481 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4482 type, packageName, activity, resultWho, 4483 requestCode, intents, resolvedTypes, flags, options, userId); 4484 WeakReference<PendingIntentRecord> ref; 4485 ref = mIntentSenderRecords.get(key); 4486 PendingIntentRecord rec = ref != null ? ref.get() : null; 4487 if (rec != null) { 4488 if (!cancelCurrent) { 4489 if (updateCurrent) { 4490 if (rec.key.requestIntent != null) { 4491 rec.key.requestIntent.replaceExtras(intents != null ? 4492 intents[intents.length - 1] : null); 4493 } 4494 if (intents != null) { 4495 intents[intents.length-1] = rec.key.requestIntent; 4496 rec.key.allIntents = intents; 4497 rec.key.allResolvedTypes = resolvedTypes; 4498 } else { 4499 rec.key.allIntents = null; 4500 rec.key.allResolvedTypes = null; 4501 } 4502 } 4503 return rec; 4504 } 4505 rec.canceled = true; 4506 mIntentSenderRecords.remove(key); 4507 } 4508 if (noCreate) { 4509 return rec; 4510 } 4511 rec = new PendingIntentRecord(this, key, callingUid); 4512 mIntentSenderRecords.put(key, rec.ref); 4513 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4514 if (activity.pendingResults == null) { 4515 activity.pendingResults 4516 = new HashSet<WeakReference<PendingIntentRecord>>(); 4517 } 4518 activity.pendingResults.add(rec.ref); 4519 } 4520 return rec; 4521 } 4522 4523 public void cancelIntentSender(IIntentSender sender) { 4524 if (!(sender instanceof PendingIntentRecord)) { 4525 return; 4526 } 4527 synchronized(this) { 4528 PendingIntentRecord rec = (PendingIntentRecord)sender; 4529 try { 4530 int uid = AppGlobals.getPackageManager() 4531 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4532 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4533 String msg = "Permission Denial: cancelIntentSender() from pid=" 4534 + Binder.getCallingPid() 4535 + ", uid=" + Binder.getCallingUid() 4536 + " is not allowed to cancel packges " 4537 + rec.key.packageName; 4538 Slog.w(TAG, msg); 4539 throw new SecurityException(msg); 4540 } 4541 } catch (RemoteException e) { 4542 throw new SecurityException(e); 4543 } 4544 cancelIntentSenderLocked(rec, true); 4545 } 4546 } 4547 4548 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4549 rec.canceled = true; 4550 mIntentSenderRecords.remove(rec.key); 4551 if (cleanActivity && rec.key.activity != null) { 4552 rec.key.activity.pendingResults.remove(rec.ref); 4553 } 4554 } 4555 4556 public String getPackageForIntentSender(IIntentSender pendingResult) { 4557 if (!(pendingResult instanceof PendingIntentRecord)) { 4558 return null; 4559 } 4560 try { 4561 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4562 return res.key.packageName; 4563 } catch (ClassCastException e) { 4564 } 4565 return null; 4566 } 4567 4568 public int getUidForIntentSender(IIntentSender sender) { 4569 if (sender instanceof PendingIntentRecord) { 4570 try { 4571 PendingIntentRecord res = (PendingIntentRecord)sender; 4572 return res.uid; 4573 } catch (ClassCastException e) { 4574 } 4575 } 4576 return -1; 4577 } 4578 4579 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4580 if (!(pendingResult instanceof PendingIntentRecord)) { 4581 return false; 4582 } 4583 try { 4584 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4585 if (res.key.allIntents == null) { 4586 return false; 4587 } 4588 for (int i=0; i<res.key.allIntents.length; i++) { 4589 Intent intent = res.key.allIntents[i]; 4590 if (intent.getPackage() != null && intent.getComponent() != null) { 4591 return false; 4592 } 4593 } 4594 return true; 4595 } catch (ClassCastException e) { 4596 } 4597 return false; 4598 } 4599 4600 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4601 if (!(pendingResult instanceof PendingIntentRecord)) { 4602 return false; 4603 } 4604 try { 4605 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4606 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4607 return true; 4608 } 4609 return false; 4610 } catch (ClassCastException e) { 4611 } 4612 return false; 4613 } 4614 4615 public void setProcessLimit(int max) { 4616 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4617 "setProcessLimit()"); 4618 synchronized (this) { 4619 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4620 mProcessLimitOverride = max; 4621 } 4622 trimApplications(); 4623 } 4624 4625 public int getProcessLimit() { 4626 synchronized (this) { 4627 return mProcessLimitOverride; 4628 } 4629 } 4630 4631 void foregroundTokenDied(ForegroundToken token) { 4632 synchronized (ActivityManagerService.this) { 4633 synchronized (mPidsSelfLocked) { 4634 ForegroundToken cur 4635 = mForegroundProcesses.get(token.pid); 4636 if (cur != token) { 4637 return; 4638 } 4639 mForegroundProcesses.remove(token.pid); 4640 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4641 if (pr == null) { 4642 return; 4643 } 4644 pr.forcingToForeground = null; 4645 pr.foregroundServices = false; 4646 } 4647 updateOomAdjLocked(); 4648 } 4649 } 4650 4651 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4652 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4653 "setProcessForeground()"); 4654 synchronized(this) { 4655 boolean changed = false; 4656 4657 synchronized (mPidsSelfLocked) { 4658 ProcessRecord pr = mPidsSelfLocked.get(pid); 4659 if (pr == null && isForeground) { 4660 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4661 return; 4662 } 4663 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4664 if (oldToken != null) { 4665 oldToken.token.unlinkToDeath(oldToken, 0); 4666 mForegroundProcesses.remove(pid); 4667 if (pr != null) { 4668 pr.forcingToForeground = null; 4669 } 4670 changed = true; 4671 } 4672 if (isForeground && token != null) { 4673 ForegroundToken newToken = new ForegroundToken() { 4674 public void binderDied() { 4675 foregroundTokenDied(this); 4676 } 4677 }; 4678 newToken.pid = pid; 4679 newToken.token = token; 4680 try { 4681 token.linkToDeath(newToken, 0); 4682 mForegroundProcesses.put(pid, newToken); 4683 pr.forcingToForeground = token; 4684 changed = true; 4685 } catch (RemoteException e) { 4686 // If the process died while doing this, we will later 4687 // do the cleanup with the process death link. 4688 } 4689 } 4690 } 4691 4692 if (changed) { 4693 updateOomAdjLocked(); 4694 } 4695 } 4696 } 4697 4698 // ========================================================= 4699 // PERMISSIONS 4700 // ========================================================= 4701 4702 static class PermissionController extends IPermissionController.Stub { 4703 ActivityManagerService mActivityManagerService; 4704 PermissionController(ActivityManagerService activityManagerService) { 4705 mActivityManagerService = activityManagerService; 4706 } 4707 4708 public boolean checkPermission(String permission, int pid, int uid) { 4709 return mActivityManagerService.checkPermission(permission, pid, 4710 uid) == PackageManager.PERMISSION_GRANTED; 4711 } 4712 } 4713 4714 /** 4715 * This can be called with or without the global lock held. 4716 */ 4717 int checkComponentPermission(String permission, int pid, int uid, 4718 int owningUid, boolean exported) { 4719 // We might be performing an operation on behalf of an indirect binder 4720 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4721 // client identity accordingly before proceeding. 4722 Identity tlsIdentity = sCallerIdentity.get(); 4723 if (tlsIdentity != null) { 4724 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4725 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4726 uid = tlsIdentity.uid; 4727 pid = tlsIdentity.pid; 4728 } 4729 4730 if (pid == MY_PID) { 4731 return PackageManager.PERMISSION_GRANTED; 4732 } 4733 4734 return ActivityManager.checkComponentPermission(permission, uid, 4735 owningUid, exported); 4736 } 4737 4738 /** 4739 * As the only public entry point for permissions checking, this method 4740 * can enforce the semantic that requesting a check on a null global 4741 * permission is automatically denied. (Internally a null permission 4742 * string is used when calling {@link #checkComponentPermission} in cases 4743 * when only uid-based security is needed.) 4744 * 4745 * This can be called with or without the global lock held. 4746 */ 4747 public int checkPermission(String permission, int pid, int uid) { 4748 if (permission == null) { 4749 return PackageManager.PERMISSION_DENIED; 4750 } 4751 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4752 } 4753 4754 /** 4755 * Binder IPC calls go through the public entry point. 4756 * This can be called with or without the global lock held. 4757 */ 4758 int checkCallingPermission(String permission) { 4759 return checkPermission(permission, 4760 Binder.getCallingPid(), 4761 UserHandle.getAppId(Binder.getCallingUid())); 4762 } 4763 4764 /** 4765 * This can be called with or without the global lock held. 4766 */ 4767 void enforceCallingPermission(String permission, String func) { 4768 if (checkCallingPermission(permission) 4769 == PackageManager.PERMISSION_GRANTED) { 4770 return; 4771 } 4772 4773 String msg = "Permission Denial: " + func + " from pid=" 4774 + Binder.getCallingPid() 4775 + ", uid=" + Binder.getCallingUid() 4776 + " requires " + permission; 4777 Slog.w(TAG, msg); 4778 throw new SecurityException(msg); 4779 } 4780 4781 /** 4782 * Determine if UID is holding permissions required to access {@link Uri} in 4783 * the given {@link ProviderInfo}. Final permission checking is always done 4784 * in {@link ContentProvider}. 4785 */ 4786 private final boolean checkHoldingPermissionsLocked( 4787 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4788 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4789 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4790 4791 if (pi.applicationInfo.uid == uid) { 4792 return true; 4793 } else if (!pi.exported) { 4794 return false; 4795 } 4796 4797 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4798 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4799 try { 4800 // check if target holds top-level <provider> permissions 4801 if (!readMet && pi.readPermission != null 4802 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4803 readMet = true; 4804 } 4805 if (!writeMet && pi.writePermission != null 4806 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4807 writeMet = true; 4808 } 4809 4810 // track if unprotected read/write is allowed; any denied 4811 // <path-permission> below removes this ability 4812 boolean allowDefaultRead = pi.readPermission == null; 4813 boolean allowDefaultWrite = pi.writePermission == null; 4814 4815 // check if target holds any <path-permission> that match uri 4816 final PathPermission[] pps = pi.pathPermissions; 4817 if (pps != null) { 4818 final String path = uri.getPath(); 4819 int i = pps.length; 4820 while (i > 0 && (!readMet || !writeMet)) { 4821 i--; 4822 PathPermission pp = pps[i]; 4823 if (pp.match(path)) { 4824 if (!readMet) { 4825 final String pprperm = pp.getReadPermission(); 4826 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4827 + pprperm + " for " + pp.getPath() 4828 + ": match=" + pp.match(path) 4829 + " check=" + pm.checkUidPermission(pprperm, uid)); 4830 if (pprperm != null) { 4831 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4832 readMet = true; 4833 } else { 4834 allowDefaultRead = false; 4835 } 4836 } 4837 } 4838 if (!writeMet) { 4839 final String ppwperm = pp.getWritePermission(); 4840 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4841 + ppwperm + " for " + pp.getPath() 4842 + ": match=" + pp.match(path) 4843 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4844 if (ppwperm != null) { 4845 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4846 writeMet = true; 4847 } else { 4848 allowDefaultWrite = false; 4849 } 4850 } 4851 } 4852 } 4853 } 4854 } 4855 4856 // grant unprotected <provider> read/write, if not blocked by 4857 // <path-permission> above 4858 if (allowDefaultRead) readMet = true; 4859 if (allowDefaultWrite) writeMet = true; 4860 4861 } catch (RemoteException e) { 4862 return false; 4863 } 4864 4865 return readMet && writeMet; 4866 } 4867 4868 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4869 int modeFlags) { 4870 // Root gets to do everything. 4871 if (uid == 0) { 4872 return true; 4873 } 4874 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4875 if (perms == null) return false; 4876 UriPermission perm = perms.get(uri); 4877 if (perm == null) return false; 4878 return (modeFlags&perm.modeFlags) == modeFlags; 4879 } 4880 4881 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4882 enforceNotIsolatedCaller("checkUriPermission"); 4883 4884 // Another redirected-binder-call permissions check as in 4885 // {@link checkComponentPermission}. 4886 Identity tlsIdentity = sCallerIdentity.get(); 4887 if (tlsIdentity != null) { 4888 uid = tlsIdentity.uid; 4889 pid = tlsIdentity.pid; 4890 } 4891 4892 uid = UserHandle.getAppId(uid); 4893 // Our own process gets to do everything. 4894 if (pid == MY_PID) { 4895 return PackageManager.PERMISSION_GRANTED; 4896 } 4897 synchronized(this) { 4898 return checkUriPermissionLocked(uri, uid, modeFlags) 4899 ? PackageManager.PERMISSION_GRANTED 4900 : PackageManager.PERMISSION_DENIED; 4901 } 4902 } 4903 4904 /** 4905 * Check if the targetPkg can be granted permission to access uri by 4906 * the callingUid using the given modeFlags. Throws a security exception 4907 * if callingUid is not allowed to do this. Returns the uid of the target 4908 * if the URI permission grant should be performed; returns -1 if it is not 4909 * needed (for example targetPkg already has permission to access the URI). 4910 * If you already know the uid of the target, you can supply it in 4911 * lastTargetUid else set that to -1. 4912 */ 4913 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4914 Uri uri, int modeFlags, int lastTargetUid) { 4915 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4916 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4917 if (modeFlags == 0) { 4918 return -1; 4919 } 4920 4921 if (targetPkg != null) { 4922 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4923 "Checking grant " + targetPkg + " permission to " + uri); 4924 } 4925 4926 final IPackageManager pm = AppGlobals.getPackageManager(); 4927 4928 // If this is not a content: uri, we can't do anything with it. 4929 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4930 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4931 "Can't grant URI permission for non-content URI: " + uri); 4932 return -1; 4933 } 4934 4935 String name = uri.getAuthority(); 4936 ProviderInfo pi = null; 4937 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4938 UserHandle.getUserId(callingUid)); 4939 if (cpr != null) { 4940 pi = cpr.info; 4941 } else { 4942 try { 4943 pi = pm.resolveContentProvider(name, 4944 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4945 } catch (RemoteException ex) { 4946 } 4947 } 4948 if (pi == null) { 4949 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4950 return -1; 4951 } 4952 4953 int targetUid = lastTargetUid; 4954 if (targetUid < 0 && targetPkg != null) { 4955 try { 4956 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4957 if (targetUid < 0) { 4958 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4959 "Can't grant URI permission no uid for: " + targetPkg); 4960 return -1; 4961 } 4962 } catch (RemoteException ex) { 4963 return -1; 4964 } 4965 } 4966 4967 if (targetUid >= 0) { 4968 // First... does the target actually need this permission? 4969 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4970 // No need to grant the target this permission. 4971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4972 "Target " + targetPkg + " already has full permission to " + uri); 4973 return -1; 4974 } 4975 } else { 4976 // First... there is no target package, so can anyone access it? 4977 boolean allowed = pi.exported; 4978 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4979 if (pi.readPermission != null) { 4980 allowed = false; 4981 } 4982 } 4983 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4984 if (pi.writePermission != null) { 4985 allowed = false; 4986 } 4987 } 4988 if (allowed) { 4989 return -1; 4990 } 4991 } 4992 4993 // Second... is the provider allowing granting of URI permissions? 4994 if (!pi.grantUriPermissions) { 4995 throw new SecurityException("Provider " + pi.packageName 4996 + "/" + pi.name 4997 + " does not allow granting of Uri permissions (uri " 4998 + uri + ")"); 4999 } 5000 if (pi.uriPermissionPatterns != null) { 5001 final int N = pi.uriPermissionPatterns.length; 5002 boolean allowed = false; 5003 for (int i=0; i<N; i++) { 5004 if (pi.uriPermissionPatterns[i] != null 5005 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5006 allowed = true; 5007 break; 5008 } 5009 } 5010 if (!allowed) { 5011 throw new SecurityException("Provider " + pi.packageName 5012 + "/" + pi.name 5013 + " does not allow granting of permission to path of Uri " 5014 + uri); 5015 } 5016 } 5017 5018 // Third... does the caller itself have permission to access 5019 // this uri? 5020 if (callingUid != Process.myUid()) { 5021 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5022 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5023 throw new SecurityException("Uid " + callingUid 5024 + " does not have permission to uri " + uri); 5025 } 5026 } 5027 } 5028 5029 return targetUid; 5030 } 5031 5032 public int checkGrantUriPermission(int callingUid, String targetPkg, 5033 Uri uri, int modeFlags) { 5034 enforceNotIsolatedCaller("checkGrantUriPermission"); 5035 synchronized(this) { 5036 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5037 } 5038 } 5039 5040 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5041 Uri uri, int modeFlags, UriPermissionOwner owner) { 5042 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5043 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5044 if (modeFlags == 0) { 5045 return; 5046 } 5047 5048 // So here we are: the caller has the assumed permission 5049 // to the uri, and the target doesn't. Let's now give this to 5050 // the target. 5051 5052 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5053 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5054 5055 HashMap<Uri, UriPermission> targetUris 5056 = mGrantedUriPermissions.get(targetUid); 5057 if (targetUris == null) { 5058 targetUris = new HashMap<Uri, UriPermission>(); 5059 mGrantedUriPermissions.put(targetUid, targetUris); 5060 } 5061 5062 UriPermission perm = targetUris.get(uri); 5063 if (perm == null) { 5064 perm = new UriPermission(targetUid, uri); 5065 targetUris.put(uri, perm); 5066 } 5067 5068 perm.modeFlags |= modeFlags; 5069 if (owner == null) { 5070 perm.globalModeFlags |= modeFlags; 5071 } else { 5072 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5073 perm.readOwners.add(owner); 5074 owner.addReadPermission(perm); 5075 } 5076 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5077 perm.writeOwners.add(owner); 5078 owner.addWritePermission(perm); 5079 } 5080 } 5081 } 5082 5083 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5084 int modeFlags, UriPermissionOwner owner) { 5085 if (targetPkg == null) { 5086 throw new NullPointerException("targetPkg"); 5087 } 5088 5089 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5090 if (targetUid < 0) { 5091 return; 5092 } 5093 5094 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5095 } 5096 5097 static class NeededUriGrants extends ArrayList<Uri> { 5098 final String targetPkg; 5099 final int targetUid; 5100 final int flags; 5101 5102 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5103 targetPkg = _targetPkg; 5104 targetUid = _targetUid; 5105 flags = _flags; 5106 } 5107 } 5108 5109 /** 5110 * Like checkGrantUriPermissionLocked, but takes an Intent. 5111 */ 5112 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5113 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5115 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5116 + " clip=" + (intent != null ? intent.getClipData() : null) 5117 + " from " + intent + "; flags=0x" 5118 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5119 5120 if (targetPkg == null) { 5121 throw new NullPointerException("targetPkg"); 5122 } 5123 5124 if (intent == null) { 5125 return null; 5126 } 5127 Uri data = intent.getData(); 5128 ClipData clip = intent.getClipData(); 5129 if (data == null && clip == null) { 5130 return null; 5131 } 5132 if (data != null) { 5133 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5134 mode, needed != null ? needed.targetUid : -1); 5135 if (target > 0) { 5136 if (needed == null) { 5137 needed = new NeededUriGrants(targetPkg, target, mode); 5138 } 5139 needed.add(data); 5140 } 5141 } 5142 if (clip != null) { 5143 for (int i=0; i<clip.getItemCount(); i++) { 5144 Uri uri = clip.getItemAt(i).getUri(); 5145 if (uri != null) { 5146 int target = -1; 5147 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5148 mode, needed != null ? needed.targetUid : -1); 5149 if (target > 0) { 5150 if (needed == null) { 5151 needed = new NeededUriGrants(targetPkg, target, mode); 5152 } 5153 needed.add(uri); 5154 } 5155 } else { 5156 Intent clipIntent = clip.getItemAt(i).getIntent(); 5157 if (clipIntent != null) { 5158 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5159 callingUid, targetPkg, clipIntent, mode, needed); 5160 if (newNeeded != null) { 5161 needed = newNeeded; 5162 } 5163 } 5164 } 5165 } 5166 } 5167 5168 return needed; 5169 } 5170 5171 /** 5172 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5173 */ 5174 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5175 UriPermissionOwner owner) { 5176 if (needed != null) { 5177 for (int i=0; i<needed.size(); i++) { 5178 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5179 needed.get(i), needed.flags, owner); 5180 } 5181 } 5182 } 5183 5184 void grantUriPermissionFromIntentLocked(int callingUid, 5185 String targetPkg, Intent intent, UriPermissionOwner owner) { 5186 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5187 intent, intent != null ? intent.getFlags() : 0, null); 5188 if (needed == null) { 5189 return; 5190 } 5191 5192 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5193 } 5194 5195 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5196 Uri uri, int modeFlags) { 5197 enforceNotIsolatedCaller("grantUriPermission"); 5198 synchronized(this) { 5199 final ProcessRecord r = getRecordForAppLocked(caller); 5200 if (r == null) { 5201 throw new SecurityException("Unable to find app for caller " 5202 + caller 5203 + " when granting permission to uri " + uri); 5204 } 5205 if (targetPkg == null) { 5206 throw new IllegalArgumentException("null target"); 5207 } 5208 if (uri == null) { 5209 throw new IllegalArgumentException("null uri"); 5210 } 5211 5212 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5213 null); 5214 } 5215 } 5216 5217 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5218 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5219 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5220 HashMap<Uri, UriPermission> perms 5221 = mGrantedUriPermissions.get(perm.uid); 5222 if (perms != null) { 5223 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5224 "Removing " + perm.uid + " permission to " + perm.uri); 5225 perms.remove(perm.uri); 5226 if (perms.size() == 0) { 5227 mGrantedUriPermissions.remove(perm.uid); 5228 } 5229 } 5230 } 5231 } 5232 5233 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5234 int modeFlags) { 5235 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5236 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5237 if (modeFlags == 0) { 5238 return; 5239 } 5240 5241 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5242 "Revoking all granted permissions to " + uri); 5243 5244 final IPackageManager pm = AppGlobals.getPackageManager(); 5245 5246 final String authority = uri.getAuthority(); 5247 ProviderInfo pi = null; 5248 int userId = UserHandle.getUserId(callingUid); 5249 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5250 if (cpr != null) { 5251 pi = cpr.info; 5252 } else { 5253 try { 5254 pi = pm.resolveContentProvider(authority, 5255 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5256 } catch (RemoteException ex) { 5257 } 5258 } 5259 if (pi == null) { 5260 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5261 return; 5262 } 5263 5264 // Does the caller have this permission on the URI? 5265 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5266 // Right now, if you are not the original owner of the permission, 5267 // you are not allowed to revoke it. 5268 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5269 throw new SecurityException("Uid " + callingUid 5270 + " does not have permission to uri " + uri); 5271 //} 5272 } 5273 5274 // Go through all of the permissions and remove any that match. 5275 final List<String> SEGMENTS = uri.getPathSegments(); 5276 if (SEGMENTS != null) { 5277 final int NS = SEGMENTS.size(); 5278 int N = mGrantedUriPermissions.size(); 5279 for (int i=0; i<N; i++) { 5280 HashMap<Uri, UriPermission> perms 5281 = mGrantedUriPermissions.valueAt(i); 5282 Iterator<UriPermission> it = perms.values().iterator(); 5283 toploop: 5284 while (it.hasNext()) { 5285 UriPermission perm = it.next(); 5286 Uri targetUri = perm.uri; 5287 if (!authority.equals(targetUri.getAuthority())) { 5288 continue; 5289 } 5290 List<String> targetSegments = targetUri.getPathSegments(); 5291 if (targetSegments == null) { 5292 continue; 5293 } 5294 if (targetSegments.size() < NS) { 5295 continue; 5296 } 5297 for (int j=0; j<NS; j++) { 5298 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5299 continue toploop; 5300 } 5301 } 5302 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5303 "Revoking " + perm.uid + " permission to " + perm.uri); 5304 perm.clearModes(modeFlags); 5305 if (perm.modeFlags == 0) { 5306 it.remove(); 5307 } 5308 } 5309 if (perms.size() == 0) { 5310 mGrantedUriPermissions.remove( 5311 mGrantedUriPermissions.keyAt(i)); 5312 N--; 5313 i--; 5314 } 5315 } 5316 } 5317 } 5318 5319 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5320 int modeFlags) { 5321 enforceNotIsolatedCaller("revokeUriPermission"); 5322 synchronized(this) { 5323 final ProcessRecord r = getRecordForAppLocked(caller); 5324 if (r == null) { 5325 throw new SecurityException("Unable to find app for caller " 5326 + caller 5327 + " when revoking permission to uri " + uri); 5328 } 5329 if (uri == null) { 5330 Slog.w(TAG, "revokeUriPermission: null uri"); 5331 return; 5332 } 5333 5334 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5335 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5336 if (modeFlags == 0) { 5337 return; 5338 } 5339 5340 final IPackageManager pm = AppGlobals.getPackageManager(); 5341 5342 final String authority = uri.getAuthority(); 5343 ProviderInfo pi = null; 5344 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5345 if (cpr != null) { 5346 pi = cpr.info; 5347 } else { 5348 try { 5349 pi = pm.resolveContentProvider(authority, 5350 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5351 } catch (RemoteException ex) { 5352 } 5353 } 5354 if (pi == null) { 5355 Slog.w(TAG, "No content provider found for permission revoke: " 5356 + uri.toSafeString()); 5357 return; 5358 } 5359 5360 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5361 } 5362 } 5363 5364 @Override 5365 public IBinder newUriPermissionOwner(String name) { 5366 enforceNotIsolatedCaller("newUriPermissionOwner"); 5367 synchronized(this) { 5368 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5369 return owner.getExternalTokenLocked(); 5370 } 5371 } 5372 5373 @Override 5374 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5375 Uri uri, int modeFlags) { 5376 synchronized(this) { 5377 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5378 if (owner == null) { 5379 throw new IllegalArgumentException("Unknown owner: " + token); 5380 } 5381 if (fromUid != Binder.getCallingUid()) { 5382 if (Binder.getCallingUid() != Process.myUid()) { 5383 // Only system code can grant URI permissions on behalf 5384 // of other users. 5385 throw new SecurityException("nice try"); 5386 } 5387 } 5388 if (targetPkg == null) { 5389 throw new IllegalArgumentException("null target"); 5390 } 5391 if (uri == null) { 5392 throw new IllegalArgumentException("null uri"); 5393 } 5394 5395 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5396 } 5397 } 5398 5399 @Override 5400 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5401 synchronized(this) { 5402 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5403 if (owner == null) { 5404 throw new IllegalArgumentException("Unknown owner: " + token); 5405 } 5406 5407 if (uri == null) { 5408 owner.removeUriPermissionsLocked(mode); 5409 } else { 5410 owner.removeUriPermissionLocked(uri, mode); 5411 } 5412 } 5413 } 5414 5415 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5416 synchronized (this) { 5417 ProcessRecord app = 5418 who != null ? getRecordForAppLocked(who) : null; 5419 if (app == null) return; 5420 5421 Message msg = Message.obtain(); 5422 msg.what = WAIT_FOR_DEBUGGER_MSG; 5423 msg.obj = app; 5424 msg.arg1 = waiting ? 1 : 0; 5425 mHandler.sendMessage(msg); 5426 } 5427 } 5428 5429 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5430 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5431 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5432 outInfo.availMem = Process.getFreeMemory(); 5433 outInfo.totalMem = Process.getTotalMemory(); 5434 outInfo.threshold = homeAppMem; 5435 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5436 outInfo.hiddenAppThreshold = hiddenAppMem; 5437 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5438 ProcessList.SERVICE_ADJ); 5439 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5440 ProcessList.VISIBLE_APP_ADJ); 5441 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5442 ProcessList.FOREGROUND_APP_ADJ); 5443 } 5444 5445 // ========================================================= 5446 // TASK MANAGEMENT 5447 // ========================================================= 5448 5449 public List getTasks(int maxNum, int flags, 5450 IThumbnailReceiver receiver) { 5451 ArrayList list = new ArrayList(); 5452 5453 PendingThumbnailsRecord pending = null; 5454 IApplicationThread topThumbnail = null; 5455 ActivityRecord topRecord = null; 5456 5457 synchronized(this) { 5458 if (localLOGV) Slog.v( 5459 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5460 + ", receiver=" + receiver); 5461 5462 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5463 != PackageManager.PERMISSION_GRANTED) { 5464 if (receiver != null) { 5465 // If the caller wants to wait for pending thumbnails, 5466 // it ain't gonna get them. 5467 try { 5468 receiver.finished(); 5469 } catch (RemoteException ex) { 5470 } 5471 } 5472 String msg = "Permission Denial: getTasks() from pid=" 5473 + Binder.getCallingPid() 5474 + ", uid=" + Binder.getCallingUid() 5475 + " requires " + android.Manifest.permission.GET_TASKS; 5476 Slog.w(TAG, msg); 5477 throw new SecurityException(msg); 5478 } 5479 5480 int pos = mMainStack.mHistory.size()-1; 5481 ActivityRecord next = 5482 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5483 ActivityRecord top = null; 5484 TaskRecord curTask = null; 5485 int numActivities = 0; 5486 int numRunning = 0; 5487 while (pos >= 0 && maxNum > 0) { 5488 final ActivityRecord r = next; 5489 pos--; 5490 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5491 5492 // Initialize state for next task if needed. 5493 if (top == null || 5494 (top.state == ActivityState.INITIALIZING 5495 && top.task == r.task)) { 5496 top = r; 5497 curTask = r.task; 5498 numActivities = numRunning = 0; 5499 } 5500 5501 // Add 'r' into the current task. 5502 numActivities++; 5503 if (r.app != null && r.app.thread != null) { 5504 numRunning++; 5505 } 5506 5507 if (localLOGV) Slog.v( 5508 TAG, r.intent.getComponent().flattenToShortString() 5509 + ": task=" + r.task); 5510 5511 // If the next one is a different task, generate a new 5512 // TaskInfo entry for what we have. 5513 if (next == null || next.task != curTask) { 5514 ActivityManager.RunningTaskInfo ci 5515 = new ActivityManager.RunningTaskInfo(); 5516 ci.id = curTask.taskId; 5517 ci.baseActivity = r.intent.getComponent(); 5518 ci.topActivity = top.intent.getComponent(); 5519 if (top.thumbHolder != null) { 5520 ci.description = top.thumbHolder.lastDescription; 5521 } 5522 ci.numActivities = numActivities; 5523 ci.numRunning = numRunning; 5524 //System.out.println( 5525 // "#" + maxNum + ": " + " descr=" + ci.description); 5526 if (ci.thumbnail == null && receiver != null) { 5527 if (localLOGV) Slog.v( 5528 TAG, "State=" + top.state + "Idle=" + top.idle 5529 + " app=" + top.app 5530 + " thr=" + (top.app != null ? top.app.thread : null)); 5531 if (top.state == ActivityState.RESUMED 5532 || top.state == ActivityState.PAUSING) { 5533 if (top.idle && top.app != null 5534 && top.app.thread != null) { 5535 topRecord = top; 5536 topThumbnail = top.app.thread; 5537 } else { 5538 top.thumbnailNeeded = true; 5539 } 5540 } 5541 if (pending == null) { 5542 pending = new PendingThumbnailsRecord(receiver); 5543 } 5544 pending.pendingRecords.add(top); 5545 } 5546 list.add(ci); 5547 maxNum--; 5548 top = null; 5549 } 5550 } 5551 5552 if (pending != null) { 5553 mPendingThumbnails.add(pending); 5554 } 5555 } 5556 5557 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5558 5559 if (topThumbnail != null) { 5560 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5561 try { 5562 topThumbnail.requestThumbnail(topRecord.appToken); 5563 } catch (Exception e) { 5564 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5565 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5566 } 5567 } 5568 5569 if (pending == null && receiver != null) { 5570 // In this case all thumbnails were available and the client 5571 // is being asked to be told when the remaining ones come in... 5572 // which is unusually, since the top-most currently running 5573 // activity should never have a canned thumbnail! Oh well. 5574 try { 5575 receiver.finished(); 5576 } catch (RemoteException ex) { 5577 } 5578 } 5579 5580 return list; 5581 } 5582 5583 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5584 int flags, int userId) { 5585 final int callingUid = Binder.getCallingUid(); 5586 if (userId != UserHandle.getCallingUserId()) { 5587 // Check if the caller is holding permissions for cross-user requests. 5588 if (checkComponentPermission( 5589 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5590 Binder.getCallingPid(), callingUid, -1, true) 5591 != PackageManager.PERMISSION_GRANTED) { 5592 String msg = "Permission Denial: " 5593 + "Request to get recent tasks for user " + userId 5594 + " but is calling from user " + UserHandle.getUserId(callingUid) 5595 + "; this requires " 5596 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5597 Slog.w(TAG, msg); 5598 throw new SecurityException(msg); 5599 } else { 5600 if (userId == UserHandle.USER_CURRENT) { 5601 userId = mCurrentUserId; 5602 } 5603 } 5604 } 5605 5606 synchronized (this) { 5607 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5608 "getRecentTasks()"); 5609 final boolean detailed = checkCallingPermission( 5610 android.Manifest.permission.GET_DETAILED_TASKS) 5611 == PackageManager.PERMISSION_GRANTED; 5612 5613 IPackageManager pm = AppGlobals.getPackageManager(); 5614 5615 final int N = mRecentTasks.size(); 5616 ArrayList<ActivityManager.RecentTaskInfo> res 5617 = new ArrayList<ActivityManager.RecentTaskInfo>( 5618 maxNum < N ? maxNum : N); 5619 for (int i=0; i<N && maxNum > 0; i++) { 5620 TaskRecord tr = mRecentTasks.get(i); 5621 // Only add calling user's recent tasks 5622 if (tr.userId != userId) continue; 5623 // Return the entry if desired by the caller. We always return 5624 // the first entry, because callers always expect this to be the 5625 // foreground app. We may filter others if the caller has 5626 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5627 // we should exclude the entry. 5628 5629 if (i == 0 5630 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5631 || (tr.intent == null) 5632 || ((tr.intent.getFlags() 5633 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5634 ActivityManager.RecentTaskInfo rti 5635 = new ActivityManager.RecentTaskInfo(); 5636 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5637 rti.persistentId = tr.taskId; 5638 rti.baseIntent = new Intent( 5639 tr.intent != null ? tr.intent : tr.affinityIntent); 5640 if (!detailed) { 5641 rti.baseIntent.replaceExtras((Bundle)null); 5642 } 5643 rti.origActivity = tr.origActivity; 5644 rti.description = tr.lastDescription; 5645 5646 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5647 // Check whether this activity is currently available. 5648 try { 5649 if (rti.origActivity != null) { 5650 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5651 == null) { 5652 continue; 5653 } 5654 } else if (rti.baseIntent != null) { 5655 if (pm.queryIntentActivities(rti.baseIntent, 5656 null, 0, userId) == null) { 5657 continue; 5658 } 5659 } 5660 } catch (RemoteException e) { 5661 // Will never happen. 5662 } 5663 } 5664 5665 res.add(rti); 5666 maxNum--; 5667 } 5668 } 5669 return res; 5670 } 5671 } 5672 5673 private TaskRecord taskForIdLocked(int id) { 5674 final int N = mRecentTasks.size(); 5675 for (int i=0; i<N; i++) { 5676 TaskRecord tr = mRecentTasks.get(i); 5677 if (tr.taskId == id) { 5678 return tr; 5679 } 5680 } 5681 return null; 5682 } 5683 5684 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5685 synchronized (this) { 5686 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5687 "getTaskThumbnails()"); 5688 TaskRecord tr = taskForIdLocked(id); 5689 if (tr != null) { 5690 return mMainStack.getTaskThumbnailsLocked(tr); 5691 } 5692 } 5693 return null; 5694 } 5695 5696 public boolean removeSubTask(int taskId, int subTaskIndex) { 5697 synchronized (this) { 5698 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5699 "removeSubTask()"); 5700 long ident = Binder.clearCallingIdentity(); 5701 try { 5702 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5703 true) != null; 5704 } finally { 5705 Binder.restoreCallingIdentity(ident); 5706 } 5707 } 5708 } 5709 5710 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5711 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5712 Intent baseIntent = new Intent( 5713 tr.intent != null ? tr.intent : tr.affinityIntent); 5714 ComponentName component = baseIntent.getComponent(); 5715 if (component == null) { 5716 Slog.w(TAG, "Now component for base intent of task: " + tr); 5717 return; 5718 } 5719 5720 // Find any running services associated with this app. 5721 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5722 5723 if (killProcesses) { 5724 // Find any running processes associated with this app. 5725 final String pkg = component.getPackageName(); 5726 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5727 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5728 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5729 for (int i=0; i<uids.size(); i++) { 5730 ProcessRecord proc = uids.valueAt(i); 5731 if (proc.userId != tr.userId) { 5732 continue; 5733 } 5734 if (!proc.pkgList.contains(pkg)) { 5735 continue; 5736 } 5737 procs.add(proc); 5738 } 5739 } 5740 5741 // Kill the running processes. 5742 for (int i=0; i<procs.size(); i++) { 5743 ProcessRecord pr = procs.get(i); 5744 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5745 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5746 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5747 pr.processName, pr.setAdj, "remove task"); 5748 pr.killedBackground = true; 5749 Process.killProcessQuiet(pr.pid); 5750 } else { 5751 pr.waitingToKill = "remove task"; 5752 } 5753 } 5754 } 5755 } 5756 5757 public boolean removeTask(int taskId, int flags) { 5758 synchronized (this) { 5759 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5760 "removeTask()"); 5761 long ident = Binder.clearCallingIdentity(); 5762 try { 5763 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5764 false); 5765 if (r != null) { 5766 mRecentTasks.remove(r.task); 5767 cleanUpRemovedTaskLocked(r.task, flags); 5768 return true; 5769 } else { 5770 TaskRecord tr = null; 5771 int i=0; 5772 while (i < mRecentTasks.size()) { 5773 TaskRecord t = mRecentTasks.get(i); 5774 if (t.taskId == taskId) { 5775 tr = t; 5776 break; 5777 } 5778 i++; 5779 } 5780 if (tr != null) { 5781 if (tr.numActivities <= 0) { 5782 // Caller is just removing a recent task that is 5783 // not actively running. That is easy! 5784 mRecentTasks.remove(i); 5785 cleanUpRemovedTaskLocked(tr, flags); 5786 return true; 5787 } else { 5788 Slog.w(TAG, "removeTask: task " + taskId 5789 + " does not have activities to remove, " 5790 + " but numActivities=" + tr.numActivities 5791 + ": " + tr); 5792 } 5793 } 5794 } 5795 } finally { 5796 Binder.restoreCallingIdentity(ident); 5797 } 5798 } 5799 return false; 5800 } 5801 5802 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5803 int j; 5804 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5805 TaskRecord jt = startTask; 5806 5807 // First look backwards 5808 for (j=startIndex-1; j>=0; j--) { 5809 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5810 if (r.task != jt) { 5811 jt = r.task; 5812 if (affinity.equals(jt.affinity)) { 5813 return j; 5814 } 5815 } 5816 } 5817 5818 // Now look forwards 5819 final int N = mMainStack.mHistory.size(); 5820 jt = startTask; 5821 for (j=startIndex+1; j<N; j++) { 5822 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5823 if (r.task != jt) { 5824 if (affinity.equals(jt.affinity)) { 5825 return j; 5826 } 5827 jt = r.task; 5828 } 5829 } 5830 5831 // Might it be at the top? 5832 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5833 return N-1; 5834 } 5835 5836 return -1; 5837 } 5838 5839 /** 5840 * TODO: Add mController hook 5841 */ 5842 public void moveTaskToFront(int task, int flags, Bundle options) { 5843 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5844 "moveTaskToFront()"); 5845 5846 synchronized(this) { 5847 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5848 Binder.getCallingUid(), "Task to front")) { 5849 ActivityOptions.abort(options); 5850 return; 5851 } 5852 final long origId = Binder.clearCallingIdentity(); 5853 try { 5854 TaskRecord tr = taskForIdLocked(task); 5855 if (tr != null) { 5856 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5857 mMainStack.mUserLeaving = true; 5858 } 5859 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5860 // Caller wants the home activity moved with it. To accomplish this, 5861 // we'll just move the home task to the top first. 5862 mMainStack.moveHomeToFrontLocked(); 5863 } 5864 mMainStack.moveTaskToFrontLocked(tr, null, options); 5865 return; 5866 } 5867 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5868 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5869 if (hr.task.taskId == task) { 5870 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5871 mMainStack.mUserLeaving = true; 5872 } 5873 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5874 // Caller wants the home activity moved with it. To accomplish this, 5875 // we'll just move the home task to the top first. 5876 mMainStack.moveHomeToFrontLocked(); 5877 } 5878 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5879 return; 5880 } 5881 } 5882 } finally { 5883 Binder.restoreCallingIdentity(origId); 5884 } 5885 ActivityOptions.abort(options); 5886 } 5887 } 5888 5889 public void moveTaskToBack(int task) { 5890 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5891 "moveTaskToBack()"); 5892 5893 synchronized(this) { 5894 if (mMainStack.mResumedActivity != null 5895 && mMainStack.mResumedActivity.task.taskId == task) { 5896 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5897 Binder.getCallingUid(), "Task to back")) { 5898 return; 5899 } 5900 } 5901 final long origId = Binder.clearCallingIdentity(); 5902 mMainStack.moveTaskToBackLocked(task, null); 5903 Binder.restoreCallingIdentity(origId); 5904 } 5905 } 5906 5907 /** 5908 * Moves an activity, and all of the other activities within the same task, to the bottom 5909 * of the history stack. The activity's order within the task is unchanged. 5910 * 5911 * @param token A reference to the activity we wish to move 5912 * @param nonRoot If false then this only works if the activity is the root 5913 * of a task; if true it will work for any activity in a task. 5914 * @return Returns true if the move completed, false if not. 5915 */ 5916 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5917 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5918 synchronized(this) { 5919 final long origId = Binder.clearCallingIdentity(); 5920 int taskId = getTaskForActivityLocked(token, !nonRoot); 5921 if (taskId >= 0) { 5922 return mMainStack.moveTaskToBackLocked(taskId, null); 5923 } 5924 Binder.restoreCallingIdentity(origId); 5925 } 5926 return false; 5927 } 5928 5929 public void moveTaskBackwards(int task) { 5930 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5931 "moveTaskBackwards()"); 5932 5933 synchronized(this) { 5934 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5935 Binder.getCallingUid(), "Task backwards")) { 5936 return; 5937 } 5938 final long origId = Binder.clearCallingIdentity(); 5939 moveTaskBackwardsLocked(task); 5940 Binder.restoreCallingIdentity(origId); 5941 } 5942 } 5943 5944 private final void moveTaskBackwardsLocked(int task) { 5945 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5946 } 5947 5948 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5949 synchronized(this) { 5950 return getTaskForActivityLocked(token, onlyRoot); 5951 } 5952 } 5953 5954 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5955 final int N = mMainStack.mHistory.size(); 5956 TaskRecord lastTask = null; 5957 for (int i=0; i<N; i++) { 5958 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5959 if (r.appToken == token) { 5960 if (!onlyRoot || lastTask != r.task) { 5961 return r.task.taskId; 5962 } 5963 return -1; 5964 } 5965 lastTask = r.task; 5966 } 5967 5968 return -1; 5969 } 5970 5971 // ========================================================= 5972 // THUMBNAILS 5973 // ========================================================= 5974 5975 public void reportThumbnail(IBinder token, 5976 Bitmap thumbnail, CharSequence description) { 5977 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5978 final long origId = Binder.clearCallingIdentity(); 5979 sendPendingThumbnail(null, token, thumbnail, description, true); 5980 Binder.restoreCallingIdentity(origId); 5981 } 5982 5983 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5984 Bitmap thumbnail, CharSequence description, boolean always) { 5985 TaskRecord task = null; 5986 ArrayList receivers = null; 5987 5988 //System.out.println("Send pending thumbnail: " + r); 5989 5990 synchronized(this) { 5991 if (r == null) { 5992 r = mMainStack.isInStackLocked(token); 5993 if (r == null) { 5994 return; 5995 } 5996 } 5997 if (thumbnail == null && r.thumbHolder != null) { 5998 thumbnail = r.thumbHolder.lastThumbnail; 5999 description = r.thumbHolder.lastDescription; 6000 } 6001 if (thumbnail == null && !always) { 6002 // If there is no thumbnail, and this entry is not actually 6003 // going away, then abort for now and pick up the next 6004 // thumbnail we get. 6005 return; 6006 } 6007 task = r.task; 6008 6009 int N = mPendingThumbnails.size(); 6010 int i=0; 6011 while (i<N) { 6012 PendingThumbnailsRecord pr = 6013 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6014 //System.out.println("Looking in " + pr.pendingRecords); 6015 if (pr.pendingRecords.remove(r)) { 6016 if (receivers == null) { 6017 receivers = new ArrayList(); 6018 } 6019 receivers.add(pr); 6020 if (pr.pendingRecords.size() == 0) { 6021 pr.finished = true; 6022 mPendingThumbnails.remove(i); 6023 N--; 6024 continue; 6025 } 6026 } 6027 i++; 6028 } 6029 } 6030 6031 if (receivers != null) { 6032 final int N = receivers.size(); 6033 for (int i=0; i<N; i++) { 6034 try { 6035 PendingThumbnailsRecord pr = 6036 (PendingThumbnailsRecord)receivers.get(i); 6037 pr.receiver.newThumbnail( 6038 task != null ? task.taskId : -1, thumbnail, description); 6039 if (pr.finished) { 6040 pr.receiver.finished(); 6041 } 6042 } catch (Exception e) { 6043 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6044 } 6045 } 6046 } 6047 } 6048 6049 // ========================================================= 6050 // CONTENT PROVIDERS 6051 // ========================================================= 6052 6053 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6054 List<ProviderInfo> providers = null; 6055 try { 6056 providers = AppGlobals.getPackageManager(). 6057 queryContentProviders(app.processName, app.uid, 6058 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6059 } catch (RemoteException ex) { 6060 } 6061 if (DEBUG_MU) 6062 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6063 int userId = app.userId; 6064 if (providers != null) { 6065 int N = providers.size(); 6066 for (int i=0; i<N; i++) { 6067 ProviderInfo cpi = 6068 (ProviderInfo)providers.get(i); 6069 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6070 cpi.name, cpi.flags); 6071 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6072 // This is a singleton provider, but a user besides the 6073 // default user is asking to initialize a process it runs 6074 // in... well, no, it doesn't actually run in this process, 6075 // it runs in the process of the default user. Get rid of it. 6076 providers.remove(i); 6077 N--; 6078 continue; 6079 } 6080 6081 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6082 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6083 if (cpr == null) { 6084 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6085 mProviderMap.putProviderByClass(comp, cpr); 6086 } 6087 if (DEBUG_MU) 6088 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6089 app.pubProviders.put(cpi.name, cpr); 6090 app.addPackage(cpi.applicationInfo.packageName); 6091 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6092 } 6093 } 6094 return providers; 6095 } 6096 6097 /** 6098 * Check if {@link ProcessRecord} has a possible chance at accessing the 6099 * given {@link ProviderInfo}. Final permission checking is always done 6100 * in {@link ContentProvider}. 6101 */ 6102 private final String checkContentProviderPermissionLocked( 6103 ProviderInfo cpi, ProcessRecord r) { 6104 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6105 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6106 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6107 cpi.applicationInfo.uid, cpi.exported) 6108 == PackageManager.PERMISSION_GRANTED) { 6109 return null; 6110 } 6111 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6112 cpi.applicationInfo.uid, cpi.exported) 6113 == PackageManager.PERMISSION_GRANTED) { 6114 return null; 6115 } 6116 6117 PathPermission[] pps = cpi.pathPermissions; 6118 if (pps != null) { 6119 int i = pps.length; 6120 while (i > 0) { 6121 i--; 6122 PathPermission pp = pps[i]; 6123 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6124 cpi.applicationInfo.uid, cpi.exported) 6125 == PackageManager.PERMISSION_GRANTED) { 6126 return null; 6127 } 6128 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6129 cpi.applicationInfo.uid, cpi.exported) 6130 == PackageManager.PERMISSION_GRANTED) { 6131 return null; 6132 } 6133 } 6134 } 6135 6136 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6137 if (perms != null) { 6138 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6139 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6140 return null; 6141 } 6142 } 6143 } 6144 6145 String msg; 6146 if (!cpi.exported) { 6147 msg = "Permission Denial: opening provider " + cpi.name 6148 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6149 + ", uid=" + callingUid + ") that is not exported from uid " 6150 + cpi.applicationInfo.uid; 6151 } else { 6152 msg = "Permission Denial: opening provider " + cpi.name 6153 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6154 + ", uid=" + callingUid + ") requires " 6155 + cpi.readPermission + " or " + cpi.writePermission; 6156 } 6157 Slog.w(TAG, msg); 6158 return msg; 6159 } 6160 6161 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6162 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6163 if (r != null) { 6164 for (int i=0; i<r.conProviders.size(); i++) { 6165 ContentProviderConnection conn = r.conProviders.get(i); 6166 if (conn.provider == cpr) { 6167 if (DEBUG_PROVIDER) Slog.v(TAG, 6168 "Adding provider requested by " 6169 + r.processName + " from process " 6170 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6171 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6172 if (stable) { 6173 conn.stableCount++; 6174 conn.numStableIncs++; 6175 } else { 6176 conn.unstableCount++; 6177 conn.numUnstableIncs++; 6178 } 6179 return conn; 6180 } 6181 } 6182 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6183 if (stable) { 6184 conn.stableCount = 1; 6185 conn.numStableIncs = 1; 6186 } else { 6187 conn.unstableCount = 1; 6188 conn.numUnstableIncs = 1; 6189 } 6190 cpr.connections.add(conn); 6191 r.conProviders.add(conn); 6192 return conn; 6193 } 6194 cpr.addExternalProcessHandleLocked(externalProcessToken); 6195 return null; 6196 } 6197 6198 boolean decProviderCountLocked(ContentProviderConnection conn, 6199 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6200 if (conn != null) { 6201 cpr = conn.provider; 6202 if (DEBUG_PROVIDER) Slog.v(TAG, 6203 "Removing provider requested by " 6204 + conn.client.processName + " from process " 6205 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6206 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6207 if (stable) { 6208 conn.stableCount--; 6209 } else { 6210 conn.unstableCount--; 6211 } 6212 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6213 cpr.connections.remove(conn); 6214 conn.client.conProviders.remove(conn); 6215 return true; 6216 } 6217 return false; 6218 } 6219 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6220 return false; 6221 } 6222 6223 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6224 String name, IBinder token, boolean stable, int userId) { 6225 ContentProviderRecord cpr; 6226 ContentProviderConnection conn = null; 6227 ProviderInfo cpi = null; 6228 6229 synchronized(this) { 6230 ProcessRecord r = null; 6231 if (caller != null) { 6232 r = getRecordForAppLocked(caller); 6233 if (r == null) { 6234 throw new SecurityException( 6235 "Unable to find app for caller " + caller 6236 + " (pid=" + Binder.getCallingPid() 6237 + ") when getting content provider " + name); 6238 } 6239 if (r.userId != userId) { 6240 throw new SecurityException("Calling requested user " + userId 6241 + " but app is user " + r.userId); 6242 } 6243 } 6244 6245 // First check if this content provider has been published... 6246 cpr = mProviderMap.getProviderByName(name, userId); 6247 boolean providerRunning = cpr != null; 6248 if (providerRunning) { 6249 cpi = cpr.info; 6250 String msg; 6251 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6252 throw new SecurityException(msg); 6253 } 6254 6255 if (r != null && cpr.canRunHere(r)) { 6256 // This provider has been published or is in the process 6257 // of being published... but it is also allowed to run 6258 // in the caller's process, so don't make a connection 6259 // and just let the caller instantiate its own instance. 6260 ContentProviderHolder holder = cpr.newHolder(null); 6261 // don't give caller the provider object, it needs 6262 // to make its own. 6263 holder.provider = null; 6264 return holder; 6265 } 6266 6267 final long origId = Binder.clearCallingIdentity(); 6268 6269 // In this case the provider instance already exists, so we can 6270 // return it right away. 6271 conn = incProviderCountLocked(r, cpr, token, stable); 6272 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6273 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6274 // If this is a perceptible app accessing the provider, 6275 // make sure to count it as being accessed and thus 6276 // back up on the LRU list. This is good because 6277 // content providers are often expensive to start. 6278 updateLruProcessLocked(cpr.proc, false, true); 6279 } 6280 } 6281 6282 if (cpr.proc != null) { 6283 if (false) { 6284 if (cpr.name.flattenToShortString().equals( 6285 "com.android.providers.calendar/.CalendarProvider2")) { 6286 Slog.v(TAG, "****************** KILLING " 6287 + cpr.name.flattenToShortString()); 6288 Process.killProcess(cpr.proc.pid); 6289 } 6290 } 6291 boolean success = updateOomAdjLocked(cpr.proc); 6292 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6293 // NOTE: there is still a race here where a signal could be 6294 // pending on the process even though we managed to update its 6295 // adj level. Not sure what to do about this, but at least 6296 // the race is now smaller. 6297 if (!success) { 6298 // Uh oh... it looks like the provider's process 6299 // has been killed on us. We need to wait for a new 6300 // process to be started, and make sure its death 6301 // doesn't kill our process. 6302 Slog.i(TAG, 6303 "Existing provider " + cpr.name.flattenToShortString() 6304 + " is crashing; detaching " + r); 6305 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6306 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6307 if (!lastRef) { 6308 // This wasn't the last ref our process had on 6309 // the provider... we have now been killed, bail. 6310 return null; 6311 } 6312 providerRunning = false; 6313 conn = null; 6314 } 6315 } 6316 6317 Binder.restoreCallingIdentity(origId); 6318 } 6319 6320 boolean singleton; 6321 if (!providerRunning) { 6322 try { 6323 cpi = AppGlobals.getPackageManager(). 6324 resolveContentProvider(name, 6325 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6326 } catch (RemoteException ex) { 6327 } 6328 if (cpi == null) { 6329 return null; 6330 } 6331 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6332 cpi.name, cpi.flags); 6333 if (singleton) { 6334 userId = 0; 6335 } 6336 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6337 6338 String msg; 6339 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6340 throw new SecurityException(msg); 6341 } 6342 6343 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6344 && !cpi.processName.equals("system")) { 6345 // If this content provider does not run in the system 6346 // process, and the system is not yet ready to run other 6347 // processes, then fail fast instead of hanging. 6348 throw new IllegalArgumentException( 6349 "Attempt to launch content provider before system ready"); 6350 } 6351 6352 // Make sure that the user who owns this provider is started. If not, 6353 // we don't want to allow it to run. 6354 if (mStartedUsers.get(userId) == null) { 6355 Slog.w(TAG, "Unable to launch app " 6356 + cpi.applicationInfo.packageName + "/" 6357 + cpi.applicationInfo.uid + " for provider " 6358 + name + ": user " + userId + " is stopped"); 6359 return null; 6360 } 6361 6362 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6363 cpr = mProviderMap.getProviderByClass(comp, userId); 6364 final boolean firstClass = cpr == null; 6365 if (firstClass) { 6366 try { 6367 ApplicationInfo ai = 6368 AppGlobals.getPackageManager(). 6369 getApplicationInfo( 6370 cpi.applicationInfo.packageName, 6371 STOCK_PM_FLAGS, userId); 6372 if (ai == null) { 6373 Slog.w(TAG, "No package info for content provider " 6374 + cpi.name); 6375 return null; 6376 } 6377 ai = getAppInfoForUser(ai, userId); 6378 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6379 } catch (RemoteException ex) { 6380 // pm is in same process, this will never happen. 6381 } 6382 } 6383 6384 if (r != null && cpr.canRunHere(r)) { 6385 // If this is a multiprocess provider, then just return its 6386 // info and allow the caller to instantiate it. Only do 6387 // this if the provider is the same user as the caller's 6388 // process, or can run as root (so can be in any process). 6389 return cpr.newHolder(null); 6390 } 6391 6392 if (DEBUG_PROVIDER) { 6393 RuntimeException e = new RuntimeException("here"); 6394 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6395 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6396 } 6397 6398 // This is single process, and our app is now connecting to it. 6399 // See if we are already in the process of launching this 6400 // provider. 6401 final int N = mLaunchingProviders.size(); 6402 int i; 6403 for (i=0; i<N; i++) { 6404 if (mLaunchingProviders.get(i) == cpr) { 6405 break; 6406 } 6407 } 6408 6409 // If the provider is not already being launched, then get it 6410 // started. 6411 if (i >= N) { 6412 final long origId = Binder.clearCallingIdentity(); 6413 6414 try { 6415 // Content provider is now in use, its package can't be stopped. 6416 try { 6417 AppGlobals.getPackageManager().setPackageStoppedState( 6418 cpr.appInfo.packageName, false, userId); 6419 } catch (RemoteException e) { 6420 } catch (IllegalArgumentException e) { 6421 Slog.w(TAG, "Failed trying to unstop package " 6422 + cpr.appInfo.packageName + ": " + e); 6423 } 6424 6425 ProcessRecord proc = startProcessLocked(cpi.processName, 6426 cpr.appInfo, false, 0, "content provider", 6427 new ComponentName(cpi.applicationInfo.packageName, 6428 cpi.name), false, false); 6429 if (proc == null) { 6430 Slog.w(TAG, "Unable to launch app " 6431 + cpi.applicationInfo.packageName + "/" 6432 + cpi.applicationInfo.uid + " for provider " 6433 + name + ": process is bad"); 6434 return null; 6435 } 6436 cpr.launchingApp = proc; 6437 mLaunchingProviders.add(cpr); 6438 } finally { 6439 Binder.restoreCallingIdentity(origId); 6440 } 6441 } 6442 6443 // Make sure the provider is published (the same provider class 6444 // may be published under multiple names). 6445 if (firstClass) { 6446 mProviderMap.putProviderByClass(comp, cpr); 6447 } 6448 6449 mProviderMap.putProviderByName(name, cpr); 6450 conn = incProviderCountLocked(r, cpr, token, stable); 6451 if (conn != null) { 6452 conn.waiting = true; 6453 } 6454 } 6455 } 6456 6457 // Wait for the provider to be published... 6458 synchronized (cpr) { 6459 while (cpr.provider == null) { 6460 if (cpr.launchingApp == null) { 6461 Slog.w(TAG, "Unable to launch app " 6462 + cpi.applicationInfo.packageName + "/" 6463 + cpi.applicationInfo.uid + " for provider " 6464 + name + ": launching app became null"); 6465 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6466 cpi.applicationInfo.packageName, 6467 cpi.applicationInfo.uid, name); 6468 return null; 6469 } 6470 try { 6471 if (DEBUG_MU) { 6472 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6473 + cpr.launchingApp); 6474 } 6475 if (conn != null) { 6476 conn.waiting = true; 6477 } 6478 cpr.wait(); 6479 } catch (InterruptedException ex) { 6480 } finally { 6481 if (conn != null) { 6482 conn.waiting = false; 6483 } 6484 } 6485 } 6486 } 6487 return cpr != null ? cpr.newHolder(conn) : null; 6488 } 6489 6490 public final ContentProviderHolder getContentProvider( 6491 IApplicationThread caller, String name, boolean stable) { 6492 enforceNotIsolatedCaller("getContentProvider"); 6493 if (caller == null) { 6494 String msg = "null IApplicationThread when getting content provider " 6495 + name; 6496 Slog.w(TAG, msg); 6497 throw new SecurityException(msg); 6498 } 6499 6500 return getContentProviderImpl(caller, name, null, stable, 6501 UserHandle.getCallingUserId()); 6502 } 6503 6504 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6505 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6506 "Do not have permission in call getContentProviderExternal()"); 6507 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6508 } 6509 6510 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6511 IBinder token, int userId) { 6512 return getContentProviderImpl(null, name, token, true, userId); 6513 } 6514 6515 /** 6516 * Drop a content provider from a ProcessRecord's bookkeeping 6517 * @param cpr 6518 */ 6519 public void removeContentProvider(IBinder connection, boolean stable) { 6520 enforceNotIsolatedCaller("removeContentProvider"); 6521 synchronized (this) { 6522 ContentProviderConnection conn; 6523 try { 6524 conn = (ContentProviderConnection)connection; 6525 } catch (ClassCastException e) { 6526 String msg ="removeContentProvider: " + connection 6527 + " not a ContentProviderConnection"; 6528 Slog.w(TAG, msg); 6529 throw new IllegalArgumentException(msg); 6530 } 6531 if (conn == null) { 6532 throw new NullPointerException("connection is null"); 6533 } 6534 if (decProviderCountLocked(conn, null, null, stable)) { 6535 updateOomAdjLocked(); 6536 } 6537 } 6538 } 6539 6540 public void removeContentProviderExternal(String name, IBinder token) { 6541 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6542 "Do not have permission in call removeContentProviderExternal()"); 6543 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6544 } 6545 6546 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6547 synchronized (this) { 6548 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6549 if(cpr == null) { 6550 //remove from mProvidersByClass 6551 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6552 return; 6553 } 6554 6555 //update content provider record entry info 6556 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6557 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6558 if (localCpr.hasExternalProcessHandles()) { 6559 if (localCpr.removeExternalProcessHandleLocked(token)) { 6560 updateOomAdjLocked(); 6561 } else { 6562 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6563 + " with no external reference for token: " 6564 + token + "."); 6565 } 6566 } else { 6567 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6568 + " with no external references."); 6569 } 6570 } 6571 } 6572 6573 public final void publishContentProviders(IApplicationThread caller, 6574 List<ContentProviderHolder> providers) { 6575 if (providers == null) { 6576 return; 6577 } 6578 6579 enforceNotIsolatedCaller("publishContentProviders"); 6580 synchronized (this) { 6581 final ProcessRecord r = getRecordForAppLocked(caller); 6582 if (DEBUG_MU) 6583 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6584 if (r == null) { 6585 throw new SecurityException( 6586 "Unable to find app for caller " + caller 6587 + " (pid=" + Binder.getCallingPid() 6588 + ") when publishing content providers"); 6589 } 6590 6591 final long origId = Binder.clearCallingIdentity(); 6592 6593 final int N = providers.size(); 6594 for (int i=0; i<N; i++) { 6595 ContentProviderHolder src = providers.get(i); 6596 if (src == null || src.info == null || src.provider == null) { 6597 continue; 6598 } 6599 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6600 if (DEBUG_MU) 6601 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6602 if (dst != null) { 6603 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6604 mProviderMap.putProviderByClass(comp, dst); 6605 String names[] = dst.info.authority.split(";"); 6606 for (int j = 0; j < names.length; j++) { 6607 mProviderMap.putProviderByName(names[j], dst); 6608 } 6609 6610 int NL = mLaunchingProviders.size(); 6611 int j; 6612 for (j=0; j<NL; j++) { 6613 if (mLaunchingProviders.get(j) == dst) { 6614 mLaunchingProviders.remove(j); 6615 j--; 6616 NL--; 6617 } 6618 } 6619 synchronized (dst) { 6620 dst.provider = src.provider; 6621 dst.proc = r; 6622 dst.notifyAll(); 6623 } 6624 updateOomAdjLocked(r); 6625 } 6626 } 6627 6628 Binder.restoreCallingIdentity(origId); 6629 } 6630 } 6631 6632 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6633 ContentProviderConnection conn; 6634 try { 6635 conn = (ContentProviderConnection)connection; 6636 } catch (ClassCastException e) { 6637 String msg ="refContentProvider: " + connection 6638 + " not a ContentProviderConnection"; 6639 Slog.w(TAG, msg); 6640 throw new IllegalArgumentException(msg); 6641 } 6642 if (conn == null) { 6643 throw new NullPointerException("connection is null"); 6644 } 6645 6646 synchronized (this) { 6647 if (stable > 0) { 6648 conn.numStableIncs += stable; 6649 } 6650 stable = conn.stableCount + stable; 6651 if (stable < 0) { 6652 throw new IllegalStateException("stableCount < 0: " + stable); 6653 } 6654 6655 if (unstable > 0) { 6656 conn.numUnstableIncs += unstable; 6657 } 6658 unstable = conn.unstableCount + unstable; 6659 if (unstable < 0) { 6660 throw new IllegalStateException("unstableCount < 0: " + unstable); 6661 } 6662 6663 if ((stable+unstable) <= 0) { 6664 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6665 + stable + " unstable=" + unstable); 6666 } 6667 conn.stableCount = stable; 6668 conn.unstableCount = unstable; 6669 return !conn.dead; 6670 } 6671 } 6672 6673 public void unstableProviderDied(IBinder connection) { 6674 ContentProviderConnection conn; 6675 try { 6676 conn = (ContentProviderConnection)connection; 6677 } catch (ClassCastException e) { 6678 String msg ="refContentProvider: " + connection 6679 + " not a ContentProviderConnection"; 6680 Slog.w(TAG, msg); 6681 throw new IllegalArgumentException(msg); 6682 } 6683 if (conn == null) { 6684 throw new NullPointerException("connection is null"); 6685 } 6686 6687 // Safely retrieve the content provider associated with the connection. 6688 IContentProvider provider; 6689 synchronized (this) { 6690 provider = conn.provider.provider; 6691 } 6692 6693 if (provider == null) { 6694 // Um, yeah, we're way ahead of you. 6695 return; 6696 } 6697 6698 // Make sure the caller is being honest with us. 6699 if (provider.asBinder().pingBinder()) { 6700 // Er, no, still looks good to us. 6701 synchronized (this) { 6702 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6703 + " says " + conn + " died, but we don't agree"); 6704 return; 6705 } 6706 } 6707 6708 // Well look at that! It's dead! 6709 synchronized (this) { 6710 if (conn.provider.provider != provider) { 6711 // But something changed... good enough. 6712 return; 6713 } 6714 6715 ProcessRecord proc = conn.provider.proc; 6716 if (proc == null || proc.thread == null) { 6717 // Seems like the process is already cleaned up. 6718 return; 6719 } 6720 6721 // As far as we're concerned, this is just like receiving a 6722 // death notification... just a bit prematurely. 6723 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6724 + ") early provider death"); 6725 final long ident = Binder.clearCallingIdentity(); 6726 try { 6727 appDiedLocked(proc, proc.pid, proc.thread); 6728 } finally { 6729 Binder.restoreCallingIdentity(ident); 6730 } 6731 } 6732 } 6733 6734 public static final void installSystemProviders() { 6735 List<ProviderInfo> providers; 6736 synchronized (mSelf) { 6737 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6738 providers = mSelf.generateApplicationProvidersLocked(app); 6739 if (providers != null) { 6740 for (int i=providers.size()-1; i>=0; i--) { 6741 ProviderInfo pi = (ProviderInfo)providers.get(i); 6742 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6743 Slog.w(TAG, "Not installing system proc provider " + pi.name 6744 + ": not system .apk"); 6745 providers.remove(i); 6746 } 6747 } 6748 } 6749 } 6750 if (providers != null) { 6751 mSystemThread.installSystemProviders(providers); 6752 } 6753 6754 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6755 6756 mSelf.mUsageStatsService.monitorPackages(); 6757 } 6758 6759 /** 6760 * Allows app to retrieve the MIME type of a URI without having permission 6761 * to access its content provider. 6762 * 6763 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6764 * 6765 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6766 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6767 */ 6768 public String getProviderMimeType(Uri uri) { 6769 enforceNotIsolatedCaller("getProviderMimeType"); 6770 final String name = uri.getAuthority(); 6771 final int userId = UserHandle.getCallingUserId(); 6772 final long ident = Binder.clearCallingIdentity(); 6773 ContentProviderHolder holder = null; 6774 6775 try { 6776 holder = getContentProviderExternalUnchecked(name, null, userId); 6777 if (holder != null) { 6778 return holder.provider.getType(uri); 6779 } 6780 } catch (RemoteException e) { 6781 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6782 return null; 6783 } finally { 6784 if (holder != null) { 6785 removeContentProviderExternalUnchecked(name, null, userId); 6786 } 6787 Binder.restoreCallingIdentity(ident); 6788 } 6789 6790 return null; 6791 } 6792 6793 // ========================================================= 6794 // GLOBAL MANAGEMENT 6795 // ========================================================= 6796 6797 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6798 ApplicationInfo info, String customProcess, boolean isolated) { 6799 String proc = customProcess != null ? customProcess : info.processName; 6800 BatteryStatsImpl.Uid.Proc ps = null; 6801 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6802 int uid = info.uid; 6803 if (isolated) { 6804 int userId = UserHandle.getUserId(uid); 6805 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6806 uid = 0; 6807 while (true) { 6808 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6809 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6810 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6811 } 6812 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6813 mNextIsolatedProcessUid++; 6814 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6815 // No process for this uid, use it. 6816 break; 6817 } 6818 stepsLeft--; 6819 if (stepsLeft <= 0) { 6820 return null; 6821 } 6822 } 6823 } 6824 synchronized (stats) { 6825 ps = stats.getProcessStatsLocked(info.uid, proc); 6826 } 6827 return new ProcessRecord(ps, thread, info, proc, uid); 6828 } 6829 6830 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6831 ProcessRecord app; 6832 if (!isolated) { 6833 app = getProcessRecordLocked(info.processName, info.uid); 6834 } else { 6835 app = null; 6836 } 6837 6838 if (app == null) { 6839 app = newProcessRecordLocked(null, info, null, isolated); 6840 mProcessNames.put(info.processName, app.uid, app); 6841 if (isolated) { 6842 mIsolatedProcesses.put(app.uid, app); 6843 } 6844 updateLruProcessLocked(app, true, true); 6845 } 6846 6847 // This package really, really can not be stopped. 6848 try { 6849 AppGlobals.getPackageManager().setPackageStoppedState( 6850 info.packageName, false, UserHandle.getUserId(app.uid)); 6851 } catch (RemoteException e) { 6852 } catch (IllegalArgumentException e) { 6853 Slog.w(TAG, "Failed trying to unstop package " 6854 + info.packageName + ": " + e); 6855 } 6856 6857 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6858 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6859 app.persistent = true; 6860 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6861 } 6862 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6863 mPersistentStartingProcesses.add(app); 6864 startProcessLocked(app, "added application", app.processName); 6865 } 6866 6867 return app; 6868 } 6869 6870 public void unhandledBack() { 6871 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6872 "unhandledBack()"); 6873 6874 synchronized(this) { 6875 int count = mMainStack.mHistory.size(); 6876 if (DEBUG_SWITCH) Slog.d( 6877 TAG, "Performing unhandledBack(): stack size = " + count); 6878 if (count > 1) { 6879 final long origId = Binder.clearCallingIdentity(); 6880 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6881 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6882 Binder.restoreCallingIdentity(origId); 6883 } 6884 } 6885 } 6886 6887 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6888 enforceNotIsolatedCaller("openContentUri"); 6889 final int userId = UserHandle.getCallingUserId(); 6890 String name = uri.getAuthority(); 6891 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 6892 ParcelFileDescriptor pfd = null; 6893 if (cph != null) { 6894 // We record the binder invoker's uid in thread-local storage before 6895 // going to the content provider to open the file. Later, in the code 6896 // that handles all permissions checks, we look for this uid and use 6897 // that rather than the Activity Manager's own uid. The effect is that 6898 // we do the check against the caller's permissions even though it looks 6899 // to the content provider like the Activity Manager itself is making 6900 // the request. 6901 sCallerIdentity.set(new Identity( 6902 Binder.getCallingPid(), Binder.getCallingUid())); 6903 try { 6904 pfd = cph.provider.openFile(uri, "r"); 6905 } catch (FileNotFoundException e) { 6906 // do nothing; pfd will be returned null 6907 } finally { 6908 // Ensure that whatever happens, we clean up the identity state 6909 sCallerIdentity.remove(); 6910 } 6911 6912 // We've got the fd now, so we're done with the provider. 6913 removeContentProviderExternalUnchecked(name, null, userId); 6914 } else { 6915 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6916 } 6917 return pfd; 6918 } 6919 6920 // Actually is sleeping or shutting down or whatever else in the future 6921 // is an inactive state. 6922 public boolean isSleeping() { 6923 return mSleeping || mShuttingDown; 6924 } 6925 6926 public void goingToSleep() { 6927 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6928 != PackageManager.PERMISSION_GRANTED) { 6929 throw new SecurityException("Requires permission " 6930 + android.Manifest.permission.DEVICE_POWER); 6931 } 6932 6933 synchronized(this) { 6934 mWentToSleep = true; 6935 updateEventDispatchingLocked(); 6936 6937 if (!mSleeping) { 6938 mSleeping = true; 6939 mMainStack.stopIfSleepingLocked(); 6940 6941 // Initialize the wake times of all processes. 6942 checkExcessivePowerUsageLocked(false); 6943 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6944 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6945 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6946 } 6947 } 6948 } 6949 6950 public boolean shutdown(int timeout) { 6951 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6952 != PackageManager.PERMISSION_GRANTED) { 6953 throw new SecurityException("Requires permission " 6954 + android.Manifest.permission.SHUTDOWN); 6955 } 6956 6957 boolean timedout = false; 6958 6959 synchronized(this) { 6960 mShuttingDown = true; 6961 updateEventDispatchingLocked(); 6962 6963 if (mMainStack.mResumedActivity != null) { 6964 mMainStack.stopIfSleepingLocked(); 6965 final long endTime = System.currentTimeMillis() + timeout; 6966 while (mMainStack.mResumedActivity != null 6967 || mMainStack.mPausingActivity != null) { 6968 long delay = endTime - System.currentTimeMillis(); 6969 if (delay <= 0) { 6970 Slog.w(TAG, "Activity manager shutdown timed out"); 6971 timedout = true; 6972 break; 6973 } 6974 try { 6975 this.wait(); 6976 } catch (InterruptedException e) { 6977 } 6978 } 6979 } 6980 } 6981 6982 mUsageStatsService.shutdown(); 6983 mBatteryStatsService.shutdown(); 6984 6985 return timedout; 6986 } 6987 6988 public final void activitySlept(IBinder token) { 6989 if (localLOGV) Slog.v( 6990 TAG, "Activity slept: token=" + token); 6991 6992 ActivityRecord r = null; 6993 6994 final long origId = Binder.clearCallingIdentity(); 6995 6996 synchronized (this) { 6997 r = mMainStack.isInStackLocked(token); 6998 if (r != null) { 6999 mMainStack.activitySleptLocked(r); 7000 } 7001 } 7002 7003 Binder.restoreCallingIdentity(origId); 7004 } 7005 7006 private void comeOutOfSleepIfNeededLocked() { 7007 if (!mWentToSleep && !mLockScreenShown) { 7008 if (mSleeping) { 7009 mSleeping = false; 7010 mMainStack.awakeFromSleepingLocked(); 7011 mMainStack.resumeTopActivityLocked(null); 7012 } 7013 } 7014 } 7015 7016 public void wakingUp() { 7017 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7018 != PackageManager.PERMISSION_GRANTED) { 7019 throw new SecurityException("Requires permission " 7020 + android.Manifest.permission.DEVICE_POWER); 7021 } 7022 7023 synchronized(this) { 7024 mWentToSleep = false; 7025 updateEventDispatchingLocked(); 7026 comeOutOfSleepIfNeededLocked(); 7027 } 7028 } 7029 7030 private void updateEventDispatchingLocked() { 7031 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7032 } 7033 7034 public void setLockScreenShown(boolean shown) { 7035 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7036 != PackageManager.PERMISSION_GRANTED) { 7037 throw new SecurityException("Requires permission " 7038 + android.Manifest.permission.DEVICE_POWER); 7039 } 7040 7041 synchronized(this) { 7042 mLockScreenShown = shown; 7043 comeOutOfSleepIfNeededLocked(); 7044 } 7045 } 7046 7047 public void stopAppSwitches() { 7048 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7049 != PackageManager.PERMISSION_GRANTED) { 7050 throw new SecurityException("Requires permission " 7051 + android.Manifest.permission.STOP_APP_SWITCHES); 7052 } 7053 7054 synchronized(this) { 7055 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7056 + APP_SWITCH_DELAY_TIME; 7057 mDidAppSwitch = false; 7058 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7059 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7060 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7061 } 7062 } 7063 7064 public void resumeAppSwitches() { 7065 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7066 != PackageManager.PERMISSION_GRANTED) { 7067 throw new SecurityException("Requires permission " 7068 + android.Manifest.permission.STOP_APP_SWITCHES); 7069 } 7070 7071 synchronized(this) { 7072 // Note that we don't execute any pending app switches... we will 7073 // let those wait until either the timeout, or the next start 7074 // activity request. 7075 mAppSwitchesAllowedTime = 0; 7076 } 7077 } 7078 7079 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7080 String name) { 7081 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7082 return true; 7083 } 7084 7085 final int perm = checkComponentPermission( 7086 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7087 callingUid, -1, true); 7088 if (perm == PackageManager.PERMISSION_GRANTED) { 7089 return true; 7090 } 7091 7092 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7093 return false; 7094 } 7095 7096 public void setDebugApp(String packageName, boolean waitForDebugger, 7097 boolean persistent) { 7098 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7099 "setDebugApp()"); 7100 7101 // Note that this is not really thread safe if there are multiple 7102 // callers into it at the same time, but that's not a situation we 7103 // care about. 7104 if (persistent) { 7105 final ContentResolver resolver = mContext.getContentResolver(); 7106 Settings.System.putString( 7107 resolver, Settings.System.DEBUG_APP, 7108 packageName); 7109 Settings.System.putInt( 7110 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7111 waitForDebugger ? 1 : 0); 7112 } 7113 7114 synchronized (this) { 7115 if (!persistent) { 7116 mOrigDebugApp = mDebugApp; 7117 mOrigWaitForDebugger = mWaitForDebugger; 7118 } 7119 mDebugApp = packageName; 7120 mWaitForDebugger = waitForDebugger; 7121 mDebugTransient = !persistent; 7122 if (packageName != null) { 7123 final long origId = Binder.clearCallingIdentity(); 7124 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7125 Binder.restoreCallingIdentity(origId); 7126 } 7127 } 7128 } 7129 7130 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7131 synchronized (this) { 7132 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7133 if (!isDebuggable) { 7134 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7135 throw new SecurityException("Process not debuggable: " + app.packageName); 7136 } 7137 } 7138 7139 mOpenGlTraceApp = processName; 7140 } 7141 } 7142 7143 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7144 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7145 synchronized (this) { 7146 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7147 if (!isDebuggable) { 7148 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7149 throw new SecurityException("Process not debuggable: " + app.packageName); 7150 } 7151 } 7152 mProfileApp = processName; 7153 mProfileFile = profileFile; 7154 if (mProfileFd != null) { 7155 try { 7156 mProfileFd.close(); 7157 } catch (IOException e) { 7158 } 7159 mProfileFd = null; 7160 } 7161 mProfileFd = profileFd; 7162 mProfileType = 0; 7163 mAutoStopProfiler = autoStopProfiler; 7164 } 7165 } 7166 7167 public void setAlwaysFinish(boolean enabled) { 7168 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7169 "setAlwaysFinish()"); 7170 7171 Settings.System.putInt( 7172 mContext.getContentResolver(), 7173 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7174 7175 synchronized (this) { 7176 mAlwaysFinishActivities = enabled; 7177 } 7178 } 7179 7180 public void setActivityController(IActivityController controller) { 7181 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7182 "setActivityController()"); 7183 synchronized (this) { 7184 mController = controller; 7185 } 7186 } 7187 7188 public boolean isUserAMonkey() { 7189 // For now the fact that there is a controller implies 7190 // we have a monkey. 7191 synchronized (this) { 7192 return mController != null; 7193 } 7194 } 7195 7196 public void registerProcessObserver(IProcessObserver observer) { 7197 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7198 "registerProcessObserver()"); 7199 synchronized (this) { 7200 mProcessObservers.register(observer); 7201 } 7202 } 7203 7204 public void unregisterProcessObserver(IProcessObserver observer) { 7205 synchronized (this) { 7206 mProcessObservers.unregister(observer); 7207 } 7208 } 7209 7210 public void setImmersive(IBinder token, boolean immersive) { 7211 synchronized(this) { 7212 ActivityRecord r = mMainStack.isInStackLocked(token); 7213 if (r == null) { 7214 throw new IllegalArgumentException(); 7215 } 7216 r.immersive = immersive; 7217 } 7218 } 7219 7220 public boolean isImmersive(IBinder token) { 7221 synchronized (this) { 7222 ActivityRecord r = mMainStack.isInStackLocked(token); 7223 if (r == null) { 7224 throw new IllegalArgumentException(); 7225 } 7226 return r.immersive; 7227 } 7228 } 7229 7230 public boolean isTopActivityImmersive() { 7231 enforceNotIsolatedCaller("startActivity"); 7232 synchronized (this) { 7233 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7234 return (r != null) ? r.immersive : false; 7235 } 7236 } 7237 7238 public final void enterSafeMode() { 7239 synchronized(this) { 7240 // It only makes sense to do this before the system is ready 7241 // and started launching other packages. 7242 if (!mSystemReady) { 7243 try { 7244 AppGlobals.getPackageManager().enterSafeMode(); 7245 } catch (RemoteException e) { 7246 } 7247 } 7248 } 7249 } 7250 7251 public final void showSafeModeOverlay() { 7252 View v = LayoutInflater.from(mContext).inflate( 7253 com.android.internal.R.layout.safe_mode, null); 7254 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7255 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7256 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7257 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7258 lp.gravity = Gravity.BOTTOM | Gravity.START; 7259 lp.format = v.getBackground().getOpacity(); 7260 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7261 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7262 ((WindowManager)mContext.getSystemService( 7263 Context.WINDOW_SERVICE)).addView(v, lp); 7264 } 7265 7266 public void noteWakeupAlarm(IIntentSender sender) { 7267 if (!(sender instanceof PendingIntentRecord)) { 7268 return; 7269 } 7270 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7271 synchronized (stats) { 7272 if (mBatteryStatsService.isOnBattery()) { 7273 mBatteryStatsService.enforceCallingPermission(); 7274 PendingIntentRecord rec = (PendingIntentRecord)sender; 7275 int MY_UID = Binder.getCallingUid(); 7276 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7277 BatteryStatsImpl.Uid.Pkg pkg = 7278 stats.getPackageStatsLocked(uid, rec.key.packageName); 7279 pkg.incWakeupsLocked(); 7280 } 7281 } 7282 } 7283 7284 public boolean killPids(int[] pids, String pReason, boolean secure) { 7285 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7286 throw new SecurityException("killPids only available to the system"); 7287 } 7288 String reason = (pReason == null) ? "Unknown" : pReason; 7289 // XXX Note: don't acquire main activity lock here, because the window 7290 // manager calls in with its locks held. 7291 7292 boolean killed = false; 7293 synchronized (mPidsSelfLocked) { 7294 int[] types = new int[pids.length]; 7295 int worstType = 0; 7296 for (int i=0; i<pids.length; i++) { 7297 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7298 if (proc != null) { 7299 int type = proc.setAdj; 7300 types[i] = type; 7301 if (type > worstType) { 7302 worstType = type; 7303 } 7304 } 7305 } 7306 7307 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7308 // then constrain it so we will kill all hidden procs. 7309 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7310 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7311 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7312 } 7313 7314 // If this is not a secure call, don't let it kill processes that 7315 // are important. 7316 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7317 worstType = ProcessList.SERVICE_ADJ; 7318 } 7319 7320 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7321 for (int i=0; i<pids.length; i++) { 7322 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7323 if (proc == null) { 7324 continue; 7325 } 7326 int adj = proc.setAdj; 7327 if (adj >= worstType && !proc.killedBackground) { 7328 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7329 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7330 proc.processName, adj, reason); 7331 killed = true; 7332 proc.killedBackground = true; 7333 Process.killProcessQuiet(pids[i]); 7334 } 7335 } 7336 } 7337 return killed; 7338 } 7339 7340 @Override 7341 public boolean killProcessesBelowForeground(String reason) { 7342 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7343 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7344 } 7345 7346 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7347 } 7348 7349 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7350 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7351 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7352 } 7353 7354 boolean killed = false; 7355 synchronized (mPidsSelfLocked) { 7356 final int size = mPidsSelfLocked.size(); 7357 for (int i = 0; i < size; i++) { 7358 final int pid = mPidsSelfLocked.keyAt(i); 7359 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7360 if (proc == null) continue; 7361 7362 final int adj = proc.setAdj; 7363 if (adj > belowAdj && !proc.killedBackground) { 7364 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7365 EventLog.writeEvent( 7366 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7367 killed = true; 7368 proc.killedBackground = true; 7369 Process.killProcessQuiet(pid); 7370 } 7371 } 7372 } 7373 return killed; 7374 } 7375 7376 public final void startRunning(String pkg, String cls, String action, 7377 String data) { 7378 synchronized(this) { 7379 if (mStartRunning) { 7380 return; 7381 } 7382 mStartRunning = true; 7383 mTopComponent = pkg != null && cls != null 7384 ? new ComponentName(pkg, cls) : null; 7385 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7386 mTopData = data; 7387 if (!mSystemReady) { 7388 return; 7389 } 7390 } 7391 7392 systemReady(null); 7393 } 7394 7395 private void retrieveSettings() { 7396 final ContentResolver resolver = mContext.getContentResolver(); 7397 String debugApp = Settings.System.getString( 7398 resolver, Settings.System.DEBUG_APP); 7399 boolean waitForDebugger = Settings.System.getInt( 7400 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7401 boolean alwaysFinishActivities = Settings.System.getInt( 7402 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7403 7404 Configuration configuration = new Configuration(); 7405 Settings.System.getConfiguration(resolver, configuration); 7406 7407 synchronized (this) { 7408 mDebugApp = mOrigDebugApp = debugApp; 7409 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7410 mAlwaysFinishActivities = alwaysFinishActivities; 7411 // This happens before any activities are started, so we can 7412 // change mConfiguration in-place. 7413 updateConfigurationLocked(configuration, null, false, true); 7414 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7415 } 7416 } 7417 7418 public boolean testIsSystemReady() { 7419 // no need to synchronize(this) just to read & return the value 7420 return mSystemReady; 7421 } 7422 7423 private static File getCalledPreBootReceiversFile() { 7424 File dataDir = Environment.getDataDirectory(); 7425 File systemDir = new File(dataDir, "system"); 7426 File fname = new File(systemDir, "called_pre_boots.dat"); 7427 return fname; 7428 } 7429 7430 static final int LAST_DONE_VERSION = 10000; 7431 7432 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7433 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7434 File file = getCalledPreBootReceiversFile(); 7435 FileInputStream fis = null; 7436 try { 7437 fis = new FileInputStream(file); 7438 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7439 int fvers = dis.readInt(); 7440 if (fvers == LAST_DONE_VERSION) { 7441 String vers = dis.readUTF(); 7442 String codename = dis.readUTF(); 7443 String build = dis.readUTF(); 7444 if (android.os.Build.VERSION.RELEASE.equals(vers) 7445 && android.os.Build.VERSION.CODENAME.equals(codename) 7446 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7447 int num = dis.readInt(); 7448 while (num > 0) { 7449 num--; 7450 String pkg = dis.readUTF(); 7451 String cls = dis.readUTF(); 7452 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7453 } 7454 } 7455 } 7456 } catch (FileNotFoundException e) { 7457 } catch (IOException e) { 7458 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7459 } finally { 7460 if (fis != null) { 7461 try { 7462 fis.close(); 7463 } catch (IOException e) { 7464 } 7465 } 7466 } 7467 return lastDoneReceivers; 7468 } 7469 7470 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7471 File file = getCalledPreBootReceiversFile(); 7472 FileOutputStream fos = null; 7473 DataOutputStream dos = null; 7474 try { 7475 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7476 fos = new FileOutputStream(file); 7477 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7478 dos.writeInt(LAST_DONE_VERSION); 7479 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7480 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7481 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7482 dos.writeInt(list.size()); 7483 for (int i=0; i<list.size(); i++) { 7484 dos.writeUTF(list.get(i).getPackageName()); 7485 dos.writeUTF(list.get(i).getClassName()); 7486 } 7487 } catch (IOException e) { 7488 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7489 file.delete(); 7490 } finally { 7491 FileUtils.sync(fos); 7492 if (dos != null) { 7493 try { 7494 dos.close(); 7495 } catch (IOException e) { 7496 // TODO Auto-generated catch block 7497 e.printStackTrace(); 7498 } 7499 } 7500 } 7501 } 7502 7503 public void systemReady(final Runnable goingCallback) { 7504 synchronized(this) { 7505 if (mSystemReady) { 7506 if (goingCallback != null) goingCallback.run(); 7507 return; 7508 } 7509 7510 // Check to see if there are any update receivers to run. 7511 if (!mDidUpdate) { 7512 if (mWaitingUpdate) { 7513 return; 7514 } 7515 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7516 List<ResolveInfo> ris = null; 7517 try { 7518 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7519 intent, null, 0, 0); 7520 } catch (RemoteException e) { 7521 } 7522 if (ris != null) { 7523 for (int i=ris.size()-1; i>=0; i--) { 7524 if ((ris.get(i).activityInfo.applicationInfo.flags 7525 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7526 ris.remove(i); 7527 } 7528 } 7529 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7530 7531 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7532 7533 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7534 for (int i=0; i<ris.size(); i++) { 7535 ActivityInfo ai = ris.get(i).activityInfo; 7536 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7537 if (lastDoneReceivers.contains(comp)) { 7538 ris.remove(i); 7539 i--; 7540 } 7541 } 7542 7543 for (int i=0; i<ris.size(); i++) { 7544 ActivityInfo ai = ris.get(i).activityInfo; 7545 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7546 doneReceivers.add(comp); 7547 intent.setComponent(comp); 7548 IIntentReceiver finisher = null; 7549 if (i == ris.size()-1) { 7550 finisher = new IIntentReceiver.Stub() { 7551 public void performReceive(Intent intent, int resultCode, 7552 String data, Bundle extras, boolean ordered, 7553 boolean sticky, int sendingUser) { 7554 // The raw IIntentReceiver interface is called 7555 // with the AM lock held, so redispatch to 7556 // execute our code without the lock. 7557 mHandler.post(new Runnable() { 7558 public void run() { 7559 synchronized (ActivityManagerService.this) { 7560 mDidUpdate = true; 7561 } 7562 writeLastDonePreBootReceivers(doneReceivers); 7563 showBootMessage(mContext.getText( 7564 R.string.android_upgrading_complete), 7565 false); 7566 systemReady(goingCallback); 7567 } 7568 }); 7569 } 7570 }; 7571 } 7572 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7573 // XXX also need to send this to stopped users(!!!) 7574 broadcastIntentLocked(null, null, intent, null, finisher, 7575 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7576 UserHandle.USER_ALL); 7577 if (finisher != null) { 7578 mWaitingUpdate = true; 7579 } 7580 } 7581 } 7582 if (mWaitingUpdate) { 7583 return; 7584 } 7585 mDidUpdate = true; 7586 } 7587 7588 mSystemReady = true; 7589 if (!mStartRunning) { 7590 return; 7591 } 7592 } 7593 7594 ArrayList<ProcessRecord> procsToKill = null; 7595 synchronized(mPidsSelfLocked) { 7596 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7597 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7598 if (!isAllowedWhileBooting(proc.info)){ 7599 if (procsToKill == null) { 7600 procsToKill = new ArrayList<ProcessRecord>(); 7601 } 7602 procsToKill.add(proc); 7603 } 7604 } 7605 } 7606 7607 synchronized(this) { 7608 if (procsToKill != null) { 7609 for (int i=procsToKill.size()-1; i>=0; i--) { 7610 ProcessRecord proc = procsToKill.get(i); 7611 Slog.i(TAG, "Removing system update proc: " + proc); 7612 removeProcessLocked(proc, true, false, "system update done"); 7613 } 7614 } 7615 7616 // Now that we have cleaned up any update processes, we 7617 // are ready to start launching real processes and know that 7618 // we won't trample on them any more. 7619 mProcessesReady = true; 7620 } 7621 7622 Slog.i(TAG, "System now ready"); 7623 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7624 SystemClock.uptimeMillis()); 7625 7626 synchronized(this) { 7627 // Make sure we have no pre-ready processes sitting around. 7628 7629 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7630 ResolveInfo ri = mContext.getPackageManager() 7631 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7632 STOCK_PM_FLAGS); 7633 CharSequence errorMsg = null; 7634 if (ri != null) { 7635 ActivityInfo ai = ri.activityInfo; 7636 ApplicationInfo app = ai.applicationInfo; 7637 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7638 mTopAction = Intent.ACTION_FACTORY_TEST; 7639 mTopData = null; 7640 mTopComponent = new ComponentName(app.packageName, 7641 ai.name); 7642 } else { 7643 errorMsg = mContext.getResources().getText( 7644 com.android.internal.R.string.factorytest_not_system); 7645 } 7646 } else { 7647 errorMsg = mContext.getResources().getText( 7648 com.android.internal.R.string.factorytest_no_action); 7649 } 7650 if (errorMsg != null) { 7651 mTopAction = null; 7652 mTopData = null; 7653 mTopComponent = null; 7654 Message msg = Message.obtain(); 7655 msg.what = SHOW_FACTORY_ERROR_MSG; 7656 msg.getData().putCharSequence("msg", errorMsg); 7657 mHandler.sendMessage(msg); 7658 } 7659 } 7660 } 7661 7662 retrieveSettings(); 7663 7664 if (goingCallback != null) goingCallback.run(); 7665 7666 synchronized (this) { 7667 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7668 try { 7669 List apps = AppGlobals.getPackageManager(). 7670 getPersistentApplications(STOCK_PM_FLAGS); 7671 if (apps != null) { 7672 int N = apps.size(); 7673 int i; 7674 for (i=0; i<N; i++) { 7675 ApplicationInfo info 7676 = (ApplicationInfo)apps.get(i); 7677 if (info != null && 7678 !info.packageName.equals("android")) { 7679 addAppLocked(info, false); 7680 } 7681 } 7682 } 7683 } catch (RemoteException ex) { 7684 // pm is in same process, this will never happen. 7685 } 7686 } 7687 7688 // Start up initial activity. 7689 mBooting = true; 7690 7691 try { 7692 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7693 Message msg = Message.obtain(); 7694 msg.what = SHOW_UID_ERROR_MSG; 7695 mHandler.sendMessage(msg); 7696 } 7697 } catch (RemoteException e) { 7698 } 7699 7700 mMainStack.resumeTopActivityLocked(null); 7701 } 7702 } 7703 7704 private boolean makeAppCrashingLocked(ProcessRecord app, 7705 String shortMsg, String longMsg, String stackTrace) { 7706 app.crashing = true; 7707 app.crashingReport = generateProcessError(app, 7708 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7709 startAppProblemLocked(app); 7710 app.stopFreezingAllLocked(); 7711 return handleAppCrashLocked(app); 7712 } 7713 7714 private void makeAppNotRespondingLocked(ProcessRecord app, 7715 String activity, String shortMsg, String longMsg) { 7716 app.notResponding = true; 7717 app.notRespondingReport = generateProcessError(app, 7718 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7719 activity, shortMsg, longMsg, null); 7720 startAppProblemLocked(app); 7721 app.stopFreezingAllLocked(); 7722 } 7723 7724 /** 7725 * Generate a process error record, suitable for attachment to a ProcessRecord. 7726 * 7727 * @param app The ProcessRecord in which the error occurred. 7728 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7729 * ActivityManager.AppErrorStateInfo 7730 * @param activity The activity associated with the crash, if known. 7731 * @param shortMsg Short message describing the crash. 7732 * @param longMsg Long message describing the crash. 7733 * @param stackTrace Full crash stack trace, may be null. 7734 * 7735 * @return Returns a fully-formed AppErrorStateInfo record. 7736 */ 7737 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7738 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7739 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7740 7741 report.condition = condition; 7742 report.processName = app.processName; 7743 report.pid = app.pid; 7744 report.uid = app.info.uid; 7745 report.tag = activity; 7746 report.shortMsg = shortMsg; 7747 report.longMsg = longMsg; 7748 report.stackTrace = stackTrace; 7749 7750 return report; 7751 } 7752 7753 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7754 synchronized (this) { 7755 app.crashing = false; 7756 app.crashingReport = null; 7757 app.notResponding = false; 7758 app.notRespondingReport = null; 7759 if (app.anrDialog == fromDialog) { 7760 app.anrDialog = null; 7761 } 7762 if (app.waitDialog == fromDialog) { 7763 app.waitDialog = null; 7764 } 7765 if (app.pid > 0 && app.pid != MY_PID) { 7766 handleAppCrashLocked(app); 7767 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7769 app.processName, app.setAdj, "user's request after error"); 7770 Process.killProcessQuiet(app.pid); 7771 } 7772 } 7773 } 7774 7775 private boolean handleAppCrashLocked(ProcessRecord app) { 7776 if (mHeadless) { 7777 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7778 return false; 7779 } 7780 long now = SystemClock.uptimeMillis(); 7781 7782 Long crashTime; 7783 if (!app.isolated) { 7784 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7785 } else { 7786 crashTime = null; 7787 } 7788 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7789 // This process loses! 7790 Slog.w(TAG, "Process " + app.info.processName 7791 + " has crashed too many times: killing!"); 7792 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7793 app.info.processName, app.uid); 7794 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7795 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7796 if (r.app == app) { 7797 Slog.w(TAG, " Force finishing activity " 7798 + r.intent.getComponent().flattenToShortString()); 7799 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7800 } 7801 } 7802 if (!app.persistent) { 7803 // We don't want to start this process again until the user 7804 // explicitly does so... but for persistent process, we really 7805 // need to keep it running. If a persistent process is actually 7806 // repeatedly crashing, then badness for everyone. 7807 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7808 app.info.processName); 7809 if (!app.isolated) { 7810 // XXX We don't have a way to mark isolated processes 7811 // as bad, since they don't have a peristent identity. 7812 mBadProcesses.put(app.info.processName, app.uid, now); 7813 mProcessCrashTimes.remove(app.info.processName, app.uid); 7814 } 7815 app.bad = true; 7816 app.removed = true; 7817 // Don't let services in this process be restarted and potentially 7818 // annoy the user repeatedly. Unless it is persistent, since those 7819 // processes run critical code. 7820 removeProcessLocked(app, false, false, "crash"); 7821 mMainStack.resumeTopActivityLocked(null); 7822 return false; 7823 } 7824 mMainStack.resumeTopActivityLocked(null); 7825 } else { 7826 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7827 if (r != null && r.app == app) { 7828 // If the top running activity is from this crashing 7829 // process, then terminate it to avoid getting in a loop. 7830 Slog.w(TAG, " Force finishing activity " 7831 + r.intent.getComponent().flattenToShortString()); 7832 int index = mMainStack.indexOfActivityLocked(r); 7833 r.stack.finishActivityLocked(r, index, 7834 Activity.RESULT_CANCELED, null, "crashed"); 7835 // Also terminate any activities below it that aren't yet 7836 // stopped, to avoid a situation where one will get 7837 // re-start our crashing activity once it gets resumed again. 7838 index--; 7839 if (index >= 0) { 7840 r = (ActivityRecord)mMainStack.mHistory.get(index); 7841 if (r.state == ActivityState.RESUMED 7842 || r.state == ActivityState.PAUSING 7843 || r.state == ActivityState.PAUSED) { 7844 if (!r.isHomeActivity || mHomeProcess != r.app) { 7845 Slog.w(TAG, " Force finishing activity " 7846 + r.intent.getComponent().flattenToShortString()); 7847 r.stack.finishActivityLocked(r, index, 7848 Activity.RESULT_CANCELED, null, "crashed"); 7849 } 7850 } 7851 } 7852 } 7853 } 7854 7855 // Bump up the crash count of any services currently running in the proc. 7856 if (app.services.size() != 0) { 7857 // Any services running in the application need to be placed 7858 // back in the pending list. 7859 Iterator<ServiceRecord> it = app.services.iterator(); 7860 while (it.hasNext()) { 7861 ServiceRecord sr = it.next(); 7862 sr.crashCount++; 7863 } 7864 } 7865 7866 // If the crashing process is what we consider to be the "home process" and it has been 7867 // replaced by a third-party app, clear the package preferred activities from packages 7868 // with a home activity running in the process to prevent a repeatedly crashing app 7869 // from blocking the user to manually clear the list. 7870 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7871 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7872 Iterator it = mHomeProcess.activities.iterator(); 7873 while (it.hasNext()) { 7874 ActivityRecord r = (ActivityRecord)it.next(); 7875 if (r.isHomeActivity) { 7876 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7877 try { 7878 ActivityThread.getPackageManager() 7879 .clearPackagePreferredActivities(r.packageName); 7880 } catch (RemoteException c) { 7881 // pm is in same process, this will never happen. 7882 } 7883 } 7884 } 7885 } 7886 7887 if (!app.isolated) { 7888 // XXX Can't keep track of crash times for isolated processes, 7889 // because they don't have a perisistent identity. 7890 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7891 } 7892 7893 return true; 7894 } 7895 7896 void startAppProblemLocked(ProcessRecord app) { 7897 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7898 mContext, app.info.packageName, app.info.flags); 7899 skipCurrentReceiverLocked(app); 7900 } 7901 7902 void skipCurrentReceiverLocked(ProcessRecord app) { 7903 for (BroadcastQueue queue : mBroadcastQueues) { 7904 queue.skipCurrentReceiverLocked(app); 7905 } 7906 } 7907 7908 /** 7909 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7910 * The application process will exit immediately after this call returns. 7911 * @param app object of the crashing app, null for the system server 7912 * @param crashInfo describing the exception 7913 */ 7914 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7915 ProcessRecord r = findAppProcess(app, "Crash"); 7916 final String processName = app == null ? "system_server" 7917 : (r == null ? "unknown" : r.processName); 7918 7919 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7920 processName, 7921 r == null ? -1 : r.info.flags, 7922 crashInfo.exceptionClassName, 7923 crashInfo.exceptionMessage, 7924 crashInfo.throwFileName, 7925 crashInfo.throwLineNumber); 7926 7927 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7928 7929 crashApplication(r, crashInfo); 7930 } 7931 7932 public void handleApplicationStrictModeViolation( 7933 IBinder app, 7934 int violationMask, 7935 StrictMode.ViolationInfo info) { 7936 ProcessRecord r = findAppProcess(app, "StrictMode"); 7937 if (r == null) { 7938 return; 7939 } 7940 7941 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7942 Integer stackFingerprint = info.hashCode(); 7943 boolean logIt = true; 7944 synchronized (mAlreadyLoggedViolatedStacks) { 7945 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7946 logIt = false; 7947 // TODO: sub-sample into EventLog for these, with 7948 // the info.durationMillis? Then we'd get 7949 // the relative pain numbers, without logging all 7950 // the stack traces repeatedly. We'd want to do 7951 // likewise in the client code, which also does 7952 // dup suppression, before the Binder call. 7953 } else { 7954 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7955 mAlreadyLoggedViolatedStacks.clear(); 7956 } 7957 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7958 } 7959 } 7960 if (logIt) { 7961 logStrictModeViolationToDropBox(r, info); 7962 } 7963 } 7964 7965 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7966 AppErrorResult result = new AppErrorResult(); 7967 synchronized (this) { 7968 final long origId = Binder.clearCallingIdentity(); 7969 7970 Message msg = Message.obtain(); 7971 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7972 HashMap<String, Object> data = new HashMap<String, Object>(); 7973 data.put("result", result); 7974 data.put("app", r); 7975 data.put("violationMask", violationMask); 7976 data.put("info", info); 7977 msg.obj = data; 7978 mHandler.sendMessage(msg); 7979 7980 Binder.restoreCallingIdentity(origId); 7981 } 7982 int res = result.get(); 7983 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7984 } 7985 } 7986 7987 // Depending on the policy in effect, there could be a bunch of 7988 // these in quick succession so we try to batch these together to 7989 // minimize disk writes, number of dropbox entries, and maximize 7990 // compression, by having more fewer, larger records. 7991 private void logStrictModeViolationToDropBox( 7992 ProcessRecord process, 7993 StrictMode.ViolationInfo info) { 7994 if (info == null) { 7995 return; 7996 } 7997 final boolean isSystemApp = process == null || 7998 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7999 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8000 final String processName = process == null ? "unknown" : process.processName; 8001 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8002 final DropBoxManager dbox = (DropBoxManager) 8003 mContext.getSystemService(Context.DROPBOX_SERVICE); 8004 8005 // Exit early if the dropbox isn't configured to accept this report type. 8006 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8007 8008 boolean bufferWasEmpty; 8009 boolean needsFlush; 8010 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8011 synchronized (sb) { 8012 bufferWasEmpty = sb.length() == 0; 8013 appendDropBoxProcessHeaders(process, processName, sb); 8014 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8015 sb.append("System-App: ").append(isSystemApp).append("\n"); 8016 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8017 if (info.violationNumThisLoop != 0) { 8018 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8019 } 8020 if (info.numAnimationsRunning != 0) { 8021 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8022 } 8023 if (info.broadcastIntentAction != null) { 8024 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8025 } 8026 if (info.durationMillis != -1) { 8027 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8028 } 8029 if (info.numInstances != -1) { 8030 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8031 } 8032 if (info.tags != null) { 8033 for (String tag : info.tags) { 8034 sb.append("Span-Tag: ").append(tag).append("\n"); 8035 } 8036 } 8037 sb.append("\n"); 8038 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8039 sb.append(info.crashInfo.stackTrace); 8040 } 8041 sb.append("\n"); 8042 8043 // Only buffer up to ~64k. Various logging bits truncate 8044 // things at 128k. 8045 needsFlush = (sb.length() > 64 * 1024); 8046 } 8047 8048 // Flush immediately if the buffer's grown too large, or this 8049 // is a non-system app. Non-system apps are isolated with a 8050 // different tag & policy and not batched. 8051 // 8052 // Batching is useful during internal testing with 8053 // StrictMode settings turned up high. Without batching, 8054 // thousands of separate files could be created on boot. 8055 if (!isSystemApp || needsFlush) { 8056 new Thread("Error dump: " + dropboxTag) { 8057 @Override 8058 public void run() { 8059 String report; 8060 synchronized (sb) { 8061 report = sb.toString(); 8062 sb.delete(0, sb.length()); 8063 sb.trimToSize(); 8064 } 8065 if (report.length() != 0) { 8066 dbox.addText(dropboxTag, report); 8067 } 8068 } 8069 }.start(); 8070 return; 8071 } 8072 8073 // System app batching: 8074 if (!bufferWasEmpty) { 8075 // An existing dropbox-writing thread is outstanding, so 8076 // we don't need to start it up. The existing thread will 8077 // catch the buffer appends we just did. 8078 return; 8079 } 8080 8081 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8082 // (After this point, we shouldn't access AMS internal data structures.) 8083 new Thread("Error dump: " + dropboxTag) { 8084 @Override 8085 public void run() { 8086 // 5 second sleep to let stacks arrive and be batched together 8087 try { 8088 Thread.sleep(5000); // 5 seconds 8089 } catch (InterruptedException e) {} 8090 8091 String errorReport; 8092 synchronized (mStrictModeBuffer) { 8093 errorReport = mStrictModeBuffer.toString(); 8094 if (errorReport.length() == 0) { 8095 return; 8096 } 8097 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8098 mStrictModeBuffer.trimToSize(); 8099 } 8100 dbox.addText(dropboxTag, errorReport); 8101 } 8102 }.start(); 8103 } 8104 8105 /** 8106 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8107 * @param app object of the crashing app, null for the system server 8108 * @param tag reported by the caller 8109 * @param crashInfo describing the context of the error 8110 * @return true if the process should exit immediately (WTF is fatal) 8111 */ 8112 public boolean handleApplicationWtf(IBinder app, String tag, 8113 ApplicationErrorReport.CrashInfo crashInfo) { 8114 ProcessRecord r = findAppProcess(app, "WTF"); 8115 final String processName = app == null ? "system_server" 8116 : (r == null ? "unknown" : r.processName); 8117 8118 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8119 processName, 8120 r == null ? -1 : r.info.flags, 8121 tag, crashInfo.exceptionMessage); 8122 8123 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8124 8125 if (r != null && r.pid != Process.myPid() && 8126 Settings.Secure.getInt(mContext.getContentResolver(), 8127 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8128 crashApplication(r, crashInfo); 8129 return true; 8130 } else { 8131 return false; 8132 } 8133 } 8134 8135 /** 8136 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8137 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8138 */ 8139 private ProcessRecord findAppProcess(IBinder app, String reason) { 8140 if (app == null) { 8141 return null; 8142 } 8143 8144 synchronized (this) { 8145 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8146 final int NA = apps.size(); 8147 for (int ia=0; ia<NA; ia++) { 8148 ProcessRecord p = apps.valueAt(ia); 8149 if (p.thread != null && p.thread.asBinder() == app) { 8150 return p; 8151 } 8152 } 8153 } 8154 8155 Slog.w(TAG, "Can't find mystery application for " + reason 8156 + " from pid=" + Binder.getCallingPid() 8157 + " uid=" + Binder.getCallingUid() + ": " + app); 8158 return null; 8159 } 8160 } 8161 8162 /** 8163 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8164 * to append various headers to the dropbox log text. 8165 */ 8166 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8167 StringBuilder sb) { 8168 // Watchdog thread ends up invoking this function (with 8169 // a null ProcessRecord) to add the stack file to dropbox. 8170 // Do not acquire a lock on this (am) in such cases, as it 8171 // could cause a potential deadlock, if and when watchdog 8172 // is invoked due to unavailability of lock on am and it 8173 // would prevent watchdog from killing system_server. 8174 if (process == null) { 8175 sb.append("Process: ").append(processName).append("\n"); 8176 return; 8177 } 8178 // Note: ProcessRecord 'process' is guarded by the service 8179 // instance. (notably process.pkgList, which could otherwise change 8180 // concurrently during execution of this method) 8181 synchronized (this) { 8182 sb.append("Process: ").append(processName).append("\n"); 8183 int flags = process.info.flags; 8184 IPackageManager pm = AppGlobals.getPackageManager(); 8185 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8186 for (String pkg : process.pkgList) { 8187 sb.append("Package: ").append(pkg); 8188 try { 8189 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8190 if (pi != null) { 8191 sb.append(" v").append(pi.versionCode); 8192 if (pi.versionName != null) { 8193 sb.append(" (").append(pi.versionName).append(")"); 8194 } 8195 } 8196 } catch (RemoteException e) { 8197 Slog.e(TAG, "Error getting package info: " + pkg, e); 8198 } 8199 sb.append("\n"); 8200 } 8201 } 8202 } 8203 8204 private static String processClass(ProcessRecord process) { 8205 if (process == null || process.pid == MY_PID) { 8206 return "system_server"; 8207 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8208 return "system_app"; 8209 } else { 8210 return "data_app"; 8211 } 8212 } 8213 8214 /** 8215 * Write a description of an error (crash, WTF, ANR) to the drop box. 8216 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8217 * @param process which caused the error, null means the system server 8218 * @param activity which triggered the error, null if unknown 8219 * @param parent activity related to the error, null if unknown 8220 * @param subject line related to the error, null if absent 8221 * @param report in long form describing the error, null if absent 8222 * @param logFile to include in the report, null if none 8223 * @param crashInfo giving an application stack trace, null if absent 8224 */ 8225 public void addErrorToDropBox(String eventType, 8226 ProcessRecord process, String processName, ActivityRecord activity, 8227 ActivityRecord parent, String subject, 8228 final String report, final File logFile, 8229 final ApplicationErrorReport.CrashInfo crashInfo) { 8230 // NOTE -- this must never acquire the ActivityManagerService lock, 8231 // otherwise the watchdog may be prevented from resetting the system. 8232 8233 final String dropboxTag = processClass(process) + "_" + eventType; 8234 final DropBoxManager dbox = (DropBoxManager) 8235 mContext.getSystemService(Context.DROPBOX_SERVICE); 8236 8237 // Exit early if the dropbox isn't configured to accept this report type. 8238 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8239 8240 final StringBuilder sb = new StringBuilder(1024); 8241 appendDropBoxProcessHeaders(process, processName, sb); 8242 if (activity != null) { 8243 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8244 } 8245 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8246 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8247 } 8248 if (parent != null && parent != activity) { 8249 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8250 } 8251 if (subject != null) { 8252 sb.append("Subject: ").append(subject).append("\n"); 8253 } 8254 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8255 if (Debug.isDebuggerConnected()) { 8256 sb.append("Debugger: Connected\n"); 8257 } 8258 sb.append("\n"); 8259 8260 // Do the rest in a worker thread to avoid blocking the caller on I/O 8261 // (After this point, we shouldn't access AMS internal data structures.) 8262 Thread worker = new Thread("Error dump: " + dropboxTag) { 8263 @Override 8264 public void run() { 8265 if (report != null) { 8266 sb.append(report); 8267 } 8268 if (logFile != null) { 8269 try { 8270 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8271 } catch (IOException e) { 8272 Slog.e(TAG, "Error reading " + logFile, e); 8273 } 8274 } 8275 if (crashInfo != null && crashInfo.stackTrace != null) { 8276 sb.append(crashInfo.stackTrace); 8277 } 8278 8279 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8280 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8281 if (lines > 0) { 8282 sb.append("\n"); 8283 8284 // Merge several logcat streams, and take the last N lines 8285 InputStreamReader input = null; 8286 try { 8287 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8288 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8289 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8290 8291 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8292 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8293 input = new InputStreamReader(logcat.getInputStream()); 8294 8295 int num; 8296 char[] buf = new char[8192]; 8297 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8298 } catch (IOException e) { 8299 Slog.e(TAG, "Error running logcat", e); 8300 } finally { 8301 if (input != null) try { input.close(); } catch (IOException e) {} 8302 } 8303 } 8304 8305 dbox.addText(dropboxTag, sb.toString()); 8306 } 8307 }; 8308 8309 if (process == null) { 8310 // If process is null, we are being called from some internal code 8311 // and may be about to die -- run this synchronously. 8312 worker.run(); 8313 } else { 8314 worker.start(); 8315 } 8316 } 8317 8318 /** 8319 * Bring up the "unexpected error" dialog box for a crashing app. 8320 * Deal with edge cases (intercepts from instrumented applications, 8321 * ActivityController, error intent receivers, that sort of thing). 8322 * @param r the application crashing 8323 * @param crashInfo describing the failure 8324 */ 8325 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8326 long timeMillis = System.currentTimeMillis(); 8327 String shortMsg = crashInfo.exceptionClassName; 8328 String longMsg = crashInfo.exceptionMessage; 8329 String stackTrace = crashInfo.stackTrace; 8330 if (shortMsg != null && longMsg != null) { 8331 longMsg = shortMsg + ": " + longMsg; 8332 } else if (shortMsg != null) { 8333 longMsg = shortMsg; 8334 } 8335 8336 AppErrorResult result = new AppErrorResult(); 8337 synchronized (this) { 8338 if (mController != null) { 8339 try { 8340 String name = r != null ? r.processName : null; 8341 int pid = r != null ? r.pid : Binder.getCallingPid(); 8342 if (!mController.appCrashed(name, pid, 8343 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8344 Slog.w(TAG, "Force-killing crashed app " + name 8345 + " at watcher's request"); 8346 Process.killProcess(pid); 8347 return; 8348 } 8349 } catch (RemoteException e) { 8350 mController = null; 8351 } 8352 } 8353 8354 final long origId = Binder.clearCallingIdentity(); 8355 8356 // If this process is running instrumentation, finish it. 8357 if (r != null && r.instrumentationClass != null) { 8358 Slog.w(TAG, "Error in app " + r.processName 8359 + " running instrumentation " + r.instrumentationClass + ":"); 8360 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8361 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8362 Bundle info = new Bundle(); 8363 info.putString("shortMsg", shortMsg); 8364 info.putString("longMsg", longMsg); 8365 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8366 Binder.restoreCallingIdentity(origId); 8367 return; 8368 } 8369 8370 // If we can't identify the process or it's already exceeded its crash quota, 8371 // quit right away without showing a crash dialog. 8372 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8373 Binder.restoreCallingIdentity(origId); 8374 return; 8375 } 8376 8377 Message msg = Message.obtain(); 8378 msg.what = SHOW_ERROR_MSG; 8379 HashMap data = new HashMap(); 8380 data.put("result", result); 8381 data.put("app", r); 8382 msg.obj = data; 8383 mHandler.sendMessage(msg); 8384 8385 Binder.restoreCallingIdentity(origId); 8386 } 8387 8388 int res = result.get(); 8389 8390 Intent appErrorIntent = null; 8391 synchronized (this) { 8392 if (r != null && !r.isolated) { 8393 // XXX Can't keep track of crash time for isolated processes, 8394 // since they don't have a persistent identity. 8395 mProcessCrashTimes.put(r.info.processName, r.uid, 8396 SystemClock.uptimeMillis()); 8397 } 8398 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8399 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8400 } 8401 } 8402 8403 if (appErrorIntent != null) { 8404 try { 8405 mContext.startActivity(appErrorIntent); 8406 } catch (ActivityNotFoundException e) { 8407 Slog.w(TAG, "bug report receiver dissappeared", e); 8408 } 8409 } 8410 } 8411 8412 Intent createAppErrorIntentLocked(ProcessRecord r, 8413 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8414 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8415 if (report == null) { 8416 return null; 8417 } 8418 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8419 result.setComponent(r.errorReportReceiver); 8420 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8421 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8422 return result; 8423 } 8424 8425 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8426 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8427 if (r.errorReportReceiver == null) { 8428 return null; 8429 } 8430 8431 if (!r.crashing && !r.notResponding) { 8432 return null; 8433 } 8434 8435 ApplicationErrorReport report = new ApplicationErrorReport(); 8436 report.packageName = r.info.packageName; 8437 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8438 report.processName = r.processName; 8439 report.time = timeMillis; 8440 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8441 8442 if (r.crashing) { 8443 report.type = ApplicationErrorReport.TYPE_CRASH; 8444 report.crashInfo = crashInfo; 8445 } else if (r.notResponding) { 8446 report.type = ApplicationErrorReport.TYPE_ANR; 8447 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8448 8449 report.anrInfo.activity = r.notRespondingReport.tag; 8450 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8451 report.anrInfo.info = r.notRespondingReport.longMsg; 8452 } 8453 8454 return report; 8455 } 8456 8457 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8458 enforceNotIsolatedCaller("getProcessesInErrorState"); 8459 // assume our apps are happy - lazy create the list 8460 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8461 8462 final boolean allUsers = ActivityManager.checkUidPermission( 8463 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8464 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8465 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8466 8467 synchronized (this) { 8468 8469 // iterate across all processes 8470 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8471 ProcessRecord app = mLruProcesses.get(i); 8472 if (!allUsers && app.userId != userId) { 8473 continue; 8474 } 8475 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8476 // This one's in trouble, so we'll generate a report for it 8477 // crashes are higher priority (in case there's a crash *and* an anr) 8478 ActivityManager.ProcessErrorStateInfo report = null; 8479 if (app.crashing) { 8480 report = app.crashingReport; 8481 } else if (app.notResponding) { 8482 report = app.notRespondingReport; 8483 } 8484 8485 if (report != null) { 8486 if (errList == null) { 8487 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8488 } 8489 errList.add(report); 8490 } else { 8491 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8492 " crashing = " + app.crashing + 8493 " notResponding = " + app.notResponding); 8494 } 8495 } 8496 } 8497 } 8498 8499 return errList; 8500 } 8501 8502 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8503 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8504 if (currApp != null) { 8505 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8506 } 8507 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8508 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8510 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8511 if (currApp != null) { 8512 currApp.lru = 0; 8513 } 8514 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8515 } else if (adj >= ProcessList.SERVICE_ADJ) { 8516 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8517 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8518 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8519 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8520 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8521 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8522 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8523 } else { 8524 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8525 } 8526 } 8527 8528 private void fillInProcMemInfo(ProcessRecord app, 8529 ActivityManager.RunningAppProcessInfo outInfo) { 8530 outInfo.pid = app.pid; 8531 outInfo.uid = app.info.uid; 8532 if (mHeavyWeightProcess == app) { 8533 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8534 } 8535 if (app.persistent) { 8536 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8537 } 8538 if (app.hasActivities) { 8539 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8540 } 8541 outInfo.lastTrimLevel = app.trimMemoryLevel; 8542 int adj = app.curAdj; 8543 outInfo.importance = oomAdjToImportance(adj, outInfo); 8544 outInfo.importanceReasonCode = app.adjTypeCode; 8545 } 8546 8547 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8548 enforceNotIsolatedCaller("getRunningAppProcesses"); 8549 // Lazy instantiation of list 8550 List<ActivityManager.RunningAppProcessInfo> runList = null; 8551 final boolean allUsers = ActivityManager.checkUidPermission( 8552 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8553 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8554 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8555 synchronized (this) { 8556 // Iterate across all processes 8557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8558 ProcessRecord app = mLruProcesses.get(i); 8559 if (!allUsers && app.userId != userId) { 8560 continue; 8561 } 8562 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8563 // Generate process state info for running application 8564 ActivityManager.RunningAppProcessInfo currApp = 8565 new ActivityManager.RunningAppProcessInfo(app.processName, 8566 app.pid, app.getPackageList()); 8567 fillInProcMemInfo(app, currApp); 8568 if (app.adjSource instanceof ProcessRecord) { 8569 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8570 currApp.importanceReasonImportance = oomAdjToImportance( 8571 app.adjSourceOom, null); 8572 } else if (app.adjSource instanceof ActivityRecord) { 8573 ActivityRecord r = (ActivityRecord)app.adjSource; 8574 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8575 } 8576 if (app.adjTarget instanceof ComponentName) { 8577 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8578 } 8579 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8580 // + " lru=" + currApp.lru); 8581 if (runList == null) { 8582 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8583 } 8584 runList.add(currApp); 8585 } 8586 } 8587 } 8588 return runList; 8589 } 8590 8591 public List<ApplicationInfo> getRunningExternalApplications() { 8592 enforceNotIsolatedCaller("getRunningExternalApplications"); 8593 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8594 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8595 if (runningApps != null && runningApps.size() > 0) { 8596 Set<String> extList = new HashSet<String>(); 8597 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8598 if (app.pkgList != null) { 8599 for (String pkg : app.pkgList) { 8600 extList.add(pkg); 8601 } 8602 } 8603 } 8604 IPackageManager pm = AppGlobals.getPackageManager(); 8605 for (String pkg : extList) { 8606 try { 8607 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8608 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8609 retList.add(info); 8610 } 8611 } catch (RemoteException e) { 8612 } 8613 } 8614 } 8615 return retList; 8616 } 8617 8618 @Override 8619 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8620 enforceNotIsolatedCaller("getMyMemoryState"); 8621 synchronized (this) { 8622 ProcessRecord proc; 8623 synchronized (mPidsSelfLocked) { 8624 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8625 } 8626 fillInProcMemInfo(proc, outInfo); 8627 } 8628 } 8629 8630 @Override 8631 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8632 if (checkCallingPermission(android.Manifest.permission.DUMP) 8633 != PackageManager.PERMISSION_GRANTED) { 8634 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8635 + Binder.getCallingPid() 8636 + ", uid=" + Binder.getCallingUid() 8637 + " without permission " 8638 + android.Manifest.permission.DUMP); 8639 return; 8640 } 8641 8642 boolean dumpAll = false; 8643 boolean dumpClient = false; 8644 String dumpPackage = null; 8645 8646 int opti = 0; 8647 while (opti < args.length) { 8648 String opt = args[opti]; 8649 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8650 break; 8651 } 8652 opti++; 8653 if ("-a".equals(opt)) { 8654 dumpAll = true; 8655 } else if ("-c".equals(opt)) { 8656 dumpClient = true; 8657 } else if ("-h".equals(opt)) { 8658 pw.println("Activity manager dump options:"); 8659 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8660 pw.println(" cmd may be one of:"); 8661 pw.println(" a[ctivities]: activity stack state"); 8662 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8663 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8664 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8665 pw.println(" o[om]: out of memory management"); 8666 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8667 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8668 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8669 pw.println(" service [COMP_SPEC]: service client-side state"); 8670 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8671 pw.println(" all: dump all activities"); 8672 pw.println(" top: dump the top activity"); 8673 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8674 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8675 pw.println(" a partial substring in a component name, a"); 8676 pw.println(" hex object identifier."); 8677 pw.println(" -a: include all available server state."); 8678 pw.println(" -c: include client state."); 8679 return; 8680 } else { 8681 pw.println("Unknown argument: " + opt + "; use -h for help"); 8682 } 8683 } 8684 8685 long origId = Binder.clearCallingIdentity(); 8686 boolean more = false; 8687 // Is the caller requesting to dump a particular piece of data? 8688 if (opti < args.length) { 8689 String cmd = args[opti]; 8690 opti++; 8691 if ("activities".equals(cmd) || "a".equals(cmd)) { 8692 synchronized (this) { 8693 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8694 } 8695 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8696 String[] newArgs; 8697 String name; 8698 if (opti >= args.length) { 8699 name = null; 8700 newArgs = EMPTY_STRING_ARRAY; 8701 } else { 8702 name = args[opti]; 8703 opti++; 8704 newArgs = new String[args.length - opti]; 8705 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8706 args.length - opti); 8707 } 8708 synchronized (this) { 8709 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8710 } 8711 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8712 String[] newArgs; 8713 String name; 8714 if (opti >= args.length) { 8715 name = null; 8716 newArgs = EMPTY_STRING_ARRAY; 8717 } else { 8718 name = args[opti]; 8719 opti++; 8720 newArgs = new String[args.length - opti]; 8721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8722 args.length - opti); 8723 } 8724 synchronized (this) { 8725 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8726 } 8727 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8728 String[] newArgs; 8729 String name; 8730 if (opti >= args.length) { 8731 name = null; 8732 newArgs = EMPTY_STRING_ARRAY; 8733 } else { 8734 name = args[opti]; 8735 opti++; 8736 newArgs = new String[args.length - opti]; 8737 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8738 args.length - opti); 8739 } 8740 synchronized (this) { 8741 dumpProcessesLocked(fd, pw, args, opti, true, name); 8742 } 8743 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8744 synchronized (this) { 8745 dumpOomLocked(fd, pw, args, opti, true); 8746 } 8747 } else if ("provider".equals(cmd)) { 8748 String[] newArgs; 8749 String name; 8750 if (opti >= args.length) { 8751 name = null; 8752 newArgs = EMPTY_STRING_ARRAY; 8753 } else { 8754 name = args[opti]; 8755 opti++; 8756 newArgs = new String[args.length - opti]; 8757 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8758 } 8759 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8760 pw.println("No providers match: " + name); 8761 pw.println("Use -h for help."); 8762 } 8763 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8764 synchronized (this) { 8765 dumpProvidersLocked(fd, pw, args, opti, true, null); 8766 } 8767 } else if ("service".equals(cmd)) { 8768 String[] newArgs; 8769 String name; 8770 if (opti >= args.length) { 8771 name = null; 8772 newArgs = EMPTY_STRING_ARRAY; 8773 } else { 8774 name = args[opti]; 8775 opti++; 8776 newArgs = new String[args.length - opti]; 8777 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8778 args.length - opti); 8779 } 8780 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8781 pw.println("No services match: " + name); 8782 pw.println("Use -h for help."); 8783 } 8784 } else if ("package".equals(cmd)) { 8785 String[] newArgs; 8786 if (opti >= args.length) { 8787 pw.println("package: no package name specified"); 8788 pw.println("Use -h for help."); 8789 } else { 8790 dumpPackage = args[opti]; 8791 opti++; 8792 newArgs = new String[args.length - opti]; 8793 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8794 args.length - opti); 8795 args = newArgs; 8796 opti = 0; 8797 more = true; 8798 } 8799 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8800 synchronized (this) { 8801 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8802 } 8803 } else { 8804 // Dumping a single activity? 8805 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8806 pw.println("Bad activity command, or no activities match: " + cmd); 8807 pw.println("Use -h for help."); 8808 } 8809 } 8810 if (!more) { 8811 Binder.restoreCallingIdentity(origId); 8812 return; 8813 } 8814 } 8815 8816 // No piece of data specified, dump everything. 8817 synchronized (this) { 8818 boolean needSep; 8819 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8820 if (needSep) { 8821 pw.println(" "); 8822 } 8823 if (dumpAll) { 8824 pw.println("-------------------------------------------------------------------------------"); 8825 } 8826 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8827 if (needSep) { 8828 pw.println(" "); 8829 } 8830 if (dumpAll) { 8831 pw.println("-------------------------------------------------------------------------------"); 8832 } 8833 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8834 if (needSep) { 8835 pw.println(" "); 8836 } 8837 if (dumpAll) { 8838 pw.println("-------------------------------------------------------------------------------"); 8839 } 8840 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8841 if (needSep) { 8842 pw.println(" "); 8843 } 8844 if (dumpAll) { 8845 pw.println("-------------------------------------------------------------------------------"); 8846 } 8847 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8848 if (needSep) { 8849 pw.println(" "); 8850 } 8851 if (dumpAll) { 8852 pw.println("-------------------------------------------------------------------------------"); 8853 } 8854 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8855 } 8856 Binder.restoreCallingIdentity(origId); 8857 } 8858 8859 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8860 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8861 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8862 pw.println(" Main stack:"); 8863 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8864 dumpPackage); 8865 pw.println(" "); 8866 pw.println(" Running activities (most recent first):"); 8867 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8868 dumpPackage); 8869 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8870 pw.println(" "); 8871 pw.println(" Activities waiting for another to become visible:"); 8872 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8873 !dumpAll, false, dumpPackage); 8874 } 8875 if (mMainStack.mStoppingActivities.size() > 0) { 8876 pw.println(" "); 8877 pw.println(" Activities waiting to stop:"); 8878 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8879 !dumpAll, false, dumpPackage); 8880 } 8881 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8882 pw.println(" "); 8883 pw.println(" Activities waiting to sleep:"); 8884 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8885 !dumpAll, false, dumpPackage); 8886 } 8887 if (mMainStack.mFinishingActivities.size() > 0) { 8888 pw.println(" "); 8889 pw.println(" Activities waiting to finish:"); 8890 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8891 !dumpAll, false, dumpPackage); 8892 } 8893 8894 pw.println(" "); 8895 if (mMainStack.mPausingActivity != null) { 8896 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8897 } 8898 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8899 pw.println(" mFocusedActivity: " + mFocusedActivity); 8900 if (dumpAll) { 8901 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8902 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8903 pw.println(" mDismissKeyguardOnNextActivity: " 8904 + mMainStack.mDismissKeyguardOnNextActivity); 8905 } 8906 8907 if (mRecentTasks.size() > 0) { 8908 pw.println(); 8909 pw.println(" Recent tasks:"); 8910 8911 final int N = mRecentTasks.size(); 8912 for (int i=0; i<N; i++) { 8913 TaskRecord tr = mRecentTasks.get(i); 8914 if (dumpPackage != null) { 8915 if (tr.realActivity == null || 8916 !dumpPackage.equals(tr.realActivity)) { 8917 continue; 8918 } 8919 } 8920 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8921 pw.println(tr); 8922 if (dumpAll) { 8923 mRecentTasks.get(i).dump(pw, " "); 8924 } 8925 } 8926 } 8927 8928 if (dumpAll) { 8929 pw.println(" "); 8930 pw.println(" mCurTask: " + mCurTask); 8931 } 8932 8933 return true; 8934 } 8935 8936 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8937 int opti, boolean dumpAll, String dumpPackage) { 8938 boolean needSep = false; 8939 int numPers = 0; 8940 8941 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8942 8943 if (dumpAll) { 8944 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8945 final int NA = procs.size(); 8946 for (int ia=0; ia<NA; ia++) { 8947 ProcessRecord r = procs.valueAt(ia); 8948 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8949 continue; 8950 } 8951 if (!needSep) { 8952 pw.println(" All known processes:"); 8953 needSep = true; 8954 } 8955 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8956 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8957 pw.print(" "); pw.println(r); 8958 r.dump(pw, " "); 8959 if (r.persistent) { 8960 numPers++; 8961 } 8962 } 8963 } 8964 } 8965 8966 if (mIsolatedProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Isolated process list (sorted by uid):"); 8970 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8971 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8972 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8973 continue; 8974 } 8975 pw.println(String.format("%sIsolated #%2d: %s", 8976 " ", i, r.toString())); 8977 } 8978 } 8979 8980 if (mLruProcesses.size() > 0) { 8981 if (needSep) pw.println(" "); 8982 needSep = true; 8983 pw.println(" Process LRU list (sorted by oom_adj):"); 8984 dumpProcessOomList(pw, this, mLruProcesses, " ", 8985 "Proc", "PERS", false, dumpPackage); 8986 needSep = true; 8987 } 8988 8989 if (dumpAll) { 8990 synchronized (mPidsSelfLocked) { 8991 boolean printed = false; 8992 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8993 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8994 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8995 continue; 8996 } 8997 if (!printed) { 8998 if (needSep) pw.println(" "); 8999 needSep = true; 9000 pw.println(" PID mappings:"); 9001 printed = true; 9002 } 9003 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9004 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9005 } 9006 } 9007 } 9008 9009 if (mForegroundProcesses.size() > 0) { 9010 synchronized (mPidsSelfLocked) { 9011 boolean printed = false; 9012 for (int i=0; i<mForegroundProcesses.size(); i++) { 9013 ProcessRecord r = mPidsSelfLocked.get( 9014 mForegroundProcesses.valueAt(i).pid); 9015 if (dumpPackage != null && (r == null 9016 || !dumpPackage.equals(r.info.packageName))) { 9017 continue; 9018 } 9019 if (!printed) { 9020 if (needSep) pw.println(" "); 9021 needSep = true; 9022 pw.println(" Foreground Processes:"); 9023 printed = true; 9024 } 9025 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9026 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9027 } 9028 } 9029 } 9030 9031 if (mPersistentStartingProcesses.size() > 0) { 9032 if (needSep) pw.println(" "); 9033 needSep = true; 9034 pw.println(" Persisent processes that are starting:"); 9035 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9036 "Starting Norm", "Restarting PERS", dumpPackage); 9037 } 9038 9039 if (mRemovedProcesses.size() > 0) { 9040 if (needSep) pw.println(" "); 9041 needSep = true; 9042 pw.println(" Processes that are being removed:"); 9043 dumpProcessList(pw, this, mRemovedProcesses, " ", 9044 "Removed Norm", "Removed PERS", dumpPackage); 9045 } 9046 9047 if (mProcessesOnHold.size() > 0) { 9048 if (needSep) pw.println(" "); 9049 needSep = true; 9050 pw.println(" Processes that are on old until the system is ready:"); 9051 dumpProcessList(pw, this, mProcessesOnHold, " ", 9052 "OnHold Norm", "OnHold PERS", dumpPackage); 9053 } 9054 9055 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9056 9057 if (mProcessCrashTimes.getMap().size() > 0) { 9058 boolean printed = false; 9059 long now = SystemClock.uptimeMillis(); 9060 for (Map.Entry<String, SparseArray<Long>> procs 9061 : mProcessCrashTimes.getMap().entrySet()) { 9062 String pname = procs.getKey(); 9063 SparseArray<Long> uids = procs.getValue(); 9064 final int N = uids.size(); 9065 for (int i=0; i<N; i++) { 9066 int puid = uids.keyAt(i); 9067 ProcessRecord r = mProcessNames.get(pname, puid); 9068 if (dumpPackage != null && (r == null 9069 || !dumpPackage.equals(r.info.packageName))) { 9070 continue; 9071 } 9072 if (!printed) { 9073 if (needSep) pw.println(" "); 9074 needSep = true; 9075 pw.println(" Time since processes crashed:"); 9076 printed = true; 9077 } 9078 pw.print(" Process "); pw.print(pname); 9079 pw.print(" uid "); pw.print(puid); 9080 pw.print(": last crashed "); 9081 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9082 pw.println(" ago"); 9083 } 9084 } 9085 } 9086 9087 if (mBadProcesses.getMap().size() > 0) { 9088 boolean printed = false; 9089 for (Map.Entry<String, SparseArray<Long>> procs 9090 : mBadProcesses.getMap().entrySet()) { 9091 String pname = procs.getKey(); 9092 SparseArray<Long> uids = procs.getValue(); 9093 final int N = uids.size(); 9094 for (int i=0; i<N; i++) { 9095 int puid = uids.keyAt(i); 9096 ProcessRecord r = mProcessNames.get(pname, puid); 9097 if (dumpPackage != null && (r == null 9098 || !dumpPackage.equals(r.info.packageName))) { 9099 continue; 9100 } 9101 if (!printed) { 9102 if (needSep) pw.println(" "); 9103 needSep = true; 9104 pw.println(" Bad processes:"); 9105 } 9106 pw.print(" Bad process "); pw.print(pname); 9107 pw.print(" uid "); pw.print(puid); 9108 pw.print(": crashed at time "); 9109 pw.println(uids.valueAt(i)); 9110 } 9111 } 9112 } 9113 9114 pw.println(); 9115 pw.println(" mStartedUsers:"); 9116 for (int i=0; i<mStartedUsers.size(); i++) { 9117 UserStartedState uss = mStartedUsers.valueAt(i); 9118 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9119 pw.println(":"); 9120 uss.dump(" ", pw); 9121 } 9122 pw.println(" mHomeProcess: " + mHomeProcess); 9123 pw.println(" mPreviousProcess: " + mPreviousProcess); 9124 if (dumpAll) { 9125 StringBuilder sb = new StringBuilder(128); 9126 sb.append(" mPreviousProcessVisibleTime: "); 9127 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9128 pw.println(sb); 9129 } 9130 if (mHeavyWeightProcess != null) { 9131 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9132 } 9133 pw.println(" mConfiguration: " + mConfiguration); 9134 if (dumpAll) { 9135 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9136 if (mCompatModePackages.getPackages().size() > 0) { 9137 boolean printed = false; 9138 for (Map.Entry<String, Integer> entry 9139 : mCompatModePackages.getPackages().entrySet()) { 9140 String pkg = entry.getKey(); 9141 int mode = entry.getValue(); 9142 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9143 continue; 9144 } 9145 if (!printed) { 9146 pw.println(" mScreenCompatPackages:"); 9147 printed = true; 9148 } 9149 pw.print(" "); pw.print(pkg); pw.print(": "); 9150 pw.print(mode); pw.println(); 9151 } 9152 } 9153 } 9154 if (mSleeping || mWentToSleep || mLockScreenShown) { 9155 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9156 + " mLockScreenShown " + mLockScreenShown); 9157 } 9158 if (mShuttingDown) { 9159 pw.println(" mShuttingDown=" + mShuttingDown); 9160 } 9161 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9162 || mOrigWaitForDebugger) { 9163 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9164 + " mDebugTransient=" + mDebugTransient 9165 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9166 } 9167 if (mOpenGlTraceApp != null) { 9168 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9169 } 9170 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9171 || mProfileFd != null) { 9172 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9173 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9174 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9175 + mAutoStopProfiler); 9176 } 9177 if (mAlwaysFinishActivities || mController != null) { 9178 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9179 + " mController=" + mController); 9180 } 9181 if (dumpAll) { 9182 pw.println(" Total persistent processes: " + numPers); 9183 pw.println(" mStartRunning=" + mStartRunning 9184 + " mProcessesReady=" + mProcessesReady 9185 + " mSystemReady=" + mSystemReady); 9186 pw.println(" mBooting=" + mBooting 9187 + " mBooted=" + mBooted 9188 + " mFactoryTest=" + mFactoryTest); 9189 pw.print(" mLastPowerCheckRealtime="); 9190 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9191 pw.println(""); 9192 pw.print(" mLastPowerCheckUptime="); 9193 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9194 pw.println(""); 9195 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9196 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9197 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9198 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9199 + " mNumHiddenProcs=" + mNumHiddenProcs 9200 + " mNumServiceProcs=" + mNumServiceProcs 9201 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9202 } 9203 9204 return true; 9205 } 9206 9207 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9208 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9209 if (mProcessesToGc.size() > 0) { 9210 boolean printed = false; 9211 long now = SystemClock.uptimeMillis(); 9212 for (int i=0; i<mProcessesToGc.size(); i++) { 9213 ProcessRecord proc = mProcessesToGc.get(i); 9214 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9215 continue; 9216 } 9217 if (!printed) { 9218 if (needSep) pw.println(" "); 9219 needSep = true; 9220 pw.println(" Processes that are waiting to GC:"); 9221 printed = true; 9222 } 9223 pw.print(" Process "); pw.println(proc); 9224 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9225 pw.print(", last gced="); 9226 pw.print(now-proc.lastRequestedGc); 9227 pw.print(" ms ago, last lowMem="); 9228 pw.print(now-proc.lastLowMemory); 9229 pw.println(" ms ago"); 9230 9231 } 9232 } 9233 return needSep; 9234 } 9235 9236 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9237 int opti, boolean dumpAll) { 9238 boolean needSep = false; 9239 9240 if (mLruProcesses.size() > 0) { 9241 if (needSep) pw.println(" "); 9242 needSep = true; 9243 pw.println(" OOM levels:"); 9244 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9245 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9246 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9247 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9248 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9249 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9250 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9251 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9252 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9253 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9254 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9255 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9256 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9257 9258 if (needSep) pw.println(" "); 9259 needSep = true; 9260 pw.println(" Process OOM control:"); 9261 dumpProcessOomList(pw, this, mLruProcesses, " ", 9262 "Proc", "PERS", true, null); 9263 needSep = true; 9264 } 9265 9266 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9267 9268 pw.println(); 9269 pw.println(" mHomeProcess: " + mHomeProcess); 9270 pw.println(" mPreviousProcess: " + mPreviousProcess); 9271 if (mHeavyWeightProcess != null) { 9272 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9273 } 9274 9275 return true; 9276 } 9277 9278 /** 9279 * There are three ways to call this: 9280 * - no provider specified: dump all the providers 9281 * - a flattened component name that matched an existing provider was specified as the 9282 * first arg: dump that one provider 9283 * - the first arg isn't the flattened component name of an existing provider: 9284 * dump all providers whose component contains the first arg as a substring 9285 */ 9286 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9287 int opti, boolean dumpAll) { 9288 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9289 } 9290 9291 static class ItemMatcher { 9292 ArrayList<ComponentName> components; 9293 ArrayList<String> strings; 9294 ArrayList<Integer> objects; 9295 boolean all; 9296 9297 ItemMatcher() { 9298 all = true; 9299 } 9300 9301 void build(String name) { 9302 ComponentName componentName = ComponentName.unflattenFromString(name); 9303 if (componentName != null) { 9304 if (components == null) { 9305 components = new ArrayList<ComponentName>(); 9306 } 9307 components.add(componentName); 9308 all = false; 9309 } else { 9310 int objectId = 0; 9311 // Not a '/' separated full component name; maybe an object ID? 9312 try { 9313 objectId = Integer.parseInt(name, 16); 9314 if (objects == null) { 9315 objects = new ArrayList<Integer>(); 9316 } 9317 objects.add(objectId); 9318 all = false; 9319 } catch (RuntimeException e) { 9320 // Not an integer; just do string match. 9321 if (strings == null) { 9322 strings = new ArrayList<String>(); 9323 } 9324 strings.add(name); 9325 all = false; 9326 } 9327 } 9328 } 9329 9330 int build(String[] args, int opti) { 9331 for (; opti<args.length; opti++) { 9332 String name = args[opti]; 9333 if ("--".equals(name)) { 9334 return opti+1; 9335 } 9336 build(name); 9337 } 9338 return opti; 9339 } 9340 9341 boolean match(Object object, ComponentName comp) { 9342 if (all) { 9343 return true; 9344 } 9345 if (components != null) { 9346 for (int i=0; i<components.size(); i++) { 9347 if (components.get(i).equals(comp)) { 9348 return true; 9349 } 9350 } 9351 } 9352 if (objects != null) { 9353 for (int i=0; i<objects.size(); i++) { 9354 if (System.identityHashCode(object) == objects.get(i)) { 9355 return true; 9356 } 9357 } 9358 } 9359 if (strings != null) { 9360 String flat = comp.flattenToString(); 9361 for (int i=0; i<strings.size(); i++) { 9362 if (flat.contains(strings.get(i))) { 9363 return true; 9364 } 9365 } 9366 } 9367 return false; 9368 } 9369 } 9370 9371 /** 9372 * There are three things that cmd can be: 9373 * - a flattened component name that matches an existing activity 9374 * - the cmd arg isn't the flattened component name of an existing activity: 9375 * dump all activity whose component contains the cmd as a substring 9376 * - A hex number of the ActivityRecord object instance. 9377 */ 9378 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9379 int opti, boolean dumpAll) { 9380 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9381 9382 if ("all".equals(name)) { 9383 synchronized (this) { 9384 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9385 activities.add(r1); 9386 } 9387 } 9388 } else if ("top".equals(name)) { 9389 synchronized (this) { 9390 final int N = mMainStack.mHistory.size(); 9391 if (N > 0) { 9392 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9393 } 9394 } 9395 } else { 9396 ItemMatcher matcher = new ItemMatcher(); 9397 matcher.build(name); 9398 9399 synchronized (this) { 9400 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9401 if (matcher.match(r1, r1.intent.getComponent())) { 9402 activities.add(r1); 9403 } 9404 } 9405 } 9406 } 9407 9408 if (activities.size() <= 0) { 9409 return false; 9410 } 9411 9412 String[] newArgs = new String[args.length - opti]; 9413 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9414 9415 TaskRecord lastTask = null; 9416 boolean needSep = false; 9417 for (int i=activities.size()-1; i>=0; i--) { 9418 ActivityRecord r = (ActivityRecord)activities.get(i); 9419 if (needSep) { 9420 pw.println(); 9421 } 9422 needSep = true; 9423 synchronized (this) { 9424 if (lastTask != r.task) { 9425 lastTask = r.task; 9426 pw.print("TASK "); pw.print(lastTask.affinity); 9427 pw.print(" id="); pw.println(lastTask.taskId); 9428 if (dumpAll) { 9429 lastTask.dump(pw, " "); 9430 } 9431 } 9432 } 9433 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9434 } 9435 return true; 9436 } 9437 9438 /** 9439 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9440 * there is a thread associated with the activity. 9441 */ 9442 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9443 final ActivityRecord r, String[] args, boolean dumpAll) { 9444 String innerPrefix = prefix + " "; 9445 synchronized (this) { 9446 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9447 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9448 pw.print(" pid="); 9449 if (r.app != null) pw.println(r.app.pid); 9450 else pw.println("(not running)"); 9451 if (dumpAll) { 9452 r.dump(pw, innerPrefix); 9453 } 9454 } 9455 if (r.app != null && r.app.thread != null) { 9456 // flush anything that is already in the PrintWriter since the thread is going 9457 // to write to the file descriptor directly 9458 pw.flush(); 9459 try { 9460 TransferPipe tp = new TransferPipe(); 9461 try { 9462 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9463 r.appToken, innerPrefix, args); 9464 tp.go(fd); 9465 } finally { 9466 tp.kill(); 9467 } 9468 } catch (IOException e) { 9469 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9470 } catch (RemoteException e) { 9471 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9472 } 9473 } 9474 } 9475 9476 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9477 int opti, boolean dumpAll, String dumpPackage) { 9478 boolean needSep = false; 9479 boolean onlyHistory = false; 9480 9481 if ("history".equals(dumpPackage)) { 9482 onlyHistory = true; 9483 dumpPackage = null; 9484 } 9485 9486 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9487 if (!onlyHistory && dumpAll) { 9488 if (mRegisteredReceivers.size() > 0) { 9489 boolean printed = false; 9490 Iterator it = mRegisteredReceivers.values().iterator(); 9491 while (it.hasNext()) { 9492 ReceiverList r = (ReceiverList)it.next(); 9493 if (dumpPackage != null && (r.app == null || 9494 !dumpPackage.equals(r.app.info.packageName))) { 9495 continue; 9496 } 9497 if (!printed) { 9498 pw.println(" Registered Receivers:"); 9499 needSep = true; 9500 printed = true; 9501 } 9502 pw.print(" * "); pw.println(r); 9503 r.dump(pw, " "); 9504 } 9505 } 9506 9507 if (mReceiverResolver.dump(pw, needSep ? 9508 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9509 " ", dumpPackage, false)) { 9510 needSep = true; 9511 } 9512 } 9513 9514 for (BroadcastQueue q : mBroadcastQueues) { 9515 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9516 } 9517 9518 needSep = true; 9519 9520 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9521 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9522 if (needSep) { 9523 pw.println(); 9524 } 9525 needSep = true; 9526 pw.print(" Sticky broadcasts for user "); 9527 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9528 StringBuilder sb = new StringBuilder(128); 9529 for (Map.Entry<String, ArrayList<Intent>> ent 9530 : mStickyBroadcasts.valueAt(user).entrySet()) { 9531 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9532 if (dumpAll) { 9533 pw.println(":"); 9534 ArrayList<Intent> intents = ent.getValue(); 9535 final int N = intents.size(); 9536 for (int i=0; i<N; i++) { 9537 sb.setLength(0); 9538 sb.append(" Intent: "); 9539 intents.get(i).toShortString(sb, false, true, false, false); 9540 pw.println(sb.toString()); 9541 Bundle bundle = intents.get(i).getExtras(); 9542 if (bundle != null) { 9543 pw.print(" "); 9544 pw.println(bundle.toString()); 9545 } 9546 } 9547 } else { 9548 pw.println(""); 9549 } 9550 } 9551 } 9552 } 9553 9554 if (!onlyHistory && dumpAll) { 9555 pw.println(); 9556 for (BroadcastQueue queue : mBroadcastQueues) { 9557 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9558 + queue.mBroadcastsScheduled); 9559 } 9560 pw.println(" mHandler:"); 9561 mHandler.dump(new PrintWriterPrinter(pw), " "); 9562 needSep = true; 9563 } 9564 9565 return needSep; 9566 } 9567 9568 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9569 int opti, boolean dumpAll, String dumpPackage) { 9570 boolean needSep = true; 9571 9572 ItemMatcher matcher = new ItemMatcher(); 9573 matcher.build(args, opti); 9574 9575 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9576 9577 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9578 9579 if (mLaunchingProviders.size() > 0) { 9580 boolean printed = false; 9581 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9582 ContentProviderRecord r = mLaunchingProviders.get(i); 9583 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9584 continue; 9585 } 9586 if (!printed) { 9587 if (needSep) pw.println(" "); 9588 needSep = true; 9589 pw.println(" Launching content providers:"); 9590 printed = true; 9591 } 9592 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9593 pw.println(r); 9594 } 9595 } 9596 9597 if (mGrantedUriPermissions.size() > 0) { 9598 if (needSep) pw.println(); 9599 needSep = true; 9600 pw.println("Granted Uri Permissions:"); 9601 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9602 int uid = mGrantedUriPermissions.keyAt(i); 9603 HashMap<Uri, UriPermission> perms 9604 = mGrantedUriPermissions.valueAt(i); 9605 pw.print(" * UID "); pw.print(uid); 9606 pw.println(" holds:"); 9607 for (UriPermission perm : perms.values()) { 9608 pw.print(" "); pw.println(perm); 9609 if (dumpAll) { 9610 perm.dump(pw, " "); 9611 } 9612 } 9613 } 9614 needSep = true; 9615 } 9616 9617 return needSep; 9618 } 9619 9620 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9621 int opti, boolean dumpAll, String dumpPackage) { 9622 boolean needSep = false; 9623 9624 if (mIntentSenderRecords.size() > 0) { 9625 boolean printed = false; 9626 Iterator<WeakReference<PendingIntentRecord>> it 9627 = mIntentSenderRecords.values().iterator(); 9628 while (it.hasNext()) { 9629 WeakReference<PendingIntentRecord> ref = it.next(); 9630 PendingIntentRecord rec = ref != null ? ref.get(): null; 9631 if (dumpPackage != null && (rec == null 9632 || !dumpPackage.equals(rec.key.packageName))) { 9633 continue; 9634 } 9635 if (!printed) { 9636 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9637 printed = true; 9638 } 9639 needSep = true; 9640 if (rec != null) { 9641 pw.print(" * "); pw.println(rec); 9642 if (dumpAll) { 9643 rec.dump(pw, " "); 9644 } 9645 } else { 9646 pw.print(" * "); pw.println(ref); 9647 } 9648 } 9649 } 9650 9651 return needSep; 9652 } 9653 9654 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9655 String prefix, String label, boolean complete, boolean brief, boolean client, 9656 String dumpPackage) { 9657 TaskRecord lastTask = null; 9658 boolean needNL = false; 9659 final String innerPrefix = prefix + " "; 9660 final String[] args = new String[0]; 9661 for (int i=list.size()-1; i>=0; i--) { 9662 final ActivityRecord r = (ActivityRecord)list.get(i); 9663 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9664 continue; 9665 } 9666 final boolean full = !brief && (complete || !r.isInHistory()); 9667 if (needNL) { 9668 pw.println(" "); 9669 needNL = false; 9670 } 9671 if (lastTask != r.task) { 9672 lastTask = r.task; 9673 pw.print(prefix); 9674 pw.print(full ? "* " : " "); 9675 pw.println(lastTask); 9676 if (full) { 9677 lastTask.dump(pw, prefix + " "); 9678 } else if (complete) { 9679 // Complete + brief == give a summary. Isn't that obvious?!? 9680 if (lastTask.intent != null) { 9681 pw.print(prefix); pw.print(" "); 9682 pw.println(lastTask.intent.toInsecureStringWithClip()); 9683 } 9684 } 9685 } 9686 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9687 pw.print(" #"); pw.print(i); pw.print(": "); 9688 pw.println(r); 9689 if (full) { 9690 r.dump(pw, innerPrefix); 9691 } else if (complete) { 9692 // Complete + brief == give a summary. Isn't that obvious?!? 9693 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9694 if (r.app != null) { 9695 pw.print(innerPrefix); pw.println(r.app); 9696 } 9697 } 9698 if (client && r.app != null && r.app.thread != null) { 9699 // flush anything that is already in the PrintWriter since the thread is going 9700 // to write to the file descriptor directly 9701 pw.flush(); 9702 try { 9703 TransferPipe tp = new TransferPipe(); 9704 try { 9705 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9706 r.appToken, innerPrefix, args); 9707 // Short timeout, since blocking here can 9708 // deadlock with the application. 9709 tp.go(fd, 2000); 9710 } finally { 9711 tp.kill(); 9712 } 9713 } catch (IOException e) { 9714 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9715 } catch (RemoteException e) { 9716 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9717 } 9718 needNL = true; 9719 } 9720 } 9721 } 9722 9723 private static String buildOomTag(String prefix, String space, int val, int base) { 9724 if (val == base) { 9725 if (space == null) return prefix; 9726 return prefix + " "; 9727 } 9728 return prefix + "+" + Integer.toString(val-base); 9729 } 9730 9731 private static final int dumpProcessList(PrintWriter pw, 9732 ActivityManagerService service, List list, 9733 String prefix, String normalLabel, String persistentLabel, 9734 String dumpPackage) { 9735 int numPers = 0; 9736 final int N = list.size()-1; 9737 for (int i=N; i>=0; i--) { 9738 ProcessRecord r = (ProcessRecord)list.get(i); 9739 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9740 continue; 9741 } 9742 pw.println(String.format("%s%s #%2d: %s", 9743 prefix, (r.persistent ? persistentLabel : normalLabel), 9744 i, r.toString())); 9745 if (r.persistent) { 9746 numPers++; 9747 } 9748 } 9749 return numPers; 9750 } 9751 9752 private static final boolean dumpProcessOomList(PrintWriter pw, 9753 ActivityManagerService service, List<ProcessRecord> origList, 9754 String prefix, String normalLabel, String persistentLabel, 9755 boolean inclDetails, String dumpPackage) { 9756 9757 ArrayList<Pair<ProcessRecord, Integer>> list 9758 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9759 for (int i=0; i<origList.size(); i++) { 9760 ProcessRecord r = origList.get(i); 9761 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9762 continue; 9763 } 9764 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9765 } 9766 9767 if (list.size() <= 0) { 9768 return false; 9769 } 9770 9771 Comparator<Pair<ProcessRecord, Integer>> comparator 9772 = new Comparator<Pair<ProcessRecord, Integer>>() { 9773 @Override 9774 public int compare(Pair<ProcessRecord, Integer> object1, 9775 Pair<ProcessRecord, Integer> object2) { 9776 if (object1.first.setAdj != object2.first.setAdj) { 9777 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9778 } 9779 if (object1.second.intValue() != object2.second.intValue()) { 9780 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9781 } 9782 return 0; 9783 } 9784 }; 9785 9786 Collections.sort(list, comparator); 9787 9788 final long curRealtime = SystemClock.elapsedRealtime(); 9789 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9790 final long curUptime = SystemClock.uptimeMillis(); 9791 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9792 9793 for (int i=list.size()-1; i>=0; i--) { 9794 ProcessRecord r = list.get(i).first; 9795 String oomAdj; 9796 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9797 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9798 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9799 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9800 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9801 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9802 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9803 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9804 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9805 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9806 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9807 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9808 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9809 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9810 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9811 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9812 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9813 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9814 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9815 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9816 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9817 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9818 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9819 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9820 } else { 9821 oomAdj = Integer.toString(r.setAdj); 9822 } 9823 String schedGroup; 9824 switch (r.setSchedGroup) { 9825 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9826 schedGroup = "B"; 9827 break; 9828 case Process.THREAD_GROUP_DEFAULT: 9829 schedGroup = "F"; 9830 break; 9831 default: 9832 schedGroup = Integer.toString(r.setSchedGroup); 9833 break; 9834 } 9835 String foreground; 9836 if (r.foregroundActivities) { 9837 foreground = "A"; 9838 } else if (r.foregroundServices) { 9839 foreground = "S"; 9840 } else { 9841 foreground = " "; 9842 } 9843 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9844 prefix, (r.persistent ? persistentLabel : normalLabel), 9845 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9846 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9847 if (r.adjSource != null || r.adjTarget != null) { 9848 pw.print(prefix); 9849 pw.print(" "); 9850 if (r.adjTarget instanceof ComponentName) { 9851 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9852 } else if (r.adjTarget != null) { 9853 pw.print(r.adjTarget.toString()); 9854 } else { 9855 pw.print("{null}"); 9856 } 9857 pw.print("<="); 9858 if (r.adjSource instanceof ProcessRecord) { 9859 pw.print("Proc{"); 9860 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9861 pw.println("}"); 9862 } else if (r.adjSource != null) { 9863 pw.println(r.adjSource.toString()); 9864 } else { 9865 pw.println("{null}"); 9866 } 9867 } 9868 if (inclDetails) { 9869 pw.print(prefix); 9870 pw.print(" "); 9871 pw.print("oom: max="); pw.print(r.maxAdj); 9872 pw.print(" hidden="); pw.print(r.hiddenAdj); 9873 pw.print(" empty="); pw.print(r.emptyAdj); 9874 pw.print(" curRaw="); pw.print(r.curRawAdj); 9875 pw.print(" setRaw="); pw.print(r.setRawAdj); 9876 pw.print(" cur="); pw.print(r.curAdj); 9877 pw.print(" set="); pw.println(r.setAdj); 9878 pw.print(prefix); 9879 pw.print(" "); 9880 pw.print("keeping="); pw.print(r.keeping); 9881 pw.print(" hidden="); pw.print(r.hidden); 9882 pw.print(" empty="); pw.print(r.empty); 9883 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9884 9885 if (!r.keeping) { 9886 if (r.lastWakeTime != 0) { 9887 long wtime; 9888 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9889 synchronized (stats) { 9890 wtime = stats.getProcessWakeTime(r.info.uid, 9891 r.pid, curRealtime); 9892 } 9893 long timeUsed = wtime - r.lastWakeTime; 9894 pw.print(prefix); 9895 pw.print(" "); 9896 pw.print("keep awake over "); 9897 TimeUtils.formatDuration(realtimeSince, pw); 9898 pw.print(" used "); 9899 TimeUtils.formatDuration(timeUsed, pw); 9900 pw.print(" ("); 9901 pw.print((timeUsed*100)/realtimeSince); 9902 pw.println("%)"); 9903 } 9904 if (r.lastCpuTime != 0) { 9905 long timeUsed = r.curCpuTime - r.lastCpuTime; 9906 pw.print(prefix); 9907 pw.print(" "); 9908 pw.print("run cpu over "); 9909 TimeUtils.formatDuration(uptimeSince, pw); 9910 pw.print(" used "); 9911 TimeUtils.formatDuration(timeUsed, pw); 9912 pw.print(" ("); 9913 pw.print((timeUsed*100)/uptimeSince); 9914 pw.println("%)"); 9915 } 9916 } 9917 } 9918 } 9919 return true; 9920 } 9921 9922 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9923 ArrayList<ProcessRecord> procs; 9924 synchronized (this) { 9925 if (args != null && args.length > start 9926 && args[start].charAt(0) != '-') { 9927 procs = new ArrayList<ProcessRecord>(); 9928 int pid = -1; 9929 try { 9930 pid = Integer.parseInt(args[start]); 9931 } catch (NumberFormatException e) { 9932 9933 } 9934 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9935 ProcessRecord proc = mLruProcesses.get(i); 9936 if (proc.pid == pid) { 9937 procs.add(proc); 9938 } else if (proc.processName.equals(args[start])) { 9939 procs.add(proc); 9940 } 9941 } 9942 if (procs.size() <= 0) { 9943 pw.println("No process found for: " + args[start]); 9944 return null; 9945 } 9946 } else { 9947 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9948 } 9949 } 9950 return procs; 9951 } 9952 9953 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9954 PrintWriter pw, String[] args) { 9955 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9956 if (procs == null) { 9957 return; 9958 } 9959 9960 long uptime = SystemClock.uptimeMillis(); 9961 long realtime = SystemClock.elapsedRealtime(); 9962 pw.println("Applications Graphics Acceleration Info:"); 9963 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9964 9965 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9966 ProcessRecord r = procs.get(i); 9967 if (r.thread != null) { 9968 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 9969 pw.flush(); 9970 try { 9971 TransferPipe tp = new TransferPipe(); 9972 try { 9973 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 9974 tp.go(fd); 9975 } finally { 9976 tp.kill(); 9977 } 9978 } catch (IOException e) { 9979 pw.println("Failure while dumping the app: " + r); 9980 pw.flush(); 9981 } catch (RemoteException e) { 9982 pw.println("Got a RemoteException while dumping the app " + r); 9983 pw.flush(); 9984 } 9985 } 9986 } 9987 } 9988 9989 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 9990 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9991 if (procs == null) { 9992 return; 9993 } 9994 9995 pw.println("Applications Database Info:"); 9996 9997 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 9998 ProcessRecord r = procs.get(i); 9999 if (r.thread != null) { 10000 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10001 pw.flush(); 10002 try { 10003 TransferPipe tp = new TransferPipe(); 10004 try { 10005 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10006 tp.go(fd); 10007 } finally { 10008 tp.kill(); 10009 } 10010 } catch (IOException e) { 10011 pw.println("Failure while dumping the app: " + r); 10012 pw.flush(); 10013 } catch (RemoteException e) { 10014 pw.println("Got a RemoteException while dumping the app " + r); 10015 pw.flush(); 10016 } 10017 } 10018 } 10019 } 10020 10021 final static class MemItem { 10022 final String label; 10023 final String shortLabel; 10024 final long pss; 10025 final int id; 10026 ArrayList<MemItem> subitems; 10027 10028 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10029 label = _label; 10030 shortLabel = _shortLabel; 10031 pss = _pss; 10032 id = _id; 10033 } 10034 } 10035 10036 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10037 boolean sort) { 10038 if (sort) { 10039 Collections.sort(items, new Comparator<MemItem>() { 10040 @Override 10041 public int compare(MemItem lhs, MemItem rhs) { 10042 if (lhs.pss < rhs.pss) { 10043 return 1; 10044 } else if (lhs.pss > rhs.pss) { 10045 return -1; 10046 } 10047 return 0; 10048 } 10049 }); 10050 } 10051 10052 for (int i=0; i<items.size(); i++) { 10053 MemItem mi = items.get(i); 10054 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10055 if (mi.subitems != null) { 10056 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10057 } 10058 } 10059 } 10060 10061 // These are in KB. 10062 static final long[] DUMP_MEM_BUCKETS = new long[] { 10063 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10064 120*1024, 160*1024, 200*1024, 10065 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10066 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10067 }; 10068 10069 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10070 boolean stackLike) { 10071 int start = label.lastIndexOf('.'); 10072 if (start >= 0) start++; 10073 else start = 0; 10074 int end = label.length(); 10075 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10076 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10077 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10078 out.append(bucket); 10079 out.append(stackLike ? "MB." : "MB "); 10080 out.append(label, start, end); 10081 return; 10082 } 10083 } 10084 out.append(memKB/1024); 10085 out.append(stackLike ? "MB." : "MB "); 10086 out.append(label, start, end); 10087 } 10088 10089 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10090 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10091 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10092 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10093 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10094 }; 10095 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10096 "System", "Persistent", "Foreground", 10097 "Visible", "Perceptible", "Heavy Weight", 10098 "Backup", "A Services", "Home", "Previous", 10099 "B Services", "Background" 10100 }; 10101 10102 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10103 PrintWriter pw, String prefix, String[] args, boolean brief, 10104 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10105 boolean dumpAll = false; 10106 boolean oomOnly = false; 10107 10108 int opti = 0; 10109 while (opti < args.length) { 10110 String opt = args[opti]; 10111 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10112 break; 10113 } 10114 opti++; 10115 if ("-a".equals(opt)) { 10116 dumpAll = true; 10117 } else if ("--oom".equals(opt)) { 10118 oomOnly = true; 10119 } else if ("-h".equals(opt)) { 10120 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10121 pw.println(" -a: include all available information for each process."); 10122 pw.println(" --oom: only show processes organized by oom adj."); 10123 pw.println("If [process] is specified it can be the name or "); 10124 pw.println("pid of a specific process to dump."); 10125 return; 10126 } else { 10127 pw.println("Unknown argument: " + opt + "; use -h for help"); 10128 } 10129 } 10130 10131 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10132 if (procs == null) { 10133 return; 10134 } 10135 10136 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10137 long uptime = SystemClock.uptimeMillis(); 10138 long realtime = SystemClock.elapsedRealtime(); 10139 10140 if (procs.size() == 1 || isCheckinRequest) { 10141 dumpAll = true; 10142 } 10143 10144 if (isCheckinRequest) { 10145 // short checkin version 10146 pw.println(uptime + "," + realtime); 10147 pw.flush(); 10148 } else { 10149 pw.println("Applications Memory Usage (kB):"); 10150 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10151 } 10152 10153 String[] innerArgs = new String[args.length-opti]; 10154 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10155 10156 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10157 long nativePss=0, dalvikPss=0, otherPss=0; 10158 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10159 10160 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10161 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10162 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10163 10164 long totalPss = 0; 10165 10166 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10167 ProcessRecord r = procs.get(i); 10168 if (r.thread != null) { 10169 if (!isCheckinRequest && dumpAll) { 10170 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10171 pw.flush(); 10172 } 10173 Debug.MemoryInfo mi = null; 10174 if (dumpAll) { 10175 try { 10176 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10177 } catch (RemoteException e) { 10178 if (!isCheckinRequest) { 10179 pw.println("Got RemoteException!"); 10180 pw.flush(); 10181 } 10182 } 10183 } else { 10184 mi = new Debug.MemoryInfo(); 10185 Debug.getMemoryInfo(r.pid, mi); 10186 } 10187 10188 if (!isCheckinRequest && mi != null) { 10189 long myTotalPss = mi.getTotalPss(); 10190 totalPss += myTotalPss; 10191 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10192 r.processName, myTotalPss, 0); 10193 procMems.add(pssItem); 10194 10195 nativePss += mi.nativePss; 10196 dalvikPss += mi.dalvikPss; 10197 otherPss += mi.otherPss; 10198 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10199 long mem = mi.getOtherPss(j); 10200 miscPss[j] += mem; 10201 otherPss -= mem; 10202 } 10203 10204 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10205 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10206 || oomIndex == (oomPss.length-1)) { 10207 oomPss[oomIndex] += myTotalPss; 10208 if (oomProcs[oomIndex] == null) { 10209 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10210 } 10211 oomProcs[oomIndex].add(pssItem); 10212 break; 10213 } 10214 } 10215 } 10216 } 10217 } 10218 10219 if (!isCheckinRequest && procs.size() > 1) { 10220 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10221 10222 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10223 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10224 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10225 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10226 String label = Debug.MemoryInfo.getOtherLabel(j); 10227 catMems.add(new MemItem(label, label, miscPss[j], j)); 10228 } 10229 10230 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10231 for (int j=0; j<oomPss.length; j++) { 10232 if (oomPss[j] != 0) { 10233 String label = DUMP_MEM_OOM_LABEL[j]; 10234 MemItem item = new MemItem(label, label, oomPss[j], 10235 DUMP_MEM_OOM_ADJ[j]); 10236 item.subitems = oomProcs[j]; 10237 oomMems.add(item); 10238 } 10239 } 10240 10241 if (outTag != null || outStack != null) { 10242 if (outTag != null) { 10243 appendMemBucket(outTag, totalPss, "total", false); 10244 } 10245 if (outStack != null) { 10246 appendMemBucket(outStack, totalPss, "total", true); 10247 } 10248 boolean firstLine = true; 10249 for (int i=0; i<oomMems.size(); i++) { 10250 MemItem miCat = oomMems.get(i); 10251 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10252 continue; 10253 } 10254 if (miCat.id < ProcessList.SERVICE_ADJ 10255 || miCat.id == ProcessList.HOME_APP_ADJ 10256 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10257 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10258 outTag.append(" / "); 10259 } 10260 if (outStack != null) { 10261 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10262 if (firstLine) { 10263 outStack.append(":"); 10264 firstLine = false; 10265 } 10266 outStack.append("\n\t at "); 10267 } else { 10268 outStack.append("$"); 10269 } 10270 } 10271 for (int j=0; j<miCat.subitems.size(); j++) { 10272 MemItem mi = miCat.subitems.get(j); 10273 if (j > 0) { 10274 if (outTag != null) { 10275 outTag.append(" "); 10276 } 10277 if (outStack != null) { 10278 outStack.append("$"); 10279 } 10280 } 10281 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10282 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10283 } 10284 if (outStack != null) { 10285 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10286 } 10287 } 10288 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10289 outStack.append("("); 10290 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10291 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10292 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10293 outStack.append(":"); 10294 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10295 } 10296 } 10297 outStack.append(")"); 10298 } 10299 } 10300 } 10301 } 10302 10303 if (!brief && !oomOnly) { 10304 pw.println(); 10305 pw.println("Total PSS by process:"); 10306 dumpMemItems(pw, " ", procMems, true); 10307 pw.println(); 10308 } 10309 pw.println("Total PSS by OOM adjustment:"); 10310 dumpMemItems(pw, " ", oomMems, false); 10311 if (!oomOnly) { 10312 PrintWriter out = categoryPw != null ? categoryPw : pw; 10313 out.println(); 10314 out.println("Total PSS by category:"); 10315 dumpMemItems(out, " ", catMems, true); 10316 } 10317 pw.println(); 10318 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10319 final int[] SINGLE_LONG_FORMAT = new int[] { 10320 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10321 }; 10322 long[] longOut = new long[1]; 10323 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10324 SINGLE_LONG_FORMAT, null, longOut, null); 10325 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10326 longOut[0] = 0; 10327 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10328 SINGLE_LONG_FORMAT, null, longOut, null); 10329 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10330 longOut[0] = 0; 10331 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10332 SINGLE_LONG_FORMAT, null, longOut, null); 10333 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10334 longOut[0] = 0; 10335 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10336 SINGLE_LONG_FORMAT, null, longOut, null); 10337 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10338 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10339 pw.print(shared); pw.println(" kB"); 10340 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10341 pw.print(voltile); pw.println(" kB volatile"); 10342 } 10343 } 10344 10345 /** 10346 * Searches array of arguments for the specified string 10347 * @param args array of argument strings 10348 * @param value value to search for 10349 * @return true if the value is contained in the array 10350 */ 10351 private static boolean scanArgs(String[] args, String value) { 10352 if (args != null) { 10353 for (String arg : args) { 10354 if (value.equals(arg)) { 10355 return true; 10356 } 10357 } 10358 } 10359 return false; 10360 } 10361 10362 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10363 ContentProviderRecord cpr, boolean always) { 10364 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10365 10366 if (!inLaunching || always) { 10367 synchronized (cpr) { 10368 cpr.launchingApp = null; 10369 cpr.notifyAll(); 10370 } 10371 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10372 String names[] = cpr.info.authority.split(";"); 10373 for (int j = 0; j < names.length; j++) { 10374 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10375 } 10376 } 10377 10378 for (int i=0; i<cpr.connections.size(); i++) { 10379 ContentProviderConnection conn = cpr.connections.get(i); 10380 if (conn.waiting) { 10381 // If this connection is waiting for the provider, then we don't 10382 // need to mess with its process unless we are always removing 10383 // or for some reason the provider is not currently launching. 10384 if (inLaunching && !always) { 10385 continue; 10386 } 10387 } 10388 ProcessRecord capp = conn.client; 10389 conn.dead = true; 10390 if (conn.stableCount > 0) { 10391 if (!capp.persistent && capp.thread != null 10392 && capp.pid != 0 10393 && capp.pid != MY_PID) { 10394 Slog.i(TAG, "Kill " + capp.processName 10395 + " (pid " + capp.pid + "): provider " + cpr.info.name 10396 + " in dying process " + (proc != null ? proc.processName : "??")); 10397 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10398 capp.processName, capp.setAdj, "dying provider " 10399 + cpr.name.toShortString()); 10400 Process.killProcessQuiet(capp.pid); 10401 } 10402 } else if (capp.thread != null && conn.provider.provider != null) { 10403 try { 10404 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10405 } catch (RemoteException e) { 10406 } 10407 // In the protocol here, we don't expect the client to correctly 10408 // clean up this connection, we'll just remove it. 10409 cpr.connections.remove(i); 10410 conn.client.conProviders.remove(conn); 10411 } 10412 } 10413 10414 if (inLaunching && always) { 10415 mLaunchingProviders.remove(cpr); 10416 } 10417 return inLaunching; 10418 } 10419 10420 /** 10421 * Main code for cleaning up a process when it has gone away. This is 10422 * called both as a result of the process dying, or directly when stopping 10423 * a process when running in single process mode. 10424 */ 10425 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10426 boolean restarting, boolean allowRestart, int index) { 10427 if (index >= 0) { 10428 mLruProcesses.remove(index); 10429 } 10430 10431 mProcessesToGc.remove(app); 10432 10433 // Dismiss any open dialogs. 10434 if (app.crashDialog != null) { 10435 app.crashDialog.dismiss(); 10436 app.crashDialog = null; 10437 } 10438 if (app.anrDialog != null) { 10439 app.anrDialog.dismiss(); 10440 app.anrDialog = null; 10441 } 10442 if (app.waitDialog != null) { 10443 app.waitDialog.dismiss(); 10444 app.waitDialog = null; 10445 } 10446 10447 app.crashing = false; 10448 app.notResponding = false; 10449 10450 app.resetPackageList(); 10451 app.unlinkDeathRecipient(); 10452 app.thread = null; 10453 app.forcingToForeground = null; 10454 app.foregroundServices = false; 10455 app.foregroundActivities = false; 10456 app.hasShownUi = false; 10457 app.hasAboveClient = false; 10458 10459 mServices.killServicesLocked(app, allowRestart); 10460 10461 boolean restart = false; 10462 10463 // Remove published content providers. 10464 if (!app.pubProviders.isEmpty()) { 10465 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10466 while (it.hasNext()) { 10467 ContentProviderRecord cpr = it.next(); 10468 10469 final boolean always = app.bad || !allowRestart; 10470 if (removeDyingProviderLocked(app, cpr, always) || always) { 10471 // We left the provider in the launching list, need to 10472 // restart it. 10473 restart = true; 10474 } 10475 10476 cpr.provider = null; 10477 cpr.proc = null; 10478 } 10479 app.pubProviders.clear(); 10480 } 10481 10482 // Take care of any launching providers waiting for this process. 10483 if (checkAppInLaunchingProvidersLocked(app, false)) { 10484 restart = true; 10485 } 10486 10487 // Unregister from connected content providers. 10488 if (!app.conProviders.isEmpty()) { 10489 for (int i=0; i<app.conProviders.size(); i++) { 10490 ContentProviderConnection conn = app.conProviders.get(i); 10491 conn.provider.connections.remove(conn); 10492 } 10493 app.conProviders.clear(); 10494 } 10495 10496 // At this point there may be remaining entries in mLaunchingProviders 10497 // where we were the only one waiting, so they are no longer of use. 10498 // Look for these and clean up if found. 10499 // XXX Commented out for now. Trying to figure out a way to reproduce 10500 // the actual situation to identify what is actually going on. 10501 if (false) { 10502 for (int i=0; i<mLaunchingProviders.size(); i++) { 10503 ContentProviderRecord cpr = (ContentProviderRecord) 10504 mLaunchingProviders.get(i); 10505 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10506 synchronized (cpr) { 10507 cpr.launchingApp = null; 10508 cpr.notifyAll(); 10509 } 10510 } 10511 } 10512 } 10513 10514 skipCurrentReceiverLocked(app); 10515 10516 // Unregister any receivers. 10517 if (app.receivers.size() > 0) { 10518 Iterator<ReceiverList> it = app.receivers.iterator(); 10519 while (it.hasNext()) { 10520 removeReceiverLocked(it.next()); 10521 } 10522 app.receivers.clear(); 10523 } 10524 10525 // If the app is undergoing backup, tell the backup manager about it 10526 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10527 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10528 try { 10529 IBackupManager bm = IBackupManager.Stub.asInterface( 10530 ServiceManager.getService(Context.BACKUP_SERVICE)); 10531 bm.agentDisconnected(app.info.packageName); 10532 } catch (RemoteException e) { 10533 // can't happen; backup manager is local 10534 } 10535 } 10536 10537 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10538 ProcessChangeItem item = mPendingProcessChanges.get(i); 10539 if (item.pid == app.pid) { 10540 mPendingProcessChanges.remove(i); 10541 mAvailProcessChanges.add(item); 10542 } 10543 } 10544 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10545 10546 // If the caller is restarting this app, then leave it in its 10547 // current lists and let the caller take care of it. 10548 if (restarting) { 10549 return; 10550 } 10551 10552 if (!app.persistent || app.isolated) { 10553 if (DEBUG_PROCESSES) Slog.v(TAG, 10554 "Removing non-persistent process during cleanup: " + app); 10555 mProcessNames.remove(app.processName, app.uid); 10556 mIsolatedProcesses.remove(app.uid); 10557 if (mHeavyWeightProcess == app) { 10558 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10559 mHeavyWeightProcess.userId, 0)); 10560 mHeavyWeightProcess = null; 10561 } 10562 } else if (!app.removed) { 10563 // This app is persistent, so we need to keep its record around. 10564 // If it is not already on the pending app list, add it there 10565 // and start a new process for it. 10566 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10567 mPersistentStartingProcesses.add(app); 10568 restart = true; 10569 } 10570 } 10571 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10572 "Clean-up removing on hold: " + app); 10573 mProcessesOnHold.remove(app); 10574 10575 if (app == mHomeProcess) { 10576 mHomeProcess = null; 10577 } 10578 if (app == mPreviousProcess) { 10579 mPreviousProcess = null; 10580 } 10581 10582 if (restart && !app.isolated) { 10583 // We have components that still need to be running in the 10584 // process, so re-launch it. 10585 mProcessNames.put(app.processName, app.uid, app); 10586 startProcessLocked(app, "restart", app.processName); 10587 } else if (app.pid > 0 && app.pid != MY_PID) { 10588 // Goodbye! 10589 synchronized (mPidsSelfLocked) { 10590 mPidsSelfLocked.remove(app.pid); 10591 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10592 } 10593 app.setPid(0); 10594 } 10595 } 10596 10597 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10598 // Look through the content providers we are waiting to have launched, 10599 // and if any run in this process then either schedule a restart of 10600 // the process or kill the client waiting for it if this process has 10601 // gone bad. 10602 int NL = mLaunchingProviders.size(); 10603 boolean restart = false; 10604 for (int i=0; i<NL; i++) { 10605 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10606 if (cpr.launchingApp == app) { 10607 if (!alwaysBad && !app.bad) { 10608 restart = true; 10609 } else { 10610 removeDyingProviderLocked(app, cpr, true); 10611 NL = mLaunchingProviders.size(); 10612 } 10613 } 10614 } 10615 return restart; 10616 } 10617 10618 // ========================================================= 10619 // SERVICES 10620 // ========================================================= 10621 10622 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10623 int flags) { 10624 enforceNotIsolatedCaller("getServices"); 10625 synchronized (this) { 10626 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10627 } 10628 } 10629 10630 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10631 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10632 synchronized (this) { 10633 return mServices.getRunningServiceControlPanelLocked(name); 10634 } 10635 } 10636 10637 public ComponentName startService(IApplicationThread caller, Intent service, 10638 String resolvedType, int userId) { 10639 enforceNotIsolatedCaller("startService"); 10640 // Refuse possible leaked file descriptors 10641 if (service != null && service.hasFileDescriptors() == true) { 10642 throw new IllegalArgumentException("File descriptors passed in Intent"); 10643 } 10644 10645 if (DEBUG_SERVICE) 10646 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10647 synchronized(this) { 10648 final int callingPid = Binder.getCallingPid(); 10649 final int callingUid = Binder.getCallingUid(); 10650 checkValidCaller(callingUid, userId); 10651 final long origId = Binder.clearCallingIdentity(); 10652 ComponentName res = mServices.startServiceLocked(caller, service, 10653 resolvedType, callingPid, callingUid, userId); 10654 Binder.restoreCallingIdentity(origId); 10655 return res; 10656 } 10657 } 10658 10659 ComponentName startServiceInPackage(int uid, 10660 Intent service, String resolvedType, int userId) { 10661 synchronized(this) { 10662 if (DEBUG_SERVICE) 10663 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10664 final long origId = Binder.clearCallingIdentity(); 10665 ComponentName res = mServices.startServiceLocked(null, service, 10666 resolvedType, -1, uid, userId); 10667 Binder.restoreCallingIdentity(origId); 10668 return res; 10669 } 10670 } 10671 10672 public int stopService(IApplicationThread caller, Intent service, 10673 String resolvedType, int userId) { 10674 enforceNotIsolatedCaller("stopService"); 10675 // Refuse possible leaked file descriptors 10676 if (service != null && service.hasFileDescriptors() == true) { 10677 throw new IllegalArgumentException("File descriptors passed in Intent"); 10678 } 10679 10680 checkValidCaller(Binder.getCallingUid(), userId); 10681 10682 synchronized(this) { 10683 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10684 } 10685 } 10686 10687 public IBinder peekService(Intent service, String resolvedType) { 10688 enforceNotIsolatedCaller("peekService"); 10689 // Refuse possible leaked file descriptors 10690 if (service != null && service.hasFileDescriptors() == true) { 10691 throw new IllegalArgumentException("File descriptors passed in Intent"); 10692 } 10693 synchronized(this) { 10694 return mServices.peekServiceLocked(service, resolvedType); 10695 } 10696 } 10697 10698 public boolean stopServiceToken(ComponentName className, IBinder token, 10699 int startId) { 10700 synchronized(this) { 10701 return mServices.stopServiceTokenLocked(className, token, startId); 10702 } 10703 } 10704 10705 public void setServiceForeground(ComponentName className, IBinder token, 10706 int id, Notification notification, boolean removeNotification) { 10707 synchronized(this) { 10708 mServices.setServiceForegroundLocked(className, token, id, notification, 10709 removeNotification); 10710 } 10711 } 10712 10713 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10714 boolean requireFull, String name, String callerPackage) { 10715 synchronized(this) { 10716 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10717 requireFull, name, callerPackage); 10718 } 10719 } 10720 10721 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10722 boolean requireFull, String name, String callerPackage) { 10723 final int callingUserId = UserHandle.getUserId(callingUid); 10724 if (callingUserId != userId) { 10725 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10726 if ((requireFull || checkComponentPermission( 10727 android.Manifest.permission.INTERACT_ACROSS_USERS, 10728 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10729 && checkComponentPermission( 10730 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10731 callingPid, callingUid, -1, true) 10732 != PackageManager.PERMISSION_GRANTED) { 10733 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10734 // In this case, they would like to just execute as their 10735 // owner user instead of failing. 10736 userId = callingUserId; 10737 } else { 10738 StringBuilder builder = new StringBuilder(128); 10739 builder.append("Permission Denial: "); 10740 builder.append(name); 10741 if (callerPackage != null) { 10742 builder.append(" from "); 10743 builder.append(callerPackage); 10744 } 10745 builder.append(" asks to run as user "); 10746 builder.append(userId); 10747 builder.append(" but is calling from user "); 10748 builder.append(UserHandle.getUserId(callingUid)); 10749 builder.append("; this requires "); 10750 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10751 if (!requireFull) { 10752 builder.append("or"); 10753 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10754 } 10755 String msg = builder.toString(); 10756 Slog.w(TAG, msg); 10757 throw new SecurityException(msg); 10758 } 10759 } 10760 } 10761 if (userId == UserHandle.USER_CURRENT 10762 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10763 userId = mCurrentUserId; 10764 } 10765 if (!allowAll && userId < 0) { 10766 throw new IllegalArgumentException( 10767 "Call does not support special user #" + userId); 10768 } 10769 } 10770 return userId; 10771 } 10772 10773 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10774 String className, int flags) { 10775 boolean result = false; 10776 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10777 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10778 if (ActivityManager.checkUidPermission( 10779 android.Manifest.permission.INTERACT_ACROSS_USERS, 10780 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10781 ComponentName comp = new ComponentName(aInfo.packageName, className); 10782 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10783 + " requests FLAG_SINGLE_USER, but app does not hold " 10784 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10785 Slog.w(TAG, msg); 10786 throw new SecurityException(msg); 10787 } 10788 result = true; 10789 } 10790 } else if (componentProcessName == aInfo.packageName) { 10791 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10792 } else if ("system".equals(componentProcessName)) { 10793 result = true; 10794 } 10795 if (DEBUG_MU) { 10796 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10797 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10798 } 10799 return result; 10800 } 10801 10802 public int bindService(IApplicationThread caller, IBinder token, 10803 Intent service, String resolvedType, 10804 IServiceConnection connection, int flags, int userId) { 10805 enforceNotIsolatedCaller("bindService"); 10806 // Refuse possible leaked file descriptors 10807 if (service != null && service.hasFileDescriptors() == true) { 10808 throw new IllegalArgumentException("File descriptors passed in Intent"); 10809 } 10810 10811 synchronized(this) { 10812 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10813 connection, flags, userId); 10814 } 10815 } 10816 10817 public boolean unbindService(IServiceConnection connection) { 10818 synchronized (this) { 10819 return mServices.unbindServiceLocked(connection); 10820 } 10821 } 10822 10823 public void publishService(IBinder token, Intent intent, IBinder service) { 10824 // Refuse possible leaked file descriptors 10825 if (intent != null && intent.hasFileDescriptors() == true) { 10826 throw new IllegalArgumentException("File descriptors passed in Intent"); 10827 } 10828 10829 synchronized(this) { 10830 if (!(token instanceof ServiceRecord)) { 10831 throw new IllegalArgumentException("Invalid service token"); 10832 } 10833 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10834 } 10835 } 10836 10837 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10838 // Refuse possible leaked file descriptors 10839 if (intent != null && intent.hasFileDescriptors() == true) { 10840 throw new IllegalArgumentException("File descriptors passed in Intent"); 10841 } 10842 10843 synchronized(this) { 10844 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10845 } 10846 } 10847 10848 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10849 synchronized(this) { 10850 if (!(token instanceof ServiceRecord)) { 10851 throw new IllegalArgumentException("Invalid service token"); 10852 } 10853 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10854 } 10855 } 10856 10857 // ========================================================= 10858 // BACKUP AND RESTORE 10859 // ========================================================= 10860 10861 // Cause the target app to be launched if necessary and its backup agent 10862 // instantiated. The backup agent will invoke backupAgentCreated() on the 10863 // activity manager to announce its creation. 10864 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10865 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10866 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10867 10868 synchronized(this) { 10869 // !!! TODO: currently no check here that we're already bound 10870 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10871 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10872 synchronized (stats) { 10873 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10874 } 10875 10876 // Backup agent is now in use, its package can't be stopped. 10877 try { 10878 AppGlobals.getPackageManager().setPackageStoppedState( 10879 app.packageName, false, UserHandle.getUserId(app.uid)); 10880 } catch (RemoteException e) { 10881 } catch (IllegalArgumentException e) { 10882 Slog.w(TAG, "Failed trying to unstop package " 10883 + app.packageName + ": " + e); 10884 } 10885 10886 BackupRecord r = new BackupRecord(ss, app, backupMode); 10887 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10888 ? new ComponentName(app.packageName, app.backupAgentName) 10889 : new ComponentName("android", "FullBackupAgent"); 10890 // startProcessLocked() returns existing proc's record if it's already running 10891 ProcessRecord proc = startProcessLocked(app.processName, app, 10892 false, 0, "backup", hostingName, false, false); 10893 if (proc == null) { 10894 Slog.e(TAG, "Unable to start backup agent process " + r); 10895 return false; 10896 } 10897 10898 r.app = proc; 10899 mBackupTarget = r; 10900 mBackupAppName = app.packageName; 10901 10902 // Try not to kill the process during backup 10903 updateOomAdjLocked(proc); 10904 10905 // If the process is already attached, schedule the creation of the backup agent now. 10906 // If it is not yet live, this will be done when it attaches to the framework. 10907 if (proc.thread != null) { 10908 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10909 try { 10910 proc.thread.scheduleCreateBackupAgent(app, 10911 compatibilityInfoForPackageLocked(app), backupMode); 10912 } catch (RemoteException e) { 10913 // Will time out on the backup manager side 10914 } 10915 } else { 10916 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10917 } 10918 // Invariants: at this point, the target app process exists and the application 10919 // is either already running or in the process of coming up. mBackupTarget and 10920 // mBackupAppName describe the app, so that when it binds back to the AM we 10921 // know that it's scheduled for a backup-agent operation. 10922 } 10923 10924 return true; 10925 } 10926 10927 // A backup agent has just come up 10928 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10929 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10930 + " = " + agent); 10931 10932 synchronized(this) { 10933 if (!agentPackageName.equals(mBackupAppName)) { 10934 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10935 return; 10936 } 10937 } 10938 10939 long oldIdent = Binder.clearCallingIdentity(); 10940 try { 10941 IBackupManager bm = IBackupManager.Stub.asInterface( 10942 ServiceManager.getService(Context.BACKUP_SERVICE)); 10943 bm.agentConnected(agentPackageName, agent); 10944 } catch (RemoteException e) { 10945 // can't happen; the backup manager service is local 10946 } catch (Exception e) { 10947 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10948 e.printStackTrace(); 10949 } finally { 10950 Binder.restoreCallingIdentity(oldIdent); 10951 } 10952 } 10953 10954 // done with this agent 10955 public void unbindBackupAgent(ApplicationInfo appInfo) { 10956 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10957 if (appInfo == null) { 10958 Slog.w(TAG, "unbind backup agent for null app"); 10959 return; 10960 } 10961 10962 synchronized(this) { 10963 if (mBackupAppName == null) { 10964 Slog.w(TAG, "Unbinding backup agent with no active backup"); 10965 return; 10966 } 10967 10968 if (!mBackupAppName.equals(appInfo.packageName)) { 10969 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10970 return; 10971 } 10972 10973 ProcessRecord proc = mBackupTarget.app; 10974 mBackupTarget = null; 10975 mBackupAppName = null; 10976 10977 // Not backing this app up any more; reset its OOM adjustment 10978 updateOomAdjLocked(proc); 10979 10980 // If the app crashed during backup, 'thread' will be null here 10981 if (proc.thread != null) { 10982 try { 10983 proc.thread.scheduleDestroyBackupAgent(appInfo, 10984 compatibilityInfoForPackageLocked(appInfo)); 10985 } catch (Exception e) { 10986 Slog.e(TAG, "Exception when unbinding backup agent:"); 10987 e.printStackTrace(); 10988 } 10989 } 10990 } 10991 } 10992 // ========================================================= 10993 // BROADCASTS 10994 // ========================================================= 10995 10996 private final List getStickiesLocked(String action, IntentFilter filter, 10997 List cur, int userId) { 10998 final ContentResolver resolver = mContext.getContentResolver(); 10999 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11000 if (stickies == null) { 11001 return cur; 11002 } 11003 final ArrayList<Intent> list = stickies.get(action); 11004 if (list == null) { 11005 return cur; 11006 } 11007 int N = list.size(); 11008 for (int i=0; i<N; i++) { 11009 Intent intent = list.get(i); 11010 if (filter.match(resolver, intent, true, TAG) >= 0) { 11011 if (cur == null) { 11012 cur = new ArrayList<Intent>(); 11013 } 11014 cur.add(intent); 11015 } 11016 } 11017 return cur; 11018 } 11019 11020 boolean isPendingBroadcastProcessLocked(int pid) { 11021 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11022 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11023 } 11024 11025 void skipPendingBroadcastLocked(int pid) { 11026 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11027 for (BroadcastQueue queue : mBroadcastQueues) { 11028 queue.skipPendingBroadcastLocked(pid); 11029 } 11030 } 11031 11032 // The app just attached; send any pending broadcasts that it should receive 11033 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11034 boolean didSomething = false; 11035 for (BroadcastQueue queue : mBroadcastQueues) { 11036 didSomething |= queue.sendPendingBroadcastsLocked(app); 11037 } 11038 return didSomething; 11039 } 11040 11041 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11042 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11043 enforceNotIsolatedCaller("registerReceiver"); 11044 int callingUid; 11045 int callingPid; 11046 synchronized(this) { 11047 ProcessRecord callerApp = null; 11048 if (caller != null) { 11049 callerApp = getRecordForAppLocked(caller); 11050 if (callerApp == null) { 11051 throw new SecurityException( 11052 "Unable to find app for caller " + caller 11053 + " (pid=" + Binder.getCallingPid() 11054 + ") when registering receiver " + receiver); 11055 } 11056 if (callerApp.info.uid != Process.SYSTEM_UID && 11057 !callerApp.pkgList.contains(callerPackage)) { 11058 throw new SecurityException("Given caller package " + callerPackage 11059 + " is not running in process " + callerApp); 11060 } 11061 callingUid = callerApp.info.uid; 11062 callingPid = callerApp.pid; 11063 } else { 11064 callerPackage = null; 11065 callingUid = Binder.getCallingUid(); 11066 callingPid = Binder.getCallingPid(); 11067 } 11068 11069 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11070 true, true, "registerReceiver", callerPackage); 11071 11072 List allSticky = null; 11073 11074 // Look for any matching sticky broadcasts... 11075 Iterator actions = filter.actionsIterator(); 11076 if (actions != null) { 11077 while (actions.hasNext()) { 11078 String action = (String)actions.next(); 11079 allSticky = getStickiesLocked(action, filter, allSticky, 11080 UserHandle.USER_ALL); 11081 allSticky = getStickiesLocked(action, filter, allSticky, 11082 UserHandle.getUserId(callingUid)); 11083 } 11084 } else { 11085 allSticky = getStickiesLocked(null, filter, allSticky, 11086 UserHandle.USER_ALL); 11087 allSticky = getStickiesLocked(null, filter, allSticky, 11088 UserHandle.getUserId(callingUid)); 11089 } 11090 11091 // The first sticky in the list is returned directly back to 11092 // the client. 11093 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11094 11095 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11096 + ": " + sticky); 11097 11098 if (receiver == null) { 11099 return sticky; 11100 } 11101 11102 ReceiverList rl 11103 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11104 if (rl == null) { 11105 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11106 userId, receiver); 11107 if (rl.app != null) { 11108 rl.app.receivers.add(rl); 11109 } else { 11110 try { 11111 receiver.asBinder().linkToDeath(rl, 0); 11112 } catch (RemoteException e) { 11113 return sticky; 11114 } 11115 rl.linkedToDeath = true; 11116 } 11117 mRegisteredReceivers.put(receiver.asBinder(), rl); 11118 } else if (rl.uid != callingUid) { 11119 throw new IllegalArgumentException( 11120 "Receiver requested to register for uid " + callingUid 11121 + " was previously registered for uid " + rl.uid); 11122 } else if (rl.pid != callingPid) { 11123 throw new IllegalArgumentException( 11124 "Receiver requested to register for pid " + callingPid 11125 + " was previously registered for pid " + rl.pid); 11126 } else if (rl.userId != userId) { 11127 throw new IllegalArgumentException( 11128 "Receiver requested to register for user " + userId 11129 + " was previously registered for user " + rl.userId); 11130 } 11131 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11132 permission, callingUid, userId); 11133 rl.add(bf); 11134 if (!bf.debugCheck()) { 11135 Slog.w(TAG, "==> For Dynamic broadast"); 11136 } 11137 mReceiverResolver.addFilter(bf); 11138 11139 // Enqueue broadcasts for all existing stickies that match 11140 // this filter. 11141 if (allSticky != null) { 11142 ArrayList receivers = new ArrayList(); 11143 receivers.add(bf); 11144 11145 int N = allSticky.size(); 11146 for (int i=0; i<N; i++) { 11147 Intent intent = (Intent)allSticky.get(i); 11148 BroadcastQueue queue = broadcastQueueForIntent(intent); 11149 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11150 null, -1, -1, null, receivers, null, 0, null, null, 11151 false, true, true, -1); 11152 queue.enqueueParallelBroadcastLocked(r); 11153 queue.scheduleBroadcastsLocked(); 11154 } 11155 } 11156 11157 return sticky; 11158 } 11159 } 11160 11161 public void unregisterReceiver(IIntentReceiver receiver) { 11162 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11163 11164 final long origId = Binder.clearCallingIdentity(); 11165 try { 11166 boolean doTrim = false; 11167 11168 synchronized(this) { 11169 ReceiverList rl 11170 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11171 if (rl != null) { 11172 if (rl.curBroadcast != null) { 11173 BroadcastRecord r = rl.curBroadcast; 11174 final boolean doNext = finishReceiverLocked( 11175 receiver.asBinder(), r.resultCode, r.resultData, 11176 r.resultExtras, r.resultAbort, true); 11177 if (doNext) { 11178 doTrim = true; 11179 r.queue.processNextBroadcast(false); 11180 } 11181 } 11182 11183 if (rl.app != null) { 11184 rl.app.receivers.remove(rl); 11185 } 11186 removeReceiverLocked(rl); 11187 if (rl.linkedToDeath) { 11188 rl.linkedToDeath = false; 11189 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11190 } 11191 } 11192 } 11193 11194 // If we actually concluded any broadcasts, we might now be able 11195 // to trim the recipients' apps from our working set 11196 if (doTrim) { 11197 trimApplications(); 11198 return; 11199 } 11200 11201 } finally { 11202 Binder.restoreCallingIdentity(origId); 11203 } 11204 } 11205 11206 void removeReceiverLocked(ReceiverList rl) { 11207 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11208 int N = rl.size(); 11209 for (int i=0; i<N; i++) { 11210 mReceiverResolver.removeFilter(rl.get(i)); 11211 } 11212 } 11213 11214 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11215 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11216 ProcessRecord r = mLruProcesses.get(i); 11217 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11218 try { 11219 r.thread.dispatchPackageBroadcast(cmd, packages); 11220 } catch (RemoteException ex) { 11221 } 11222 } 11223 } 11224 } 11225 11226 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11227 int[] users) { 11228 List<ResolveInfo> receivers = null; 11229 try { 11230 HashSet<ComponentName> singleUserReceivers = null; 11231 boolean scannedFirstReceivers = false; 11232 for (int user : users) { 11233 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11234 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11235 if (newReceivers != null && newReceivers.size() == 0) { 11236 newReceivers = null; 11237 } 11238 if (receivers == null) { 11239 receivers = newReceivers; 11240 } else if (newReceivers != null) { 11241 // We need to concatenate the additional receivers 11242 // found with what we have do far. This would be easy, 11243 // but we also need to de-dup any receivers that are 11244 // singleUser. 11245 if (!scannedFirstReceivers) { 11246 // Collect any single user receivers we had already retrieved. 11247 scannedFirstReceivers = true; 11248 for (int i=0; i<receivers.size(); i++) { 11249 ResolveInfo ri = receivers.get(i); 11250 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11251 ComponentName cn = new ComponentName( 11252 ri.activityInfo.packageName, ri.activityInfo.name); 11253 if (singleUserReceivers == null) { 11254 singleUserReceivers = new HashSet<ComponentName>(); 11255 } 11256 singleUserReceivers.add(cn); 11257 } 11258 } 11259 } 11260 // Add the new results to the existing results, tracking 11261 // and de-dupping single user receivers. 11262 for (int i=0; i<newReceivers.size(); i++) { 11263 ResolveInfo ri = receivers.get(i); 11264 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11265 ComponentName cn = new ComponentName( 11266 ri.activityInfo.packageName, ri.activityInfo.name); 11267 if (singleUserReceivers == null) { 11268 singleUserReceivers = new HashSet<ComponentName>(); 11269 } 11270 if (!singleUserReceivers.contains(cn)) { 11271 singleUserReceivers.add(cn); 11272 receivers.add(ri); 11273 } 11274 } else { 11275 receivers.add(ri); 11276 } 11277 } 11278 } 11279 } 11280 } catch (RemoteException ex) { 11281 // pm is in same process, this will never happen. 11282 } 11283 return receivers; 11284 } 11285 11286 private final int broadcastIntentLocked(ProcessRecord callerApp, 11287 String callerPackage, Intent intent, String resolvedType, 11288 IIntentReceiver resultTo, int resultCode, String resultData, 11289 Bundle map, String requiredPermission, 11290 boolean ordered, boolean sticky, int callingPid, int callingUid, 11291 int userId) { 11292 intent = new Intent(intent); 11293 11294 // By default broadcasts do not go to stopped apps. 11295 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11296 11297 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11298 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11299 + " ordered=" + ordered + " userid=" + userId); 11300 if ((resultTo != null) && !ordered) { 11301 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11302 } 11303 11304 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11305 true, false, "broadcast", callerPackage); 11306 11307 // Make sure that the user who is receiving this broadcast is started 11308 // If not, we will just skip it. 11309 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11310 Slog.w(TAG, "Skipping broadcast of " + intent 11311 + ": user " + userId + " is stopped"); 11312 return ActivityManager.BROADCAST_SUCCESS; 11313 } 11314 11315 /* 11316 * Prevent non-system code (defined here to be non-persistent 11317 * processes) from sending protected broadcasts. 11318 */ 11319 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11320 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11321 callingUid == 0) { 11322 // Always okay. 11323 } else if (callerApp == null || !callerApp.persistent) { 11324 try { 11325 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11326 intent.getAction())) { 11327 String msg = "Permission Denial: not allowed to send broadcast " 11328 + intent.getAction() + " from pid=" 11329 + callingPid + ", uid=" + callingUid; 11330 Slog.w(TAG, msg); 11331 throw new SecurityException(msg); 11332 } 11333 } catch (RemoteException e) { 11334 Slog.w(TAG, "Remote exception", e); 11335 return ActivityManager.BROADCAST_SUCCESS; 11336 } 11337 } 11338 11339 // Handle special intents: if this broadcast is from the package 11340 // manager about a package being removed, we need to remove all of 11341 // its activities from the history stack. 11342 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11343 intent.getAction()); 11344 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11345 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11346 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11347 || uidRemoved) { 11348 if (checkComponentPermission( 11349 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11350 callingPid, callingUid, -1, true) 11351 == PackageManager.PERMISSION_GRANTED) { 11352 if (uidRemoved) { 11353 final Bundle intentExtras = intent.getExtras(); 11354 final int uid = intentExtras != null 11355 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11356 if (uid >= 0) { 11357 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11358 synchronized (bs) { 11359 bs.removeUidStatsLocked(uid); 11360 } 11361 } 11362 } else { 11363 // If resources are unavailable just force stop all 11364 // those packages and flush the attribute cache as well. 11365 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11366 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11367 if (list != null && (list.length > 0)) { 11368 for (String pkg : list) { 11369 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11370 } 11371 sendPackageBroadcastLocked( 11372 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11373 } 11374 } else { 11375 Uri data = intent.getData(); 11376 String ssp; 11377 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11378 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11379 forceStopPackageLocked(ssp, 11380 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11381 false, userId); 11382 } 11383 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11384 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11385 new String[] {ssp}, userId); 11386 } 11387 } 11388 } 11389 } 11390 } else { 11391 String msg = "Permission Denial: " + intent.getAction() 11392 + " broadcast from " + callerPackage + " (pid=" + callingPid 11393 + ", uid=" + callingUid + ")" 11394 + " requires " 11395 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11396 Slog.w(TAG, msg); 11397 throw new SecurityException(msg); 11398 } 11399 11400 // Special case for adding a package: by default turn on compatibility 11401 // mode. 11402 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11403 Uri data = intent.getData(); 11404 String ssp; 11405 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11406 mCompatModePackages.handlePackageAddedLocked(ssp, 11407 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11408 } 11409 } 11410 11411 /* 11412 * If this is the time zone changed action, queue up a message that will reset the timezone 11413 * of all currently running processes. This message will get queued up before the broadcast 11414 * happens. 11415 */ 11416 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11417 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11418 } 11419 11420 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11421 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11422 } 11423 11424 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11425 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11426 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11427 } 11428 11429 // Add to the sticky list if requested. 11430 if (sticky) { 11431 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11432 callingPid, callingUid) 11433 != PackageManager.PERMISSION_GRANTED) { 11434 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11435 + callingPid + ", uid=" + callingUid 11436 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11437 Slog.w(TAG, msg); 11438 throw new SecurityException(msg); 11439 } 11440 if (requiredPermission != null) { 11441 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11442 + " and enforce permission " + requiredPermission); 11443 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11444 } 11445 if (intent.getComponent() != null) { 11446 throw new SecurityException( 11447 "Sticky broadcasts can't target a specific component"); 11448 } 11449 // We use userId directly here, since the "all" target is maintained 11450 // as a separate set of sticky broadcasts. 11451 if (userId != UserHandle.USER_ALL) { 11452 // But first, if this is not a broadcast to all users, then 11453 // make sure it doesn't conflict with an existing broadcast to 11454 // all users. 11455 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11456 UserHandle.USER_ALL); 11457 if (stickies != null) { 11458 ArrayList<Intent> list = stickies.get(intent.getAction()); 11459 if (list != null) { 11460 int N = list.size(); 11461 int i; 11462 for (i=0; i<N; i++) { 11463 if (intent.filterEquals(list.get(i))) { 11464 throw new IllegalArgumentException( 11465 "Sticky broadcast " + intent + " for user " 11466 + userId + " conflicts with existing global broadcast"); 11467 } 11468 } 11469 } 11470 } 11471 } 11472 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11473 if (stickies == null) { 11474 stickies = new HashMap<String, ArrayList<Intent>>(); 11475 mStickyBroadcasts.put(userId, stickies); 11476 } 11477 ArrayList<Intent> list = stickies.get(intent.getAction()); 11478 if (list == null) { 11479 list = new ArrayList<Intent>(); 11480 stickies.put(intent.getAction(), list); 11481 } 11482 int N = list.size(); 11483 int i; 11484 for (i=0; i<N; i++) { 11485 if (intent.filterEquals(list.get(i))) { 11486 // This sticky already exists, replace it. 11487 list.set(i, new Intent(intent)); 11488 break; 11489 } 11490 } 11491 if (i >= N) { 11492 list.add(new Intent(intent)); 11493 } 11494 } 11495 11496 int[] users; 11497 if (userId == UserHandle.USER_ALL) { 11498 // Caller wants broadcast to go to all started users. 11499 users = new int[mStartedUsers.size()]; 11500 for (int i=0; i<mStartedUsers.size(); i++) { 11501 users[i] = mStartedUsers.keyAt(i); 11502 } 11503 } else { 11504 // Caller wants broadcast to go to one specific user. 11505 users = new int[] {userId}; 11506 } 11507 11508 // Figure out who all will receive this broadcast. 11509 List receivers = null; 11510 List<BroadcastFilter> registeredReceivers = null; 11511 // Need to resolve the intent to interested receivers... 11512 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11513 == 0) { 11514 receivers = collectReceiverComponents(intent, resolvedType, users); 11515 } 11516 if (intent.getComponent() == null) { 11517 registeredReceivers = mReceiverResolver.queryIntent(intent, 11518 resolvedType, false, userId); 11519 } 11520 11521 final boolean replacePending = 11522 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11523 11524 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11525 + " replacePending=" + replacePending); 11526 11527 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11528 if (!ordered && NR > 0) { 11529 // If we are not serializing this broadcast, then send the 11530 // registered receivers separately so they don't wait for the 11531 // components to be launched. 11532 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11533 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11534 callerPackage, callingPid, callingUid, requiredPermission, 11535 registeredReceivers, resultTo, resultCode, resultData, map, 11536 ordered, sticky, false, userId); 11537 if (DEBUG_BROADCAST) Slog.v( 11538 TAG, "Enqueueing parallel broadcast " + r); 11539 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11540 if (!replaced) { 11541 queue.enqueueParallelBroadcastLocked(r); 11542 queue.scheduleBroadcastsLocked(); 11543 } 11544 registeredReceivers = null; 11545 NR = 0; 11546 } 11547 11548 // Merge into one list. 11549 int ir = 0; 11550 if (receivers != null) { 11551 // A special case for PACKAGE_ADDED: do not allow the package 11552 // being added to see this broadcast. This prevents them from 11553 // using this as a back door to get run as soon as they are 11554 // installed. Maybe in the future we want to have a special install 11555 // broadcast or such for apps, but we'd like to deliberately make 11556 // this decision. 11557 String skipPackages[] = null; 11558 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11559 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11560 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11561 Uri data = intent.getData(); 11562 if (data != null) { 11563 String pkgName = data.getSchemeSpecificPart(); 11564 if (pkgName != null) { 11565 skipPackages = new String[] { pkgName }; 11566 } 11567 } 11568 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11569 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11570 } 11571 if (skipPackages != null && (skipPackages.length > 0)) { 11572 for (String skipPackage : skipPackages) { 11573 if (skipPackage != null) { 11574 int NT = receivers.size(); 11575 for (int it=0; it<NT; it++) { 11576 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11577 if (curt.activityInfo.packageName.equals(skipPackage)) { 11578 receivers.remove(it); 11579 it--; 11580 NT--; 11581 } 11582 } 11583 } 11584 } 11585 } 11586 11587 int NT = receivers != null ? receivers.size() : 0; 11588 int it = 0; 11589 ResolveInfo curt = null; 11590 BroadcastFilter curr = null; 11591 while (it < NT && ir < NR) { 11592 if (curt == null) { 11593 curt = (ResolveInfo)receivers.get(it); 11594 } 11595 if (curr == null) { 11596 curr = registeredReceivers.get(ir); 11597 } 11598 if (curr.getPriority() >= curt.priority) { 11599 // Insert this broadcast record into the final list. 11600 receivers.add(it, curr); 11601 ir++; 11602 curr = null; 11603 it++; 11604 NT++; 11605 } else { 11606 // Skip to the next ResolveInfo in the final list. 11607 it++; 11608 curt = null; 11609 } 11610 } 11611 } 11612 while (ir < NR) { 11613 if (receivers == null) { 11614 receivers = new ArrayList(); 11615 } 11616 receivers.add(registeredReceivers.get(ir)); 11617 ir++; 11618 } 11619 11620 if ((receivers != null && receivers.size() > 0) 11621 || resultTo != null) { 11622 BroadcastQueue queue = broadcastQueueForIntent(intent); 11623 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11624 callerPackage, callingPid, callingUid, requiredPermission, 11625 receivers, resultTo, resultCode, resultData, map, ordered, 11626 sticky, false, userId); 11627 if (DEBUG_BROADCAST) Slog.v( 11628 TAG, "Enqueueing ordered broadcast " + r 11629 + ": prev had " + queue.mOrderedBroadcasts.size()); 11630 if (DEBUG_BROADCAST) { 11631 int seq = r.intent.getIntExtra("seq", -1); 11632 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11633 } 11634 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11635 if (!replaced) { 11636 queue.enqueueOrderedBroadcastLocked(r); 11637 queue.scheduleBroadcastsLocked(); 11638 } 11639 } 11640 11641 return ActivityManager.BROADCAST_SUCCESS; 11642 } 11643 11644 final Intent verifyBroadcastLocked(Intent intent) { 11645 // Refuse possible leaked file descriptors 11646 if (intent != null && intent.hasFileDescriptors() == true) { 11647 throw new IllegalArgumentException("File descriptors passed in Intent"); 11648 } 11649 11650 int flags = intent.getFlags(); 11651 11652 if (!mProcessesReady) { 11653 // if the caller really truly claims to know what they're doing, go 11654 // ahead and allow the broadcast without launching any receivers 11655 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11656 intent = new Intent(intent); 11657 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11658 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11659 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11660 + " before boot completion"); 11661 throw new IllegalStateException("Cannot broadcast before boot completed"); 11662 } 11663 } 11664 11665 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11666 throw new IllegalArgumentException( 11667 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11668 } 11669 11670 return intent; 11671 } 11672 11673 public final int broadcastIntent(IApplicationThread caller, 11674 Intent intent, String resolvedType, IIntentReceiver resultTo, 11675 int resultCode, String resultData, Bundle map, 11676 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11677 enforceNotIsolatedCaller("broadcastIntent"); 11678 synchronized(this) { 11679 intent = verifyBroadcastLocked(intent); 11680 11681 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11682 final int callingPid = Binder.getCallingPid(); 11683 final int callingUid = Binder.getCallingUid(); 11684 final long origId = Binder.clearCallingIdentity(); 11685 int res = broadcastIntentLocked(callerApp, 11686 callerApp != null ? callerApp.info.packageName : null, 11687 intent, resolvedType, resultTo, 11688 resultCode, resultData, map, requiredPermission, serialized, sticky, 11689 callingPid, callingUid, userId); 11690 Binder.restoreCallingIdentity(origId); 11691 return res; 11692 } 11693 } 11694 11695 int broadcastIntentInPackage(String packageName, int uid, 11696 Intent intent, String resolvedType, IIntentReceiver resultTo, 11697 int resultCode, String resultData, Bundle map, 11698 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11699 synchronized(this) { 11700 intent = verifyBroadcastLocked(intent); 11701 11702 final long origId = Binder.clearCallingIdentity(); 11703 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11704 resultTo, resultCode, resultData, map, requiredPermission, 11705 serialized, sticky, -1, uid, userId); 11706 Binder.restoreCallingIdentity(origId); 11707 return res; 11708 } 11709 } 11710 11711 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11712 // Refuse possible leaked file descriptors 11713 if (intent != null && intent.hasFileDescriptors() == true) { 11714 throw new IllegalArgumentException("File descriptors passed in Intent"); 11715 } 11716 11717 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11718 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11719 11720 synchronized(this) { 11721 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11722 != PackageManager.PERMISSION_GRANTED) { 11723 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11724 + Binder.getCallingPid() 11725 + ", uid=" + Binder.getCallingUid() 11726 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11727 Slog.w(TAG, msg); 11728 throw new SecurityException(msg); 11729 } 11730 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11731 if (stickies != null) { 11732 ArrayList<Intent> list = stickies.get(intent.getAction()); 11733 if (list != null) { 11734 int N = list.size(); 11735 int i; 11736 for (i=0; i<N; i++) { 11737 if (intent.filterEquals(list.get(i))) { 11738 list.remove(i); 11739 break; 11740 } 11741 } 11742 if (list.size() <= 0) { 11743 stickies.remove(intent.getAction()); 11744 } 11745 } 11746 if (stickies.size() <= 0) { 11747 mStickyBroadcasts.remove(userId); 11748 } 11749 } 11750 } 11751 } 11752 11753 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11754 String resultData, Bundle resultExtras, boolean resultAbort, 11755 boolean explicit) { 11756 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11757 if (r == null) { 11758 Slog.w(TAG, "finishReceiver called but not found on queue"); 11759 return false; 11760 } 11761 11762 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11763 explicit); 11764 } 11765 11766 public void finishReceiver(IBinder who, int resultCode, String resultData, 11767 Bundle resultExtras, boolean resultAbort) { 11768 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11769 11770 // Refuse possible leaked file descriptors 11771 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11772 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11773 } 11774 11775 final long origId = Binder.clearCallingIdentity(); 11776 try { 11777 boolean doNext = false; 11778 BroadcastRecord r = null; 11779 11780 synchronized(this) { 11781 r = broadcastRecordForReceiverLocked(who); 11782 if (r != null) { 11783 doNext = r.queue.finishReceiverLocked(r, resultCode, 11784 resultData, resultExtras, resultAbort, true); 11785 } 11786 } 11787 11788 if (doNext) { 11789 r.queue.processNextBroadcast(false); 11790 } 11791 trimApplications(); 11792 } finally { 11793 Binder.restoreCallingIdentity(origId); 11794 } 11795 } 11796 11797 // ========================================================= 11798 // INSTRUMENTATION 11799 // ========================================================= 11800 11801 public boolean startInstrumentation(ComponentName className, 11802 String profileFile, int flags, Bundle arguments, 11803 IInstrumentationWatcher watcher) { 11804 enforceNotIsolatedCaller("startInstrumentation"); 11805 // Refuse possible leaked file descriptors 11806 if (arguments != null && arguments.hasFileDescriptors()) { 11807 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11808 } 11809 11810 synchronized(this) { 11811 InstrumentationInfo ii = null; 11812 ApplicationInfo ai = null; 11813 try { 11814 ii = mContext.getPackageManager().getInstrumentationInfo( 11815 className, STOCK_PM_FLAGS); 11816 ai = mContext.getPackageManager().getApplicationInfo( 11817 ii.targetPackage, STOCK_PM_FLAGS); 11818 } catch (PackageManager.NameNotFoundException e) { 11819 } 11820 if (ii == null) { 11821 reportStartInstrumentationFailure(watcher, className, 11822 "Unable to find instrumentation info for: " + className); 11823 return false; 11824 } 11825 if (ai == null) { 11826 reportStartInstrumentationFailure(watcher, className, 11827 "Unable to find instrumentation target package: " + ii.targetPackage); 11828 return false; 11829 } 11830 11831 int match = mContext.getPackageManager().checkSignatures( 11832 ii.targetPackage, ii.packageName); 11833 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11834 String msg = "Permission Denial: starting instrumentation " 11835 + className + " from pid=" 11836 + Binder.getCallingPid() 11837 + ", uid=" + Binder.getCallingPid() 11838 + " not allowed because package " + ii.packageName 11839 + " does not have a signature matching the target " 11840 + ii.targetPackage; 11841 reportStartInstrumentationFailure(watcher, className, msg); 11842 throw new SecurityException(msg); 11843 } 11844 11845 int userId = UserHandle.getCallingUserId(); 11846 final long origId = Binder.clearCallingIdentity(); 11847 // Instrumentation can kill and relaunch even persistent processes 11848 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11849 ProcessRecord app = addAppLocked(ai, false); 11850 app.instrumentationClass = className; 11851 app.instrumentationInfo = ai; 11852 app.instrumentationProfileFile = profileFile; 11853 app.instrumentationArguments = arguments; 11854 app.instrumentationWatcher = watcher; 11855 app.instrumentationResultClass = className; 11856 Binder.restoreCallingIdentity(origId); 11857 } 11858 11859 return true; 11860 } 11861 11862 /** 11863 * Report errors that occur while attempting to start Instrumentation. Always writes the 11864 * error to the logs, but if somebody is watching, send the report there too. This enables 11865 * the "am" command to report errors with more information. 11866 * 11867 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11868 * @param cn The component name of the instrumentation. 11869 * @param report The error report. 11870 */ 11871 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11872 ComponentName cn, String report) { 11873 Slog.w(TAG, report); 11874 try { 11875 if (watcher != null) { 11876 Bundle results = new Bundle(); 11877 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11878 results.putString("Error", report); 11879 watcher.instrumentationStatus(cn, -1, results); 11880 } 11881 } catch (RemoteException e) { 11882 Slog.w(TAG, e); 11883 } 11884 } 11885 11886 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11887 if (app.instrumentationWatcher != null) { 11888 try { 11889 // NOTE: IInstrumentationWatcher *must* be oneway here 11890 app.instrumentationWatcher.instrumentationFinished( 11891 app.instrumentationClass, 11892 resultCode, 11893 results); 11894 } catch (RemoteException e) { 11895 } 11896 } 11897 app.instrumentationWatcher = null; 11898 app.instrumentationClass = null; 11899 app.instrumentationInfo = null; 11900 app.instrumentationProfileFile = null; 11901 app.instrumentationArguments = null; 11902 11903 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 11904 } 11905 11906 public void finishInstrumentation(IApplicationThread target, 11907 int resultCode, Bundle results) { 11908 int userId = UserHandle.getCallingUserId(); 11909 // Refuse possible leaked file descriptors 11910 if (results != null && results.hasFileDescriptors()) { 11911 throw new IllegalArgumentException("File descriptors passed in Intent"); 11912 } 11913 11914 synchronized(this) { 11915 ProcessRecord app = getRecordForAppLocked(target); 11916 if (app == null) { 11917 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11918 return; 11919 } 11920 final long origId = Binder.clearCallingIdentity(); 11921 finishInstrumentationLocked(app, resultCode, results); 11922 Binder.restoreCallingIdentity(origId); 11923 } 11924 } 11925 11926 // ========================================================= 11927 // CONFIGURATION 11928 // ========================================================= 11929 11930 public ConfigurationInfo getDeviceConfigurationInfo() { 11931 ConfigurationInfo config = new ConfigurationInfo(); 11932 synchronized (this) { 11933 config.reqTouchScreen = mConfiguration.touchscreen; 11934 config.reqKeyboardType = mConfiguration.keyboard; 11935 config.reqNavigation = mConfiguration.navigation; 11936 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11937 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11938 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11939 } 11940 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11941 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11942 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11943 } 11944 config.reqGlEsVersion = GL_ES_VERSION; 11945 } 11946 return config; 11947 } 11948 11949 public Configuration getConfiguration() { 11950 Configuration ci; 11951 synchronized(this) { 11952 ci = new Configuration(mConfiguration); 11953 } 11954 return ci; 11955 } 11956 11957 public void updatePersistentConfiguration(Configuration values) { 11958 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11959 "updateConfiguration()"); 11960 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11961 "updateConfiguration()"); 11962 if (values == null) { 11963 throw new NullPointerException("Configuration must not be null"); 11964 } 11965 11966 synchronized(this) { 11967 final long origId = Binder.clearCallingIdentity(); 11968 updateConfigurationLocked(values, null, true, false); 11969 Binder.restoreCallingIdentity(origId); 11970 } 11971 } 11972 11973 public void updateConfiguration(Configuration values) { 11974 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11975 "updateConfiguration()"); 11976 11977 synchronized(this) { 11978 if (values == null && mWindowManager != null) { 11979 // sentinel: fetch the current configuration from the window manager 11980 values = mWindowManager.computeNewConfiguration(); 11981 } 11982 11983 if (mWindowManager != null) { 11984 mProcessList.applyDisplaySize(mWindowManager); 11985 } 11986 11987 final long origId = Binder.clearCallingIdentity(); 11988 if (values != null) { 11989 Settings.System.clearConfiguration(values); 11990 } 11991 updateConfigurationLocked(values, null, false, false); 11992 Binder.restoreCallingIdentity(origId); 11993 } 11994 } 11995 11996 /** 11997 * Do either or both things: (1) change the current configuration, and (2) 11998 * make sure the given activity is running with the (now) current 11999 * configuration. Returns true if the activity has been left running, or 12000 * false if <var>starting</var> is being destroyed to match the new 12001 * configuration. 12002 * @param persistent TODO 12003 */ 12004 boolean updateConfigurationLocked(Configuration values, 12005 ActivityRecord starting, boolean persistent, boolean initLocale) { 12006 // do nothing if we are headless 12007 if (mHeadless) return true; 12008 12009 int changes = 0; 12010 12011 boolean kept = true; 12012 12013 if (values != null) { 12014 Configuration newConfig = new Configuration(mConfiguration); 12015 changes = newConfig.updateFrom(values); 12016 if (changes != 0) { 12017 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12018 Slog.i(TAG, "Updating configuration to: " + values); 12019 } 12020 12021 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12022 12023 if (values.locale != null && !initLocale) { 12024 saveLocaleLocked(values.locale, 12025 !values.locale.equals(mConfiguration.locale), 12026 values.userSetLocale); 12027 } 12028 12029 mConfigurationSeq++; 12030 if (mConfigurationSeq <= 0) { 12031 mConfigurationSeq = 1; 12032 } 12033 newConfig.seq = mConfigurationSeq; 12034 mConfiguration = newConfig; 12035 Slog.i(TAG, "Config changed: " + newConfig); 12036 12037 final Configuration configCopy = new Configuration(mConfiguration); 12038 12039 // TODO: If our config changes, should we auto dismiss any currently 12040 // showing dialogs? 12041 mShowDialogs = shouldShowDialogs(newConfig); 12042 12043 AttributeCache ac = AttributeCache.instance(); 12044 if (ac != null) { 12045 ac.updateConfiguration(configCopy); 12046 } 12047 12048 // Make sure all resources in our process are updated 12049 // right now, so that anyone who is going to retrieve 12050 // resource values after we return will be sure to get 12051 // the new ones. This is especially important during 12052 // boot, where the first config change needs to guarantee 12053 // all resources have that config before following boot 12054 // code is executed. 12055 mSystemThread.applyConfigurationToResources(configCopy); 12056 12057 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12058 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12059 msg.obj = new Configuration(configCopy); 12060 mHandler.sendMessage(msg); 12061 } 12062 12063 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12064 ProcessRecord app = mLruProcesses.get(i); 12065 try { 12066 if (app.thread != null) { 12067 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12068 + app.processName + " new config " + mConfiguration); 12069 app.thread.scheduleConfigurationChanged(configCopy); 12070 } 12071 } catch (Exception e) { 12072 } 12073 } 12074 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12075 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12076 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12077 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12078 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12079 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12080 broadcastIntentLocked(null, null, 12081 new Intent(Intent.ACTION_LOCALE_CHANGED), 12082 null, null, 0, null, null, 12083 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12084 } 12085 } 12086 } 12087 12088 if (changes != 0 && starting == null) { 12089 // If the configuration changed, and the caller is not already 12090 // in the process of starting an activity, then find the top 12091 // activity to check if its configuration needs to change. 12092 starting = mMainStack.topRunningActivityLocked(null); 12093 } 12094 12095 if (starting != null) { 12096 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12097 // And we need to make sure at this point that all other activities 12098 // are made visible with the correct configuration. 12099 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12100 } 12101 12102 if (values != null && mWindowManager != null) { 12103 mWindowManager.setNewConfiguration(mConfiguration); 12104 } 12105 12106 return kept; 12107 } 12108 12109 /** 12110 * Decide based on the configuration whether we should shouw the ANR, 12111 * crash, etc dialogs. The idea is that if there is no affordnace to 12112 * press the on-screen buttons, we shouldn't show the dialog. 12113 * 12114 * A thought: SystemUI might also want to get told about this, the Power 12115 * dialog / global actions also might want different behaviors. 12116 */ 12117 private static final boolean shouldShowDialogs(Configuration config) { 12118 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12119 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12120 } 12121 12122 /** 12123 * Save the locale. You must be inside a synchronized (this) block. 12124 */ 12125 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12126 if(isDiff) { 12127 SystemProperties.set("user.language", l.getLanguage()); 12128 SystemProperties.set("user.region", l.getCountry()); 12129 } 12130 12131 if(isPersist) { 12132 SystemProperties.set("persist.sys.language", l.getLanguage()); 12133 SystemProperties.set("persist.sys.country", l.getCountry()); 12134 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12135 } 12136 } 12137 12138 @Override 12139 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12140 ActivityRecord srec = ActivityRecord.forToken(token); 12141 return srec != null && srec.task.affinity != null && 12142 srec.task.affinity.equals(destAffinity); 12143 } 12144 12145 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12146 Intent resultData) { 12147 ComponentName dest = destIntent.getComponent(); 12148 12149 synchronized (this) { 12150 ActivityRecord srec = ActivityRecord.forToken(token); 12151 if (srec == null) { 12152 return false; 12153 } 12154 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12155 final int start = history.indexOf(srec); 12156 if (start < 0) { 12157 // Current activity is not in history stack; do nothing. 12158 return false; 12159 } 12160 int finishTo = start - 1; 12161 ActivityRecord parent = null; 12162 boolean foundParentInTask = false; 12163 if (dest != null) { 12164 TaskRecord tr = srec.task; 12165 for (int i = start - 1; i >= 0; i--) { 12166 ActivityRecord r = history.get(i); 12167 if (tr != r.task) { 12168 // Couldn't find parent in the same task; stop at the one above this. 12169 // (Root of current task; in-app "home" behavior) 12170 // Always at least finish the current activity. 12171 finishTo = Math.min(start - 1, i + 1); 12172 parent = history.get(finishTo); 12173 break; 12174 } else if (r.info.packageName.equals(dest.getPackageName()) && 12175 r.info.name.equals(dest.getClassName())) { 12176 finishTo = i; 12177 parent = r; 12178 foundParentInTask = true; 12179 break; 12180 } 12181 } 12182 } 12183 12184 if (mController != null) { 12185 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12186 if (next != null) { 12187 // ask watcher if this is allowed 12188 boolean resumeOK = true; 12189 try { 12190 resumeOK = mController.activityResuming(next.packageName); 12191 } catch (RemoteException e) { 12192 mController = null; 12193 } 12194 12195 if (!resumeOK) { 12196 return false; 12197 } 12198 } 12199 } 12200 final long origId = Binder.clearCallingIdentity(); 12201 for (int i = start; i > finishTo; i--) { 12202 ActivityRecord r = history.get(i); 12203 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12204 "navigate-up"); 12205 // Only return the supplied result for the first activity finished 12206 resultCode = Activity.RESULT_CANCELED; 12207 resultData = null; 12208 } 12209 12210 if (parent != null && foundParentInTask) { 12211 final int parentLaunchMode = parent.info.launchMode; 12212 final int destIntentFlags = destIntent.getFlags(); 12213 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12214 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12215 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12216 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12217 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12218 } else { 12219 try { 12220 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12221 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12222 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12223 null, aInfo, parent.appToken, null, 12224 0, -1, parent.launchedFromUid, 0, null, true, null); 12225 foundParentInTask = res == ActivityManager.START_SUCCESS; 12226 } catch (RemoteException e) { 12227 foundParentInTask = false; 12228 } 12229 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12230 resultData, "navigate-up"); 12231 } 12232 } 12233 Binder.restoreCallingIdentity(origId); 12234 return foundParentInTask; 12235 } 12236 } 12237 12238 public int getLaunchedFromUid(IBinder activityToken) { 12239 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12240 if (srec == null) { 12241 return -1; 12242 } 12243 return srec.launchedFromUid; 12244 } 12245 12246 // ========================================================= 12247 // LIFETIME MANAGEMENT 12248 // ========================================================= 12249 12250 // Returns which broadcast queue the app is the current [or imminent] receiver 12251 // on, or 'null' if the app is not an active broadcast recipient. 12252 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12253 BroadcastRecord r = app.curReceiver; 12254 if (r != null) { 12255 return r.queue; 12256 } 12257 12258 // It's not the current receiver, but it might be starting up to become one 12259 synchronized (this) { 12260 for (BroadcastQueue queue : mBroadcastQueues) { 12261 r = queue.mPendingBroadcast; 12262 if (r != null && r.curApp == app) { 12263 // found it; report which queue it's in 12264 return queue; 12265 } 12266 } 12267 } 12268 12269 return null; 12270 } 12271 12272 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12273 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12274 if (mAdjSeq == app.adjSeq) { 12275 // This adjustment has already been computed. If we are calling 12276 // from the top, we may have already computed our adjustment with 12277 // an earlier hidden adjustment that isn't really for us... if 12278 // so, use the new hidden adjustment. 12279 if (!recursed && app.hidden) { 12280 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12281 app.hasActivities ? hiddenAdj : emptyAdj; 12282 } 12283 return app.curRawAdj; 12284 } 12285 12286 if (app.thread == null) { 12287 app.adjSeq = mAdjSeq; 12288 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12289 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12290 } 12291 12292 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12293 app.adjSource = null; 12294 app.adjTarget = null; 12295 app.empty = false; 12296 app.hidden = false; 12297 12298 final int activitiesSize = app.activities.size(); 12299 12300 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12301 // The max adjustment doesn't allow this app to be anything 12302 // below foreground, so it is not worth doing work for it. 12303 app.adjType = "fixed"; 12304 app.adjSeq = mAdjSeq; 12305 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12306 app.hasActivities = false; 12307 app.foregroundActivities = false; 12308 app.keeping = true; 12309 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12310 // System process can do UI, and when they do we want to have 12311 // them trim their memory after the user leaves the UI. To 12312 // facilitate this, here we need to determine whether or not it 12313 // is currently showing UI. 12314 app.systemNoUi = true; 12315 if (app == TOP_APP) { 12316 app.systemNoUi = false; 12317 app.hasActivities = true; 12318 } else if (activitiesSize > 0) { 12319 for (int j = 0; j < activitiesSize; j++) { 12320 final ActivityRecord r = app.activities.get(j); 12321 if (r.visible) { 12322 app.systemNoUi = false; 12323 } 12324 if (r.app == app) { 12325 app.hasActivities = true; 12326 } 12327 } 12328 } 12329 return (app.curAdj=app.maxAdj); 12330 } 12331 12332 app.keeping = false; 12333 app.systemNoUi = false; 12334 app.hasActivities = false; 12335 12336 // Determine the importance of the process, starting with most 12337 // important to least, and assign an appropriate OOM adjustment. 12338 int adj; 12339 int schedGroup; 12340 boolean foregroundActivities = false; 12341 boolean interesting = false; 12342 BroadcastQueue queue; 12343 if (app == TOP_APP) { 12344 // The last app on the list is the foreground app. 12345 adj = ProcessList.FOREGROUND_APP_ADJ; 12346 schedGroup = Process.THREAD_GROUP_DEFAULT; 12347 app.adjType = "top-activity"; 12348 foregroundActivities = true; 12349 interesting = true; 12350 app.hasActivities = true; 12351 } else if (app.instrumentationClass != null) { 12352 // Don't want to kill running instrumentation. 12353 adj = ProcessList.FOREGROUND_APP_ADJ; 12354 schedGroup = Process.THREAD_GROUP_DEFAULT; 12355 app.adjType = "instrumentation"; 12356 interesting = true; 12357 } else if ((queue = isReceivingBroadcast(app)) != null) { 12358 // An app that is currently receiving a broadcast also 12359 // counts as being in the foreground for OOM killer purposes. 12360 // It's placed in a sched group based on the nature of the 12361 // broadcast as reflected by which queue it's active in. 12362 adj = ProcessList.FOREGROUND_APP_ADJ; 12363 schedGroup = (queue == mFgBroadcastQueue) 12364 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12365 app.adjType = "broadcast"; 12366 } else if (app.executingServices.size() > 0) { 12367 // An app that is currently executing a service callback also 12368 // counts as being in the foreground. 12369 adj = ProcessList.FOREGROUND_APP_ADJ; 12370 schedGroup = Process.THREAD_GROUP_DEFAULT; 12371 app.adjType = "exec-service"; 12372 } else { 12373 // Assume process is hidden (has activities); we will correct 12374 // later if this is not the case. 12375 adj = hiddenAdj; 12376 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12377 app.hidden = true; 12378 app.adjType = "bg-activities"; 12379 } 12380 12381 boolean hasStoppingActivities = false; 12382 12383 // Examine all activities if not already foreground. 12384 if (!foregroundActivities && activitiesSize > 0) { 12385 for (int j = 0; j < activitiesSize; j++) { 12386 final ActivityRecord r = app.activities.get(j); 12387 if (r.visible) { 12388 // App has a visible activity; only upgrade adjustment. 12389 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12390 adj = ProcessList.VISIBLE_APP_ADJ; 12391 app.adjType = "visible"; 12392 } 12393 schedGroup = Process.THREAD_GROUP_DEFAULT; 12394 app.hidden = false; 12395 app.hasActivities = true; 12396 foregroundActivities = true; 12397 break; 12398 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12399 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12400 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12401 app.adjType = "pausing"; 12402 } 12403 app.hidden = false; 12404 foregroundActivities = true; 12405 } else if (r.state == ActivityState.STOPPING) { 12406 // We will apply the actual adjustment later, because 12407 // we want to allow this process to immediately go through 12408 // any memory trimming that is in effect. 12409 app.hidden = false; 12410 foregroundActivities = true; 12411 hasStoppingActivities = true; 12412 } 12413 if (r.app == app) { 12414 app.hasActivities = true; 12415 } 12416 } 12417 } 12418 12419 if (adj == hiddenAdj && !app.hasActivities) { 12420 // Whoops, this process is completely empty as far as we know 12421 // at this point. 12422 adj = emptyAdj; 12423 app.empty = true; 12424 app.adjType = "bg-empty"; 12425 } 12426 12427 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12428 if (app.foregroundServices) { 12429 // The user is aware of this app, so make it visible. 12430 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12431 app.hidden = false; 12432 app.adjType = "foreground-service"; 12433 schedGroup = Process.THREAD_GROUP_DEFAULT; 12434 } else if (app.forcingToForeground != null) { 12435 // The user is aware of this app, so make it visible. 12436 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12437 app.hidden = false; 12438 app.adjType = "force-foreground"; 12439 app.adjSource = app.forcingToForeground; 12440 schedGroup = Process.THREAD_GROUP_DEFAULT; 12441 } 12442 } 12443 12444 if (app.foregroundServices) { 12445 interesting = true; 12446 } 12447 12448 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12449 // We don't want to kill the current heavy-weight process. 12450 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12451 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12452 app.hidden = false; 12453 app.adjType = "heavy"; 12454 } 12455 12456 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12457 // This process is hosting what we currently consider to be the 12458 // home app, so we don't want to let it go into the background. 12459 adj = ProcessList.HOME_APP_ADJ; 12460 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12461 app.hidden = false; 12462 app.adjType = "home"; 12463 } 12464 12465 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12466 && app.activities.size() > 0) { 12467 // This was the previous process that showed UI to the user. 12468 // We want to try to keep it around more aggressively, to give 12469 // a good experience around switching between two apps. 12470 adj = ProcessList.PREVIOUS_APP_ADJ; 12471 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12472 app.hidden = false; 12473 app.adjType = "previous"; 12474 } 12475 12476 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12477 + " reason=" + app.adjType); 12478 12479 // By default, we use the computed adjustment. It may be changed if 12480 // there are applications dependent on our services or providers, but 12481 // this gives us a baseline and makes sure we don't get into an 12482 // infinite recursion. 12483 app.adjSeq = mAdjSeq; 12484 app.curRawAdj = app.nonStoppingAdj = adj; 12485 12486 if (mBackupTarget != null && app == mBackupTarget.app) { 12487 // If possible we want to avoid killing apps while they're being backed up 12488 if (adj > ProcessList.BACKUP_APP_ADJ) { 12489 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12490 adj = ProcessList.BACKUP_APP_ADJ; 12491 app.adjType = "backup"; 12492 app.hidden = false; 12493 } 12494 } 12495 12496 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12497 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12498 final long now = SystemClock.uptimeMillis(); 12499 // This process is more important if the top activity is 12500 // bound to the service. 12501 Iterator<ServiceRecord> jt = app.services.iterator(); 12502 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12503 ServiceRecord s = jt.next(); 12504 if (s.startRequested) { 12505 if (app.hasShownUi && app != mHomeProcess) { 12506 // If this process has shown some UI, let it immediately 12507 // go to the LRU list because it may be pretty heavy with 12508 // UI stuff. We'll tag it with a label just to help 12509 // debug and understand what is going on. 12510 if (adj > ProcessList.SERVICE_ADJ) { 12511 app.adjType = "started-bg-ui-services"; 12512 } 12513 } else { 12514 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12515 // This service has seen some activity within 12516 // recent memory, so we will keep its process ahead 12517 // of the background processes. 12518 if (adj > ProcessList.SERVICE_ADJ) { 12519 adj = ProcessList.SERVICE_ADJ; 12520 app.adjType = "started-services"; 12521 app.hidden = false; 12522 } 12523 } 12524 // If we have let the service slide into the background 12525 // state, still have some text describing what it is doing 12526 // even though the service no longer has an impact. 12527 if (adj > ProcessList.SERVICE_ADJ) { 12528 app.adjType = "started-bg-services"; 12529 } 12530 } 12531 // Don't kill this process because it is doing work; it 12532 // has said it is doing work. 12533 app.keeping = true; 12534 } 12535 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12536 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12537 Iterator<ArrayList<ConnectionRecord>> kt 12538 = s.connections.values().iterator(); 12539 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12540 ArrayList<ConnectionRecord> clist = kt.next(); 12541 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12542 // XXX should compute this based on the max of 12543 // all connected clients. 12544 ConnectionRecord cr = clist.get(i); 12545 if (cr.binding.client == app) { 12546 // Binding to ourself is not interesting. 12547 continue; 12548 } 12549 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12550 ProcessRecord client = cr.binding.client; 12551 int clientAdj = adj; 12552 int myHiddenAdj = hiddenAdj; 12553 if (myHiddenAdj > client.hiddenAdj) { 12554 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12555 myHiddenAdj = client.hiddenAdj; 12556 } else { 12557 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12558 } 12559 } 12560 int myEmptyAdj = emptyAdj; 12561 if (myEmptyAdj > client.emptyAdj) { 12562 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12563 myEmptyAdj = client.emptyAdj; 12564 } else { 12565 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12566 } 12567 } 12568 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12569 myEmptyAdj, TOP_APP, true, doingAll); 12570 String adjType = null; 12571 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12572 // Not doing bind OOM management, so treat 12573 // this guy more like a started service. 12574 if (app.hasShownUi && app != mHomeProcess) { 12575 // If this process has shown some UI, let it immediately 12576 // go to the LRU list because it may be pretty heavy with 12577 // UI stuff. We'll tag it with a label just to help 12578 // debug and understand what is going on. 12579 if (adj > clientAdj) { 12580 adjType = "bound-bg-ui-services"; 12581 } 12582 app.hidden = false; 12583 clientAdj = adj; 12584 } else { 12585 if (now >= (s.lastActivity 12586 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12587 // This service has not seen activity within 12588 // recent memory, so allow it to drop to the 12589 // LRU list if there is no other reason to keep 12590 // it around. We'll also tag it with a label just 12591 // to help debug and undertand what is going on. 12592 if (adj > clientAdj) { 12593 adjType = "bound-bg-services"; 12594 } 12595 clientAdj = adj; 12596 } 12597 } 12598 } 12599 if (adj > clientAdj) { 12600 // If this process has recently shown UI, and 12601 // the process that is binding to it is less 12602 // important than being visible, then we don't 12603 // care about the binding as much as we care 12604 // about letting this process get into the LRU 12605 // list to be killed and restarted if needed for 12606 // memory. 12607 if (app.hasShownUi && app != mHomeProcess 12608 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12609 adjType = "bound-bg-ui-services"; 12610 } else { 12611 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12612 |Context.BIND_IMPORTANT)) != 0) { 12613 adj = clientAdj; 12614 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12615 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12616 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12617 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12618 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12619 adj = clientAdj; 12620 } else { 12621 app.pendingUiClean = true; 12622 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12623 adj = ProcessList.VISIBLE_APP_ADJ; 12624 } 12625 } 12626 if (!client.hidden) { 12627 app.hidden = false; 12628 } 12629 if (client.keeping) { 12630 app.keeping = true; 12631 } 12632 adjType = "service"; 12633 } 12634 } 12635 if (adjType != null) { 12636 app.adjType = adjType; 12637 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12638 .REASON_SERVICE_IN_USE; 12639 app.adjSource = cr.binding.client; 12640 app.adjSourceOom = clientAdj; 12641 app.adjTarget = s.name; 12642 } 12643 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12644 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12645 schedGroup = Process.THREAD_GROUP_DEFAULT; 12646 } 12647 } 12648 } 12649 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12650 ActivityRecord a = cr.activity; 12651 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12652 (a.visible || a.state == ActivityState.RESUMED 12653 || a.state == ActivityState.PAUSING)) { 12654 adj = ProcessList.FOREGROUND_APP_ADJ; 12655 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12656 schedGroup = Process.THREAD_GROUP_DEFAULT; 12657 } 12658 app.hidden = false; 12659 app.adjType = "service"; 12660 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12661 .REASON_SERVICE_IN_USE; 12662 app.adjSource = a; 12663 app.adjSourceOom = adj; 12664 app.adjTarget = s.name; 12665 } 12666 } 12667 } 12668 } 12669 } 12670 } 12671 12672 // Finally, if this process has active services running in it, we 12673 // would like to avoid killing it unless it would prevent the current 12674 // application from running. By default we put the process in 12675 // with the rest of the background processes; as we scan through 12676 // its services we may bump it up from there. 12677 if (adj > hiddenAdj) { 12678 adj = hiddenAdj; 12679 app.hidden = false; 12680 app.adjType = "bg-services"; 12681 } 12682 } 12683 12684 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12685 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12686 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12687 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12688 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12689 ContentProviderRecord cpr = jt.next(); 12690 for (int i = cpr.connections.size()-1; 12691 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12692 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12693 i--) { 12694 ContentProviderConnection conn = cpr.connections.get(i); 12695 ProcessRecord client = conn.client; 12696 if (client == app) { 12697 // Being our own client is not interesting. 12698 continue; 12699 } 12700 int myHiddenAdj = hiddenAdj; 12701 if (myHiddenAdj > client.hiddenAdj) { 12702 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12703 myHiddenAdj = client.hiddenAdj; 12704 } else { 12705 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12706 } 12707 } 12708 int myEmptyAdj = emptyAdj; 12709 if (myEmptyAdj > client.emptyAdj) { 12710 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12711 myEmptyAdj = client.emptyAdj; 12712 } else { 12713 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12714 } 12715 } 12716 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12717 myEmptyAdj, TOP_APP, true, doingAll); 12718 if (adj > clientAdj) { 12719 if (app.hasShownUi && app != mHomeProcess 12720 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12721 app.adjType = "bg-ui-provider"; 12722 } else { 12723 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12724 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12725 app.adjType = "provider"; 12726 } 12727 if (!client.hidden) { 12728 app.hidden = false; 12729 } 12730 if (client.keeping) { 12731 app.keeping = true; 12732 } 12733 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12734 .REASON_PROVIDER_IN_USE; 12735 app.adjSource = client; 12736 app.adjSourceOom = clientAdj; 12737 app.adjTarget = cpr.name; 12738 } 12739 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12740 schedGroup = Process.THREAD_GROUP_DEFAULT; 12741 } 12742 } 12743 // If the provider has external (non-framework) process 12744 // dependencies, ensure that its adjustment is at least 12745 // FOREGROUND_APP_ADJ. 12746 if (cpr.hasExternalProcessHandles()) { 12747 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12748 adj = ProcessList.FOREGROUND_APP_ADJ; 12749 schedGroup = Process.THREAD_GROUP_DEFAULT; 12750 app.hidden = false; 12751 app.keeping = true; 12752 app.adjType = "provider"; 12753 app.adjTarget = cpr.name; 12754 } 12755 } 12756 } 12757 } 12758 12759 if (adj == ProcessList.SERVICE_ADJ) { 12760 if (doingAll) { 12761 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12762 mNewNumServiceProcs++; 12763 } 12764 if (app.serviceb) { 12765 adj = ProcessList.SERVICE_B_ADJ; 12766 } 12767 } else { 12768 app.serviceb = false; 12769 } 12770 12771 app.nonStoppingAdj = adj; 12772 12773 if (hasStoppingActivities) { 12774 // Only upgrade adjustment. 12775 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12776 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12777 app.adjType = "stopping"; 12778 } 12779 } 12780 12781 app.curRawAdj = adj; 12782 12783 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12784 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12785 if (adj > app.maxAdj) { 12786 adj = app.maxAdj; 12787 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12788 schedGroup = Process.THREAD_GROUP_DEFAULT; 12789 } 12790 } 12791 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12792 app.keeping = true; 12793 } 12794 12795 if (app.hasAboveClient) { 12796 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12797 // then we need to drop its adjustment to be lower than the service's 12798 // in order to honor the request. We want to drop it by one adjustment 12799 // level... but there is special meaning applied to various levels so 12800 // we will skip some of them. 12801 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12802 // System process will not get dropped, ever 12803 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12804 adj = ProcessList.VISIBLE_APP_ADJ; 12805 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12806 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12807 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12808 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12809 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12810 adj++; 12811 } 12812 } 12813 12814 int importance = app.memImportance; 12815 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12816 app.curAdj = adj; 12817 app.curSchedGroup = schedGroup; 12818 if (!interesting) { 12819 // For this reporting, if there is not something explicitly 12820 // interesting in this process then we will push it to the 12821 // background importance. 12822 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12823 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12824 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12825 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12826 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12827 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12828 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12829 } else if (adj >= ProcessList.SERVICE_ADJ) { 12830 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12831 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12832 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12833 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12834 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12835 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12836 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12837 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12838 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12839 } else { 12840 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12841 } 12842 } 12843 12844 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12845 if (foregroundActivities != app.foregroundActivities) { 12846 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12847 } 12848 if (changes != 0) { 12849 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12850 app.memImportance = importance; 12851 app.foregroundActivities = foregroundActivities; 12852 int i = mPendingProcessChanges.size()-1; 12853 ProcessChangeItem item = null; 12854 while (i >= 0) { 12855 item = mPendingProcessChanges.get(i); 12856 if (item.pid == app.pid) { 12857 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12858 break; 12859 } 12860 i--; 12861 } 12862 if (i < 0) { 12863 // No existing item in pending changes; need a new one. 12864 final int NA = mAvailProcessChanges.size(); 12865 if (NA > 0) { 12866 item = mAvailProcessChanges.remove(NA-1); 12867 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12868 } else { 12869 item = new ProcessChangeItem(); 12870 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12871 } 12872 item.changes = 0; 12873 item.pid = app.pid; 12874 item.uid = app.info.uid; 12875 if (mPendingProcessChanges.size() == 0) { 12876 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12877 "*** Enqueueing dispatch processes changed!"); 12878 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12879 } 12880 mPendingProcessChanges.add(item); 12881 } 12882 item.changes |= changes; 12883 item.importance = importance; 12884 item.foregroundActivities = foregroundActivities; 12885 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12886 + Integer.toHexString(System.identityHashCode(item)) 12887 + " " + app.toShortString() + ": changes=" + item.changes 12888 + " importance=" + item.importance 12889 + " foreground=" + item.foregroundActivities 12890 + " type=" + app.adjType + " source=" + app.adjSource 12891 + " target=" + app.adjTarget); 12892 } 12893 12894 return app.curRawAdj; 12895 } 12896 12897 /** 12898 * Ask a given process to GC right now. 12899 */ 12900 final void performAppGcLocked(ProcessRecord app) { 12901 try { 12902 app.lastRequestedGc = SystemClock.uptimeMillis(); 12903 if (app.thread != null) { 12904 if (app.reportLowMemory) { 12905 app.reportLowMemory = false; 12906 app.thread.scheduleLowMemory(); 12907 } else { 12908 app.thread.processInBackground(); 12909 } 12910 } 12911 } catch (Exception e) { 12912 // whatever. 12913 } 12914 } 12915 12916 /** 12917 * Returns true if things are idle enough to perform GCs. 12918 */ 12919 private final boolean canGcNowLocked() { 12920 boolean processingBroadcasts = false; 12921 for (BroadcastQueue q : mBroadcastQueues) { 12922 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12923 processingBroadcasts = true; 12924 } 12925 } 12926 return !processingBroadcasts 12927 && (mSleeping || (mMainStack.mResumedActivity != null && 12928 mMainStack.mResumedActivity.idle)); 12929 } 12930 12931 /** 12932 * Perform GCs on all processes that are waiting for it, but only 12933 * if things are idle. 12934 */ 12935 final void performAppGcsLocked() { 12936 final int N = mProcessesToGc.size(); 12937 if (N <= 0) { 12938 return; 12939 } 12940 if (canGcNowLocked()) { 12941 while (mProcessesToGc.size() > 0) { 12942 ProcessRecord proc = mProcessesToGc.remove(0); 12943 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12944 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12945 <= SystemClock.uptimeMillis()) { 12946 // To avoid spamming the system, we will GC processes one 12947 // at a time, waiting a few seconds between each. 12948 performAppGcLocked(proc); 12949 scheduleAppGcsLocked(); 12950 return; 12951 } else { 12952 // It hasn't been long enough since we last GCed this 12953 // process... put it in the list to wait for its time. 12954 addProcessToGcListLocked(proc); 12955 break; 12956 } 12957 } 12958 } 12959 12960 scheduleAppGcsLocked(); 12961 } 12962 } 12963 12964 /** 12965 * If all looks good, perform GCs on all processes waiting for them. 12966 */ 12967 final void performAppGcsIfAppropriateLocked() { 12968 if (canGcNowLocked()) { 12969 performAppGcsLocked(); 12970 return; 12971 } 12972 // Still not idle, wait some more. 12973 scheduleAppGcsLocked(); 12974 } 12975 12976 /** 12977 * Schedule the execution of all pending app GCs. 12978 */ 12979 final void scheduleAppGcsLocked() { 12980 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12981 12982 if (mProcessesToGc.size() > 0) { 12983 // Schedule a GC for the time to the next process. 12984 ProcessRecord proc = mProcessesToGc.get(0); 12985 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12986 12987 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 12988 long now = SystemClock.uptimeMillis(); 12989 if (when < (now+GC_TIMEOUT)) { 12990 when = now + GC_TIMEOUT; 12991 } 12992 mHandler.sendMessageAtTime(msg, when); 12993 } 12994 } 12995 12996 /** 12997 * Add a process to the array of processes waiting to be GCed. Keeps the 12998 * list in sorted order by the last GC time. The process can't already be 12999 * on the list. 13000 */ 13001 final void addProcessToGcListLocked(ProcessRecord proc) { 13002 boolean added = false; 13003 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13004 if (mProcessesToGc.get(i).lastRequestedGc < 13005 proc.lastRequestedGc) { 13006 added = true; 13007 mProcessesToGc.add(i+1, proc); 13008 break; 13009 } 13010 } 13011 if (!added) { 13012 mProcessesToGc.add(0, proc); 13013 } 13014 } 13015 13016 /** 13017 * Set up to ask a process to GC itself. This will either do it 13018 * immediately, or put it on the list of processes to gc the next 13019 * time things are idle. 13020 */ 13021 final void scheduleAppGcLocked(ProcessRecord app) { 13022 long now = SystemClock.uptimeMillis(); 13023 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13024 return; 13025 } 13026 if (!mProcessesToGc.contains(app)) { 13027 addProcessToGcListLocked(app); 13028 scheduleAppGcsLocked(); 13029 } 13030 } 13031 13032 final void checkExcessivePowerUsageLocked(boolean doKills) { 13033 updateCpuStatsNow(); 13034 13035 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13036 boolean doWakeKills = doKills; 13037 boolean doCpuKills = doKills; 13038 if (mLastPowerCheckRealtime == 0) { 13039 doWakeKills = false; 13040 } 13041 if (mLastPowerCheckUptime == 0) { 13042 doCpuKills = false; 13043 } 13044 if (stats.isScreenOn()) { 13045 doWakeKills = false; 13046 } 13047 final long curRealtime = SystemClock.elapsedRealtime(); 13048 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13049 final long curUptime = SystemClock.uptimeMillis(); 13050 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13051 mLastPowerCheckRealtime = curRealtime; 13052 mLastPowerCheckUptime = curUptime; 13053 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13054 doWakeKills = false; 13055 } 13056 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13057 doCpuKills = false; 13058 } 13059 int i = mLruProcesses.size(); 13060 while (i > 0) { 13061 i--; 13062 ProcessRecord app = mLruProcesses.get(i); 13063 if (!app.keeping) { 13064 long wtime; 13065 synchronized (stats) { 13066 wtime = stats.getProcessWakeTime(app.info.uid, 13067 app.pid, curRealtime); 13068 } 13069 long wtimeUsed = wtime - app.lastWakeTime; 13070 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13071 if (DEBUG_POWER) { 13072 StringBuilder sb = new StringBuilder(128); 13073 sb.append("Wake for "); 13074 app.toShortString(sb); 13075 sb.append(": over "); 13076 TimeUtils.formatDuration(realtimeSince, sb); 13077 sb.append(" used "); 13078 TimeUtils.formatDuration(wtimeUsed, sb); 13079 sb.append(" ("); 13080 sb.append((wtimeUsed*100)/realtimeSince); 13081 sb.append("%)"); 13082 Slog.i(TAG, sb.toString()); 13083 sb.setLength(0); 13084 sb.append("CPU for "); 13085 app.toShortString(sb); 13086 sb.append(": over "); 13087 TimeUtils.formatDuration(uptimeSince, sb); 13088 sb.append(" used "); 13089 TimeUtils.formatDuration(cputimeUsed, sb); 13090 sb.append(" ("); 13091 sb.append((cputimeUsed*100)/uptimeSince); 13092 sb.append("%)"); 13093 Slog.i(TAG, sb.toString()); 13094 } 13095 // If a process has held a wake lock for more 13096 // than 50% of the time during this period, 13097 // that sounds bad. Kill! 13098 if (doWakeKills && realtimeSince > 0 13099 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13100 synchronized (stats) { 13101 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13102 realtimeSince, wtimeUsed); 13103 } 13104 Slog.w(TAG, "Excessive wake lock in " + app.processName 13105 + " (pid " + app.pid + "): held " + wtimeUsed 13106 + " during " + realtimeSince); 13107 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13108 app.processName, app.setAdj, "excessive wake lock"); 13109 Process.killProcessQuiet(app.pid); 13110 } else if (doCpuKills && uptimeSince > 0 13111 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13112 synchronized (stats) { 13113 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13114 uptimeSince, cputimeUsed); 13115 } 13116 Slog.w(TAG, "Excessive CPU in " + app.processName 13117 + " (pid " + app.pid + "): used " + cputimeUsed 13118 + " during " + uptimeSince); 13119 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13120 app.processName, app.setAdj, "excessive cpu"); 13121 Process.killProcessQuiet(app.pid); 13122 } else { 13123 app.lastWakeTime = wtime; 13124 app.lastCpuTime = app.curCpuTime; 13125 } 13126 } 13127 } 13128 } 13129 13130 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13131 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13132 app.hiddenAdj = hiddenAdj; 13133 app.emptyAdj = emptyAdj; 13134 13135 if (app.thread == null) { 13136 return false; 13137 } 13138 13139 final boolean wasKeeping = app.keeping; 13140 13141 boolean success = true; 13142 13143 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13144 13145 if (app.curRawAdj != app.setRawAdj) { 13146 if (wasKeeping && !app.keeping) { 13147 // This app is no longer something we want to keep. Note 13148 // its current wake lock time to later know to kill it if 13149 // it is not behaving well. 13150 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13151 synchronized (stats) { 13152 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13153 app.pid, SystemClock.elapsedRealtime()); 13154 } 13155 app.lastCpuTime = app.curCpuTime; 13156 } 13157 13158 app.setRawAdj = app.curRawAdj; 13159 } 13160 13161 if (app.curAdj != app.setAdj) { 13162 if (Process.setOomAdj(app.pid, app.curAdj)) { 13163 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13164 TAG, "Set " + app.pid + " " + app.processName + 13165 " adj " + app.curAdj + ": " + app.adjType); 13166 app.setAdj = app.curAdj; 13167 } else { 13168 success = false; 13169 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13170 } 13171 } 13172 if (app.setSchedGroup != app.curSchedGroup) { 13173 app.setSchedGroup = app.curSchedGroup; 13174 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13175 "Setting process group of " + app.processName 13176 + " to " + app.curSchedGroup); 13177 if (app.waitingToKill != null && 13178 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13179 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13180 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13181 app.processName, app.setAdj, app.waitingToKill); 13182 app.killedBackground = true; 13183 Process.killProcessQuiet(app.pid); 13184 success = false; 13185 } else { 13186 if (true) { 13187 long oldId = Binder.clearCallingIdentity(); 13188 try { 13189 Process.setProcessGroup(app.pid, app.curSchedGroup); 13190 } catch (Exception e) { 13191 Slog.w(TAG, "Failed setting process group of " + app.pid 13192 + " to " + app.curSchedGroup); 13193 e.printStackTrace(); 13194 } finally { 13195 Binder.restoreCallingIdentity(oldId); 13196 } 13197 } else { 13198 if (app.thread != null) { 13199 try { 13200 app.thread.setSchedulingGroup(app.curSchedGroup); 13201 } catch (RemoteException e) { 13202 } 13203 } 13204 } 13205 } 13206 } 13207 return success; 13208 } 13209 13210 private final ActivityRecord resumedAppLocked() { 13211 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13212 if (resumedActivity == null || resumedActivity.app == null) { 13213 resumedActivity = mMainStack.mPausingActivity; 13214 if (resumedActivity == null || resumedActivity.app == null) { 13215 resumedActivity = mMainStack.topRunningActivityLocked(null); 13216 } 13217 } 13218 return resumedActivity; 13219 } 13220 13221 final boolean updateOomAdjLocked(ProcessRecord app) { 13222 final ActivityRecord TOP_ACT = resumedAppLocked(); 13223 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13224 int curAdj = app.curAdj; 13225 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13226 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13227 13228 mAdjSeq++; 13229 13230 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13231 TOP_APP, false); 13232 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13233 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13234 if (nowHidden != wasHidden) { 13235 // Changed to/from hidden state, so apps after it in the LRU 13236 // list may also be changed. 13237 updateOomAdjLocked(); 13238 } 13239 return success; 13240 } 13241 13242 final void updateOomAdjLocked() { 13243 final ActivityRecord TOP_ACT = resumedAppLocked(); 13244 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13245 13246 if (false) { 13247 RuntimeException e = new RuntimeException(); 13248 e.fillInStackTrace(); 13249 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13250 } 13251 13252 mAdjSeq++; 13253 mNewNumServiceProcs = 0; 13254 13255 // Let's determine how many processes we have running vs. 13256 // how many slots we have for background processes; we may want 13257 // to put multiple processes in a slot of there are enough of 13258 // them. 13259 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13260 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13261 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13262 if (emptyFactor < 1) emptyFactor = 1; 13263 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13264 if (hiddenFactor < 1) hiddenFactor = 1; 13265 int stepHidden = 0; 13266 int stepEmpty = 0; 13267 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13268 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13269 int numHidden = 0; 13270 int numEmpty = 0; 13271 int numTrimming = 0; 13272 13273 mNumNonHiddenProcs = 0; 13274 mNumHiddenProcs = 0; 13275 13276 // First update the OOM adjustment for each of the 13277 // application processes based on their current state. 13278 int i = mLruProcesses.size(); 13279 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13280 int nextHiddenAdj = curHiddenAdj+1; 13281 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13282 int nextEmptyAdj = curEmptyAdj+2; 13283 while (i > 0) { 13284 i--; 13285 ProcessRecord app = mLruProcesses.get(i); 13286 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13287 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13288 if (!app.killedBackground) { 13289 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13290 // This process was assigned as a hidden process... step the 13291 // hidden level. 13292 mNumHiddenProcs++; 13293 if (curHiddenAdj != nextHiddenAdj) { 13294 stepHidden++; 13295 if (stepHidden >= hiddenFactor) { 13296 stepHidden = 0; 13297 curHiddenAdj = nextHiddenAdj; 13298 nextHiddenAdj += 2; 13299 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13300 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13301 } 13302 } 13303 } 13304 numHidden++; 13305 if (numHidden > hiddenProcessLimit) { 13306 Slog.i(TAG, "No longer want " + app.processName 13307 + " (pid " + app.pid + "): hidden #" + numHidden); 13308 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13309 app.processName, app.setAdj, "too many background"); 13310 app.killedBackground = true; 13311 Process.killProcessQuiet(app.pid); 13312 } 13313 } else { 13314 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13315 // This process was assigned as an empty process... step the 13316 // empty level. 13317 if (curEmptyAdj != nextEmptyAdj) { 13318 stepEmpty++; 13319 if (stepEmpty >= emptyFactor) { 13320 stepEmpty = 0; 13321 curEmptyAdj = nextEmptyAdj; 13322 nextEmptyAdj += 2; 13323 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13324 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13325 } 13326 } 13327 } 13328 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13329 mNumNonHiddenProcs++; 13330 } 13331 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13332 numEmpty++; 13333 if (numEmpty > emptyProcessLimit) { 13334 Slog.i(TAG, "No longer want " + app.processName 13335 + " (pid " + app.pid + "): empty #" + numEmpty); 13336 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13337 app.processName, app.setAdj, "too many background"); 13338 app.killedBackground = true; 13339 Process.killProcessQuiet(app.pid); 13340 } 13341 } 13342 } 13343 if (app.isolated && app.services.size() <= 0) { 13344 // If this is an isolated process, and there are no 13345 // services running in it, then the process is no longer 13346 // needed. We agressively kill these because we can by 13347 // definition not re-use the same process again, and it is 13348 // good to avoid having whatever code was running in them 13349 // left sitting around after no longer needed. 13350 Slog.i(TAG, "Isolated process " + app.processName 13351 + " (pid " + app.pid + ") no longer needed"); 13352 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13353 app.processName, app.setAdj, "isolated not needed"); 13354 app.killedBackground = true; 13355 Process.killProcessQuiet(app.pid); 13356 } 13357 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13358 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13359 && !app.killedBackground) { 13360 numTrimming++; 13361 } 13362 } 13363 } 13364 13365 mNumServiceProcs = mNewNumServiceProcs; 13366 13367 // Now determine the memory trimming level of background processes. 13368 // Unfortunately we need to start at the back of the list to do this 13369 // properly. We only do this if the number of background apps we 13370 // are managing to keep around is less than half the maximum we desire; 13371 // if we are keeping a good number around, we'll let them use whatever 13372 // memory they want. 13373 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13374 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13375 final int numHiddenAndEmpty = numHidden + numEmpty; 13376 final int N = mLruProcesses.size(); 13377 int factor = numTrimming/3; 13378 int minFactor = 2; 13379 if (mHomeProcess != null) minFactor++; 13380 if (mPreviousProcess != null) minFactor++; 13381 if (factor < minFactor) factor = minFactor; 13382 int step = 0; 13383 int fgTrimLevel; 13384 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13385 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13386 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13387 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13388 } else { 13389 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13390 } 13391 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13392 for (i=0; i<N; i++) { 13393 ProcessRecord app = mLruProcesses.get(i); 13394 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13395 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13396 && !app.killedBackground) { 13397 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13398 try { 13399 app.thread.scheduleTrimMemory(curLevel); 13400 } catch (RemoteException e) { 13401 } 13402 if (false) { 13403 // For now we won't do this; our memory trimming seems 13404 // to be good enough at this point that destroying 13405 // activities causes more harm than good. 13406 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13407 && app != mHomeProcess && app != mPreviousProcess) { 13408 // Need to do this on its own message because the stack may not 13409 // be in a consistent state at this point. 13410 // For these apps we will also finish their activities 13411 // to help them free memory. 13412 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13413 } 13414 } 13415 } 13416 app.trimMemoryLevel = curLevel; 13417 step++; 13418 if (step >= factor) { 13419 step = 0; 13420 switch (curLevel) { 13421 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13422 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13423 break; 13424 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13425 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13426 break; 13427 } 13428 } 13429 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13430 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13431 && app.thread != null) { 13432 try { 13433 app.thread.scheduleTrimMemory( 13434 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13435 } catch (RemoteException e) { 13436 } 13437 } 13438 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13439 } else { 13440 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13441 && app.pendingUiClean) { 13442 // If this application is now in the background and it 13443 // had done UI, then give it the special trim level to 13444 // have it free UI resources. 13445 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13446 if (app.trimMemoryLevel < level && app.thread != null) { 13447 try { 13448 app.thread.scheduleTrimMemory(level); 13449 } catch (RemoteException e) { 13450 } 13451 } 13452 app.pendingUiClean = false; 13453 } 13454 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13455 try { 13456 app.thread.scheduleTrimMemory(fgTrimLevel); 13457 } catch (RemoteException e) { 13458 } 13459 } 13460 app.trimMemoryLevel = fgTrimLevel; 13461 } 13462 } 13463 } else { 13464 final int N = mLruProcesses.size(); 13465 for (i=0; i<N; i++) { 13466 ProcessRecord app = mLruProcesses.get(i); 13467 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13468 && app.pendingUiClean) { 13469 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13470 && app.thread != null) { 13471 try { 13472 app.thread.scheduleTrimMemory( 13473 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13474 } catch (RemoteException e) { 13475 } 13476 } 13477 app.pendingUiClean = false; 13478 } 13479 app.trimMemoryLevel = 0; 13480 } 13481 } 13482 13483 if (mAlwaysFinishActivities) { 13484 // Need to do this on its own message because the stack may not 13485 // be in a consistent state at this point. 13486 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13487 } 13488 } 13489 13490 final void trimApplications() { 13491 synchronized (this) { 13492 int i; 13493 13494 // First remove any unused application processes whose package 13495 // has been removed. 13496 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13497 final ProcessRecord app = mRemovedProcesses.get(i); 13498 if (app.activities.size() == 0 13499 && app.curReceiver == null && app.services.size() == 0) { 13500 Slog.i( 13501 TAG, "Exiting empty application process " 13502 + app.processName + " (" 13503 + (app.thread != null ? app.thread.asBinder() : null) 13504 + ")\n"); 13505 if (app.pid > 0 && app.pid != MY_PID) { 13506 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13507 app.processName, app.setAdj, "empty"); 13508 Process.killProcessQuiet(app.pid); 13509 } else { 13510 try { 13511 app.thread.scheduleExit(); 13512 } catch (Exception e) { 13513 // Ignore exceptions. 13514 } 13515 } 13516 cleanUpApplicationRecordLocked(app, false, true, -1); 13517 mRemovedProcesses.remove(i); 13518 13519 if (app.persistent) { 13520 if (app.persistent) { 13521 addAppLocked(app.info, false); 13522 } 13523 } 13524 } 13525 } 13526 13527 // Now update the oom adj for all processes. 13528 updateOomAdjLocked(); 13529 } 13530 } 13531 13532 /** This method sends the specified signal to each of the persistent apps */ 13533 public void signalPersistentProcesses(int sig) throws RemoteException { 13534 if (sig != Process.SIGNAL_USR1) { 13535 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13536 } 13537 13538 synchronized (this) { 13539 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13540 != PackageManager.PERMISSION_GRANTED) { 13541 throw new SecurityException("Requires permission " 13542 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13543 } 13544 13545 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13546 ProcessRecord r = mLruProcesses.get(i); 13547 if (r.thread != null && r.persistent) { 13548 Process.sendSignal(r.pid, sig); 13549 } 13550 } 13551 } 13552 } 13553 13554 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13555 if (proc == null || proc == mProfileProc) { 13556 proc = mProfileProc; 13557 path = mProfileFile; 13558 profileType = mProfileType; 13559 clearProfilerLocked(); 13560 } 13561 if (proc == null) { 13562 return; 13563 } 13564 try { 13565 proc.thread.profilerControl(false, path, null, profileType); 13566 } catch (RemoteException e) { 13567 throw new IllegalStateException("Process disappeared"); 13568 } 13569 } 13570 13571 private void clearProfilerLocked() { 13572 if (mProfileFd != null) { 13573 try { 13574 mProfileFd.close(); 13575 } catch (IOException e) { 13576 } 13577 } 13578 mProfileApp = null; 13579 mProfileProc = null; 13580 mProfileFile = null; 13581 mProfileType = 0; 13582 mAutoStopProfiler = false; 13583 } 13584 13585 public boolean profileControl(String process, boolean start, 13586 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13587 13588 try { 13589 synchronized (this) { 13590 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13591 // its own permission. 13592 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13593 != PackageManager.PERMISSION_GRANTED) { 13594 throw new SecurityException("Requires permission " 13595 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13596 } 13597 13598 if (start && fd == null) { 13599 throw new IllegalArgumentException("null fd"); 13600 } 13601 13602 ProcessRecord proc = null; 13603 if (process != null) { 13604 try { 13605 int pid = Integer.parseInt(process); 13606 synchronized (mPidsSelfLocked) { 13607 proc = mPidsSelfLocked.get(pid); 13608 } 13609 } catch (NumberFormatException e) { 13610 } 13611 13612 if (proc == null) { 13613 HashMap<String, SparseArray<ProcessRecord>> all 13614 = mProcessNames.getMap(); 13615 SparseArray<ProcessRecord> procs = all.get(process); 13616 if (procs != null && procs.size() > 0) { 13617 proc = procs.valueAt(0); 13618 } 13619 } 13620 } 13621 13622 if (start && (proc == null || proc.thread == null)) { 13623 throw new IllegalArgumentException("Unknown process: " + process); 13624 } 13625 13626 if (start) { 13627 stopProfilerLocked(null, null, 0); 13628 setProfileApp(proc.info, proc.processName, path, fd, false); 13629 mProfileProc = proc; 13630 mProfileType = profileType; 13631 try { 13632 fd = fd.dup(); 13633 } catch (IOException e) { 13634 fd = null; 13635 } 13636 proc.thread.profilerControl(start, path, fd, profileType); 13637 fd = null; 13638 mProfileFd = null; 13639 } else { 13640 stopProfilerLocked(proc, path, profileType); 13641 if (fd != null) { 13642 try { 13643 fd.close(); 13644 } catch (IOException e) { 13645 } 13646 } 13647 } 13648 13649 return true; 13650 } 13651 } catch (RemoteException e) { 13652 throw new IllegalStateException("Process disappeared"); 13653 } finally { 13654 if (fd != null) { 13655 try { 13656 fd.close(); 13657 } catch (IOException e) { 13658 } 13659 } 13660 } 13661 } 13662 13663 public boolean dumpHeap(String process, boolean managed, 13664 String path, ParcelFileDescriptor fd) throws RemoteException { 13665 13666 try { 13667 synchronized (this) { 13668 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13669 // its own permission (same as profileControl). 13670 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13671 != PackageManager.PERMISSION_GRANTED) { 13672 throw new SecurityException("Requires permission " 13673 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13674 } 13675 13676 if (fd == null) { 13677 throw new IllegalArgumentException("null fd"); 13678 } 13679 13680 ProcessRecord proc = null; 13681 try { 13682 int pid = Integer.parseInt(process); 13683 synchronized (mPidsSelfLocked) { 13684 proc = mPidsSelfLocked.get(pid); 13685 } 13686 } catch (NumberFormatException e) { 13687 } 13688 13689 if (proc == null) { 13690 HashMap<String, SparseArray<ProcessRecord>> all 13691 = mProcessNames.getMap(); 13692 SparseArray<ProcessRecord> procs = all.get(process); 13693 if (procs != null && procs.size() > 0) { 13694 proc = procs.valueAt(0); 13695 } 13696 } 13697 13698 if (proc == null || proc.thread == null) { 13699 throw new IllegalArgumentException("Unknown process: " + process); 13700 } 13701 13702 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13703 if (!isDebuggable) { 13704 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13705 throw new SecurityException("Process not debuggable: " + proc); 13706 } 13707 } 13708 13709 proc.thread.dumpHeap(managed, path, fd); 13710 fd = null; 13711 return true; 13712 } 13713 } catch (RemoteException e) { 13714 throw new IllegalStateException("Process disappeared"); 13715 } finally { 13716 if (fd != null) { 13717 try { 13718 fd.close(); 13719 } catch (IOException e) { 13720 } 13721 } 13722 } 13723 } 13724 13725 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13726 public void monitor() { 13727 synchronized (this) { } 13728 } 13729 13730 void onCoreSettingsChange(Bundle settings) { 13731 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13732 ProcessRecord processRecord = mLruProcesses.get(i); 13733 try { 13734 if (processRecord.thread != null) { 13735 processRecord.thread.setCoreSettings(settings); 13736 } 13737 } catch (RemoteException re) { 13738 /* ignore */ 13739 } 13740 } 13741 } 13742 13743 // Multi-user methods 13744 13745 @Override 13746 public boolean switchUser(int userId) { 13747 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13748 != PackageManager.PERMISSION_GRANTED) { 13749 String msg = "Permission Denial: switchUser() from pid=" 13750 + Binder.getCallingPid() 13751 + ", uid=" + Binder.getCallingUid() 13752 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13753 Slog.w(TAG, msg); 13754 throw new SecurityException(msg); 13755 } 13756 synchronized (this) { 13757 if (mCurrentUserId == userId) { 13758 return true; 13759 } 13760 13761 // If the user we are switching to is not currently started, then 13762 // we need to start it now. 13763 if (mStartedUsers.get(userId) == null) { 13764 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13765 } 13766 13767 mCurrentUserId = userId; 13768 boolean haveActivities = mMainStack.switchUser(userId); 13769 if (!haveActivities) { 13770 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13771 } 13772 } 13773 13774 long ident = Binder.clearCallingIdentity(); 13775 try { 13776 // Inform of user switch 13777 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13778 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13779 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 13780 android.Manifest.permission.MANAGE_USERS); 13781 } finally { 13782 Binder.restoreCallingIdentity(ident); 13783 } 13784 13785 return true; 13786 } 13787 13788 void finishUserSwitch(UserStartedState uss) { 13789 synchronized (this) { 13790 if (uss.mState == UserStartedState.STATE_BOOTING 13791 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13792 uss.mState = UserStartedState.STATE_RUNNING; 13793 final int userId = uss.mHandle.getIdentifier(); 13794 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 13795 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13796 broadcastIntentLocked(null, null, intent, 13797 null, null, 0, null, null, 13798 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13799 false, false, MY_PID, Process.SYSTEM_UID, userId); 13800 } 13801 } 13802 } 13803 13804 @Override 13805 public int stopUser(final int userId, final IStopUserCallback callback) { 13806 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13807 != PackageManager.PERMISSION_GRANTED) { 13808 String msg = "Permission Denial: switchUser() from pid=" 13809 + Binder.getCallingPid() 13810 + ", uid=" + Binder.getCallingUid() 13811 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13812 Slog.w(TAG, msg); 13813 throw new SecurityException(msg); 13814 } 13815 if (userId <= 0) { 13816 throw new IllegalArgumentException("Can't stop primary user " + userId); 13817 } 13818 synchronized (this) { 13819 if (mCurrentUserId == userId) { 13820 return ActivityManager.USER_OP_IS_CURRENT; 13821 } 13822 13823 final UserStartedState uss = mStartedUsers.get(userId); 13824 if (uss == null) { 13825 // User is not started, nothing to do... but we do need to 13826 // callback if requested. 13827 if (callback != null) { 13828 mHandler.post(new Runnable() { 13829 @Override 13830 public void run() { 13831 try { 13832 callback.userStopped(userId); 13833 } catch (RemoteException e) { 13834 } 13835 } 13836 }); 13837 } 13838 return ActivityManager.USER_OP_SUCCESS; 13839 } 13840 13841 if (callback != null) { 13842 uss.mStopCallbacks.add(callback); 13843 } 13844 13845 if (uss.mState != UserStartedState.STATE_STOPPING) { 13846 uss.mState = UserStartedState.STATE_STOPPING; 13847 13848 long ident = Binder.clearCallingIdentity(); 13849 try { 13850 // Inform of user switch 13851 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13852 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13853 @Override 13854 public void performReceive(Intent intent, int resultCode, String data, 13855 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 13856 finishUserStop(uss); 13857 } 13858 }; 13859 broadcastIntentLocked(null, null, intent, 13860 null, resultReceiver, 0, null, null, null, 13861 true, false, MY_PID, Process.SYSTEM_UID, userId); 13862 } finally { 13863 Binder.restoreCallingIdentity(ident); 13864 } 13865 } 13866 } 13867 13868 return ActivityManager.USER_OP_SUCCESS; 13869 } 13870 13871 void finishUserStop(UserStartedState uss) { 13872 final int userId = uss.mHandle.getIdentifier(); 13873 boolean stopped; 13874 ArrayList<IStopUserCallback> callbacks; 13875 synchronized (this) { 13876 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13877 if (uss.mState != UserStartedState.STATE_STOPPING 13878 || mStartedUsers.get(userId) != uss) { 13879 stopped = false; 13880 } else { 13881 stopped = true; 13882 // User can no longer run. 13883 mStartedUsers.remove(userId); 13884 13885 // Clean up all state and processes associated with the user. 13886 // Kill all the processes for the user. 13887 forceStopUserLocked(userId); 13888 } 13889 } 13890 13891 for (int i=0; i<callbacks.size(); i++) { 13892 try { 13893 if (stopped) callbacks.get(i).userStopped(userId); 13894 else callbacks.get(i).userStopAborted(userId); 13895 } catch (RemoteException e) { 13896 } 13897 } 13898 } 13899 13900 @Override 13901 public UserInfo getCurrentUser() { 13902 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13903 != PackageManager.PERMISSION_GRANTED) { 13904 String msg = "Permission Denial: getCurrentUser() from pid=" 13905 + Binder.getCallingPid() 13906 + ", uid=" + Binder.getCallingUid() 13907 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13908 Slog.w(TAG, msg); 13909 throw new SecurityException(msg); 13910 } 13911 synchronized (this) { 13912 return getUserManager().getUserInfo(mCurrentUserId); 13913 } 13914 } 13915 13916 private boolean userExists(int userId) { 13917 UserInfo user = getUserManager().getUserInfo(userId); 13918 return user != null; 13919 } 13920 13921 UserManager getUserManager() { 13922 if (mUserManager == null) { 13923 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13924 } 13925 return mUserManager; 13926 } 13927 13928 private void checkValidCaller(int uid, int userId) { 13929 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13930 13931 throw new SecurityException("Caller uid=" + uid 13932 + " is not privileged to communicate with user=" + userId); 13933 } 13934 13935 private int applyUserId(int uid, int userId) { 13936 return UserHandle.getUid(userId, uid); 13937 } 13938 13939 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13940 if (info == null) return null; 13941 ApplicationInfo newInfo = new ApplicationInfo(info); 13942 newInfo.uid = applyUserId(info.uid, userId); 13943 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13944 + info.packageName; 13945 return newInfo; 13946 } 13947 13948 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13949 if (aInfo == null 13950 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13951 return aInfo; 13952 } 13953 13954 ActivityInfo info = new ActivityInfo(aInfo); 13955 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13956 return info; 13957 } 13958} 13959