ActivityManagerService.java revision 74ee8652e02fc94901177214fc9370659732c921
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.TimeUtils; 125import android.view.Gravity; 126import android.view.LayoutInflater; 127import android.view.View; 128import android.view.WindowManager; 129import android.view.WindowManagerPolicy; 130 131import java.io.BufferedInputStream; 132import java.io.BufferedOutputStream; 133import java.io.BufferedReader; 134import java.io.DataInputStream; 135import java.io.DataOutputStream; 136import java.io.File; 137import java.io.FileDescriptor; 138import java.io.FileInputStream; 139import java.io.FileNotFoundException; 140import java.io.FileOutputStream; 141import java.io.IOException; 142import java.io.InputStreamReader; 143import java.io.PrintWriter; 144import java.io.StringWriter; 145import java.lang.ref.WeakReference; 146import java.util.ArrayList; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Set; 156import java.util.concurrent.atomic.AtomicBoolean; 157import java.util.concurrent.atomic.AtomicLong; 158 159public final class ActivityManagerService extends ActivityManagerNative 160 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 161 private static final String USER_DATA_DIR = "/data/user/"; 162 static final String TAG = "ActivityManager"; 163 static final String TAG_MU = "ActivityManagerServiceMU"; 164 static final boolean DEBUG = false; 165 static final boolean localLOGV = DEBUG; 166 static final boolean DEBUG_SWITCH = localLOGV || false; 167 static final boolean DEBUG_TASKS = localLOGV || false; 168 static final boolean DEBUG_PAUSE = localLOGV || false; 169 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 170 static final boolean DEBUG_TRANSITION = localLOGV || false; 171 static final boolean DEBUG_BROADCAST = localLOGV || false; 172 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 173 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_SERVICE = localLOGV || false; 175 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 176 static final boolean DEBUG_VISBILITY = localLOGV || false; 177 static final boolean DEBUG_PROCESSES = localLOGV || false; 178 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 179 static final boolean DEBUG_PROVIDER = localLOGV || false; 180 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 181 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 182 static final boolean DEBUG_RESULTS = localLOGV || false; 183 static final boolean DEBUG_BACKUP = localLOGV || false; 184 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 185 static final boolean DEBUG_POWER = localLOGV || false; 186 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 187 static final boolean DEBUG_MU = localLOGV || false; 188 static final boolean VALIDATE_TOKENS = false; 189 static final boolean SHOW_ACTIVITY_START_TIME = true; 190 191 // Control over CPU and battery monitoring. 192 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 193 static final boolean MONITOR_CPU_USAGE = true; 194 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 195 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 196 static final boolean MONITOR_THREAD_CPU_USAGE = false; 197 198 // The flags that are set for all calls we make to the package manager. 199 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 200 201 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 202 203 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 204 205 // Maximum number of recent tasks that we can remember. 206 static final int MAX_RECENT_TASKS = 20; 207 208 // Amount of time after a call to stopAppSwitches() during which we will 209 // prevent further untrusted switches from happening. 210 static final long APP_SWITCH_DELAY_TIME = 5*1000; 211 212 // How long we wait for a launched process to attach to the activity manager 213 // before we decide it's never going to come up for real. 214 static final int PROC_START_TIMEOUT = 10*1000; 215 216 // How long we wait for a launched process to attach to the activity manager 217 // before we decide it's never going to come up for real, when the process was 218 // started with a wrapper for instrumentation (such as Valgrind) because it 219 // could take much longer than usual. 220 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 221 222 // How long to wait after going idle before forcing apps to GC. 223 static final int GC_TIMEOUT = 5*1000; 224 225 // The minimum amount of time between successive GC requests for a process. 226 static final int GC_MIN_INTERVAL = 60*1000; 227 228 // The rate at which we check for apps using excessive power -- 15 mins. 229 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 230 231 // The minimum sample duration we will allow before deciding we have 232 // enough data on wake locks to start killing things. 233 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 234 235 // The minimum sample duration we will allow before deciding we have 236 // enough data on CPU usage to start killing things. 237 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 238 239 // How long we allow a receiver to run before giving up on it. 240 static final int BROADCAST_FG_TIMEOUT = 10*1000; 241 static final int BROADCAST_BG_TIMEOUT = 60*1000; 242 243 // How long we wait until we timeout on key dispatching. 244 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 245 246 // How long we wait until we timeout on key dispatching during instrumentation. 247 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 248 249 static final int MY_PID = Process.myPid(); 250 251 static final String[] EMPTY_STRING_ARRAY = new String[0]; 252 253 public ActivityStack mMainStack; 254 255 private final boolean mHeadless; 256 257 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 258 // default actuion automatically. Important for devices without direct input 259 // devices. 260 private boolean mShowDialogs = true; 261 262 /** 263 * Description of a request to start a new activity, which has been held 264 * due to app switches being disabled. 265 */ 266 static class PendingActivityLaunch { 267 ActivityRecord r; 268 ActivityRecord sourceRecord; 269 int startFlags; 270 } 271 272 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 273 = new ArrayList<PendingActivityLaunch>(); 274 275 276 BroadcastQueue mFgBroadcastQueue; 277 BroadcastQueue mBgBroadcastQueue; 278 // Convenient for easy iteration over the queues. Foreground is first 279 // so that dispatch of foreground broadcasts gets precedence. 280 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 281 282 BroadcastQueue broadcastQueueForIntent(Intent intent) { 283 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 284 if (DEBUG_BACKGROUND_BROADCAST) { 285 Slog.i(TAG, "Broadcast intent " + intent + " on " 286 + (isFg ? "foreground" : "background") 287 + " queue"); 288 } 289 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 290 } 291 292 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 293 for (BroadcastQueue queue : mBroadcastQueues) { 294 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 295 if (r != null) { 296 return r; 297 } 298 } 299 return null; 300 } 301 302 /** 303 * Activity we have told the window manager to have key focus. 304 */ 305 ActivityRecord mFocusedActivity = null; 306 /** 307 * List of intents that were used to start the most recent tasks. 308 */ 309 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 310 311 /** 312 * Process management. 313 */ 314 final ProcessList mProcessList = new ProcessList(); 315 316 /** 317 * All of the applications we currently have running organized by name. 318 * The keys are strings of the application package name (as 319 * returned by the package manager), and the keys are ApplicationRecord 320 * objects. 321 */ 322 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 323 324 /** 325 * The currently running isolated processes. 326 */ 327 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 328 329 /** 330 * Counter for assigning isolated process uids, to avoid frequently reusing the 331 * same ones. 332 */ 333 int mNextIsolatedProcessUid = 0; 334 335 /** 336 * The currently running heavy-weight process, if any. 337 */ 338 ProcessRecord mHeavyWeightProcess = null; 339 340 /** 341 * The last time that various processes have crashed. 342 */ 343 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 344 345 /** 346 * Set of applications that we consider to be bad, and will reject 347 * incoming broadcasts from (which the user has no control over). 348 * Processes are added to this set when they have crashed twice within 349 * a minimum amount of time; they are removed from it when they are 350 * later restarted (hopefully due to some user action). The value is the 351 * time it was added to the list. 352 */ 353 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 354 355 /** 356 * All of the processes we currently have running organized by pid. 357 * The keys are the pid running the application. 358 * 359 * <p>NOTE: This object is protected by its own lock, NOT the global 360 * activity manager lock! 361 */ 362 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 363 364 /** 365 * All of the processes that have been forced to be foreground. The key 366 * is the pid of the caller who requested it (we hold a death 367 * link on it). 368 */ 369 abstract class ForegroundToken implements IBinder.DeathRecipient { 370 int pid; 371 IBinder token; 372 } 373 final SparseArray<ForegroundToken> mForegroundProcesses 374 = new SparseArray<ForegroundToken>(); 375 376 /** 377 * List of records for processes that someone had tried to start before the 378 * system was ready. We don't start them at that point, but ensure they 379 * are started by the time booting is complete. 380 */ 381 final ArrayList<ProcessRecord> mProcessesOnHold 382 = new ArrayList<ProcessRecord>(); 383 384 /** 385 * List of persistent applications that are in the process 386 * of being started. 387 */ 388 final ArrayList<ProcessRecord> mPersistentStartingProcesses 389 = new ArrayList<ProcessRecord>(); 390 391 /** 392 * Processes that are being forcibly torn down. 393 */ 394 final ArrayList<ProcessRecord> mRemovedProcesses 395 = new ArrayList<ProcessRecord>(); 396 397 /** 398 * List of running applications, sorted by recent usage. 399 * The first entry in the list is the least recently used. 400 * It contains ApplicationRecord objects. This list does NOT include 401 * any persistent application records (since we never want to exit them). 402 */ 403 final ArrayList<ProcessRecord> mLruProcesses 404 = new ArrayList<ProcessRecord>(); 405 406 /** 407 * List of processes that should gc as soon as things are idle. 408 */ 409 final ArrayList<ProcessRecord> mProcessesToGc 410 = new ArrayList<ProcessRecord>(); 411 412 /** 413 * This is the process holding what we currently consider to be 414 * the "home" activity. 415 */ 416 ProcessRecord mHomeProcess; 417 418 /** 419 * This is the process holding the activity the user last visited that 420 * is in a different process from the one they are currently in. 421 */ 422 ProcessRecord mPreviousProcess; 423 424 /** 425 * The time at which the previous process was last visible. 426 */ 427 long mPreviousProcessVisibleTime; 428 429 /** 430 * Which uses have been started, so are allowed to run code. 431 */ 432 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 433 434 /** 435 * LRU list of history of current users. Most recently current is at the end. 436 */ 437 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 438 439 /** 440 * Packages that the user has asked to have run in screen size 441 * compatibility mode instead of filling the screen. 442 */ 443 final CompatModePackages mCompatModePackages; 444 445 /** 446 * Set of PendingResultRecord objects that are currently active. 447 */ 448 final HashSet mPendingResultRecords = new HashSet(); 449 450 /** 451 * Set of IntentSenderRecord objects that are currently active. 452 */ 453 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 454 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 455 456 /** 457 * Fingerprints (hashCode()) of stack traces that we've 458 * already logged DropBox entries for. Guarded by itself. If 459 * something (rogue user app) forces this over 460 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 461 */ 462 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 463 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 464 465 /** 466 * Strict Mode background batched logging state. 467 * 468 * The string buffer is guarded by itself, and its lock is also 469 * used to determine if another batched write is already 470 * in-flight. 471 */ 472 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 473 474 /** 475 * Keeps track of all IIntentReceivers that have been registered for 476 * broadcasts. Hash keys are the receiver IBinder, hash value is 477 * a ReceiverList. 478 */ 479 final HashMap mRegisteredReceivers = new HashMap(); 480 481 /** 482 * Resolver for broadcast intents to registered receivers. 483 * Holds BroadcastFilter (subclass of IntentFilter). 484 */ 485 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 486 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 487 @Override 488 protected boolean allowFilterResult( 489 BroadcastFilter filter, List<BroadcastFilter> dest) { 490 IBinder target = filter.receiverList.receiver.asBinder(); 491 for (int i=dest.size()-1; i>=0; i--) { 492 if (dest.get(i).receiverList.receiver.asBinder() == target) { 493 return false; 494 } 495 } 496 return true; 497 } 498 499 @Override 500 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 501 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 502 || userId == filter.owningUserId) { 503 return super.newResult(filter, match, userId); 504 } 505 return null; 506 } 507 508 @Override 509 protected BroadcastFilter[] newArray(int size) { 510 return new BroadcastFilter[size]; 511 } 512 513 @Override 514 protected String packageForFilter(BroadcastFilter filter) { 515 return filter.packageName; 516 } 517 }; 518 519 /** 520 * State of all active sticky broadcasts per user. Keys are the action of the 521 * sticky Intent, values are an ArrayList of all broadcasted intents with 522 * that action (which should usually be one). The SparseArray is keyed 523 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 524 * for stickies that are sent to all users. 525 */ 526 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 527 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 528 529 final ActiveServices mServices; 530 531 /** 532 * Backup/restore process management 533 */ 534 String mBackupAppName = null; 535 BackupRecord mBackupTarget = null; 536 537 /** 538 * List of PendingThumbnailsRecord objects of clients who are still 539 * waiting to receive all of the thumbnails for a task. 540 */ 541 final ArrayList mPendingThumbnails = new ArrayList(); 542 543 /** 544 * List of HistoryRecord objects that have been finished and must 545 * still report back to a pending thumbnail receiver. 546 */ 547 final ArrayList mCancelledThumbnails = new ArrayList(); 548 549 final ProviderMap mProviderMap = new ProviderMap(); 550 551 /** 552 * List of content providers who have clients waiting for them. The 553 * application is currently being launched and the provider will be 554 * removed from this list once it is published. 555 */ 556 final ArrayList<ContentProviderRecord> mLaunchingProviders 557 = new ArrayList<ContentProviderRecord>(); 558 559 /** 560 * Global set of specific Uri permissions that have been granted. 561 */ 562 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 563 = new SparseArray<HashMap<Uri, UriPermission>>(); 564 565 CoreSettingsObserver mCoreSettingsObserver; 566 567 /** 568 * Thread-local storage used to carry caller permissions over through 569 * indirect content-provider access. 570 * @see #ActivityManagerService.openContentUri() 571 */ 572 private class Identity { 573 public int pid; 574 public int uid; 575 576 Identity(int _pid, int _uid) { 577 pid = _pid; 578 uid = _uid; 579 } 580 } 581 582 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 583 584 /** 585 * All information we have collected about the runtime performance of 586 * any user id that can impact battery performance. 587 */ 588 final BatteryStatsService mBatteryStatsService; 589 590 /** 591 * information about component usage 592 */ 593 final UsageStatsService mUsageStatsService; 594 595 /** 596 * Current configuration information. HistoryRecord objects are given 597 * a reference to this object to indicate which configuration they are 598 * currently running in, so this object must be kept immutable. 599 */ 600 Configuration mConfiguration = new Configuration(); 601 602 /** 603 * Current sequencing integer of the configuration, for skipping old 604 * configurations. 605 */ 606 int mConfigurationSeq = 0; 607 608 /** 609 * Hardware-reported OpenGLES version. 610 */ 611 final int GL_ES_VERSION; 612 613 /** 614 * List of initialization arguments to pass to all processes when binding applications to them. 615 * For example, references to the commonly used services. 616 */ 617 HashMap<String, IBinder> mAppBindArgs; 618 619 /** 620 * Temporary to avoid allocations. Protected by main lock. 621 */ 622 final StringBuilder mStringBuilder = new StringBuilder(256); 623 624 /** 625 * Used to control how we initialize the service. 626 */ 627 boolean mStartRunning = false; 628 ComponentName mTopComponent; 629 String mTopAction; 630 String mTopData; 631 boolean mProcessesReady = false; 632 boolean mSystemReady = false; 633 boolean mBooting = false; 634 boolean mWaitingUpdate = false; 635 boolean mDidUpdate = false; 636 boolean mOnBattery = false; 637 boolean mLaunchWarningShown = false; 638 639 Context mContext; 640 641 int mFactoryTest; 642 643 boolean mCheckedForSetup; 644 645 /** 646 * The time at which we will allow normal application switches again, 647 * after a call to {@link #stopAppSwitches()}. 648 */ 649 long mAppSwitchesAllowedTime; 650 651 /** 652 * This is set to true after the first switch after mAppSwitchesAllowedTime 653 * is set; any switches after that will clear the time. 654 */ 655 boolean mDidAppSwitch; 656 657 /** 658 * Last time (in realtime) at which we checked for power usage. 659 */ 660 long mLastPowerCheckRealtime; 661 662 /** 663 * Last time (in uptime) at which we checked for power usage. 664 */ 665 long mLastPowerCheckUptime; 666 667 /** 668 * Set while we are wanting to sleep, to prevent any 669 * activities from being started/resumed. 670 */ 671 boolean mSleeping = false; 672 673 /** 674 * State of external calls telling us if the device is asleep. 675 */ 676 boolean mWentToSleep = false; 677 678 /** 679 * State of external call telling us if the lock screen is shown. 680 */ 681 boolean mLockScreenShown = false; 682 683 /** 684 * Set if we are shutting down the system, similar to sleeping. 685 */ 686 boolean mShuttingDown = false; 687 688 /** 689 * Task identifier that activities are currently being started 690 * in. Incremented each time a new task is created. 691 * todo: Replace this with a TokenSpace class that generates non-repeating 692 * integers that won't wrap. 693 */ 694 int mCurTask = 1; 695 696 /** 697 * Current sequence id for oom_adj computation traversal. 698 */ 699 int mAdjSeq = 0; 700 701 /** 702 * Current sequence id for process LRU updating. 703 */ 704 int mLruSeq = 0; 705 706 /** 707 * Keep track of the non-hidden/empty process we last found, to help 708 * determine how to distribute hidden/empty processes next time. 709 */ 710 int mNumNonHiddenProcs = 0; 711 712 /** 713 * Keep track of the number of hidden procs, to balance oom adj 714 * distribution between those and empty procs. 715 */ 716 int mNumHiddenProcs = 0; 717 718 /** 719 * Keep track of the number of service processes we last found, to 720 * determine on the next iteration which should be B services. 721 */ 722 int mNumServiceProcs = 0; 723 int mNewNumServiceProcs = 0; 724 725 /** 726 * System monitoring: number of processes that died since the last 727 * N procs were started. 728 */ 729 int[] mProcDeaths = new int[20]; 730 731 /** 732 * This is set if we had to do a delayed dexopt of an app before launching 733 * it, to increasing the ANR timeouts in that case. 734 */ 735 boolean mDidDexOpt; 736 737 String mDebugApp = null; 738 boolean mWaitForDebugger = false; 739 boolean mDebugTransient = false; 740 String mOrigDebugApp = null; 741 boolean mOrigWaitForDebugger = false; 742 boolean mAlwaysFinishActivities = false; 743 IActivityController mController = null; 744 String mProfileApp = null; 745 ProcessRecord mProfileProc = null; 746 String mProfileFile; 747 ParcelFileDescriptor mProfileFd; 748 int mProfileType = 0; 749 boolean mAutoStopProfiler = false; 750 String mOpenGlTraceApp = null; 751 752 static class ProcessChangeItem { 753 static final int CHANGE_ACTIVITIES = 1<<0; 754 static final int CHANGE_IMPORTANCE= 1<<1; 755 int changes; 756 int uid; 757 int pid; 758 int importance; 759 boolean foregroundActivities; 760 } 761 762 final RemoteCallbackList<IProcessObserver> mProcessObservers 763 = new RemoteCallbackList<IProcessObserver>(); 764 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 765 766 final ArrayList<ProcessChangeItem> mPendingProcessChanges 767 = new ArrayList<ProcessChangeItem>(); 768 final ArrayList<ProcessChangeItem> mAvailProcessChanges 769 = new ArrayList<ProcessChangeItem>(); 770 771 /** 772 * Callback of last caller to {@link #requestPss}. 773 */ 774 Runnable mRequestPssCallback; 775 776 /** 777 * Remaining processes for which we are waiting results from the last 778 * call to {@link #requestPss}. 779 */ 780 final ArrayList<ProcessRecord> mRequestPssList 781 = new ArrayList<ProcessRecord>(); 782 783 /** 784 * Runtime statistics collection thread. This object's lock is used to 785 * protect all related state. 786 */ 787 final Thread mProcessStatsThread; 788 789 /** 790 * Used to collect process stats when showing not responding dialog. 791 * Protected by mProcessStatsThread. 792 */ 793 final ProcessStats mProcessStats = new ProcessStats( 794 MONITOR_THREAD_CPU_USAGE); 795 final AtomicLong mLastCpuTime = new AtomicLong(0); 796 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 797 798 long mLastWriteTime = 0; 799 800 /** 801 * Set to true after the system has finished booting. 802 */ 803 boolean mBooted = false; 804 805 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 806 int mProcessLimitOverride = -1; 807 808 WindowManagerService mWindowManager; 809 810 static ActivityManagerService mSelf; 811 static ActivityThread mSystemThread; 812 813 private int mCurrentUserId; 814 private UserManager mUserManager; 815 816 private final class AppDeathRecipient implements IBinder.DeathRecipient { 817 final ProcessRecord mApp; 818 final int mPid; 819 final IApplicationThread mAppThread; 820 821 AppDeathRecipient(ProcessRecord app, int pid, 822 IApplicationThread thread) { 823 if (localLOGV) Slog.v( 824 TAG, "New death recipient " + this 825 + " for thread " + thread.asBinder()); 826 mApp = app; 827 mPid = pid; 828 mAppThread = thread; 829 } 830 831 public void binderDied() { 832 if (localLOGV) Slog.v( 833 TAG, "Death received in " + this 834 + " for thread " + mAppThread.asBinder()); 835 synchronized(ActivityManagerService.this) { 836 appDiedLocked(mApp, mPid, mAppThread); 837 } 838 } 839 } 840 841 static final int SHOW_ERROR_MSG = 1; 842 static final int SHOW_NOT_RESPONDING_MSG = 2; 843 static final int SHOW_FACTORY_ERROR_MSG = 3; 844 static final int UPDATE_CONFIGURATION_MSG = 4; 845 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 846 static final int WAIT_FOR_DEBUGGER_MSG = 6; 847 static final int SERVICE_TIMEOUT_MSG = 12; 848 static final int UPDATE_TIME_ZONE = 13; 849 static final int SHOW_UID_ERROR_MSG = 14; 850 static final int IM_FEELING_LUCKY_MSG = 15; 851 static final int PROC_START_TIMEOUT_MSG = 20; 852 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 853 static final int KILL_APPLICATION_MSG = 22; 854 static final int FINALIZE_PENDING_INTENT_MSG = 23; 855 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 856 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 857 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 858 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 859 static final int CLEAR_DNS_CACHE = 28; 860 static final int UPDATE_HTTP_PROXY = 29; 861 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 862 static final int DISPATCH_PROCESSES_CHANGED = 31; 863 static final int DISPATCH_PROCESS_DIED = 32; 864 static final int REPORT_MEM_USAGE = 33; 865 866 static final int FIRST_ACTIVITY_STACK_MSG = 100; 867 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 868 static final int FIRST_COMPAT_MODE_MSG = 300; 869 870 AlertDialog mUidAlert; 871 CompatModeDialog mCompatModeDialog; 872 long mLastMemUsageReportTime = 0; 873 874 final Handler mHandler = new Handler() { 875 //public Handler() { 876 // if (localLOGV) Slog.v(TAG, "Handler started!"); 877 //} 878 879 public void handleMessage(Message msg) { 880 switch (msg.what) { 881 case SHOW_ERROR_MSG: { 882 HashMap data = (HashMap) msg.obj; 883 synchronized (ActivityManagerService.this) { 884 ProcessRecord proc = (ProcessRecord)data.get("app"); 885 if (proc != null && proc.crashDialog != null) { 886 Slog.e(TAG, "App already has crash dialog: " + proc); 887 return; 888 } 889 AppErrorResult res = (AppErrorResult) data.get("result"); 890 if (mShowDialogs && !mSleeping && !mShuttingDown) { 891 Dialog d = new AppErrorDialog(mContext, res, proc); 892 d.show(); 893 proc.crashDialog = d; 894 } else { 895 // The device is asleep, so just pretend that the user 896 // saw a crash dialog and hit "force quit". 897 res.set(0); 898 } 899 } 900 901 ensureBootCompleted(); 902 } break; 903 case SHOW_NOT_RESPONDING_MSG: { 904 synchronized (ActivityManagerService.this) { 905 HashMap data = (HashMap) msg.obj; 906 ProcessRecord proc = (ProcessRecord)data.get("app"); 907 if (proc != null && proc.anrDialog != null) { 908 Slog.e(TAG, "App already has anr dialog: " + proc); 909 return; 910 } 911 912 Intent intent = new Intent("android.intent.action.ANR"); 913 if (!mProcessesReady) { 914 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 915 | Intent.FLAG_RECEIVER_FOREGROUND); 916 } 917 broadcastIntentLocked(null, null, intent, 918 null, null, 0, null, null, null, 919 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 920 921 if (mShowDialogs) { 922 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 923 mContext, proc, (ActivityRecord)data.get("activity")); 924 d.show(); 925 proc.anrDialog = d; 926 } else { 927 // Just kill the app if there is no dialog to be shown. 928 killAppAtUsersRequest(proc, null); 929 } 930 } 931 932 ensureBootCompleted(); 933 } break; 934 case SHOW_STRICT_MODE_VIOLATION_MSG: { 935 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 936 synchronized (ActivityManagerService.this) { 937 ProcessRecord proc = (ProcessRecord) data.get("app"); 938 if (proc == null) { 939 Slog.e(TAG, "App not found when showing strict mode dialog."); 940 break; 941 } 942 if (proc.crashDialog != null) { 943 Slog.e(TAG, "App already has strict mode dialog: " + proc); 944 return; 945 } 946 AppErrorResult res = (AppErrorResult) data.get("result"); 947 if (mShowDialogs && !mSleeping && !mShuttingDown) { 948 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 949 d.show(); 950 proc.crashDialog = d; 951 } else { 952 // The device is asleep, so just pretend that the user 953 // saw a crash dialog and hit "force quit". 954 res.set(0); 955 } 956 } 957 ensureBootCompleted(); 958 } break; 959 case SHOW_FACTORY_ERROR_MSG: { 960 Dialog d = new FactoryErrorDialog( 961 mContext, msg.getData().getCharSequence("msg")); 962 d.show(); 963 ensureBootCompleted(); 964 } break; 965 case UPDATE_CONFIGURATION_MSG: { 966 final ContentResolver resolver = mContext.getContentResolver(); 967 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 968 } break; 969 case GC_BACKGROUND_PROCESSES_MSG: { 970 synchronized (ActivityManagerService.this) { 971 performAppGcsIfAppropriateLocked(); 972 } 973 } break; 974 case WAIT_FOR_DEBUGGER_MSG: { 975 synchronized (ActivityManagerService.this) { 976 ProcessRecord app = (ProcessRecord)msg.obj; 977 if (msg.arg1 != 0) { 978 if (!app.waitedForDebugger) { 979 Dialog d = new AppWaitingForDebuggerDialog( 980 ActivityManagerService.this, 981 mContext, app); 982 app.waitDialog = d; 983 app.waitedForDebugger = true; 984 d.show(); 985 } 986 } else { 987 if (app.waitDialog != null) { 988 app.waitDialog.dismiss(); 989 app.waitDialog = null; 990 } 991 } 992 } 993 } break; 994 case SERVICE_TIMEOUT_MSG: { 995 if (mDidDexOpt) { 996 mDidDexOpt = false; 997 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 998 nmsg.obj = msg.obj; 999 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1000 return; 1001 } 1002 mServices.serviceTimeout((ProcessRecord)msg.obj); 1003 } break; 1004 case UPDATE_TIME_ZONE: { 1005 synchronized (ActivityManagerService.this) { 1006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1007 ProcessRecord r = mLruProcesses.get(i); 1008 if (r.thread != null) { 1009 try { 1010 r.thread.updateTimeZone(); 1011 } catch (RemoteException ex) { 1012 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1013 } 1014 } 1015 } 1016 } 1017 } break; 1018 case CLEAR_DNS_CACHE: { 1019 synchronized (ActivityManagerService.this) { 1020 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1021 ProcessRecord r = mLruProcesses.get(i); 1022 if (r.thread != null) { 1023 try { 1024 r.thread.clearDnsCache(); 1025 } catch (RemoteException ex) { 1026 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1027 } 1028 } 1029 } 1030 } 1031 } break; 1032 case UPDATE_HTTP_PROXY: { 1033 ProxyProperties proxy = (ProxyProperties)msg.obj; 1034 String host = ""; 1035 String port = ""; 1036 String exclList = ""; 1037 if (proxy != null) { 1038 host = proxy.getHost(); 1039 port = Integer.toString(proxy.getPort()); 1040 exclList = proxy.getExclusionList(); 1041 } 1042 synchronized (ActivityManagerService.this) { 1043 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1044 ProcessRecord r = mLruProcesses.get(i); 1045 if (r.thread != null) { 1046 try { 1047 r.thread.setHttpProxy(host, port, exclList); 1048 } catch (RemoteException ex) { 1049 Slog.w(TAG, "Failed to update http proxy for: " + 1050 r.info.processName); 1051 } 1052 } 1053 } 1054 } 1055 } break; 1056 case SHOW_UID_ERROR_MSG: { 1057 String title = "System UIDs Inconsistent"; 1058 String text = "UIDs on the system are inconsistent, you need to wipe your" 1059 + " data partition or your device will be unstable."; 1060 Log.e(TAG, title + ": " + text); 1061 if (mShowDialogs) { 1062 // XXX This is a temporary dialog, no need to localize. 1063 AlertDialog d = new BaseErrorDialog(mContext); 1064 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1065 d.setCancelable(false); 1066 d.setTitle(title); 1067 d.setMessage(text); 1068 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1069 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1070 mUidAlert = d; 1071 d.show(); 1072 } 1073 } break; 1074 case IM_FEELING_LUCKY_MSG: { 1075 if (mUidAlert != null) { 1076 mUidAlert.dismiss(); 1077 mUidAlert = null; 1078 } 1079 } break; 1080 case PROC_START_TIMEOUT_MSG: { 1081 if (mDidDexOpt) { 1082 mDidDexOpt = false; 1083 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1084 nmsg.obj = msg.obj; 1085 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1086 return; 1087 } 1088 ProcessRecord app = (ProcessRecord)msg.obj; 1089 synchronized (ActivityManagerService.this) { 1090 processStartTimedOutLocked(app); 1091 } 1092 } break; 1093 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1094 synchronized (ActivityManagerService.this) { 1095 doPendingActivityLaunchesLocked(true); 1096 } 1097 } break; 1098 case KILL_APPLICATION_MSG: { 1099 synchronized (ActivityManagerService.this) { 1100 int appid = msg.arg1; 1101 boolean restart = (msg.arg2 == 1); 1102 String pkg = (String) msg.obj; 1103 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1104 UserHandle.USER_ALL); 1105 } 1106 } break; 1107 case FINALIZE_PENDING_INTENT_MSG: { 1108 ((PendingIntentRecord)msg.obj).completeFinalize(); 1109 } break; 1110 case POST_HEAVY_NOTIFICATION_MSG: { 1111 INotificationManager inm = NotificationManager.getService(); 1112 if (inm == null) { 1113 return; 1114 } 1115 1116 ActivityRecord root = (ActivityRecord)msg.obj; 1117 ProcessRecord process = root.app; 1118 if (process == null) { 1119 return; 1120 } 1121 1122 try { 1123 Context context = mContext.createPackageContext(process.info.packageName, 0); 1124 String text = mContext.getString(R.string.heavy_weight_notification, 1125 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1126 Notification notification = new Notification(); 1127 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1128 notification.when = 0; 1129 notification.flags = Notification.FLAG_ONGOING_EVENT; 1130 notification.tickerText = text; 1131 notification.defaults = 0; // please be quiet 1132 notification.sound = null; 1133 notification.vibrate = null; 1134 notification.setLatestEventInfo(context, text, 1135 mContext.getText(R.string.heavy_weight_notification_detail), 1136 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1137 PendingIntent.FLAG_CANCEL_CURRENT, null, 1138 new UserHandle(root.userId))); 1139 1140 try { 1141 int[] outId = new int[1]; 1142 inm.enqueueNotificationWithTag("android", null, 1143 R.string.heavy_weight_notification, 1144 notification, outId, root.userId); 1145 } catch (RuntimeException e) { 1146 Slog.w(ActivityManagerService.TAG, 1147 "Error showing notification for heavy-weight app", e); 1148 } catch (RemoteException e) { 1149 } 1150 } catch (NameNotFoundException e) { 1151 Slog.w(TAG, "Unable to create context for heavy notification", e); 1152 } 1153 } break; 1154 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1155 INotificationManager inm = NotificationManager.getService(); 1156 if (inm == null) { 1157 return; 1158 } 1159 try { 1160 inm.cancelNotificationWithTag("android", null, 1161 R.string.heavy_weight_notification, msg.arg1); 1162 } catch (RuntimeException e) { 1163 Slog.w(ActivityManagerService.TAG, 1164 "Error canceling notification for service", e); 1165 } catch (RemoteException e) { 1166 } 1167 } break; 1168 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1169 synchronized (ActivityManagerService.this) { 1170 checkExcessivePowerUsageLocked(true); 1171 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1172 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1173 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1174 } 1175 } break; 1176 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1177 synchronized (ActivityManagerService.this) { 1178 ActivityRecord ar = (ActivityRecord)msg.obj; 1179 if (mCompatModeDialog != null) { 1180 if (mCompatModeDialog.mAppInfo.packageName.equals( 1181 ar.info.applicationInfo.packageName)) { 1182 return; 1183 } 1184 mCompatModeDialog.dismiss(); 1185 mCompatModeDialog = null; 1186 } 1187 if (ar != null && false) { 1188 if (mCompatModePackages.getPackageAskCompatModeLocked( 1189 ar.packageName)) { 1190 int mode = mCompatModePackages.computeCompatModeLocked( 1191 ar.info.applicationInfo); 1192 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1193 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1194 mCompatModeDialog = new CompatModeDialog( 1195 ActivityManagerService.this, mContext, 1196 ar.info.applicationInfo); 1197 mCompatModeDialog.show(); 1198 } 1199 } 1200 } 1201 } 1202 break; 1203 } 1204 case DISPATCH_PROCESSES_CHANGED: { 1205 dispatchProcessesChanged(); 1206 break; 1207 } 1208 case DISPATCH_PROCESS_DIED: { 1209 final int pid = msg.arg1; 1210 final int uid = msg.arg2; 1211 dispatchProcessDied(pid, uid); 1212 break; 1213 } 1214 case REPORT_MEM_USAGE: { 1215 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1216 if (!isDebuggable) { 1217 return; 1218 } 1219 synchronized (ActivityManagerService.this) { 1220 long now = SystemClock.uptimeMillis(); 1221 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1222 // Don't report more than every 5 minutes to somewhat 1223 // avoid spamming. 1224 return; 1225 } 1226 mLastMemUsageReportTime = now; 1227 } 1228 Thread thread = new Thread() { 1229 @Override public void run() { 1230 StringBuilder dropBuilder = new StringBuilder(1024); 1231 StringBuilder logBuilder = new StringBuilder(1024); 1232 StringWriter oomSw = new StringWriter(); 1233 PrintWriter oomPw = new PrintWriter(oomSw); 1234 StringWriter catSw = new StringWriter(); 1235 PrintWriter catPw = new PrintWriter(catSw); 1236 String[] emptyArgs = new String[] { }; 1237 StringBuilder tag = new StringBuilder(128); 1238 StringBuilder stack = new StringBuilder(128); 1239 tag.append("Low on memory -- "); 1240 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1241 tag, stack); 1242 dropBuilder.append(stack); 1243 dropBuilder.append('\n'); 1244 dropBuilder.append('\n'); 1245 String oomString = oomSw.toString(); 1246 dropBuilder.append(oomString); 1247 dropBuilder.append('\n'); 1248 logBuilder.append(oomString); 1249 try { 1250 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1251 "procrank", }); 1252 final InputStreamReader converter = new InputStreamReader( 1253 proc.getInputStream()); 1254 BufferedReader in = new BufferedReader(converter); 1255 String line; 1256 while (true) { 1257 line = in.readLine(); 1258 if (line == null) { 1259 break; 1260 } 1261 if (line.length() > 0) { 1262 logBuilder.append(line); 1263 logBuilder.append('\n'); 1264 } 1265 dropBuilder.append(line); 1266 dropBuilder.append('\n'); 1267 } 1268 converter.close(); 1269 } catch (IOException e) { 1270 } 1271 synchronized (ActivityManagerService.this) { 1272 catPw.println(); 1273 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1274 catPw.println(); 1275 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1276 false, false, null); 1277 catPw.println(); 1278 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1279 } 1280 dropBuilder.append(catSw.toString()); 1281 addErrorToDropBox("lowmem", null, "system_server", null, 1282 null, tag.toString(), dropBuilder.toString(), null, null); 1283 Slog.i(TAG, logBuilder.toString()); 1284 synchronized (ActivityManagerService.this) { 1285 long now = SystemClock.uptimeMillis(); 1286 if (mLastMemUsageReportTime < now) { 1287 mLastMemUsageReportTime = now; 1288 } 1289 } 1290 } 1291 }; 1292 thread.start(); 1293 break; 1294 } 1295 } 1296 } 1297 }; 1298 1299 public static void setSystemProcess() { 1300 try { 1301 ActivityManagerService m = mSelf; 1302 1303 ServiceManager.addService("activity", m, true); 1304 ServiceManager.addService("meminfo", new MemBinder(m)); 1305 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1306 ServiceManager.addService("dbinfo", new DbBinder(m)); 1307 if (MONITOR_CPU_USAGE) { 1308 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1309 } 1310 ServiceManager.addService("permission", new PermissionController(m)); 1311 1312 ApplicationInfo info = 1313 mSelf.mContext.getPackageManager().getApplicationInfo( 1314 "android", STOCK_PM_FLAGS); 1315 mSystemThread.installSystemApplicationInfo(info); 1316 1317 synchronized (mSelf) { 1318 ProcessRecord app = mSelf.newProcessRecordLocked( 1319 mSystemThread.getApplicationThread(), info, 1320 info.processName, false); 1321 app.persistent = true; 1322 app.pid = MY_PID; 1323 app.maxAdj = ProcessList.SYSTEM_ADJ; 1324 mSelf.mProcessNames.put(app.processName, app.uid, app); 1325 synchronized (mSelf.mPidsSelfLocked) { 1326 mSelf.mPidsSelfLocked.put(app.pid, app); 1327 } 1328 mSelf.updateLruProcessLocked(app, true, true); 1329 } 1330 } catch (PackageManager.NameNotFoundException e) { 1331 throw new RuntimeException( 1332 "Unable to find android system package", e); 1333 } 1334 } 1335 1336 public void setWindowManager(WindowManagerService wm) { 1337 mWindowManager = wm; 1338 } 1339 1340 public static final Context main(int factoryTest) { 1341 AThread thr = new AThread(); 1342 thr.start(); 1343 1344 synchronized (thr) { 1345 while (thr.mService == null) { 1346 try { 1347 thr.wait(); 1348 } catch (InterruptedException e) { 1349 } 1350 } 1351 } 1352 1353 ActivityManagerService m = thr.mService; 1354 mSelf = m; 1355 ActivityThread at = ActivityThread.systemMain(); 1356 mSystemThread = at; 1357 Context context = at.getSystemContext(); 1358 context.setTheme(android.R.style.Theme_Holo); 1359 m.mContext = context; 1360 m.mFactoryTest = factoryTest; 1361 m.mMainStack = new ActivityStack(m, context, true); 1362 1363 m.mBatteryStatsService.publish(context); 1364 m.mUsageStatsService.publish(context); 1365 1366 synchronized (thr) { 1367 thr.mReady = true; 1368 thr.notifyAll(); 1369 } 1370 1371 m.startRunning(null, null, null, null); 1372 1373 return context; 1374 } 1375 1376 public static ActivityManagerService self() { 1377 return mSelf; 1378 } 1379 1380 static class AThread extends Thread { 1381 ActivityManagerService mService; 1382 boolean mReady = false; 1383 1384 public AThread() { 1385 super("ActivityManager"); 1386 } 1387 1388 public void run() { 1389 Looper.prepare(); 1390 1391 android.os.Process.setThreadPriority( 1392 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1393 android.os.Process.setCanSelfBackground(false); 1394 1395 ActivityManagerService m = new ActivityManagerService(); 1396 1397 synchronized (this) { 1398 mService = m; 1399 notifyAll(); 1400 } 1401 1402 synchronized (this) { 1403 while (!mReady) { 1404 try { 1405 wait(); 1406 } catch (InterruptedException e) { 1407 } 1408 } 1409 } 1410 1411 // For debug builds, log event loop stalls to dropbox for analysis. 1412 if (StrictMode.conditionallyEnableDebugLogging()) { 1413 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1414 } 1415 1416 Looper.loop(); 1417 } 1418 } 1419 1420 static class MemBinder extends Binder { 1421 ActivityManagerService mActivityManagerService; 1422 MemBinder(ActivityManagerService activityManagerService) { 1423 mActivityManagerService = activityManagerService; 1424 } 1425 1426 @Override 1427 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1428 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1429 != PackageManager.PERMISSION_GRANTED) { 1430 pw.println("Permission Denial: can't dump meminfo from from pid=" 1431 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1432 + " without permission " + android.Manifest.permission.DUMP); 1433 return; 1434 } 1435 1436 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1437 false, null, null, null); 1438 } 1439 } 1440 1441 static class GraphicsBinder extends Binder { 1442 ActivityManagerService mActivityManagerService; 1443 GraphicsBinder(ActivityManagerService activityManagerService) { 1444 mActivityManagerService = activityManagerService; 1445 } 1446 1447 @Override 1448 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1449 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1450 != PackageManager.PERMISSION_GRANTED) { 1451 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1452 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1453 + " without permission " + android.Manifest.permission.DUMP); 1454 return; 1455 } 1456 1457 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1458 } 1459 } 1460 1461 static class DbBinder extends Binder { 1462 ActivityManagerService mActivityManagerService; 1463 DbBinder(ActivityManagerService activityManagerService) { 1464 mActivityManagerService = activityManagerService; 1465 } 1466 1467 @Override 1468 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1469 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1470 != PackageManager.PERMISSION_GRANTED) { 1471 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1472 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1473 + " without permission " + android.Manifest.permission.DUMP); 1474 return; 1475 } 1476 1477 mActivityManagerService.dumpDbInfo(fd, pw, args); 1478 } 1479 } 1480 1481 static class CpuBinder extends Binder { 1482 ActivityManagerService mActivityManagerService; 1483 CpuBinder(ActivityManagerService activityManagerService) { 1484 mActivityManagerService = activityManagerService; 1485 } 1486 1487 @Override 1488 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1489 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1490 != PackageManager.PERMISSION_GRANTED) { 1491 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1492 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1493 + " without permission " + android.Manifest.permission.DUMP); 1494 return; 1495 } 1496 1497 synchronized (mActivityManagerService.mProcessStatsThread) { 1498 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1499 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1500 SystemClock.uptimeMillis())); 1501 } 1502 } 1503 } 1504 1505 private ActivityManagerService() { 1506 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1507 1508 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1509 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1510 mBroadcastQueues[0] = mFgBroadcastQueue; 1511 mBroadcastQueues[1] = mBgBroadcastQueue; 1512 1513 mServices = new ActiveServices(this); 1514 1515 File dataDir = Environment.getDataDirectory(); 1516 File systemDir = new File(dataDir, "system"); 1517 systemDir.mkdirs(); 1518 mBatteryStatsService = new BatteryStatsService(new File( 1519 systemDir, "batterystats.bin").toString()); 1520 mBatteryStatsService.getActiveStatistics().readLocked(); 1521 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1522 mOnBattery = DEBUG_POWER ? true 1523 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1524 mBatteryStatsService.getActiveStatistics().setCallback(this); 1525 1526 mUsageStatsService = new UsageStatsService(new File( 1527 systemDir, "usagestats").toString()); 1528 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1529 1530 // User 0 is the first and only user that runs at boot. 1531 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1532 mUserLru.add(Integer.valueOf(0)); 1533 1534 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1535 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1536 1537 mConfiguration.setToDefaults(); 1538 mConfiguration.setLocale(Locale.getDefault()); 1539 1540 mConfigurationSeq = mConfiguration.seq = 1; 1541 mProcessStats.init(); 1542 1543 mCompatModePackages = new CompatModePackages(this, systemDir); 1544 1545 // Add ourself to the Watchdog monitors. 1546 Watchdog.getInstance().addMonitor(this); 1547 1548 mProcessStatsThread = new Thread("ProcessStats") { 1549 public void run() { 1550 while (true) { 1551 try { 1552 try { 1553 synchronized(this) { 1554 final long now = SystemClock.uptimeMillis(); 1555 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1556 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1557 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1558 // + ", write delay=" + nextWriteDelay); 1559 if (nextWriteDelay < nextCpuDelay) { 1560 nextCpuDelay = nextWriteDelay; 1561 } 1562 if (nextCpuDelay > 0) { 1563 mProcessStatsMutexFree.set(true); 1564 this.wait(nextCpuDelay); 1565 } 1566 } 1567 } catch (InterruptedException e) { 1568 } 1569 updateCpuStatsNow(); 1570 } catch (Exception e) { 1571 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1572 } 1573 } 1574 } 1575 }; 1576 mProcessStatsThread.start(); 1577 } 1578 1579 @Override 1580 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1581 throws RemoteException { 1582 if (code == SYSPROPS_TRANSACTION) { 1583 // We need to tell all apps about the system property change. 1584 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1585 synchronized(this) { 1586 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1587 final int NA = apps.size(); 1588 for (int ia=0; ia<NA; ia++) { 1589 ProcessRecord app = apps.valueAt(ia); 1590 if (app.thread != null) { 1591 procs.add(app.thread.asBinder()); 1592 } 1593 } 1594 } 1595 } 1596 1597 int N = procs.size(); 1598 for (int i=0; i<N; i++) { 1599 Parcel data2 = Parcel.obtain(); 1600 try { 1601 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1602 } catch (RemoteException e) { 1603 } 1604 data2.recycle(); 1605 } 1606 } 1607 try { 1608 return super.onTransact(code, data, reply, flags); 1609 } catch (RuntimeException e) { 1610 // The activity manager only throws security exceptions, so let's 1611 // log all others. 1612 if (!(e instanceof SecurityException)) { 1613 Slog.e(TAG, "Activity Manager Crash", e); 1614 } 1615 throw e; 1616 } 1617 } 1618 1619 void updateCpuStats() { 1620 final long now = SystemClock.uptimeMillis(); 1621 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1622 return; 1623 } 1624 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1625 synchronized (mProcessStatsThread) { 1626 mProcessStatsThread.notify(); 1627 } 1628 } 1629 } 1630 1631 void updateCpuStatsNow() { 1632 synchronized (mProcessStatsThread) { 1633 mProcessStatsMutexFree.set(false); 1634 final long now = SystemClock.uptimeMillis(); 1635 boolean haveNewCpuStats = false; 1636 1637 if (MONITOR_CPU_USAGE && 1638 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1639 mLastCpuTime.set(now); 1640 haveNewCpuStats = true; 1641 mProcessStats.update(); 1642 //Slog.i(TAG, mProcessStats.printCurrentState()); 1643 //Slog.i(TAG, "Total CPU usage: " 1644 // + mProcessStats.getTotalCpuPercent() + "%"); 1645 1646 // Slog the cpu usage if the property is set. 1647 if ("true".equals(SystemProperties.get("events.cpu"))) { 1648 int user = mProcessStats.getLastUserTime(); 1649 int system = mProcessStats.getLastSystemTime(); 1650 int iowait = mProcessStats.getLastIoWaitTime(); 1651 int irq = mProcessStats.getLastIrqTime(); 1652 int softIrq = mProcessStats.getLastSoftIrqTime(); 1653 int idle = mProcessStats.getLastIdleTime(); 1654 1655 int total = user + system + iowait + irq + softIrq + idle; 1656 if (total == 0) total = 1; 1657 1658 EventLog.writeEvent(EventLogTags.CPU, 1659 ((user+system+iowait+irq+softIrq) * 100) / total, 1660 (user * 100) / total, 1661 (system * 100) / total, 1662 (iowait * 100) / total, 1663 (irq * 100) / total, 1664 (softIrq * 100) / total); 1665 } 1666 } 1667 1668 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1669 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1670 synchronized(bstats) { 1671 synchronized(mPidsSelfLocked) { 1672 if (haveNewCpuStats) { 1673 if (mOnBattery) { 1674 int perc = bstats.startAddingCpuLocked(); 1675 int totalUTime = 0; 1676 int totalSTime = 0; 1677 final int N = mProcessStats.countStats(); 1678 for (int i=0; i<N; i++) { 1679 ProcessStats.Stats st = mProcessStats.getStats(i); 1680 if (!st.working) { 1681 continue; 1682 } 1683 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1684 int otherUTime = (st.rel_utime*perc)/100; 1685 int otherSTime = (st.rel_stime*perc)/100; 1686 totalUTime += otherUTime; 1687 totalSTime += otherSTime; 1688 if (pr != null) { 1689 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1690 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1691 st.rel_stime-otherSTime); 1692 ps.addSpeedStepTimes(cpuSpeedTimes); 1693 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1694 } else { 1695 BatteryStatsImpl.Uid.Proc ps = 1696 bstats.getProcessStatsLocked(st.name, st.pid); 1697 if (ps != null) { 1698 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1699 st.rel_stime-otherSTime); 1700 ps.addSpeedStepTimes(cpuSpeedTimes); 1701 } 1702 } 1703 } 1704 bstats.finishAddingCpuLocked(perc, totalUTime, 1705 totalSTime, cpuSpeedTimes); 1706 } 1707 } 1708 } 1709 1710 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1711 mLastWriteTime = now; 1712 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1713 } 1714 } 1715 } 1716 } 1717 1718 @Override 1719 public void batteryNeedsCpuUpdate() { 1720 updateCpuStatsNow(); 1721 } 1722 1723 @Override 1724 public void batteryPowerChanged(boolean onBattery) { 1725 // When plugging in, update the CPU stats first before changing 1726 // the plug state. 1727 updateCpuStatsNow(); 1728 synchronized (this) { 1729 synchronized(mPidsSelfLocked) { 1730 mOnBattery = DEBUG_POWER ? true : onBattery; 1731 } 1732 } 1733 } 1734 1735 /** 1736 * Initialize the application bind args. These are passed to each 1737 * process when the bindApplication() IPC is sent to the process. They're 1738 * lazily setup to make sure the services are running when they're asked for. 1739 */ 1740 private HashMap<String, IBinder> getCommonServicesLocked() { 1741 if (mAppBindArgs == null) { 1742 mAppBindArgs = new HashMap<String, IBinder>(); 1743 1744 // Setup the application init args 1745 mAppBindArgs.put("package", ServiceManager.getService("package")); 1746 mAppBindArgs.put("window", ServiceManager.getService("window")); 1747 mAppBindArgs.put(Context.ALARM_SERVICE, 1748 ServiceManager.getService(Context.ALARM_SERVICE)); 1749 } 1750 return mAppBindArgs; 1751 } 1752 1753 final void setFocusedActivityLocked(ActivityRecord r) { 1754 if (mFocusedActivity != r) { 1755 mFocusedActivity = r; 1756 if (r != null) { 1757 mWindowManager.setFocusedApp(r.appToken, true); 1758 } 1759 } 1760 } 1761 1762 private final void updateLruProcessInternalLocked(ProcessRecord app, 1763 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1764 // put it on the LRU to keep track of when it should be exited. 1765 int lrui = mLruProcesses.indexOf(app); 1766 if (lrui >= 0) mLruProcesses.remove(lrui); 1767 1768 int i = mLruProcesses.size()-1; 1769 int skipTop = 0; 1770 1771 app.lruSeq = mLruSeq; 1772 1773 // compute the new weight for this process. 1774 if (updateActivityTime) { 1775 app.lastActivityTime = SystemClock.uptimeMillis(); 1776 } 1777 if (app.activities.size() > 0) { 1778 // If this process has activities, we more strongly want to keep 1779 // it around. 1780 app.lruWeight = app.lastActivityTime; 1781 } else if (app.pubProviders.size() > 0) { 1782 // If this process contains content providers, we want to keep 1783 // it a little more strongly. 1784 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1785 // Also don't let it kick out the first few "real" hidden processes. 1786 skipTop = ProcessList.MIN_HIDDEN_APPS; 1787 } else { 1788 // If this process doesn't have activities, we less strongly 1789 // want to keep it around, and generally want to avoid getting 1790 // in front of any very recently used activities. 1791 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1792 // Also don't let it kick out the first few "real" hidden processes. 1793 skipTop = ProcessList.MIN_HIDDEN_APPS; 1794 } 1795 1796 while (i >= 0) { 1797 ProcessRecord p = mLruProcesses.get(i); 1798 // If this app shouldn't be in front of the first N background 1799 // apps, then skip over that many that are currently hidden. 1800 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1801 skipTop--; 1802 } 1803 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1804 mLruProcesses.add(i+1, app); 1805 break; 1806 } 1807 i--; 1808 } 1809 if (i < 0) { 1810 mLruProcesses.add(0, app); 1811 } 1812 1813 // If the app is currently using a content provider or service, 1814 // bump those processes as well. 1815 if (app.connections.size() > 0) { 1816 for (ConnectionRecord cr : app.connections) { 1817 if (cr.binding != null && cr.binding.service != null 1818 && cr.binding.service.app != null 1819 && cr.binding.service.app.lruSeq != mLruSeq) { 1820 updateLruProcessInternalLocked(cr.binding.service.app, false, 1821 updateActivityTime, i+1); 1822 } 1823 } 1824 } 1825 for (int j=app.conProviders.size()-1; j>=0; j--) { 1826 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1827 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1828 updateLruProcessInternalLocked(cpr.proc, false, 1829 updateActivityTime, i+1); 1830 } 1831 } 1832 1833 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1834 if (oomAdj) { 1835 updateOomAdjLocked(); 1836 } 1837 } 1838 1839 final void updateLruProcessLocked(ProcessRecord app, 1840 boolean oomAdj, boolean updateActivityTime) { 1841 mLruSeq++; 1842 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1843 } 1844 1845 final ProcessRecord getProcessRecordLocked( 1846 String processName, int uid) { 1847 if (uid == Process.SYSTEM_UID) { 1848 // The system gets to run in any process. If there are multiple 1849 // processes with the same uid, just pick the first (this 1850 // should never happen). 1851 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1852 processName); 1853 if (procs == null) return null; 1854 final int N = procs.size(); 1855 for (int i = 0; i < N; i++) { 1856 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1857 } 1858 } 1859 ProcessRecord proc = mProcessNames.get(processName, uid); 1860 return proc; 1861 } 1862 1863 void ensurePackageDexOpt(String packageName) { 1864 IPackageManager pm = AppGlobals.getPackageManager(); 1865 try { 1866 if (pm.performDexOpt(packageName)) { 1867 mDidDexOpt = true; 1868 } 1869 } catch (RemoteException e) { 1870 } 1871 } 1872 1873 boolean isNextTransitionForward() { 1874 int transit = mWindowManager.getPendingAppTransition(); 1875 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1876 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1877 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1878 } 1879 1880 final ProcessRecord startProcessLocked(String processName, 1881 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1882 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1883 boolean isolated) { 1884 ProcessRecord app; 1885 if (!isolated) { 1886 app = getProcessRecordLocked(processName, info.uid); 1887 } else { 1888 // If this is an isolated process, it can't re-use an existing process. 1889 app = null; 1890 } 1891 // We don't have to do anything more if: 1892 // (1) There is an existing application record; and 1893 // (2) The caller doesn't think it is dead, OR there is no thread 1894 // object attached to it so we know it couldn't have crashed; and 1895 // (3) There is a pid assigned to it, so it is either starting or 1896 // already running. 1897 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1898 + " app=" + app + " knownToBeDead=" + knownToBeDead 1899 + " thread=" + (app != null ? app.thread : null) 1900 + " pid=" + (app != null ? app.pid : -1)); 1901 if (app != null && app.pid > 0) { 1902 if (!knownToBeDead || app.thread == null) { 1903 // We already have the app running, or are waiting for it to 1904 // come up (we have a pid but not yet its thread), so keep it. 1905 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1906 // If this is a new package in the process, add the package to the list 1907 app.addPackage(info.packageName); 1908 return app; 1909 } else { 1910 // An application record is attached to a previous process, 1911 // clean it up now. 1912 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1913 handleAppDiedLocked(app, true, true); 1914 } 1915 } 1916 1917 String hostingNameStr = hostingName != null 1918 ? hostingName.flattenToShortString() : null; 1919 1920 if (!isolated) { 1921 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1922 // If we are in the background, then check to see if this process 1923 // is bad. If so, we will just silently fail. 1924 if (mBadProcesses.get(info.processName, info.uid) != null) { 1925 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1926 + "/" + info.processName); 1927 return null; 1928 } 1929 } else { 1930 // When the user is explicitly starting a process, then clear its 1931 // crash count so that we won't make it bad until they see at 1932 // least one crash dialog again, and make the process good again 1933 // if it had been bad. 1934 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1935 + "/" + info.processName); 1936 mProcessCrashTimes.remove(info.processName, info.uid); 1937 if (mBadProcesses.get(info.processName, info.uid) != null) { 1938 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1939 info.processName); 1940 mBadProcesses.remove(info.processName, info.uid); 1941 if (app != null) { 1942 app.bad = false; 1943 } 1944 } 1945 } 1946 } 1947 1948 if (app == null) { 1949 app = newProcessRecordLocked(null, info, processName, isolated); 1950 if (app == null) { 1951 Slog.w(TAG, "Failed making new process record for " 1952 + processName + "/" + info.uid + " isolated=" + isolated); 1953 return null; 1954 } 1955 mProcessNames.put(processName, app.uid, app); 1956 if (isolated) { 1957 mIsolatedProcesses.put(app.uid, app); 1958 } 1959 } else { 1960 // If this is a new package in the process, add the package to the list 1961 app.addPackage(info.packageName); 1962 } 1963 1964 // If the system is not ready yet, then hold off on starting this 1965 // process until it is. 1966 if (!mProcessesReady 1967 && !isAllowedWhileBooting(info) 1968 && !allowWhileBooting) { 1969 if (!mProcessesOnHold.contains(app)) { 1970 mProcessesOnHold.add(app); 1971 } 1972 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1973 return app; 1974 } 1975 1976 startProcessLocked(app, hostingType, hostingNameStr); 1977 return (app.pid != 0) ? app : null; 1978 } 1979 1980 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1981 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1982 } 1983 1984 private final void startProcessLocked(ProcessRecord app, 1985 String hostingType, String hostingNameStr) { 1986 if (app.pid > 0 && app.pid != MY_PID) { 1987 synchronized (mPidsSelfLocked) { 1988 mPidsSelfLocked.remove(app.pid); 1989 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1990 } 1991 app.setPid(0); 1992 } 1993 1994 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1995 "startProcessLocked removing on hold: " + app); 1996 mProcessesOnHold.remove(app); 1997 1998 updateCpuStats(); 1999 2000 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2001 mProcDeaths[0] = 0; 2002 2003 try { 2004 int uid = app.uid; 2005 2006 int[] gids = null; 2007 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2008 if (!app.isolated) { 2009 try { 2010 final PackageManager pm = mContext.getPackageManager(); 2011 gids = pm.getPackageGids(app.info.packageName); 2012 2013 if (Environment.isExternalStorageEmulated()) { 2014 if (pm.checkPermission( 2015 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2016 app.info.packageName) == PERMISSION_GRANTED) { 2017 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2018 } else { 2019 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2020 } 2021 } 2022 } catch (PackageManager.NameNotFoundException e) { 2023 Slog.w(TAG, "Unable to retrieve gids", e); 2024 } 2025 } 2026 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2027 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2028 && mTopComponent != null 2029 && app.processName.equals(mTopComponent.getPackageName())) { 2030 uid = 0; 2031 } 2032 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2033 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2034 uid = 0; 2035 } 2036 } 2037 int debugFlags = 0; 2038 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2039 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2040 // Also turn on CheckJNI for debuggable apps. It's quite 2041 // awkward to turn on otherwise. 2042 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2043 } 2044 // Run the app in safe mode if its manifest requests so or the 2045 // system is booted in safe mode. 2046 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2047 Zygote.systemInSafeMode == true) { 2048 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2049 } 2050 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2051 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2052 } 2053 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2054 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2055 } 2056 if ("1".equals(SystemProperties.get("debug.assert"))) { 2057 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2058 } 2059 2060 // Start the process. It will either succeed and return a result containing 2061 // the PID of the new process, or else throw a RuntimeException. 2062 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2063 app.processName, uid, uid, gids, debugFlags, mountExternal, 2064 app.info.targetSdkVersion, null, null); 2065 2066 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2067 synchronized (bs) { 2068 if (bs.isOnBattery()) { 2069 app.batteryStats.incStartsLocked(); 2070 } 2071 } 2072 2073 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2074 app.processName, hostingType, 2075 hostingNameStr != null ? hostingNameStr : ""); 2076 2077 if (app.persistent) { 2078 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2079 } 2080 2081 StringBuilder buf = mStringBuilder; 2082 buf.setLength(0); 2083 buf.append("Start proc "); 2084 buf.append(app.processName); 2085 buf.append(" for "); 2086 buf.append(hostingType); 2087 if (hostingNameStr != null) { 2088 buf.append(" "); 2089 buf.append(hostingNameStr); 2090 } 2091 buf.append(": pid="); 2092 buf.append(startResult.pid); 2093 buf.append(" uid="); 2094 buf.append(uid); 2095 buf.append(" gids={"); 2096 if (gids != null) { 2097 for (int gi=0; gi<gids.length; gi++) { 2098 if (gi != 0) buf.append(", "); 2099 buf.append(gids[gi]); 2100 2101 } 2102 } 2103 buf.append("}"); 2104 Slog.i(TAG, buf.toString()); 2105 app.setPid(startResult.pid); 2106 app.usingWrapper = startResult.usingWrapper; 2107 app.removed = false; 2108 synchronized (mPidsSelfLocked) { 2109 this.mPidsSelfLocked.put(startResult.pid, app); 2110 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2111 msg.obj = app; 2112 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2113 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2114 } 2115 } catch (RuntimeException e) { 2116 // XXX do better error recovery. 2117 app.setPid(0); 2118 Slog.e(TAG, "Failure starting process " + app.processName, e); 2119 } 2120 } 2121 2122 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2123 if (resumed) { 2124 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2125 } else { 2126 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2127 } 2128 } 2129 2130 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2131 if (mHeadless) { 2132 // Added because none of the other calls to ensureBootCompleted seem to fire 2133 // when running headless. 2134 ensureBootCompleted(); 2135 return false; 2136 } 2137 2138 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2139 && mTopAction == null) { 2140 // We are running in factory test mode, but unable to find 2141 // the factory test app, so just sit around displaying the 2142 // error message and don't try to start anything. 2143 return false; 2144 } 2145 Intent intent = new Intent( 2146 mTopAction, 2147 mTopData != null ? Uri.parse(mTopData) : null); 2148 intent.setComponent(mTopComponent); 2149 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2150 intent.addCategory(Intent.CATEGORY_HOME); 2151 } 2152 ActivityInfo aInfo = 2153 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2154 if (aInfo != null) { 2155 intent.setComponent(new ComponentName( 2156 aInfo.applicationInfo.packageName, aInfo.name)); 2157 // Don't do this if the home app is currently being 2158 // instrumented. 2159 aInfo = new ActivityInfo(aInfo); 2160 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2161 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2162 aInfo.applicationInfo.uid); 2163 if (app == null || app.instrumentationClass == null) { 2164 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2165 mMainStack.startActivityLocked(null, intent, null, aInfo, 2166 null, null, 0, 0, 0, 0, null, false, null); 2167 } 2168 } 2169 if (startingUser != null) { 2170 mMainStack.addStartingUserLocked(startingUser); 2171 } 2172 2173 return true; 2174 } 2175 2176 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2177 ActivityInfo ai = null; 2178 ComponentName comp = intent.getComponent(); 2179 try { 2180 if (comp != null) { 2181 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2182 } else { 2183 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2184 intent, 2185 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2186 flags, userId); 2187 2188 if (info != null) { 2189 ai = info.activityInfo; 2190 } 2191 } 2192 } catch (RemoteException e) { 2193 // ignore 2194 } 2195 2196 return ai; 2197 } 2198 2199 /** 2200 * Starts the "new version setup screen" if appropriate. 2201 */ 2202 void startSetupActivityLocked() { 2203 // Only do this once per boot. 2204 if (mCheckedForSetup) { 2205 return; 2206 } 2207 2208 // We will show this screen if the current one is a different 2209 // version than the last one shown, and we are not running in 2210 // low-level factory test mode. 2211 final ContentResolver resolver = mContext.getContentResolver(); 2212 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2213 Settings.Secure.getInt(resolver, 2214 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2215 mCheckedForSetup = true; 2216 2217 // See if we should be showing the platform update setup UI. 2218 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2219 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2220 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2221 2222 // We don't allow third party apps to replace this. 2223 ResolveInfo ri = null; 2224 for (int i=0; ris != null && i<ris.size(); i++) { 2225 if ((ris.get(i).activityInfo.applicationInfo.flags 2226 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2227 ri = ris.get(i); 2228 break; 2229 } 2230 } 2231 2232 if (ri != null) { 2233 String vers = ri.activityInfo.metaData != null 2234 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2235 : null; 2236 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2237 vers = ri.activityInfo.applicationInfo.metaData.getString( 2238 Intent.METADATA_SETUP_VERSION); 2239 } 2240 String lastVers = Settings.Secure.getString( 2241 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2242 if (vers != null && !vers.equals(lastVers)) { 2243 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2244 intent.setComponent(new ComponentName( 2245 ri.activityInfo.packageName, ri.activityInfo.name)); 2246 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2247 null, null, 0, 0, 0, 0, null, false, null); 2248 } 2249 } 2250 } 2251 } 2252 2253 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2254 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2255 } 2256 2257 void enforceNotIsolatedCaller(String caller) { 2258 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2259 throw new SecurityException("Isolated process not allowed to call " + caller); 2260 } 2261 } 2262 2263 public int getFrontActivityScreenCompatMode() { 2264 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2265 synchronized (this) { 2266 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2267 } 2268 } 2269 2270 public void setFrontActivityScreenCompatMode(int mode) { 2271 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2272 "setFrontActivityScreenCompatMode"); 2273 synchronized (this) { 2274 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2275 } 2276 } 2277 2278 public int getPackageScreenCompatMode(String packageName) { 2279 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2280 synchronized (this) { 2281 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2282 } 2283 } 2284 2285 public void setPackageScreenCompatMode(String packageName, int mode) { 2286 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2287 "setPackageScreenCompatMode"); 2288 synchronized (this) { 2289 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2290 } 2291 } 2292 2293 public boolean getPackageAskScreenCompat(String packageName) { 2294 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2295 synchronized (this) { 2296 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2297 } 2298 } 2299 2300 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2301 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2302 "setPackageAskScreenCompat"); 2303 synchronized (this) { 2304 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2305 } 2306 } 2307 2308 void reportResumedActivityLocked(ActivityRecord r) { 2309 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2310 updateUsageStats(r, true); 2311 } 2312 2313 private void dispatchProcessesChanged() { 2314 int N; 2315 synchronized (this) { 2316 N = mPendingProcessChanges.size(); 2317 if (mActiveProcessChanges.length < N) { 2318 mActiveProcessChanges = new ProcessChangeItem[N]; 2319 } 2320 mPendingProcessChanges.toArray(mActiveProcessChanges); 2321 mAvailProcessChanges.addAll(mPendingProcessChanges); 2322 mPendingProcessChanges.clear(); 2323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2324 } 2325 int i = mProcessObservers.beginBroadcast(); 2326 while (i > 0) { 2327 i--; 2328 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2329 if (observer != null) { 2330 try { 2331 for (int j=0; j<N; j++) { 2332 ProcessChangeItem item = mActiveProcessChanges[j]; 2333 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2334 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2335 + item.pid + " uid=" + item.uid + ": " 2336 + item.foregroundActivities); 2337 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2338 item.foregroundActivities); 2339 } 2340 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2341 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2342 + item.pid + " uid=" + item.uid + ": " + item.importance); 2343 observer.onImportanceChanged(item.pid, item.uid, 2344 item.importance); 2345 } 2346 } 2347 } catch (RemoteException e) { 2348 } 2349 } 2350 } 2351 mProcessObservers.finishBroadcast(); 2352 } 2353 2354 private void dispatchProcessDied(int pid, int uid) { 2355 int i = mProcessObservers.beginBroadcast(); 2356 while (i > 0) { 2357 i--; 2358 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2359 if (observer != null) { 2360 try { 2361 observer.onProcessDied(pid, uid); 2362 } catch (RemoteException e) { 2363 } 2364 } 2365 } 2366 mProcessObservers.finishBroadcast(); 2367 } 2368 2369 final void doPendingActivityLaunchesLocked(boolean doResume) { 2370 final int N = mPendingActivityLaunches.size(); 2371 if (N <= 0) { 2372 return; 2373 } 2374 for (int i=0; i<N; i++) { 2375 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2376 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2377 pal.startFlags, doResume && i == (N-1), null); 2378 } 2379 mPendingActivityLaunches.clear(); 2380 } 2381 2382 public final int startActivity(IApplicationThread caller, 2383 Intent intent, String resolvedType, IBinder resultTo, 2384 String resultWho, int requestCode, int startFlags, 2385 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2386 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2387 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2388 } 2389 2390 public final int startActivityAsUser(IApplicationThread caller, 2391 Intent intent, String resolvedType, IBinder resultTo, 2392 String resultWho, int requestCode, int startFlags, 2393 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2394 enforceNotIsolatedCaller("startActivity"); 2395 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2396 false, true, "startActivity", null); 2397 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2398 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2399 null, null, options, userId); 2400 } 2401 2402 public final WaitResult startActivityAndWait(IApplicationThread caller, 2403 Intent intent, String resolvedType, IBinder resultTo, 2404 String resultWho, int requestCode, int startFlags, String profileFile, 2405 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2406 enforceNotIsolatedCaller("startActivityAndWait"); 2407 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2408 false, true, "startActivityAndWait", null); 2409 WaitResult res = new WaitResult(); 2410 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2411 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2412 res, null, options, UserHandle.getCallingUserId()); 2413 return res; 2414 } 2415 2416 public final int startActivityWithConfig(IApplicationThread caller, 2417 Intent intent, String resolvedType, IBinder resultTo, 2418 String resultWho, int requestCode, int startFlags, Configuration config, 2419 Bundle options, int userId) { 2420 enforceNotIsolatedCaller("startActivityWithConfig"); 2421 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2422 false, true, "startActivityWithConfig", null); 2423 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2424 resultTo, resultWho, requestCode, startFlags, 2425 null, null, null, config, options, userId); 2426 return ret; 2427 } 2428 2429 public int startActivityIntentSender(IApplicationThread caller, 2430 IntentSender intent, Intent fillInIntent, String resolvedType, 2431 IBinder resultTo, String resultWho, int requestCode, 2432 int flagsMask, int flagsValues, Bundle options) { 2433 enforceNotIsolatedCaller("startActivityIntentSender"); 2434 // Refuse possible leaked file descriptors 2435 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2436 throw new IllegalArgumentException("File descriptors passed in Intent"); 2437 } 2438 2439 IIntentSender sender = intent.getTarget(); 2440 if (!(sender instanceof PendingIntentRecord)) { 2441 throw new IllegalArgumentException("Bad PendingIntent object"); 2442 } 2443 2444 PendingIntentRecord pir = (PendingIntentRecord)sender; 2445 2446 synchronized (this) { 2447 // If this is coming from the currently resumed activity, it is 2448 // effectively saying that app switches are allowed at this point. 2449 if (mMainStack.mResumedActivity != null 2450 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2451 Binder.getCallingUid()) { 2452 mAppSwitchesAllowedTime = 0; 2453 } 2454 } 2455 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2456 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2457 return ret; 2458 } 2459 2460 public boolean startNextMatchingActivity(IBinder callingActivity, 2461 Intent intent, Bundle options) { 2462 // Refuse possible leaked file descriptors 2463 if (intent != null && intent.hasFileDescriptors() == true) { 2464 throw new IllegalArgumentException("File descriptors passed in Intent"); 2465 } 2466 2467 synchronized (this) { 2468 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2469 if (r == null) { 2470 ActivityOptions.abort(options); 2471 return false; 2472 } 2473 if (r.app == null || r.app.thread == null) { 2474 // The caller is not running... d'oh! 2475 ActivityOptions.abort(options); 2476 return false; 2477 } 2478 intent = new Intent(intent); 2479 // The caller is not allowed to change the data. 2480 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2481 // And we are resetting to find the next component... 2482 intent.setComponent(null); 2483 2484 ActivityInfo aInfo = null; 2485 try { 2486 List<ResolveInfo> resolves = 2487 AppGlobals.getPackageManager().queryIntentActivities( 2488 intent, r.resolvedType, 2489 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2490 UserHandle.getCallingUserId()); 2491 2492 // Look for the original activity in the list... 2493 final int N = resolves != null ? resolves.size() : 0; 2494 for (int i=0; i<N; i++) { 2495 ResolveInfo rInfo = resolves.get(i); 2496 if (rInfo.activityInfo.packageName.equals(r.packageName) 2497 && rInfo.activityInfo.name.equals(r.info.name)) { 2498 // We found the current one... the next matching is 2499 // after it. 2500 i++; 2501 if (i<N) { 2502 aInfo = resolves.get(i).activityInfo; 2503 } 2504 break; 2505 } 2506 } 2507 } catch (RemoteException e) { 2508 } 2509 2510 if (aInfo == null) { 2511 // Nobody who is next! 2512 ActivityOptions.abort(options); 2513 return false; 2514 } 2515 2516 intent.setComponent(new ComponentName( 2517 aInfo.applicationInfo.packageName, aInfo.name)); 2518 intent.setFlags(intent.getFlags()&~( 2519 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2520 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2521 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2522 Intent.FLAG_ACTIVITY_NEW_TASK)); 2523 2524 // Okay now we need to start the new activity, replacing the 2525 // currently running activity. This is a little tricky because 2526 // we want to start the new one as if the current one is finished, 2527 // but not finish the current one first so that there is no flicker. 2528 // And thus... 2529 final boolean wasFinishing = r.finishing; 2530 r.finishing = true; 2531 2532 // Propagate reply information over to the new activity. 2533 final ActivityRecord resultTo = r.resultTo; 2534 final String resultWho = r.resultWho; 2535 final int requestCode = r.requestCode; 2536 r.resultTo = null; 2537 if (resultTo != null) { 2538 resultTo.removeResultsLocked(r, resultWho, requestCode); 2539 } 2540 2541 final long origId = Binder.clearCallingIdentity(); 2542 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2543 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2544 resultWho, requestCode, -1, r.launchedFromUid, 0, 2545 options, false, null); 2546 Binder.restoreCallingIdentity(origId); 2547 2548 r.finishing = wasFinishing; 2549 if (res != ActivityManager.START_SUCCESS) { 2550 return false; 2551 } 2552 return true; 2553 } 2554 } 2555 2556 final int startActivityInPackage(int uid, 2557 Intent intent, String resolvedType, IBinder resultTo, 2558 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2559 2560 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2561 false, true, "startActivityInPackage", null); 2562 2563 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2564 resultTo, resultWho, requestCode, startFlags, 2565 null, null, null, null, options, userId); 2566 return ret; 2567 } 2568 2569 public final int startActivities(IApplicationThread caller, 2570 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2571 enforceNotIsolatedCaller("startActivities"); 2572 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2573 options, UserHandle.getCallingUserId()); 2574 return ret; 2575 } 2576 2577 final int startActivitiesInPackage(int uid, 2578 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2579 Bundle options, int userId) { 2580 2581 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2582 false, true, "startActivityInPackage", null); 2583 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2584 options, userId); 2585 return ret; 2586 } 2587 2588 final void addRecentTaskLocked(TaskRecord task) { 2589 int N = mRecentTasks.size(); 2590 // Quick case: check if the top-most recent task is the same. 2591 if (N > 0 && mRecentTasks.get(0) == task) { 2592 return; 2593 } 2594 // Remove any existing entries that are the same kind of task. 2595 for (int i=0; i<N; i++) { 2596 TaskRecord tr = mRecentTasks.get(i); 2597 if (task.userId == tr.userId 2598 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2599 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2600 mRecentTasks.remove(i); 2601 i--; 2602 N--; 2603 if (task.intent == null) { 2604 // If the new recent task we are adding is not fully 2605 // specified, then replace it with the existing recent task. 2606 task = tr; 2607 } 2608 } 2609 } 2610 if (N >= MAX_RECENT_TASKS) { 2611 mRecentTasks.remove(N-1); 2612 } 2613 mRecentTasks.add(0, task); 2614 } 2615 2616 public void setRequestedOrientation(IBinder token, 2617 int requestedOrientation) { 2618 synchronized (this) { 2619 ActivityRecord r = mMainStack.isInStackLocked(token); 2620 if (r == null) { 2621 return; 2622 } 2623 final long origId = Binder.clearCallingIdentity(); 2624 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2625 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2626 mConfiguration, 2627 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2628 if (config != null) { 2629 r.frozenBeforeDestroy = true; 2630 if (!updateConfigurationLocked(config, r, false, false)) { 2631 mMainStack.resumeTopActivityLocked(null); 2632 } 2633 } 2634 Binder.restoreCallingIdentity(origId); 2635 } 2636 } 2637 2638 public int getRequestedOrientation(IBinder token) { 2639 synchronized (this) { 2640 ActivityRecord r = mMainStack.isInStackLocked(token); 2641 if (r == null) { 2642 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2643 } 2644 return mWindowManager.getAppOrientation(r.appToken); 2645 } 2646 } 2647 2648 /** 2649 * This is the internal entry point for handling Activity.finish(). 2650 * 2651 * @param token The Binder token referencing the Activity we want to finish. 2652 * @param resultCode Result code, if any, from this Activity. 2653 * @param resultData Result data (Intent), if any, from this Activity. 2654 * 2655 * @return Returns true if the activity successfully finished, or false if it is still running. 2656 */ 2657 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2658 // Refuse possible leaked file descriptors 2659 if (resultData != null && resultData.hasFileDescriptors() == true) { 2660 throw new IllegalArgumentException("File descriptors passed in Intent"); 2661 } 2662 2663 synchronized(this) { 2664 if (mController != null) { 2665 // Find the first activity that is not finishing. 2666 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2667 if (next != null) { 2668 // ask watcher if this is allowed 2669 boolean resumeOK = true; 2670 try { 2671 resumeOK = mController.activityResuming(next.packageName); 2672 } catch (RemoteException e) { 2673 mController = null; 2674 } 2675 2676 if (!resumeOK) { 2677 return false; 2678 } 2679 } 2680 } 2681 final long origId = Binder.clearCallingIdentity(); 2682 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2683 resultData, "app-request"); 2684 Binder.restoreCallingIdentity(origId); 2685 return res; 2686 } 2687 } 2688 2689 public final void finishHeavyWeightApp() { 2690 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2691 != PackageManager.PERMISSION_GRANTED) { 2692 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2693 + Binder.getCallingPid() 2694 + ", uid=" + Binder.getCallingUid() 2695 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2696 Slog.w(TAG, msg); 2697 throw new SecurityException(msg); 2698 } 2699 2700 synchronized(this) { 2701 if (mHeavyWeightProcess == null) { 2702 return; 2703 } 2704 2705 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2706 mHeavyWeightProcess.activities); 2707 for (int i=0; i<activities.size(); i++) { 2708 ActivityRecord r = activities.get(i); 2709 if (!r.finishing) { 2710 int index = mMainStack.indexOfTokenLocked(r.appToken); 2711 if (index >= 0) { 2712 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2713 null, "finish-heavy"); 2714 } 2715 } 2716 } 2717 2718 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2719 mHeavyWeightProcess.userId, 0)); 2720 mHeavyWeightProcess = null; 2721 } 2722 } 2723 2724 public void crashApplication(int uid, int initialPid, String packageName, 2725 String message) { 2726 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2727 != PackageManager.PERMISSION_GRANTED) { 2728 String msg = "Permission Denial: crashApplication() from pid=" 2729 + Binder.getCallingPid() 2730 + ", uid=" + Binder.getCallingUid() 2731 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2732 Slog.w(TAG, msg); 2733 throw new SecurityException(msg); 2734 } 2735 2736 synchronized(this) { 2737 ProcessRecord proc = null; 2738 2739 // Figure out which process to kill. We don't trust that initialPid 2740 // still has any relation to current pids, so must scan through the 2741 // list. 2742 synchronized (mPidsSelfLocked) { 2743 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2744 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2745 if (p.uid != uid) { 2746 continue; 2747 } 2748 if (p.pid == initialPid) { 2749 proc = p; 2750 break; 2751 } 2752 for (String str : p.pkgList) { 2753 if (str.equals(packageName)) { 2754 proc = p; 2755 } 2756 } 2757 } 2758 } 2759 2760 if (proc == null) { 2761 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2762 + " initialPid=" + initialPid 2763 + " packageName=" + packageName); 2764 return; 2765 } 2766 2767 if (proc.thread != null) { 2768 if (proc.pid == Process.myPid()) { 2769 Log.w(TAG, "crashApplication: trying to crash self!"); 2770 return; 2771 } 2772 long ident = Binder.clearCallingIdentity(); 2773 try { 2774 proc.thread.scheduleCrash(message); 2775 } catch (RemoteException e) { 2776 } 2777 Binder.restoreCallingIdentity(ident); 2778 } 2779 } 2780 } 2781 2782 public final void finishSubActivity(IBinder token, String resultWho, 2783 int requestCode) { 2784 synchronized(this) { 2785 final long origId = Binder.clearCallingIdentity(); 2786 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2787 Binder.restoreCallingIdentity(origId); 2788 } 2789 } 2790 2791 public boolean finishActivityAffinity(IBinder token) { 2792 synchronized(this) { 2793 final long origId = Binder.clearCallingIdentity(); 2794 boolean res = mMainStack.finishActivityAffinityLocked(token); 2795 Binder.restoreCallingIdentity(origId); 2796 return res; 2797 } 2798 } 2799 2800 public boolean willActivityBeVisible(IBinder token) { 2801 synchronized(this) { 2802 int i; 2803 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2804 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2805 if (r.appToken == token) { 2806 return true; 2807 } 2808 if (r.fullscreen && !r.finishing) { 2809 return false; 2810 } 2811 } 2812 return true; 2813 } 2814 } 2815 2816 public void overridePendingTransition(IBinder token, String packageName, 2817 int enterAnim, int exitAnim) { 2818 synchronized(this) { 2819 ActivityRecord self = mMainStack.isInStackLocked(token); 2820 if (self == null) { 2821 return; 2822 } 2823 2824 final long origId = Binder.clearCallingIdentity(); 2825 2826 if (self.state == ActivityState.RESUMED 2827 || self.state == ActivityState.PAUSING) { 2828 mWindowManager.overridePendingAppTransition(packageName, 2829 enterAnim, exitAnim, null); 2830 } 2831 2832 Binder.restoreCallingIdentity(origId); 2833 } 2834 } 2835 2836 /** 2837 * Main function for removing an existing process from the activity manager 2838 * as a result of that process going away. Clears out all connections 2839 * to the process. 2840 */ 2841 private final void handleAppDiedLocked(ProcessRecord app, 2842 boolean restarting, boolean allowRestart) { 2843 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2844 if (!restarting) { 2845 mLruProcesses.remove(app); 2846 } 2847 2848 if (mProfileProc == app) { 2849 clearProfilerLocked(); 2850 } 2851 2852 // Just in case... 2853 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2854 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2855 mMainStack.mPausingActivity = null; 2856 } 2857 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2858 mMainStack.mLastPausedActivity = null; 2859 } 2860 2861 // Remove this application's activities from active lists. 2862 mMainStack.removeHistoryRecordsForAppLocked(app); 2863 2864 boolean atTop = true; 2865 boolean hasVisibleActivities = false; 2866 2867 // Clean out the history list. 2868 int i = mMainStack.mHistory.size(); 2869 if (localLOGV) Slog.v( 2870 TAG, "Removing app " + app + " from history with " + i + " entries"); 2871 while (i > 0) { 2872 i--; 2873 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2874 if (localLOGV) Slog.v( 2875 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2876 if (r.app == app) { 2877 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2878 if (ActivityStack.DEBUG_ADD_REMOVE) { 2879 RuntimeException here = new RuntimeException("here"); 2880 here.fillInStackTrace(); 2881 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2882 + ": haveState=" + r.haveState 2883 + " stateNotNeeded=" + r.stateNotNeeded 2884 + " finishing=" + r.finishing 2885 + " state=" + r.state, here); 2886 } 2887 if (!r.finishing) { 2888 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2889 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2890 System.identityHashCode(r), 2891 r.task.taskId, r.shortComponentName, 2892 "proc died without state saved"); 2893 } 2894 mMainStack.removeActivityFromHistoryLocked(r); 2895 2896 } else { 2897 // We have the current state for this activity, so 2898 // it can be restarted later when needed. 2899 if (localLOGV) Slog.v( 2900 TAG, "Keeping entry, setting app to null"); 2901 if (r.visible) { 2902 hasVisibleActivities = true; 2903 } 2904 r.app = null; 2905 r.nowVisible = false; 2906 if (!r.haveState) { 2907 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2908 "App died, clearing saved state of " + r); 2909 r.icicle = null; 2910 } 2911 } 2912 2913 r.stack.cleanUpActivityLocked(r, true, true); 2914 } 2915 atTop = false; 2916 } 2917 2918 app.activities.clear(); 2919 2920 if (app.instrumentationClass != null) { 2921 Slog.w(TAG, "Crash of app " + app.processName 2922 + " running instrumentation " + app.instrumentationClass); 2923 Bundle info = new Bundle(); 2924 info.putString("shortMsg", "Process crashed."); 2925 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2926 } 2927 2928 if (!restarting) { 2929 if (!mMainStack.resumeTopActivityLocked(null)) { 2930 // If there was nothing to resume, and we are not already 2931 // restarting this process, but there is a visible activity that 2932 // is hosted by the process... then make sure all visible 2933 // activities are running, taking care of restarting this 2934 // process. 2935 if (hasVisibleActivities) { 2936 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2937 } 2938 } 2939 } 2940 } 2941 2942 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2943 IBinder threadBinder = thread.asBinder(); 2944 // Find the application record. 2945 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2946 ProcessRecord rec = mLruProcesses.get(i); 2947 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2948 return i; 2949 } 2950 } 2951 return -1; 2952 } 2953 2954 final ProcessRecord getRecordForAppLocked( 2955 IApplicationThread thread) { 2956 if (thread == null) { 2957 return null; 2958 } 2959 2960 int appIndex = getLRURecordIndexForAppLocked(thread); 2961 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2962 } 2963 2964 final void appDiedLocked(ProcessRecord app, int pid, 2965 IApplicationThread thread) { 2966 2967 mProcDeaths[0]++; 2968 2969 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2970 synchronized (stats) { 2971 stats.noteProcessDiedLocked(app.info.uid, pid); 2972 } 2973 2974 // Clean up already done if the process has been re-started. 2975 if (app.pid == pid && app.thread != null && 2976 app.thread.asBinder() == thread.asBinder()) { 2977 if (!app.killedBackground) { 2978 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2979 + ") has died."); 2980 } 2981 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2982 if (localLOGV) Slog.v( 2983 TAG, "Dying app: " + app + ", pid: " + pid 2984 + ", thread: " + thread.asBinder()); 2985 boolean doLowMem = app.instrumentationClass == null; 2986 handleAppDiedLocked(app, false, true); 2987 2988 if (doLowMem) { 2989 // If there are no longer any background processes running, 2990 // and the app that died was not running instrumentation, 2991 // then tell everyone we are now low on memory. 2992 boolean haveBg = false; 2993 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2994 ProcessRecord rec = mLruProcesses.get(i); 2995 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2996 haveBg = true; 2997 break; 2998 } 2999 } 3000 3001 if (!haveBg) { 3002 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3003 long now = SystemClock.uptimeMillis(); 3004 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3005 ProcessRecord rec = mLruProcesses.get(i); 3006 if (rec != app && rec.thread != null && 3007 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3008 // The low memory report is overriding any current 3009 // state for a GC request. Make sure to do 3010 // heavy/important/visible/foreground processes first. 3011 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3012 rec.lastRequestedGc = 0; 3013 } else { 3014 rec.lastRequestedGc = rec.lastLowMemory; 3015 } 3016 rec.reportLowMemory = true; 3017 rec.lastLowMemory = now; 3018 mProcessesToGc.remove(rec); 3019 addProcessToGcListLocked(rec); 3020 } 3021 } 3022 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3023 scheduleAppGcsLocked(); 3024 } 3025 } 3026 } else if (app.pid != pid) { 3027 // A new process has already been started. 3028 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3029 + ") has died and restarted (pid " + app.pid + ")."); 3030 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3031 } else if (DEBUG_PROCESSES) { 3032 Slog.d(TAG, "Received spurious death notification for thread " 3033 + thread.asBinder()); 3034 } 3035 } 3036 3037 /** 3038 * If a stack trace dump file is configured, dump process stack traces. 3039 * @param clearTraces causes the dump file to be erased prior to the new 3040 * traces being written, if true; when false, the new traces will be 3041 * appended to any existing file content. 3042 * @param firstPids of dalvik VM processes to dump stack traces for first 3043 * @param lastPids of dalvik VM processes to dump stack traces for last 3044 * @param nativeProcs optional list of native process names to dump stack crawls 3045 * @return file containing stack traces, or null if no dump file is configured 3046 */ 3047 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3048 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3049 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3050 if (tracesPath == null || tracesPath.length() == 0) { 3051 return null; 3052 } 3053 3054 File tracesFile = new File(tracesPath); 3055 try { 3056 File tracesDir = tracesFile.getParentFile(); 3057 if (!tracesDir.exists()) { 3058 tracesFile.mkdirs(); 3059 if (!SELinux.restorecon(tracesDir)) { 3060 return null; 3061 } 3062 } 3063 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3064 3065 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3066 tracesFile.createNewFile(); 3067 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3068 } catch (IOException e) { 3069 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3070 return null; 3071 } 3072 3073 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3074 return tracesFile; 3075 } 3076 3077 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3078 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3079 // Use a FileObserver to detect when traces finish writing. 3080 // The order of traces is considered important to maintain for legibility. 3081 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3082 public synchronized void onEvent(int event, String path) { notify(); } 3083 }; 3084 3085 try { 3086 observer.startWatching(); 3087 3088 // First collect all of the stacks of the most important pids. 3089 if (firstPids != null) { 3090 try { 3091 int num = firstPids.size(); 3092 for (int i = 0; i < num; i++) { 3093 synchronized (observer) { 3094 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3095 observer.wait(200); // Wait for write-close, give up after 200msec 3096 } 3097 } 3098 } catch (InterruptedException e) { 3099 Log.wtf(TAG, e); 3100 } 3101 } 3102 3103 // Next measure CPU usage. 3104 if (processStats != null) { 3105 processStats.init(); 3106 System.gc(); 3107 processStats.update(); 3108 try { 3109 synchronized (processStats) { 3110 processStats.wait(500); // measure over 1/2 second. 3111 } 3112 } catch (InterruptedException e) { 3113 } 3114 processStats.update(); 3115 3116 // We'll take the stack crawls of just the top apps using CPU. 3117 final int N = processStats.countWorkingStats(); 3118 int numProcs = 0; 3119 for (int i=0; i<N && numProcs<5; i++) { 3120 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3121 if (lastPids.indexOfKey(stats.pid) >= 0) { 3122 numProcs++; 3123 try { 3124 synchronized (observer) { 3125 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3126 observer.wait(200); // Wait for write-close, give up after 200msec 3127 } 3128 } catch (InterruptedException e) { 3129 Log.wtf(TAG, e); 3130 } 3131 3132 } 3133 } 3134 } 3135 3136 } finally { 3137 observer.stopWatching(); 3138 } 3139 3140 if (nativeProcs != null) { 3141 int[] pids = Process.getPidsForCommands(nativeProcs); 3142 if (pids != null) { 3143 for (int pid : pids) { 3144 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3145 } 3146 } 3147 } 3148 } 3149 3150 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3151 if (true || IS_USER_BUILD) { 3152 return; 3153 } 3154 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3155 if (tracesPath == null || tracesPath.length() == 0) { 3156 return; 3157 } 3158 3159 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3160 StrictMode.allowThreadDiskWrites(); 3161 try { 3162 final File tracesFile = new File(tracesPath); 3163 final File tracesDir = tracesFile.getParentFile(); 3164 final File tracesTmp = new File(tracesDir, "__tmp__"); 3165 try { 3166 if (!tracesDir.exists()) { 3167 tracesFile.mkdirs(); 3168 if (!SELinux.restorecon(tracesDir.getPath())) { 3169 return; 3170 } 3171 } 3172 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3173 3174 if (tracesFile.exists()) { 3175 tracesTmp.delete(); 3176 tracesFile.renameTo(tracesTmp); 3177 } 3178 StringBuilder sb = new StringBuilder(); 3179 Time tobj = new Time(); 3180 tobj.set(System.currentTimeMillis()); 3181 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3182 sb.append(": "); 3183 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3184 sb.append(" since "); 3185 sb.append(msg); 3186 FileOutputStream fos = new FileOutputStream(tracesFile); 3187 fos.write(sb.toString().getBytes()); 3188 if (app == null) { 3189 fos.write("\n*** No application process!".getBytes()); 3190 } 3191 fos.close(); 3192 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3193 } catch (IOException e) { 3194 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3195 return; 3196 } 3197 3198 if (app != null) { 3199 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3200 firstPids.add(app.pid); 3201 dumpStackTraces(tracesPath, firstPids, null, null, null); 3202 } 3203 3204 File lastTracesFile = null; 3205 File curTracesFile = null; 3206 for (int i=9; i>=0; i--) { 3207 String name = String.format("slow%02d.txt", i); 3208 curTracesFile = new File(tracesDir, name); 3209 if (curTracesFile.exists()) { 3210 if (lastTracesFile != null) { 3211 curTracesFile.renameTo(lastTracesFile); 3212 } else { 3213 curTracesFile.delete(); 3214 } 3215 } 3216 lastTracesFile = curTracesFile; 3217 } 3218 tracesFile.renameTo(curTracesFile); 3219 if (tracesTmp.exists()) { 3220 tracesTmp.renameTo(tracesFile); 3221 } 3222 } finally { 3223 StrictMode.setThreadPolicy(oldPolicy); 3224 } 3225 } 3226 3227 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3228 ActivityRecord parent, final String annotation) { 3229 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3230 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3231 3232 if (mController != null) { 3233 try { 3234 // 0 == continue, -1 = kill process immediately 3235 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3236 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3237 } catch (RemoteException e) { 3238 mController = null; 3239 } 3240 } 3241 3242 long anrTime = SystemClock.uptimeMillis(); 3243 if (MONITOR_CPU_USAGE) { 3244 updateCpuStatsNow(); 3245 } 3246 3247 synchronized (this) { 3248 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3249 if (mShuttingDown) { 3250 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3251 return; 3252 } else if (app.notResponding) { 3253 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3254 return; 3255 } else if (app.crashing) { 3256 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3257 return; 3258 } 3259 3260 // In case we come through here for the same app before completing 3261 // this one, mark as anring now so we will bail out. 3262 app.notResponding = true; 3263 3264 // Log the ANR to the event log. 3265 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3266 annotation); 3267 3268 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3269 firstPids.add(app.pid); 3270 3271 int parentPid = app.pid; 3272 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3273 if (parentPid != app.pid) firstPids.add(parentPid); 3274 3275 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3276 3277 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3278 ProcessRecord r = mLruProcesses.get(i); 3279 if (r != null && r.thread != null) { 3280 int pid = r.pid; 3281 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3282 if (r.persistent) { 3283 firstPids.add(pid); 3284 } else { 3285 lastPids.put(pid, Boolean.TRUE); 3286 } 3287 } 3288 } 3289 } 3290 } 3291 3292 // Log the ANR to the main log. 3293 StringBuilder info = new StringBuilder(); 3294 info.setLength(0); 3295 info.append("ANR in ").append(app.processName); 3296 if (activity != null && activity.shortComponentName != null) { 3297 info.append(" (").append(activity.shortComponentName).append(")"); 3298 } 3299 info.append("\n"); 3300 if (annotation != null) { 3301 info.append("Reason: ").append(annotation).append("\n"); 3302 } 3303 if (parent != null && parent != activity) { 3304 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3305 } 3306 3307 final ProcessStats processStats = new ProcessStats(true); 3308 3309 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3310 3311 String cpuInfo = null; 3312 if (MONITOR_CPU_USAGE) { 3313 updateCpuStatsNow(); 3314 synchronized (mProcessStatsThread) { 3315 cpuInfo = mProcessStats.printCurrentState(anrTime); 3316 } 3317 info.append(processStats.printCurrentLoad()); 3318 info.append(cpuInfo); 3319 } 3320 3321 info.append(processStats.printCurrentState(anrTime)); 3322 3323 Slog.e(TAG, info.toString()); 3324 if (tracesFile == null) { 3325 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3326 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3327 } 3328 3329 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3330 cpuInfo, tracesFile, null); 3331 3332 if (mController != null) { 3333 try { 3334 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3335 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3336 if (res != 0) { 3337 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3338 return; 3339 } 3340 } catch (RemoteException e) { 3341 mController = null; 3342 } 3343 } 3344 3345 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3346 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3347 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3348 3349 synchronized (this) { 3350 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3351 Slog.w(TAG, "Killing " + app + ": background ANR"); 3352 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3353 app.processName, app.setAdj, "background ANR"); 3354 Process.killProcessQuiet(app.pid); 3355 return; 3356 } 3357 3358 // Set the app's notResponding state, and look up the errorReportReceiver 3359 makeAppNotRespondingLocked(app, 3360 activity != null ? activity.shortComponentName : null, 3361 annotation != null ? "ANR " + annotation : "ANR", 3362 info.toString()); 3363 3364 // Bring up the infamous App Not Responding dialog 3365 Message msg = Message.obtain(); 3366 HashMap map = new HashMap(); 3367 msg.what = SHOW_NOT_RESPONDING_MSG; 3368 msg.obj = map; 3369 map.put("app", app); 3370 if (activity != null) { 3371 map.put("activity", activity); 3372 } 3373 3374 mHandler.sendMessage(msg); 3375 } 3376 } 3377 3378 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3379 if (!mLaunchWarningShown) { 3380 mLaunchWarningShown = true; 3381 mHandler.post(new Runnable() { 3382 @Override 3383 public void run() { 3384 synchronized (ActivityManagerService.this) { 3385 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3386 d.show(); 3387 mHandler.postDelayed(new Runnable() { 3388 @Override 3389 public void run() { 3390 synchronized (ActivityManagerService.this) { 3391 d.dismiss(); 3392 mLaunchWarningShown = false; 3393 } 3394 } 3395 }, 4000); 3396 } 3397 } 3398 }); 3399 } 3400 } 3401 3402 public boolean clearApplicationUserData(final String packageName, 3403 final IPackageDataObserver observer, final int userId) { 3404 enforceNotIsolatedCaller("clearApplicationUserData"); 3405 int uid = Binder.getCallingUid(); 3406 int pid = Binder.getCallingPid(); 3407 long callingId = Binder.clearCallingIdentity(); 3408 try { 3409 IPackageManager pm = AppGlobals.getPackageManager(); 3410 int pkgUid = -1; 3411 synchronized(this) { 3412 try { 3413 pkgUid = pm.getPackageUid(packageName, userId); 3414 } catch (RemoteException e) { 3415 } 3416 if (pkgUid == -1) { 3417 Slog.w(TAG, "Invalid packageName:" + packageName); 3418 return false; 3419 } 3420 if (uid == pkgUid || checkComponentPermission( 3421 android.Manifest.permission.CLEAR_APP_USER_DATA, 3422 pid, uid, -1, true) 3423 == PackageManager.PERMISSION_GRANTED) { 3424 forceStopPackageLocked(packageName, pkgUid); 3425 } else { 3426 throw new SecurityException(pid+" does not have permission:"+ 3427 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3428 "for process:"+packageName); 3429 } 3430 } 3431 3432 try { 3433 //clear application user data 3434 pm.clearApplicationUserData(packageName, observer, userId); 3435 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3436 Uri.fromParts("package", packageName, null)); 3437 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3438 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3439 null, null, 0, null, null, null, false, false, userId); 3440 } catch (RemoteException e) { 3441 } 3442 } finally { 3443 Binder.restoreCallingIdentity(callingId); 3444 } 3445 return true; 3446 } 3447 3448 public void killBackgroundProcesses(final String packageName) { 3449 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3450 != PackageManager.PERMISSION_GRANTED && 3451 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3452 != PackageManager.PERMISSION_GRANTED) { 3453 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3454 + Binder.getCallingPid() 3455 + ", uid=" + Binder.getCallingUid() 3456 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3457 Slog.w(TAG, msg); 3458 throw new SecurityException(msg); 3459 } 3460 3461 int userId = UserHandle.getCallingUserId(); 3462 long callingId = Binder.clearCallingIdentity(); 3463 try { 3464 IPackageManager pm = AppGlobals.getPackageManager(); 3465 int pkgUid = -1; 3466 synchronized(this) { 3467 try { 3468 pkgUid = pm.getPackageUid(packageName, userId); 3469 } catch (RemoteException e) { 3470 } 3471 if (pkgUid == -1) { 3472 Slog.w(TAG, "Invalid packageName: " + packageName); 3473 return; 3474 } 3475 killPackageProcessesLocked(packageName, pkgUid, -1, 3476 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3477 } 3478 } finally { 3479 Binder.restoreCallingIdentity(callingId); 3480 } 3481 } 3482 3483 public void killAllBackgroundProcesses() { 3484 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3485 != PackageManager.PERMISSION_GRANTED) { 3486 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3487 + Binder.getCallingPid() 3488 + ", uid=" + Binder.getCallingUid() 3489 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3490 Slog.w(TAG, msg); 3491 throw new SecurityException(msg); 3492 } 3493 3494 long callingId = Binder.clearCallingIdentity(); 3495 try { 3496 synchronized(this) { 3497 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3498 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3499 final int NA = apps.size(); 3500 for (int ia=0; ia<NA; ia++) { 3501 ProcessRecord app = apps.valueAt(ia); 3502 if (app.persistent) { 3503 // we don't kill persistent processes 3504 continue; 3505 } 3506 if (app.removed) { 3507 procs.add(app); 3508 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3509 app.removed = true; 3510 procs.add(app); 3511 } 3512 } 3513 } 3514 3515 int N = procs.size(); 3516 for (int i=0; i<N; i++) { 3517 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3518 } 3519 } 3520 } finally { 3521 Binder.restoreCallingIdentity(callingId); 3522 } 3523 } 3524 3525 public void forceStopPackage(final String packageName) { 3526 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3527 != PackageManager.PERMISSION_GRANTED) { 3528 String msg = "Permission Denial: forceStopPackage() from pid=" 3529 + Binder.getCallingPid() 3530 + ", uid=" + Binder.getCallingUid() 3531 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3532 Slog.w(TAG, msg); 3533 throw new SecurityException(msg); 3534 } 3535 final int userId = UserHandle.getCallingUserId(); 3536 long callingId = Binder.clearCallingIdentity(); 3537 try { 3538 IPackageManager pm = AppGlobals.getPackageManager(); 3539 int pkgUid = -1; 3540 synchronized(this) { 3541 try { 3542 pkgUid = pm.getPackageUid(packageName, userId); 3543 } catch (RemoteException e) { 3544 } 3545 if (pkgUid == -1) { 3546 Slog.w(TAG, "Invalid packageName: " + packageName); 3547 return; 3548 } 3549 forceStopPackageLocked(packageName, pkgUid); 3550 try { 3551 pm.setPackageStoppedState(packageName, true, userId); 3552 } catch (RemoteException e) { 3553 } catch (IllegalArgumentException e) { 3554 Slog.w(TAG, "Failed trying to unstop package " 3555 + packageName + ": " + e); 3556 } 3557 } 3558 } finally { 3559 Binder.restoreCallingIdentity(callingId); 3560 } 3561 } 3562 3563 /* 3564 * The pkg name and app id have to be specified. 3565 */ 3566 public void killApplicationWithAppId(String pkg, int appid) { 3567 if (pkg == null) { 3568 return; 3569 } 3570 // Make sure the uid is valid. 3571 if (appid < 0) { 3572 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3573 return; 3574 } 3575 int callerUid = Binder.getCallingUid(); 3576 // Only the system server can kill an application 3577 if (callerUid == Process.SYSTEM_UID) { 3578 // Post an aysnc message to kill the application 3579 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3580 msg.arg1 = appid; 3581 msg.arg2 = 0; 3582 msg.obj = pkg; 3583 mHandler.sendMessage(msg); 3584 } else { 3585 throw new SecurityException(callerUid + " cannot kill pkg: " + 3586 pkg); 3587 } 3588 } 3589 3590 public void closeSystemDialogs(String reason) { 3591 enforceNotIsolatedCaller("closeSystemDialogs"); 3592 3593 final int pid = Binder.getCallingPid(); 3594 final int uid = Binder.getCallingUid(); 3595 final long origId = Binder.clearCallingIdentity(); 3596 try { 3597 synchronized (this) { 3598 // Only allow this from foreground processes, so that background 3599 // applications can't abuse it to prevent system UI from being shown. 3600 if (uid >= Process.FIRST_APPLICATION_UID) { 3601 ProcessRecord proc; 3602 synchronized (mPidsSelfLocked) { 3603 proc = mPidsSelfLocked.get(pid); 3604 } 3605 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3606 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3607 + " from background process " + proc); 3608 return; 3609 } 3610 } 3611 closeSystemDialogsLocked(reason); 3612 } 3613 } finally { 3614 Binder.restoreCallingIdentity(origId); 3615 } 3616 } 3617 3618 void closeSystemDialogsLocked(String reason) { 3619 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3620 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3621 if (reason != null) { 3622 intent.putExtra("reason", reason); 3623 } 3624 mWindowManager.closeSystemDialogs(reason); 3625 3626 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3627 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3628 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3629 r.stack.finishActivityLocked(r, i, 3630 Activity.RESULT_CANCELED, null, "close-sys"); 3631 } 3632 } 3633 3634 broadcastIntentLocked(null, null, intent, null, 3635 null, 0, null, null, null, false, false, -1, 3636 Process.SYSTEM_UID, UserHandle.USER_ALL); 3637 } 3638 3639 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3640 throws RemoteException { 3641 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3642 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3643 for (int i=pids.length-1; i>=0; i--) { 3644 infos[i] = new Debug.MemoryInfo(); 3645 Debug.getMemoryInfo(pids[i], infos[i]); 3646 } 3647 return infos; 3648 } 3649 3650 public long[] getProcessPss(int[] pids) throws RemoteException { 3651 enforceNotIsolatedCaller("getProcessPss"); 3652 long[] pss = new long[pids.length]; 3653 for (int i=pids.length-1; i>=0; i--) { 3654 pss[i] = Debug.getPss(pids[i]); 3655 } 3656 return pss; 3657 } 3658 3659 public void killApplicationProcess(String processName, int uid) { 3660 if (processName == null) { 3661 return; 3662 } 3663 3664 int callerUid = Binder.getCallingUid(); 3665 // Only the system server can kill an application 3666 if (callerUid == Process.SYSTEM_UID) { 3667 synchronized (this) { 3668 ProcessRecord app = getProcessRecordLocked(processName, uid); 3669 if (app != null && app.thread != null) { 3670 try { 3671 app.thread.scheduleSuicide(); 3672 } catch (RemoteException e) { 3673 // If the other end already died, then our work here is done. 3674 } 3675 } else { 3676 Slog.w(TAG, "Process/uid not found attempting kill of " 3677 + processName + " / " + uid); 3678 } 3679 } 3680 } else { 3681 throw new SecurityException(callerUid + " cannot kill app process: " + 3682 processName); 3683 } 3684 } 3685 3686 private void forceStopPackageLocked(final String packageName, int uid) { 3687 forceStopPackageLocked(packageName, uid, false, false, true, false, 3688 UserHandle.getUserId(uid)); 3689 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3690 Uri.fromParts("package", packageName, null)); 3691 if (!mProcessesReady) { 3692 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3693 } 3694 intent.putExtra(Intent.EXTRA_UID, uid); 3695 broadcastIntentLocked(null, null, intent, 3696 null, null, 0, null, null, null, 3697 false, false, 3698 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3699 } 3700 3701 private void forceStopUserLocked(int userId) { 3702 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3703 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3704 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3705 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3706 broadcastIntentLocked(null, null, intent, 3707 null, null, 0, null, null, null, 3708 false, false, 3709 MY_PID, Process.SYSTEM_UID, userId); 3710 } 3711 3712 private final boolean killPackageProcessesLocked(String packageName, int appId, 3713 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3714 boolean doit, boolean evenPersistent, String reason) { 3715 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3716 3717 // Remove all processes this package may have touched: all with the 3718 // same UID (except for the system or root user), and all whose name 3719 // matches the package name. 3720 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3721 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3722 final int NA = apps.size(); 3723 for (int ia=0; ia<NA; ia++) { 3724 ProcessRecord app = apps.valueAt(ia); 3725 if (app.persistent && !evenPersistent) { 3726 // we don't kill persistent processes 3727 continue; 3728 } 3729 if (app.removed) { 3730 if (doit) { 3731 procs.add(app); 3732 } 3733 continue; 3734 } 3735 3736 // Skip process if it doesn't meet our oom adj requirement. 3737 if (app.setAdj < minOomAdj) { 3738 continue; 3739 } 3740 3741 // If no package is specified, we call all processes under the 3742 // give user id. 3743 if (packageName == null) { 3744 if (app.userId != userId) { 3745 continue; 3746 } 3747 // Package has been specified, we want to hit all processes 3748 // that match it. We need to qualify this by the processes 3749 // that are running under the specified app and user ID. 3750 } else { 3751 if (UserHandle.getAppId(app.uid) != appId) { 3752 continue; 3753 } 3754 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3755 continue; 3756 } 3757 if (!app.pkgList.contains(packageName)) { 3758 continue; 3759 } 3760 } 3761 3762 // Process has passed all conditions, kill it! 3763 if (!doit) { 3764 return true; 3765 } 3766 app.removed = true; 3767 procs.add(app); 3768 } 3769 } 3770 3771 int N = procs.size(); 3772 for (int i=0; i<N; i++) { 3773 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3774 } 3775 return N > 0; 3776 } 3777 3778 private final boolean forceStopPackageLocked(String name, int appId, 3779 boolean callerWillRestart, boolean purgeCache, boolean doit, 3780 boolean evenPersistent, int userId) { 3781 int i; 3782 int N; 3783 3784 if (userId == UserHandle.USER_ALL && name == null) { 3785 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3786 } 3787 3788 if (appId < 0 && name != null) { 3789 try { 3790 appId = UserHandle.getAppId( 3791 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3792 } catch (RemoteException e) { 3793 } 3794 } 3795 3796 if (doit) { 3797 if (name != null) { 3798 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3799 + " user=" + userId); 3800 } else { 3801 Slog.i(TAG, "Force stopping user " + userId); 3802 } 3803 3804 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3805 while (badApps.hasNext()) { 3806 SparseArray<Long> ba = badApps.next(); 3807 for (i=ba.size()-1; i>=0; i--) { 3808 boolean remove = false; 3809 final int entUid = ba.keyAt(i); 3810 if (name != null) { 3811 if (userId == UserHandle.USER_ALL) { 3812 if (UserHandle.getAppId(entUid) == appId) { 3813 remove = true; 3814 } 3815 } else { 3816 if (entUid == UserHandle.getUid(userId, appId)) { 3817 remove = true; 3818 } 3819 } 3820 } else if (UserHandle.getUserId(entUid) == userId) { 3821 remove = true; 3822 } 3823 if (remove) { 3824 ba.removeAt(i); 3825 } 3826 } 3827 if (ba.size() == 0) { 3828 badApps.remove(); 3829 } 3830 } 3831 } 3832 3833 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3834 -100, callerWillRestart, false, doit, evenPersistent, 3835 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3836 3837 TaskRecord lastTask = null; 3838 for (i=0; i<mMainStack.mHistory.size(); i++) { 3839 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3840 final boolean samePackage = r.packageName.equals(name) 3841 || (name == null && r.userId == userId); 3842 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3843 && (samePackage || r.task == lastTask) 3844 && (r.app == null || evenPersistent || !r.app.persistent)) { 3845 if (!doit) { 3846 if (r.finishing) { 3847 // If this activity is just finishing, then it is not 3848 // interesting as far as something to stop. 3849 continue; 3850 } 3851 return true; 3852 } 3853 didSomething = true; 3854 Slog.i(TAG, " Force finishing activity " + r); 3855 if (samePackage) { 3856 if (r.app != null) { 3857 r.app.removed = true; 3858 } 3859 r.app = null; 3860 } 3861 lastTask = r.task; 3862 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3863 null, "force-stop", true)) { 3864 i--; 3865 } 3866 } 3867 } 3868 3869 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3870 if (!doit) { 3871 return true; 3872 } 3873 didSomething = true; 3874 } 3875 3876 if (name == null) { 3877 // Remove all sticky broadcasts from this user. 3878 mStickyBroadcasts.remove(userId); 3879 } 3880 3881 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3882 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3883 userId, providers)) { 3884 if (!doit) { 3885 return true; 3886 } 3887 didSomething = true; 3888 } 3889 N = providers.size(); 3890 for (i=0; i<N; i++) { 3891 removeDyingProviderLocked(null, providers.get(i), true); 3892 } 3893 3894 if (mIntentSenderRecords.size() > 0) { 3895 Iterator<WeakReference<PendingIntentRecord>> it 3896 = mIntentSenderRecords.values().iterator(); 3897 while (it.hasNext()) { 3898 WeakReference<PendingIntentRecord> wpir = it.next(); 3899 if (wpir == null) { 3900 it.remove(); 3901 continue; 3902 } 3903 PendingIntentRecord pir = wpir.get(); 3904 if (pir == null) { 3905 it.remove(); 3906 continue; 3907 } 3908 if (name == null) { 3909 // Stopping user, remove all objects for the user. 3910 if (pir.key.userId != userId) { 3911 // Not the same user, skip it. 3912 continue; 3913 } 3914 } else { 3915 if (UserHandle.getAppId(pir.uid) != appId) { 3916 // Different app id, skip it. 3917 continue; 3918 } 3919 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3920 // Different user, skip it. 3921 continue; 3922 } 3923 if (!pir.key.packageName.equals(name)) { 3924 // Different package, skip it. 3925 continue; 3926 } 3927 } 3928 if (!doit) { 3929 return true; 3930 } 3931 didSomething = true; 3932 it.remove(); 3933 pir.canceled = true; 3934 if (pir.key.activity != null) { 3935 pir.key.activity.pendingResults.remove(pir.ref); 3936 } 3937 } 3938 } 3939 3940 if (doit) { 3941 if (purgeCache && name != null) { 3942 AttributeCache ac = AttributeCache.instance(); 3943 if (ac != null) { 3944 ac.removePackage(name); 3945 } 3946 } 3947 if (mBooted) { 3948 mMainStack.resumeTopActivityLocked(null); 3949 mMainStack.scheduleIdleLocked(); 3950 } 3951 } 3952 3953 return didSomething; 3954 } 3955 3956 private final boolean removeProcessLocked(ProcessRecord app, 3957 boolean callerWillRestart, boolean allowRestart, String reason) { 3958 final String name = app.processName; 3959 final int uid = app.uid; 3960 if (DEBUG_PROCESSES) Slog.d( 3961 TAG, "Force removing proc " + app.toShortString() + " (" + name 3962 + "/" + uid + ")"); 3963 3964 mProcessNames.remove(name, uid); 3965 mIsolatedProcesses.remove(app.uid); 3966 if (mHeavyWeightProcess == app) { 3967 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3968 mHeavyWeightProcess.userId, 0)); 3969 mHeavyWeightProcess = null; 3970 } 3971 boolean needRestart = false; 3972 if (app.pid > 0 && app.pid != MY_PID) { 3973 int pid = app.pid; 3974 synchronized (mPidsSelfLocked) { 3975 mPidsSelfLocked.remove(pid); 3976 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3977 } 3978 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3979 handleAppDiedLocked(app, true, allowRestart); 3980 mLruProcesses.remove(app); 3981 Process.killProcessQuiet(pid); 3982 3983 if (app.persistent && !app.isolated) { 3984 if (!callerWillRestart) { 3985 addAppLocked(app.info, false); 3986 } else { 3987 needRestart = true; 3988 } 3989 } 3990 } else { 3991 mRemovedProcesses.add(app); 3992 } 3993 3994 return needRestart; 3995 } 3996 3997 private final void processStartTimedOutLocked(ProcessRecord app) { 3998 final int pid = app.pid; 3999 boolean gone = false; 4000 synchronized (mPidsSelfLocked) { 4001 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4002 if (knownApp != null && knownApp.thread == null) { 4003 mPidsSelfLocked.remove(pid); 4004 gone = true; 4005 } 4006 } 4007 4008 if (gone) { 4009 Slog.w(TAG, "Process " + app + " failed to attach"); 4010 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4011 app.processName); 4012 mProcessNames.remove(app.processName, app.uid); 4013 mIsolatedProcesses.remove(app.uid); 4014 if (mHeavyWeightProcess == app) { 4015 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4016 mHeavyWeightProcess.userId, 0)); 4017 mHeavyWeightProcess = null; 4018 } 4019 // Take care of any launching providers waiting for this process. 4020 checkAppInLaunchingProvidersLocked(app, true); 4021 // Take care of any services that are waiting for the process. 4022 mServices.processStartTimedOutLocked(app); 4023 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4024 app.processName, app.setAdj, "start timeout"); 4025 Process.killProcessQuiet(pid); 4026 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4027 Slog.w(TAG, "Unattached app died before backup, skipping"); 4028 try { 4029 IBackupManager bm = IBackupManager.Stub.asInterface( 4030 ServiceManager.getService(Context.BACKUP_SERVICE)); 4031 bm.agentDisconnected(app.info.packageName); 4032 } catch (RemoteException e) { 4033 // Can't happen; the backup manager is local 4034 } 4035 } 4036 if (isPendingBroadcastProcessLocked(pid)) { 4037 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4038 skipPendingBroadcastLocked(pid); 4039 } 4040 } else { 4041 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4042 } 4043 } 4044 4045 private final boolean attachApplicationLocked(IApplicationThread thread, 4046 int pid) { 4047 4048 // Find the application record that is being attached... either via 4049 // the pid if we are running in multiple processes, or just pull the 4050 // next app record if we are emulating process with anonymous threads. 4051 ProcessRecord app; 4052 if (pid != MY_PID && pid >= 0) { 4053 synchronized (mPidsSelfLocked) { 4054 app = mPidsSelfLocked.get(pid); 4055 } 4056 } else { 4057 app = null; 4058 } 4059 4060 if (app == null) { 4061 Slog.w(TAG, "No pending application record for pid " + pid 4062 + " (IApplicationThread " + thread + "); dropping process"); 4063 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4064 if (pid > 0 && pid != MY_PID) { 4065 Process.killProcessQuiet(pid); 4066 } else { 4067 try { 4068 thread.scheduleExit(); 4069 } catch (Exception e) { 4070 // Ignore exceptions. 4071 } 4072 } 4073 return false; 4074 } 4075 4076 // If this application record is still attached to a previous 4077 // process, clean it up now. 4078 if (app.thread != null) { 4079 handleAppDiedLocked(app, true, true); 4080 } 4081 4082 // Tell the process all about itself. 4083 4084 if (localLOGV) Slog.v( 4085 TAG, "Binding process pid " + pid + " to record " + app); 4086 4087 String processName = app.processName; 4088 try { 4089 AppDeathRecipient adr = new AppDeathRecipient( 4090 app, pid, thread); 4091 thread.asBinder().linkToDeath(adr, 0); 4092 app.deathRecipient = adr; 4093 } catch (RemoteException e) { 4094 app.resetPackageList(); 4095 startProcessLocked(app, "link fail", processName); 4096 return false; 4097 } 4098 4099 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4100 4101 app.thread = thread; 4102 app.curAdj = app.setAdj = -100; 4103 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4104 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4105 app.forcingToForeground = null; 4106 app.foregroundServices = false; 4107 app.hasShownUi = false; 4108 app.debugging = false; 4109 4110 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4111 4112 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4113 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4114 4115 if (!normalMode) { 4116 Slog.i(TAG, "Launching preboot mode app: " + app); 4117 } 4118 4119 if (localLOGV) Slog.v( 4120 TAG, "New app record " + app 4121 + " thread=" + thread.asBinder() + " pid=" + pid); 4122 try { 4123 int testMode = IApplicationThread.DEBUG_OFF; 4124 if (mDebugApp != null && mDebugApp.equals(processName)) { 4125 testMode = mWaitForDebugger 4126 ? IApplicationThread.DEBUG_WAIT 4127 : IApplicationThread.DEBUG_ON; 4128 app.debugging = true; 4129 if (mDebugTransient) { 4130 mDebugApp = mOrigDebugApp; 4131 mWaitForDebugger = mOrigWaitForDebugger; 4132 } 4133 } 4134 String profileFile = app.instrumentationProfileFile; 4135 ParcelFileDescriptor profileFd = null; 4136 boolean profileAutoStop = false; 4137 if (mProfileApp != null && mProfileApp.equals(processName)) { 4138 mProfileProc = app; 4139 profileFile = mProfileFile; 4140 profileFd = mProfileFd; 4141 profileAutoStop = mAutoStopProfiler; 4142 } 4143 boolean enableOpenGlTrace = false; 4144 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4145 enableOpenGlTrace = true; 4146 mOpenGlTraceApp = null; 4147 } 4148 4149 // If the app is being launched for restore or full backup, set it up specially 4150 boolean isRestrictedBackupMode = false; 4151 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4152 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4153 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4154 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4155 } 4156 4157 ensurePackageDexOpt(app.instrumentationInfo != null 4158 ? app.instrumentationInfo.packageName 4159 : app.info.packageName); 4160 if (app.instrumentationClass != null) { 4161 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4162 } 4163 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4164 + processName + " with config " + mConfiguration); 4165 ApplicationInfo appInfo = app.instrumentationInfo != null 4166 ? app.instrumentationInfo : app.info; 4167 app.compat = compatibilityInfoForPackageLocked(appInfo); 4168 if (profileFd != null) { 4169 profileFd = profileFd.dup(); 4170 } 4171 thread.bindApplication(processName, appInfo, providers, 4172 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4173 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4174 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4175 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4176 mCoreSettingsObserver.getCoreSettingsLocked()); 4177 updateLruProcessLocked(app, false, true); 4178 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4179 } catch (Exception e) { 4180 // todo: Yikes! What should we do? For now we will try to 4181 // start another process, but that could easily get us in 4182 // an infinite loop of restarting processes... 4183 Slog.w(TAG, "Exception thrown during bind!", e); 4184 4185 app.resetPackageList(); 4186 app.unlinkDeathRecipient(); 4187 startProcessLocked(app, "bind fail", processName); 4188 return false; 4189 } 4190 4191 // Remove this record from the list of starting applications. 4192 mPersistentStartingProcesses.remove(app); 4193 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4194 "Attach application locked removing on hold: " + app); 4195 mProcessesOnHold.remove(app); 4196 4197 boolean badApp = false; 4198 boolean didSomething = false; 4199 4200 // See if the top visible activity is waiting to run in this process... 4201 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4202 if (hr != null && normalMode) { 4203 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4204 && processName.equals(hr.processName)) { 4205 try { 4206 if (mHeadless) { 4207 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4208 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4209 didSomething = true; 4210 } 4211 } catch (Exception e) { 4212 Slog.w(TAG, "Exception in new application when starting activity " 4213 + hr.intent.getComponent().flattenToShortString(), e); 4214 badApp = true; 4215 } 4216 } else { 4217 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4218 } 4219 } 4220 4221 // Find any services that should be running in this process... 4222 if (!badApp) { 4223 try { 4224 didSomething |= mServices.attachApplicationLocked(app, processName); 4225 } catch (Exception e) { 4226 badApp = true; 4227 } 4228 } 4229 4230 // Check if a next-broadcast receiver is in this process... 4231 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4232 try { 4233 didSomething = sendPendingBroadcastsLocked(app); 4234 } catch (Exception e) { 4235 // If the app died trying to launch the receiver we declare it 'bad' 4236 badApp = true; 4237 } 4238 } 4239 4240 // Check whether the next backup agent is in this process... 4241 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4242 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4243 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4244 try { 4245 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4246 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4247 mBackupTarget.backupMode); 4248 } catch (Exception e) { 4249 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4250 e.printStackTrace(); 4251 } 4252 } 4253 4254 if (badApp) { 4255 // todo: Also need to kill application to deal with all 4256 // kinds of exceptions. 4257 handleAppDiedLocked(app, false, true); 4258 return false; 4259 } 4260 4261 if (!didSomething) { 4262 updateOomAdjLocked(); 4263 } 4264 4265 return true; 4266 } 4267 4268 public final void attachApplication(IApplicationThread thread) { 4269 synchronized (this) { 4270 int callingPid = Binder.getCallingPid(); 4271 final long origId = Binder.clearCallingIdentity(); 4272 attachApplicationLocked(thread, callingPid); 4273 Binder.restoreCallingIdentity(origId); 4274 } 4275 } 4276 4277 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4278 final long origId = Binder.clearCallingIdentity(); 4279 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4280 if (stopProfiling) { 4281 synchronized (this) { 4282 if (mProfileProc == r.app) { 4283 if (mProfileFd != null) { 4284 try { 4285 mProfileFd.close(); 4286 } catch (IOException e) { 4287 } 4288 clearProfilerLocked(); 4289 } 4290 } 4291 } 4292 } 4293 Binder.restoreCallingIdentity(origId); 4294 } 4295 4296 void enableScreenAfterBoot() { 4297 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4298 SystemClock.uptimeMillis()); 4299 mWindowManager.enableScreenAfterBoot(); 4300 4301 synchronized (this) { 4302 updateEventDispatchingLocked(); 4303 } 4304 } 4305 4306 public void showBootMessage(final CharSequence msg, final boolean always) { 4307 enforceNotIsolatedCaller("showBootMessage"); 4308 mWindowManager.showBootMessage(msg, always); 4309 } 4310 4311 public void dismissKeyguardOnNextActivity() { 4312 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4313 final long token = Binder.clearCallingIdentity(); 4314 try { 4315 synchronized (this) { 4316 if (mLockScreenShown) { 4317 mLockScreenShown = false; 4318 comeOutOfSleepIfNeededLocked(); 4319 } 4320 mMainStack.dismissKeyguardOnNextActivityLocked(); 4321 } 4322 } finally { 4323 Binder.restoreCallingIdentity(token); 4324 } 4325 } 4326 4327 final void finishBooting() { 4328 IntentFilter pkgFilter = new IntentFilter(); 4329 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4330 pkgFilter.addDataScheme("package"); 4331 mContext.registerReceiver(new BroadcastReceiver() { 4332 @Override 4333 public void onReceive(Context context, Intent intent) { 4334 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4335 if (pkgs != null) { 4336 for (String pkg : pkgs) { 4337 synchronized (ActivityManagerService.this) { 4338 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4339 setResultCode(Activity.RESULT_OK); 4340 return; 4341 } 4342 } 4343 } 4344 } 4345 } 4346 }, pkgFilter); 4347 4348 synchronized (this) { 4349 // Ensure that any processes we had put on hold are now started 4350 // up. 4351 final int NP = mProcessesOnHold.size(); 4352 if (NP > 0) { 4353 ArrayList<ProcessRecord> procs = 4354 new ArrayList<ProcessRecord>(mProcessesOnHold); 4355 for (int ip=0; ip<NP; ip++) { 4356 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4357 + procs.get(ip)); 4358 startProcessLocked(procs.get(ip), "on-hold", null); 4359 } 4360 } 4361 4362 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4363 // Start looking for apps that are abusing wake locks. 4364 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4365 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4366 // Tell anyone interested that we are done booting! 4367 SystemProperties.set("sys.boot_completed", "1"); 4368 SystemProperties.set("dev.bootcomplete", "1"); 4369 for (int i=0; i<mStartedUsers.size(); i++) { 4370 UserStartedState uss = mStartedUsers.valueAt(i); 4371 if (uss.mState == UserStartedState.STATE_BOOTING) { 4372 uss.mState = UserStartedState.STATE_RUNNING; 4373 final int userId = mStartedUsers.keyAt(i); 4374 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4375 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4376 broadcastIntentLocked(null, null, intent, 4377 null, null, 0, null, null, 4378 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4379 false, false, MY_PID, Process.SYSTEM_UID, userId); 4380 } 4381 } 4382 } 4383 } 4384 } 4385 4386 final void ensureBootCompleted() { 4387 boolean booting; 4388 boolean enableScreen; 4389 synchronized (this) { 4390 booting = mBooting; 4391 mBooting = false; 4392 enableScreen = !mBooted; 4393 mBooted = true; 4394 } 4395 4396 if (booting) { 4397 finishBooting(); 4398 } 4399 4400 if (enableScreen) { 4401 enableScreenAfterBoot(); 4402 } 4403 } 4404 4405 public final void activityPaused(IBinder token) { 4406 final long origId = Binder.clearCallingIdentity(); 4407 mMainStack.activityPaused(token, false); 4408 Binder.restoreCallingIdentity(origId); 4409 } 4410 4411 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4412 CharSequence description) { 4413 if (localLOGV) Slog.v( 4414 TAG, "Activity stopped: token=" + token); 4415 4416 // Refuse possible leaked file descriptors 4417 if (icicle != null && icicle.hasFileDescriptors()) { 4418 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4419 } 4420 4421 ActivityRecord r = null; 4422 4423 final long origId = Binder.clearCallingIdentity(); 4424 4425 synchronized (this) { 4426 r = mMainStack.isInStackLocked(token); 4427 if (r != null) { 4428 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4429 } 4430 } 4431 4432 if (r != null) { 4433 sendPendingThumbnail(r, null, null, null, false); 4434 } 4435 4436 trimApplications(); 4437 4438 Binder.restoreCallingIdentity(origId); 4439 } 4440 4441 public final void activityDestroyed(IBinder token) { 4442 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4443 mMainStack.activityDestroyed(token); 4444 } 4445 4446 public String getCallingPackage(IBinder token) { 4447 synchronized (this) { 4448 ActivityRecord r = getCallingRecordLocked(token); 4449 return r != null && r.app != null ? r.info.packageName : null; 4450 } 4451 } 4452 4453 public ComponentName getCallingActivity(IBinder token) { 4454 synchronized (this) { 4455 ActivityRecord r = getCallingRecordLocked(token); 4456 return r != null ? r.intent.getComponent() : null; 4457 } 4458 } 4459 4460 private ActivityRecord getCallingRecordLocked(IBinder token) { 4461 ActivityRecord r = mMainStack.isInStackLocked(token); 4462 if (r == null) { 4463 return null; 4464 } 4465 return r.resultTo; 4466 } 4467 4468 public ComponentName getActivityClassForToken(IBinder token) { 4469 synchronized(this) { 4470 ActivityRecord r = mMainStack.isInStackLocked(token); 4471 if (r == null) { 4472 return null; 4473 } 4474 return r.intent.getComponent(); 4475 } 4476 } 4477 4478 public String getPackageForToken(IBinder token) { 4479 synchronized(this) { 4480 ActivityRecord r = mMainStack.isInStackLocked(token); 4481 if (r == null) { 4482 return null; 4483 } 4484 return r.packageName; 4485 } 4486 } 4487 4488 public IIntentSender getIntentSender(int type, 4489 String packageName, IBinder token, String resultWho, 4490 int requestCode, Intent[] intents, String[] resolvedTypes, 4491 int flags, Bundle options, int userId) { 4492 enforceNotIsolatedCaller("getIntentSender"); 4493 // Refuse possible leaked file descriptors 4494 if (intents != null) { 4495 if (intents.length < 1) { 4496 throw new IllegalArgumentException("Intents array length must be >= 1"); 4497 } 4498 for (int i=0; i<intents.length; i++) { 4499 Intent intent = intents[i]; 4500 if (intent != null) { 4501 if (intent.hasFileDescriptors()) { 4502 throw new IllegalArgumentException("File descriptors passed in Intent"); 4503 } 4504 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4505 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4506 throw new IllegalArgumentException( 4507 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4508 } 4509 intents[i] = new Intent(intent); 4510 } 4511 } 4512 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4513 throw new IllegalArgumentException( 4514 "Intent array length does not match resolvedTypes length"); 4515 } 4516 } 4517 if (options != null) { 4518 if (options.hasFileDescriptors()) { 4519 throw new IllegalArgumentException("File descriptors passed in options"); 4520 } 4521 } 4522 4523 synchronized(this) { 4524 int callingUid = Binder.getCallingUid(); 4525 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4526 false, true, "getIntentSender", null); 4527 try { 4528 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4529 int uid = AppGlobals.getPackageManager() 4530 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4531 if (!UserHandle.isSameApp(callingUid, uid)) { 4532 String msg = "Permission Denial: getIntentSender() from pid=" 4533 + Binder.getCallingPid() 4534 + ", uid=" + Binder.getCallingUid() 4535 + ", (need uid=" + uid + ")" 4536 + " is not allowed to send as package " + packageName; 4537 Slog.w(TAG, msg); 4538 throw new SecurityException(msg); 4539 } 4540 } 4541 4542 return getIntentSenderLocked(type, packageName, callingUid, userId, 4543 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4544 4545 } catch (RemoteException e) { 4546 throw new SecurityException(e); 4547 } 4548 } 4549 } 4550 4551 IIntentSender getIntentSenderLocked(int type, String packageName, 4552 int callingUid, int userId, IBinder token, String resultWho, 4553 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4554 Bundle options) { 4555 if (DEBUG_MU) 4556 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4557 ActivityRecord activity = null; 4558 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4559 activity = mMainStack.isInStackLocked(token); 4560 if (activity == null) { 4561 return null; 4562 } 4563 if (activity.finishing) { 4564 return null; 4565 } 4566 } 4567 4568 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4569 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4570 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4571 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4572 |PendingIntent.FLAG_UPDATE_CURRENT); 4573 4574 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4575 type, packageName, activity, resultWho, 4576 requestCode, intents, resolvedTypes, flags, options, userId); 4577 WeakReference<PendingIntentRecord> ref; 4578 ref = mIntentSenderRecords.get(key); 4579 PendingIntentRecord rec = ref != null ? ref.get() : null; 4580 if (rec != null) { 4581 if (!cancelCurrent) { 4582 if (updateCurrent) { 4583 if (rec.key.requestIntent != null) { 4584 rec.key.requestIntent.replaceExtras(intents != null ? 4585 intents[intents.length - 1] : null); 4586 } 4587 if (intents != null) { 4588 intents[intents.length-1] = rec.key.requestIntent; 4589 rec.key.allIntents = intents; 4590 rec.key.allResolvedTypes = resolvedTypes; 4591 } else { 4592 rec.key.allIntents = null; 4593 rec.key.allResolvedTypes = null; 4594 } 4595 } 4596 return rec; 4597 } 4598 rec.canceled = true; 4599 mIntentSenderRecords.remove(key); 4600 } 4601 if (noCreate) { 4602 return rec; 4603 } 4604 rec = new PendingIntentRecord(this, key, callingUid); 4605 mIntentSenderRecords.put(key, rec.ref); 4606 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4607 if (activity.pendingResults == null) { 4608 activity.pendingResults 4609 = new HashSet<WeakReference<PendingIntentRecord>>(); 4610 } 4611 activity.pendingResults.add(rec.ref); 4612 } 4613 return rec; 4614 } 4615 4616 public void cancelIntentSender(IIntentSender sender) { 4617 if (!(sender instanceof PendingIntentRecord)) { 4618 return; 4619 } 4620 synchronized(this) { 4621 PendingIntentRecord rec = (PendingIntentRecord)sender; 4622 try { 4623 int uid = AppGlobals.getPackageManager() 4624 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4625 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4626 String msg = "Permission Denial: cancelIntentSender() from pid=" 4627 + Binder.getCallingPid() 4628 + ", uid=" + Binder.getCallingUid() 4629 + " is not allowed to cancel packges " 4630 + rec.key.packageName; 4631 Slog.w(TAG, msg); 4632 throw new SecurityException(msg); 4633 } 4634 } catch (RemoteException e) { 4635 throw new SecurityException(e); 4636 } 4637 cancelIntentSenderLocked(rec, true); 4638 } 4639 } 4640 4641 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4642 rec.canceled = true; 4643 mIntentSenderRecords.remove(rec.key); 4644 if (cleanActivity && rec.key.activity != null) { 4645 rec.key.activity.pendingResults.remove(rec.ref); 4646 } 4647 } 4648 4649 public String getPackageForIntentSender(IIntentSender pendingResult) { 4650 if (!(pendingResult instanceof PendingIntentRecord)) { 4651 return null; 4652 } 4653 try { 4654 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4655 return res.key.packageName; 4656 } catch (ClassCastException e) { 4657 } 4658 return null; 4659 } 4660 4661 public int getUidForIntentSender(IIntentSender sender) { 4662 if (sender instanceof PendingIntentRecord) { 4663 try { 4664 PendingIntentRecord res = (PendingIntentRecord)sender; 4665 return res.uid; 4666 } catch (ClassCastException e) { 4667 } 4668 } 4669 return -1; 4670 } 4671 4672 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4673 if (!(pendingResult instanceof PendingIntentRecord)) { 4674 return false; 4675 } 4676 try { 4677 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4678 if (res.key.allIntents == null) { 4679 return false; 4680 } 4681 for (int i=0; i<res.key.allIntents.length; i++) { 4682 Intent intent = res.key.allIntents[i]; 4683 if (intent.getPackage() != null && intent.getComponent() != null) { 4684 return false; 4685 } 4686 } 4687 return true; 4688 } catch (ClassCastException e) { 4689 } 4690 return false; 4691 } 4692 4693 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4694 if (!(pendingResult instanceof PendingIntentRecord)) { 4695 return false; 4696 } 4697 try { 4698 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4699 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4700 return true; 4701 } 4702 return false; 4703 } catch (ClassCastException e) { 4704 } 4705 return false; 4706 } 4707 4708 public void setProcessLimit(int max) { 4709 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4710 "setProcessLimit()"); 4711 synchronized (this) { 4712 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4713 mProcessLimitOverride = max; 4714 } 4715 trimApplications(); 4716 } 4717 4718 public int getProcessLimit() { 4719 synchronized (this) { 4720 return mProcessLimitOverride; 4721 } 4722 } 4723 4724 void foregroundTokenDied(ForegroundToken token) { 4725 synchronized (ActivityManagerService.this) { 4726 synchronized (mPidsSelfLocked) { 4727 ForegroundToken cur 4728 = mForegroundProcesses.get(token.pid); 4729 if (cur != token) { 4730 return; 4731 } 4732 mForegroundProcesses.remove(token.pid); 4733 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4734 if (pr == null) { 4735 return; 4736 } 4737 pr.forcingToForeground = null; 4738 pr.foregroundServices = false; 4739 } 4740 updateOomAdjLocked(); 4741 } 4742 } 4743 4744 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4745 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4746 "setProcessForeground()"); 4747 synchronized(this) { 4748 boolean changed = false; 4749 4750 synchronized (mPidsSelfLocked) { 4751 ProcessRecord pr = mPidsSelfLocked.get(pid); 4752 if (pr == null && isForeground) { 4753 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4754 return; 4755 } 4756 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4757 if (oldToken != null) { 4758 oldToken.token.unlinkToDeath(oldToken, 0); 4759 mForegroundProcesses.remove(pid); 4760 if (pr != null) { 4761 pr.forcingToForeground = null; 4762 } 4763 changed = true; 4764 } 4765 if (isForeground && token != null) { 4766 ForegroundToken newToken = new ForegroundToken() { 4767 public void binderDied() { 4768 foregroundTokenDied(this); 4769 } 4770 }; 4771 newToken.pid = pid; 4772 newToken.token = token; 4773 try { 4774 token.linkToDeath(newToken, 0); 4775 mForegroundProcesses.put(pid, newToken); 4776 pr.forcingToForeground = token; 4777 changed = true; 4778 } catch (RemoteException e) { 4779 // If the process died while doing this, we will later 4780 // do the cleanup with the process death link. 4781 } 4782 } 4783 } 4784 4785 if (changed) { 4786 updateOomAdjLocked(); 4787 } 4788 } 4789 } 4790 4791 // ========================================================= 4792 // PERMISSIONS 4793 // ========================================================= 4794 4795 static class PermissionController extends IPermissionController.Stub { 4796 ActivityManagerService mActivityManagerService; 4797 PermissionController(ActivityManagerService activityManagerService) { 4798 mActivityManagerService = activityManagerService; 4799 } 4800 4801 public boolean checkPermission(String permission, int pid, int uid) { 4802 return mActivityManagerService.checkPermission(permission, pid, 4803 uid) == PackageManager.PERMISSION_GRANTED; 4804 } 4805 } 4806 4807 /** 4808 * This can be called with or without the global lock held. 4809 */ 4810 int checkComponentPermission(String permission, int pid, int uid, 4811 int owningUid, boolean exported) { 4812 // We might be performing an operation on behalf of an indirect binder 4813 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4814 // client identity accordingly before proceeding. 4815 Identity tlsIdentity = sCallerIdentity.get(); 4816 if (tlsIdentity != null) { 4817 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4818 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4819 uid = tlsIdentity.uid; 4820 pid = tlsIdentity.pid; 4821 } 4822 4823 if (pid == MY_PID) { 4824 return PackageManager.PERMISSION_GRANTED; 4825 } 4826 4827 return ActivityManager.checkComponentPermission(permission, uid, 4828 owningUid, exported); 4829 } 4830 4831 /** 4832 * As the only public entry point for permissions checking, this method 4833 * can enforce the semantic that requesting a check on a null global 4834 * permission is automatically denied. (Internally a null permission 4835 * string is used when calling {@link #checkComponentPermission} in cases 4836 * when only uid-based security is needed.) 4837 * 4838 * This can be called with or without the global lock held. 4839 */ 4840 public int checkPermission(String permission, int pid, int uid) { 4841 if (permission == null) { 4842 return PackageManager.PERMISSION_DENIED; 4843 } 4844 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4845 } 4846 4847 /** 4848 * Binder IPC calls go through the public entry point. 4849 * This can be called with or without the global lock held. 4850 */ 4851 int checkCallingPermission(String permission) { 4852 return checkPermission(permission, 4853 Binder.getCallingPid(), 4854 UserHandle.getAppId(Binder.getCallingUid())); 4855 } 4856 4857 /** 4858 * This can be called with or without the global lock held. 4859 */ 4860 void enforceCallingPermission(String permission, String func) { 4861 if (checkCallingPermission(permission) 4862 == PackageManager.PERMISSION_GRANTED) { 4863 return; 4864 } 4865 4866 String msg = "Permission Denial: " + func + " from pid=" 4867 + Binder.getCallingPid() 4868 + ", uid=" + Binder.getCallingUid() 4869 + " requires " + permission; 4870 Slog.w(TAG, msg); 4871 throw new SecurityException(msg); 4872 } 4873 4874 /** 4875 * Determine if UID is holding permissions required to access {@link Uri} in 4876 * the given {@link ProviderInfo}. Final permission checking is always done 4877 * in {@link ContentProvider}. 4878 */ 4879 private final boolean checkHoldingPermissionsLocked( 4880 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4881 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4882 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4883 4884 if (pi.applicationInfo.uid == uid) { 4885 return true; 4886 } else if (!pi.exported) { 4887 return false; 4888 } 4889 4890 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4891 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4892 try { 4893 // check if target holds top-level <provider> permissions 4894 if (!readMet && pi.readPermission != null 4895 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4896 readMet = true; 4897 } 4898 if (!writeMet && pi.writePermission != null 4899 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4900 writeMet = true; 4901 } 4902 4903 // track if unprotected read/write is allowed; any denied 4904 // <path-permission> below removes this ability 4905 boolean allowDefaultRead = pi.readPermission == null; 4906 boolean allowDefaultWrite = pi.writePermission == null; 4907 4908 // check if target holds any <path-permission> that match uri 4909 final PathPermission[] pps = pi.pathPermissions; 4910 if (pps != null) { 4911 final String path = uri.getPath(); 4912 int i = pps.length; 4913 while (i > 0 && (!readMet || !writeMet)) { 4914 i--; 4915 PathPermission pp = pps[i]; 4916 if (pp.match(path)) { 4917 if (!readMet) { 4918 final String pprperm = pp.getReadPermission(); 4919 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4920 + pprperm + " for " + pp.getPath() 4921 + ": match=" + pp.match(path) 4922 + " check=" + pm.checkUidPermission(pprperm, uid)); 4923 if (pprperm != null) { 4924 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4925 readMet = true; 4926 } else { 4927 allowDefaultRead = false; 4928 } 4929 } 4930 } 4931 if (!writeMet) { 4932 final String ppwperm = pp.getWritePermission(); 4933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4934 + ppwperm + " for " + pp.getPath() 4935 + ": match=" + pp.match(path) 4936 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4937 if (ppwperm != null) { 4938 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4939 writeMet = true; 4940 } else { 4941 allowDefaultWrite = false; 4942 } 4943 } 4944 } 4945 } 4946 } 4947 } 4948 4949 // grant unprotected <provider> read/write, if not blocked by 4950 // <path-permission> above 4951 if (allowDefaultRead) readMet = true; 4952 if (allowDefaultWrite) writeMet = true; 4953 4954 } catch (RemoteException e) { 4955 return false; 4956 } 4957 4958 return readMet && writeMet; 4959 } 4960 4961 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4962 int modeFlags) { 4963 // Root gets to do everything. 4964 if (uid == 0) { 4965 return true; 4966 } 4967 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4968 if (perms == null) return false; 4969 UriPermission perm = perms.get(uri); 4970 if (perm == null) return false; 4971 return (modeFlags&perm.modeFlags) == modeFlags; 4972 } 4973 4974 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4975 enforceNotIsolatedCaller("checkUriPermission"); 4976 4977 // Another redirected-binder-call permissions check as in 4978 // {@link checkComponentPermission}. 4979 Identity tlsIdentity = sCallerIdentity.get(); 4980 if (tlsIdentity != null) { 4981 uid = tlsIdentity.uid; 4982 pid = tlsIdentity.pid; 4983 } 4984 4985 uid = UserHandle.getAppId(uid); 4986 // Our own process gets to do everything. 4987 if (pid == MY_PID) { 4988 return PackageManager.PERMISSION_GRANTED; 4989 } 4990 synchronized(this) { 4991 return checkUriPermissionLocked(uri, uid, modeFlags) 4992 ? PackageManager.PERMISSION_GRANTED 4993 : PackageManager.PERMISSION_DENIED; 4994 } 4995 } 4996 4997 /** 4998 * Check if the targetPkg can be granted permission to access uri by 4999 * the callingUid using the given modeFlags. Throws a security exception 5000 * if callingUid is not allowed to do this. Returns the uid of the target 5001 * if the URI permission grant should be performed; returns -1 if it is not 5002 * needed (for example targetPkg already has permission to access the URI). 5003 * If you already know the uid of the target, you can supply it in 5004 * lastTargetUid else set that to -1. 5005 */ 5006 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5007 Uri uri, int modeFlags, int lastTargetUid) { 5008 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5009 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5010 if (modeFlags == 0) { 5011 return -1; 5012 } 5013 5014 if (targetPkg != null) { 5015 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5016 "Checking grant " + targetPkg + " permission to " + uri); 5017 } 5018 5019 final IPackageManager pm = AppGlobals.getPackageManager(); 5020 5021 // If this is not a content: uri, we can't do anything with it. 5022 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5023 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5024 "Can't grant URI permission for non-content URI: " + uri); 5025 return -1; 5026 } 5027 5028 String name = uri.getAuthority(); 5029 ProviderInfo pi = null; 5030 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5031 UserHandle.getUserId(callingUid)); 5032 if (cpr != null) { 5033 pi = cpr.info; 5034 } else { 5035 try { 5036 pi = pm.resolveContentProvider(name, 5037 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 5038 } catch (RemoteException ex) { 5039 } 5040 } 5041 if (pi == null) { 5042 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5043 return -1; 5044 } 5045 5046 int targetUid = lastTargetUid; 5047 if (targetUid < 0 && targetPkg != null) { 5048 try { 5049 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5050 if (targetUid < 0) { 5051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5052 "Can't grant URI permission no uid for: " + targetPkg); 5053 return -1; 5054 } 5055 } catch (RemoteException ex) { 5056 return -1; 5057 } 5058 } 5059 5060 if (targetUid >= 0) { 5061 // First... does the target actually need this permission? 5062 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5063 // No need to grant the target this permission. 5064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5065 "Target " + targetPkg + " already has full permission to " + uri); 5066 return -1; 5067 } 5068 } else { 5069 // First... there is no target package, so can anyone access it? 5070 boolean allowed = pi.exported; 5071 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5072 if (pi.readPermission != null) { 5073 allowed = false; 5074 } 5075 } 5076 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5077 if (pi.writePermission != null) { 5078 allowed = false; 5079 } 5080 } 5081 if (allowed) { 5082 return -1; 5083 } 5084 } 5085 5086 // Second... is the provider allowing granting of URI permissions? 5087 if (!pi.grantUriPermissions) { 5088 throw new SecurityException("Provider " + pi.packageName 5089 + "/" + pi.name 5090 + " does not allow granting of Uri permissions (uri " 5091 + uri + ")"); 5092 } 5093 if (pi.uriPermissionPatterns != null) { 5094 final int N = pi.uriPermissionPatterns.length; 5095 boolean allowed = false; 5096 for (int i=0; i<N; i++) { 5097 if (pi.uriPermissionPatterns[i] != null 5098 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5099 allowed = true; 5100 break; 5101 } 5102 } 5103 if (!allowed) { 5104 throw new SecurityException("Provider " + pi.packageName 5105 + "/" + pi.name 5106 + " does not allow granting of permission to path of Uri " 5107 + uri); 5108 } 5109 } 5110 5111 // Third... does the caller itself have permission to access 5112 // this uri? 5113 if (callingUid != Process.myUid()) { 5114 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5115 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5116 throw new SecurityException("Uid " + callingUid 5117 + " does not have permission to uri " + uri); 5118 } 5119 } 5120 } 5121 5122 return targetUid; 5123 } 5124 5125 public int checkGrantUriPermission(int callingUid, String targetPkg, 5126 Uri uri, int modeFlags) { 5127 enforceNotIsolatedCaller("checkGrantUriPermission"); 5128 synchronized(this) { 5129 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5130 } 5131 } 5132 5133 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5134 Uri uri, int modeFlags, UriPermissionOwner owner) { 5135 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5136 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5137 if (modeFlags == 0) { 5138 return; 5139 } 5140 5141 // So here we are: the caller has the assumed permission 5142 // to the uri, and the target doesn't. Let's now give this to 5143 // the target. 5144 5145 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5146 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5147 5148 HashMap<Uri, UriPermission> targetUris 5149 = mGrantedUriPermissions.get(targetUid); 5150 if (targetUris == null) { 5151 targetUris = new HashMap<Uri, UriPermission>(); 5152 mGrantedUriPermissions.put(targetUid, targetUris); 5153 } 5154 5155 UriPermission perm = targetUris.get(uri); 5156 if (perm == null) { 5157 perm = new UriPermission(targetUid, uri); 5158 targetUris.put(uri, perm); 5159 } 5160 5161 perm.modeFlags |= modeFlags; 5162 if (owner == null) { 5163 perm.globalModeFlags |= modeFlags; 5164 } else { 5165 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5166 perm.readOwners.add(owner); 5167 owner.addReadPermission(perm); 5168 } 5169 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5170 perm.writeOwners.add(owner); 5171 owner.addWritePermission(perm); 5172 } 5173 } 5174 } 5175 5176 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5177 int modeFlags, UriPermissionOwner owner) { 5178 if (targetPkg == null) { 5179 throw new NullPointerException("targetPkg"); 5180 } 5181 5182 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5183 if (targetUid < 0) { 5184 return; 5185 } 5186 5187 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5188 } 5189 5190 static class NeededUriGrants extends ArrayList<Uri> { 5191 final String targetPkg; 5192 final int targetUid; 5193 final int flags; 5194 5195 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5196 targetPkg = _targetPkg; 5197 targetUid = _targetUid; 5198 flags = _flags; 5199 } 5200 } 5201 5202 /** 5203 * Like checkGrantUriPermissionLocked, but takes an Intent. 5204 */ 5205 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5206 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5207 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5208 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5209 + " clip=" + (intent != null ? intent.getClipData() : null) 5210 + " from " + intent + "; flags=0x" 5211 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5212 5213 if (targetPkg == null) { 5214 throw new NullPointerException("targetPkg"); 5215 } 5216 5217 if (intent == null) { 5218 return null; 5219 } 5220 Uri data = intent.getData(); 5221 ClipData clip = intent.getClipData(); 5222 if (data == null && clip == null) { 5223 return null; 5224 } 5225 if (data != null) { 5226 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5227 mode, needed != null ? needed.targetUid : -1); 5228 if (target > 0) { 5229 if (needed == null) { 5230 needed = new NeededUriGrants(targetPkg, target, mode); 5231 } 5232 needed.add(data); 5233 } 5234 } 5235 if (clip != null) { 5236 for (int i=0; i<clip.getItemCount(); i++) { 5237 Uri uri = clip.getItemAt(i).getUri(); 5238 if (uri != null) { 5239 int target = -1; 5240 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5241 mode, needed != null ? needed.targetUid : -1); 5242 if (target > 0) { 5243 if (needed == null) { 5244 needed = new NeededUriGrants(targetPkg, target, mode); 5245 } 5246 needed.add(uri); 5247 } 5248 } else { 5249 Intent clipIntent = clip.getItemAt(i).getIntent(); 5250 if (clipIntent != null) { 5251 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5252 callingUid, targetPkg, clipIntent, mode, needed); 5253 if (newNeeded != null) { 5254 needed = newNeeded; 5255 } 5256 } 5257 } 5258 } 5259 } 5260 5261 return needed; 5262 } 5263 5264 /** 5265 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5266 */ 5267 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5268 UriPermissionOwner owner) { 5269 if (needed != null) { 5270 for (int i=0; i<needed.size(); i++) { 5271 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5272 needed.get(i), needed.flags, owner); 5273 } 5274 } 5275 } 5276 5277 void grantUriPermissionFromIntentLocked(int callingUid, 5278 String targetPkg, Intent intent, UriPermissionOwner owner) { 5279 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5280 intent, intent != null ? intent.getFlags() : 0, null); 5281 if (needed == null) { 5282 return; 5283 } 5284 5285 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5286 } 5287 5288 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5289 Uri uri, int modeFlags) { 5290 enforceNotIsolatedCaller("grantUriPermission"); 5291 synchronized(this) { 5292 final ProcessRecord r = getRecordForAppLocked(caller); 5293 if (r == null) { 5294 throw new SecurityException("Unable to find app for caller " 5295 + caller 5296 + " when granting permission to uri " + uri); 5297 } 5298 if (targetPkg == null) { 5299 throw new IllegalArgumentException("null target"); 5300 } 5301 if (uri == null) { 5302 throw new IllegalArgumentException("null uri"); 5303 } 5304 5305 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5306 null); 5307 } 5308 } 5309 5310 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5311 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5312 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5313 HashMap<Uri, UriPermission> perms 5314 = mGrantedUriPermissions.get(perm.uid); 5315 if (perms != null) { 5316 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5317 "Removing " + perm.uid + " permission to " + perm.uri); 5318 perms.remove(perm.uri); 5319 if (perms.size() == 0) { 5320 mGrantedUriPermissions.remove(perm.uid); 5321 } 5322 } 5323 } 5324 } 5325 5326 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5327 int modeFlags) { 5328 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5329 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5330 if (modeFlags == 0) { 5331 return; 5332 } 5333 5334 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5335 "Revoking all granted permissions to " + uri); 5336 5337 final IPackageManager pm = AppGlobals.getPackageManager(); 5338 5339 final String authority = uri.getAuthority(); 5340 ProviderInfo pi = null; 5341 int userId = UserHandle.getUserId(callingUid); 5342 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5343 if (cpr != null) { 5344 pi = cpr.info; 5345 } else { 5346 try { 5347 pi = pm.resolveContentProvider(authority, 5348 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5349 } catch (RemoteException ex) { 5350 } 5351 } 5352 if (pi == null) { 5353 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5354 return; 5355 } 5356 5357 // Does the caller have this permission on the URI? 5358 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5359 // Right now, if you are not the original owner of the permission, 5360 // you are not allowed to revoke it. 5361 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5362 throw new SecurityException("Uid " + callingUid 5363 + " does not have permission to uri " + uri); 5364 //} 5365 } 5366 5367 // Go through all of the permissions and remove any that match. 5368 final List<String> SEGMENTS = uri.getPathSegments(); 5369 if (SEGMENTS != null) { 5370 final int NS = SEGMENTS.size(); 5371 int N = mGrantedUriPermissions.size(); 5372 for (int i=0; i<N; i++) { 5373 HashMap<Uri, UriPermission> perms 5374 = mGrantedUriPermissions.valueAt(i); 5375 Iterator<UriPermission> it = perms.values().iterator(); 5376 toploop: 5377 while (it.hasNext()) { 5378 UriPermission perm = it.next(); 5379 Uri targetUri = perm.uri; 5380 if (!authority.equals(targetUri.getAuthority())) { 5381 continue; 5382 } 5383 List<String> targetSegments = targetUri.getPathSegments(); 5384 if (targetSegments == null) { 5385 continue; 5386 } 5387 if (targetSegments.size() < NS) { 5388 continue; 5389 } 5390 for (int j=0; j<NS; j++) { 5391 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5392 continue toploop; 5393 } 5394 } 5395 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5396 "Revoking " + perm.uid + " permission to " + perm.uri); 5397 perm.clearModes(modeFlags); 5398 if (perm.modeFlags == 0) { 5399 it.remove(); 5400 } 5401 } 5402 if (perms.size() == 0) { 5403 mGrantedUriPermissions.remove( 5404 mGrantedUriPermissions.keyAt(i)); 5405 N--; 5406 i--; 5407 } 5408 } 5409 } 5410 } 5411 5412 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5413 int modeFlags) { 5414 enforceNotIsolatedCaller("revokeUriPermission"); 5415 synchronized(this) { 5416 final ProcessRecord r = getRecordForAppLocked(caller); 5417 if (r == null) { 5418 throw new SecurityException("Unable to find app for caller " 5419 + caller 5420 + " when revoking permission to uri " + uri); 5421 } 5422 if (uri == null) { 5423 Slog.w(TAG, "revokeUriPermission: null uri"); 5424 return; 5425 } 5426 5427 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5428 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5429 if (modeFlags == 0) { 5430 return; 5431 } 5432 5433 final IPackageManager pm = AppGlobals.getPackageManager(); 5434 5435 final String authority = uri.getAuthority(); 5436 ProviderInfo pi = null; 5437 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5438 if (cpr != null) { 5439 pi = cpr.info; 5440 } else { 5441 try { 5442 pi = pm.resolveContentProvider(authority, 5443 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5444 } catch (RemoteException ex) { 5445 } 5446 } 5447 if (pi == null) { 5448 Slog.w(TAG, "No content provider found for permission revoke: " 5449 + uri.toSafeString()); 5450 return; 5451 } 5452 5453 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5454 } 5455 } 5456 5457 @Override 5458 public IBinder newUriPermissionOwner(String name) { 5459 enforceNotIsolatedCaller("newUriPermissionOwner"); 5460 synchronized(this) { 5461 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5462 return owner.getExternalTokenLocked(); 5463 } 5464 } 5465 5466 @Override 5467 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5468 Uri uri, int modeFlags) { 5469 synchronized(this) { 5470 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5471 if (owner == null) { 5472 throw new IllegalArgumentException("Unknown owner: " + token); 5473 } 5474 if (fromUid != Binder.getCallingUid()) { 5475 if (Binder.getCallingUid() != Process.myUid()) { 5476 // Only system code can grant URI permissions on behalf 5477 // of other users. 5478 throw new SecurityException("nice try"); 5479 } 5480 } 5481 if (targetPkg == null) { 5482 throw new IllegalArgumentException("null target"); 5483 } 5484 if (uri == null) { 5485 throw new IllegalArgumentException("null uri"); 5486 } 5487 5488 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5489 } 5490 } 5491 5492 @Override 5493 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5494 synchronized(this) { 5495 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5496 if (owner == null) { 5497 throw new IllegalArgumentException("Unknown owner: " + token); 5498 } 5499 5500 if (uri == null) { 5501 owner.removeUriPermissionsLocked(mode); 5502 } else { 5503 owner.removeUriPermissionLocked(uri, mode); 5504 } 5505 } 5506 } 5507 5508 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5509 synchronized (this) { 5510 ProcessRecord app = 5511 who != null ? getRecordForAppLocked(who) : null; 5512 if (app == null) return; 5513 5514 Message msg = Message.obtain(); 5515 msg.what = WAIT_FOR_DEBUGGER_MSG; 5516 msg.obj = app; 5517 msg.arg1 = waiting ? 1 : 0; 5518 mHandler.sendMessage(msg); 5519 } 5520 } 5521 5522 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5523 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5524 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5525 outInfo.availMem = Process.getFreeMemory(); 5526 outInfo.totalMem = Process.getTotalMemory(); 5527 outInfo.threshold = homeAppMem; 5528 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5529 outInfo.hiddenAppThreshold = hiddenAppMem; 5530 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5531 ProcessList.SERVICE_ADJ); 5532 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5533 ProcessList.VISIBLE_APP_ADJ); 5534 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5535 ProcessList.FOREGROUND_APP_ADJ); 5536 } 5537 5538 // ========================================================= 5539 // TASK MANAGEMENT 5540 // ========================================================= 5541 5542 public List getTasks(int maxNum, int flags, 5543 IThumbnailReceiver receiver) { 5544 ArrayList list = new ArrayList(); 5545 5546 PendingThumbnailsRecord pending = null; 5547 IApplicationThread topThumbnail = null; 5548 ActivityRecord topRecord = null; 5549 5550 synchronized(this) { 5551 if (localLOGV) Slog.v( 5552 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5553 + ", receiver=" + receiver); 5554 5555 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5556 != PackageManager.PERMISSION_GRANTED) { 5557 if (receiver != null) { 5558 // If the caller wants to wait for pending thumbnails, 5559 // it ain't gonna get them. 5560 try { 5561 receiver.finished(); 5562 } catch (RemoteException ex) { 5563 } 5564 } 5565 String msg = "Permission Denial: getTasks() from pid=" 5566 + Binder.getCallingPid() 5567 + ", uid=" + Binder.getCallingUid() 5568 + " requires " + android.Manifest.permission.GET_TASKS; 5569 Slog.w(TAG, msg); 5570 throw new SecurityException(msg); 5571 } 5572 5573 int pos = mMainStack.mHistory.size()-1; 5574 ActivityRecord next = 5575 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5576 ActivityRecord top = null; 5577 TaskRecord curTask = null; 5578 int numActivities = 0; 5579 int numRunning = 0; 5580 while (pos >= 0 && maxNum > 0) { 5581 final ActivityRecord r = next; 5582 pos--; 5583 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5584 5585 // Initialize state for next task if needed. 5586 if (top == null || 5587 (top.state == ActivityState.INITIALIZING 5588 && top.task == r.task)) { 5589 top = r; 5590 curTask = r.task; 5591 numActivities = numRunning = 0; 5592 } 5593 5594 // Add 'r' into the current task. 5595 numActivities++; 5596 if (r.app != null && r.app.thread != null) { 5597 numRunning++; 5598 } 5599 5600 if (localLOGV) Slog.v( 5601 TAG, r.intent.getComponent().flattenToShortString() 5602 + ": task=" + r.task); 5603 5604 // If the next one is a different task, generate a new 5605 // TaskInfo entry for what we have. 5606 if (next == null || next.task != curTask) { 5607 ActivityManager.RunningTaskInfo ci 5608 = new ActivityManager.RunningTaskInfo(); 5609 ci.id = curTask.taskId; 5610 ci.baseActivity = r.intent.getComponent(); 5611 ci.topActivity = top.intent.getComponent(); 5612 if (top.thumbHolder != null) { 5613 ci.description = top.thumbHolder.lastDescription; 5614 } 5615 ci.numActivities = numActivities; 5616 ci.numRunning = numRunning; 5617 //System.out.println( 5618 // "#" + maxNum + ": " + " descr=" + ci.description); 5619 if (ci.thumbnail == null && receiver != null) { 5620 if (localLOGV) Slog.v( 5621 TAG, "State=" + top.state + "Idle=" + top.idle 5622 + " app=" + top.app 5623 + " thr=" + (top.app != null ? top.app.thread : null)); 5624 if (top.state == ActivityState.RESUMED 5625 || top.state == ActivityState.PAUSING) { 5626 if (top.idle && top.app != null 5627 && top.app.thread != null) { 5628 topRecord = top; 5629 topThumbnail = top.app.thread; 5630 } else { 5631 top.thumbnailNeeded = true; 5632 } 5633 } 5634 if (pending == null) { 5635 pending = new PendingThumbnailsRecord(receiver); 5636 } 5637 pending.pendingRecords.add(top); 5638 } 5639 list.add(ci); 5640 maxNum--; 5641 top = null; 5642 } 5643 } 5644 5645 if (pending != null) { 5646 mPendingThumbnails.add(pending); 5647 } 5648 } 5649 5650 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5651 5652 if (topThumbnail != null) { 5653 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5654 try { 5655 topThumbnail.requestThumbnail(topRecord.appToken); 5656 } catch (Exception e) { 5657 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5658 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5659 } 5660 } 5661 5662 if (pending == null && receiver != null) { 5663 // In this case all thumbnails were available and the client 5664 // is being asked to be told when the remaining ones come in... 5665 // which is unusually, since the top-most currently running 5666 // activity should never have a canned thumbnail! Oh well. 5667 try { 5668 receiver.finished(); 5669 } catch (RemoteException ex) { 5670 } 5671 } 5672 5673 return list; 5674 } 5675 5676 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5677 int flags, int userId) { 5678 final int callingUid = Binder.getCallingUid(); 5679 if (userId != UserHandle.getCallingUserId()) { 5680 // Check if the caller is holding permissions for cross-user requests. 5681 if (checkComponentPermission( 5682 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5683 Binder.getCallingPid(), callingUid, -1, true) 5684 != PackageManager.PERMISSION_GRANTED) { 5685 String msg = "Permission Denial: " 5686 + "Request to get recent tasks for user " + userId 5687 + " but is calling from user " + UserHandle.getUserId(callingUid) 5688 + "; this requires " 5689 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5690 Slog.w(TAG, msg); 5691 throw new SecurityException(msg); 5692 } else { 5693 if (userId == UserHandle.USER_CURRENT) { 5694 userId = mCurrentUserId; 5695 } 5696 } 5697 } 5698 5699 synchronized (this) { 5700 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5701 "getRecentTasks()"); 5702 final boolean detailed = checkCallingPermission( 5703 android.Manifest.permission.GET_DETAILED_TASKS) 5704 == PackageManager.PERMISSION_GRANTED; 5705 5706 IPackageManager pm = AppGlobals.getPackageManager(); 5707 5708 final int N = mRecentTasks.size(); 5709 ArrayList<ActivityManager.RecentTaskInfo> res 5710 = new ArrayList<ActivityManager.RecentTaskInfo>( 5711 maxNum < N ? maxNum : N); 5712 for (int i=0; i<N && maxNum > 0; i++) { 5713 TaskRecord tr = mRecentTasks.get(i); 5714 // Only add calling user's recent tasks 5715 if (tr.userId != userId) continue; 5716 // Return the entry if desired by the caller. We always return 5717 // the first entry, because callers always expect this to be the 5718 // foreground app. We may filter others if the caller has 5719 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5720 // we should exclude the entry. 5721 5722 if (i == 0 5723 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5724 || (tr.intent == null) 5725 || ((tr.intent.getFlags() 5726 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5727 ActivityManager.RecentTaskInfo rti 5728 = new ActivityManager.RecentTaskInfo(); 5729 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5730 rti.persistentId = tr.taskId; 5731 rti.baseIntent = new Intent( 5732 tr.intent != null ? tr.intent : tr.affinityIntent); 5733 if (!detailed) { 5734 rti.baseIntent.replaceExtras((Bundle)null); 5735 } 5736 rti.origActivity = tr.origActivity; 5737 rti.description = tr.lastDescription; 5738 5739 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5740 // Check whether this activity is currently available. 5741 try { 5742 if (rti.origActivity != null) { 5743 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5744 == null) { 5745 continue; 5746 } 5747 } else if (rti.baseIntent != null) { 5748 if (pm.queryIntentActivities(rti.baseIntent, 5749 null, 0, userId) == null) { 5750 continue; 5751 } 5752 } 5753 } catch (RemoteException e) { 5754 // Will never happen. 5755 } 5756 } 5757 5758 res.add(rti); 5759 maxNum--; 5760 } 5761 } 5762 return res; 5763 } 5764 } 5765 5766 private TaskRecord taskForIdLocked(int id) { 5767 final int N = mRecentTasks.size(); 5768 for (int i=0; i<N; i++) { 5769 TaskRecord tr = mRecentTasks.get(i); 5770 if (tr.taskId == id) { 5771 return tr; 5772 } 5773 } 5774 return null; 5775 } 5776 5777 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5778 synchronized (this) { 5779 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5780 "getTaskThumbnails()"); 5781 TaskRecord tr = taskForIdLocked(id); 5782 if (tr != null) { 5783 return mMainStack.getTaskThumbnailsLocked(tr); 5784 } 5785 } 5786 return null; 5787 } 5788 5789 public boolean removeSubTask(int taskId, int subTaskIndex) { 5790 synchronized (this) { 5791 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5792 "removeSubTask()"); 5793 long ident = Binder.clearCallingIdentity(); 5794 try { 5795 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5796 true) != null; 5797 } finally { 5798 Binder.restoreCallingIdentity(ident); 5799 } 5800 } 5801 } 5802 5803 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5804 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5805 Intent baseIntent = new Intent( 5806 tr.intent != null ? tr.intent : tr.affinityIntent); 5807 ComponentName component = baseIntent.getComponent(); 5808 if (component == null) { 5809 Slog.w(TAG, "Now component for base intent of task: " + tr); 5810 return; 5811 } 5812 5813 // Find any running services associated with this app. 5814 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5815 5816 if (killProcesses) { 5817 // Find any running processes associated with this app. 5818 final String pkg = component.getPackageName(); 5819 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5820 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5821 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5822 for (int i=0; i<uids.size(); i++) { 5823 ProcessRecord proc = uids.valueAt(i); 5824 if (proc.userId != tr.userId) { 5825 continue; 5826 } 5827 if (!proc.pkgList.contains(pkg)) { 5828 continue; 5829 } 5830 procs.add(proc); 5831 } 5832 } 5833 5834 // Kill the running processes. 5835 for (int i=0; i<procs.size(); i++) { 5836 ProcessRecord pr = procs.get(i); 5837 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5838 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5839 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5840 pr.processName, pr.setAdj, "remove task"); 5841 pr.killedBackground = true; 5842 Process.killProcessQuiet(pr.pid); 5843 } else { 5844 pr.waitingToKill = "remove task"; 5845 } 5846 } 5847 } 5848 } 5849 5850 public boolean removeTask(int taskId, int flags) { 5851 synchronized (this) { 5852 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5853 "removeTask()"); 5854 long ident = Binder.clearCallingIdentity(); 5855 try { 5856 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5857 false); 5858 if (r != null) { 5859 mRecentTasks.remove(r.task); 5860 cleanUpRemovedTaskLocked(r.task, flags); 5861 return true; 5862 } else { 5863 TaskRecord tr = null; 5864 int i=0; 5865 while (i < mRecentTasks.size()) { 5866 TaskRecord t = mRecentTasks.get(i); 5867 if (t.taskId == taskId) { 5868 tr = t; 5869 break; 5870 } 5871 i++; 5872 } 5873 if (tr != null) { 5874 if (tr.numActivities <= 0) { 5875 // Caller is just removing a recent task that is 5876 // not actively running. That is easy! 5877 mRecentTasks.remove(i); 5878 cleanUpRemovedTaskLocked(tr, flags); 5879 return true; 5880 } else { 5881 Slog.w(TAG, "removeTask: task " + taskId 5882 + " does not have activities to remove, " 5883 + " but numActivities=" + tr.numActivities 5884 + ": " + tr); 5885 } 5886 } 5887 } 5888 } finally { 5889 Binder.restoreCallingIdentity(ident); 5890 } 5891 } 5892 return false; 5893 } 5894 5895 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5896 int j; 5897 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5898 TaskRecord jt = startTask; 5899 5900 // First look backwards 5901 for (j=startIndex-1; j>=0; j--) { 5902 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5903 if (r.task != jt) { 5904 jt = r.task; 5905 if (affinity.equals(jt.affinity)) { 5906 return j; 5907 } 5908 } 5909 } 5910 5911 // Now look forwards 5912 final int N = mMainStack.mHistory.size(); 5913 jt = startTask; 5914 for (j=startIndex+1; j<N; j++) { 5915 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5916 if (r.task != jt) { 5917 if (affinity.equals(jt.affinity)) { 5918 return j; 5919 } 5920 jt = r.task; 5921 } 5922 } 5923 5924 // Might it be at the top? 5925 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5926 return N-1; 5927 } 5928 5929 return -1; 5930 } 5931 5932 /** 5933 * TODO: Add mController hook 5934 */ 5935 public void moveTaskToFront(int task, int flags, Bundle options) { 5936 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5937 "moveTaskToFront()"); 5938 5939 synchronized(this) { 5940 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5941 Binder.getCallingUid(), "Task to front")) { 5942 ActivityOptions.abort(options); 5943 return; 5944 } 5945 final long origId = Binder.clearCallingIdentity(); 5946 try { 5947 TaskRecord tr = taskForIdLocked(task); 5948 if (tr != null) { 5949 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5950 mMainStack.mUserLeaving = true; 5951 } 5952 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5953 // Caller wants the home activity moved with it. To accomplish this, 5954 // we'll just move the home task to the top first. 5955 mMainStack.moveHomeToFrontLocked(); 5956 } 5957 mMainStack.moveTaskToFrontLocked(tr, null, options); 5958 return; 5959 } 5960 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5961 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5962 if (hr.task.taskId == task) { 5963 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5964 mMainStack.mUserLeaving = true; 5965 } 5966 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5967 // Caller wants the home activity moved with it. To accomplish this, 5968 // we'll just move the home task to the top first. 5969 mMainStack.moveHomeToFrontLocked(); 5970 } 5971 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5972 return; 5973 } 5974 } 5975 } finally { 5976 Binder.restoreCallingIdentity(origId); 5977 } 5978 ActivityOptions.abort(options); 5979 } 5980 } 5981 5982 public void moveTaskToBack(int task) { 5983 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5984 "moveTaskToBack()"); 5985 5986 synchronized(this) { 5987 if (mMainStack.mResumedActivity != null 5988 && mMainStack.mResumedActivity.task.taskId == task) { 5989 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5990 Binder.getCallingUid(), "Task to back")) { 5991 return; 5992 } 5993 } 5994 final long origId = Binder.clearCallingIdentity(); 5995 mMainStack.moveTaskToBackLocked(task, null); 5996 Binder.restoreCallingIdentity(origId); 5997 } 5998 } 5999 6000 /** 6001 * Moves an activity, and all of the other activities within the same task, to the bottom 6002 * of the history stack. The activity's order within the task is unchanged. 6003 * 6004 * @param token A reference to the activity we wish to move 6005 * @param nonRoot If false then this only works if the activity is the root 6006 * of a task; if true it will work for any activity in a task. 6007 * @return Returns true if the move completed, false if not. 6008 */ 6009 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6010 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6011 synchronized(this) { 6012 final long origId = Binder.clearCallingIdentity(); 6013 int taskId = getTaskForActivityLocked(token, !nonRoot); 6014 if (taskId >= 0) { 6015 return mMainStack.moveTaskToBackLocked(taskId, null); 6016 } 6017 Binder.restoreCallingIdentity(origId); 6018 } 6019 return false; 6020 } 6021 6022 public void moveTaskBackwards(int task) { 6023 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6024 "moveTaskBackwards()"); 6025 6026 synchronized(this) { 6027 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6028 Binder.getCallingUid(), "Task backwards")) { 6029 return; 6030 } 6031 final long origId = Binder.clearCallingIdentity(); 6032 moveTaskBackwardsLocked(task); 6033 Binder.restoreCallingIdentity(origId); 6034 } 6035 } 6036 6037 private final void moveTaskBackwardsLocked(int task) { 6038 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6039 } 6040 6041 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6042 synchronized(this) { 6043 return getTaskForActivityLocked(token, onlyRoot); 6044 } 6045 } 6046 6047 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6048 final int N = mMainStack.mHistory.size(); 6049 TaskRecord lastTask = null; 6050 for (int i=0; i<N; i++) { 6051 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6052 if (r.appToken == token) { 6053 if (!onlyRoot || lastTask != r.task) { 6054 return r.task.taskId; 6055 } 6056 return -1; 6057 } 6058 lastTask = r.task; 6059 } 6060 6061 return -1; 6062 } 6063 6064 // ========================================================= 6065 // THUMBNAILS 6066 // ========================================================= 6067 6068 public void reportThumbnail(IBinder token, 6069 Bitmap thumbnail, CharSequence description) { 6070 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6071 final long origId = Binder.clearCallingIdentity(); 6072 sendPendingThumbnail(null, token, thumbnail, description, true); 6073 Binder.restoreCallingIdentity(origId); 6074 } 6075 6076 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6077 Bitmap thumbnail, CharSequence description, boolean always) { 6078 TaskRecord task = null; 6079 ArrayList receivers = null; 6080 6081 //System.out.println("Send pending thumbnail: " + r); 6082 6083 synchronized(this) { 6084 if (r == null) { 6085 r = mMainStack.isInStackLocked(token); 6086 if (r == null) { 6087 return; 6088 } 6089 } 6090 if (thumbnail == null && r.thumbHolder != null) { 6091 thumbnail = r.thumbHolder.lastThumbnail; 6092 description = r.thumbHolder.lastDescription; 6093 } 6094 if (thumbnail == null && !always) { 6095 // If there is no thumbnail, and this entry is not actually 6096 // going away, then abort for now and pick up the next 6097 // thumbnail we get. 6098 return; 6099 } 6100 task = r.task; 6101 6102 int N = mPendingThumbnails.size(); 6103 int i=0; 6104 while (i<N) { 6105 PendingThumbnailsRecord pr = 6106 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6107 //System.out.println("Looking in " + pr.pendingRecords); 6108 if (pr.pendingRecords.remove(r)) { 6109 if (receivers == null) { 6110 receivers = new ArrayList(); 6111 } 6112 receivers.add(pr); 6113 if (pr.pendingRecords.size() == 0) { 6114 pr.finished = true; 6115 mPendingThumbnails.remove(i); 6116 N--; 6117 continue; 6118 } 6119 } 6120 i++; 6121 } 6122 } 6123 6124 if (receivers != null) { 6125 final int N = receivers.size(); 6126 for (int i=0; i<N; i++) { 6127 try { 6128 PendingThumbnailsRecord pr = 6129 (PendingThumbnailsRecord)receivers.get(i); 6130 pr.receiver.newThumbnail( 6131 task != null ? task.taskId : -1, thumbnail, description); 6132 if (pr.finished) { 6133 pr.receiver.finished(); 6134 } 6135 } catch (Exception e) { 6136 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6137 } 6138 } 6139 } 6140 } 6141 6142 // ========================================================= 6143 // CONTENT PROVIDERS 6144 // ========================================================= 6145 6146 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6147 List<ProviderInfo> providers = null; 6148 try { 6149 providers = AppGlobals.getPackageManager(). 6150 queryContentProviders(app.processName, app.uid, 6151 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6152 } catch (RemoteException ex) { 6153 } 6154 if (DEBUG_MU) 6155 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6156 int userId = app.userId; 6157 if (providers != null) { 6158 int N = providers.size(); 6159 for (int i=0; i<N; i++) { 6160 ProviderInfo cpi = 6161 (ProviderInfo)providers.get(i); 6162 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6163 cpi.name, cpi.flags); 6164 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6165 // This is a singleton provider, but a user besides the 6166 // default user is asking to initialize a process it runs 6167 // in... well, no, it doesn't actually run in this process, 6168 // it runs in the process of the default user. Get rid of it. 6169 providers.remove(i); 6170 N--; 6171 continue; 6172 } 6173 6174 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6175 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6176 if (cpr == null) { 6177 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6178 mProviderMap.putProviderByClass(comp, cpr); 6179 } 6180 if (DEBUG_MU) 6181 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6182 app.pubProviders.put(cpi.name, cpr); 6183 app.addPackage(cpi.applicationInfo.packageName); 6184 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6185 } 6186 } 6187 return providers; 6188 } 6189 6190 /** 6191 * Check if {@link ProcessRecord} has a possible chance at accessing the 6192 * given {@link ProviderInfo}. Final permission checking is always done 6193 * in {@link ContentProvider}. 6194 */ 6195 private final String checkContentProviderPermissionLocked( 6196 ProviderInfo cpi, ProcessRecord r) { 6197 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6198 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6199 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6200 cpi.applicationInfo.uid, cpi.exported) 6201 == PackageManager.PERMISSION_GRANTED) { 6202 return null; 6203 } 6204 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6205 cpi.applicationInfo.uid, cpi.exported) 6206 == PackageManager.PERMISSION_GRANTED) { 6207 return null; 6208 } 6209 6210 PathPermission[] pps = cpi.pathPermissions; 6211 if (pps != null) { 6212 int i = pps.length; 6213 while (i > 0) { 6214 i--; 6215 PathPermission pp = pps[i]; 6216 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6217 cpi.applicationInfo.uid, cpi.exported) 6218 == PackageManager.PERMISSION_GRANTED) { 6219 return null; 6220 } 6221 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6222 cpi.applicationInfo.uid, cpi.exported) 6223 == PackageManager.PERMISSION_GRANTED) { 6224 return null; 6225 } 6226 } 6227 } 6228 6229 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6230 if (perms != null) { 6231 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6232 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6233 return null; 6234 } 6235 } 6236 } 6237 6238 String msg; 6239 if (!cpi.exported) { 6240 msg = "Permission Denial: opening provider " + cpi.name 6241 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6242 + ", uid=" + callingUid + ") that is not exported from uid " 6243 + cpi.applicationInfo.uid; 6244 } else { 6245 msg = "Permission Denial: opening provider " + cpi.name 6246 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6247 + ", uid=" + callingUid + ") requires " 6248 + cpi.readPermission + " or " + cpi.writePermission; 6249 } 6250 Slog.w(TAG, msg); 6251 return msg; 6252 } 6253 6254 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6255 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6256 if (r != null) { 6257 for (int i=0; i<r.conProviders.size(); i++) { 6258 ContentProviderConnection conn = r.conProviders.get(i); 6259 if (conn.provider == cpr) { 6260 if (DEBUG_PROVIDER) Slog.v(TAG, 6261 "Adding provider requested by " 6262 + r.processName + " from process " 6263 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6264 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6265 if (stable) { 6266 conn.stableCount++; 6267 conn.numStableIncs++; 6268 } else { 6269 conn.unstableCount++; 6270 conn.numUnstableIncs++; 6271 } 6272 return conn; 6273 } 6274 } 6275 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6276 if (stable) { 6277 conn.stableCount = 1; 6278 conn.numStableIncs = 1; 6279 } else { 6280 conn.unstableCount = 1; 6281 conn.numUnstableIncs = 1; 6282 } 6283 cpr.connections.add(conn); 6284 r.conProviders.add(conn); 6285 return conn; 6286 } 6287 cpr.addExternalProcessHandleLocked(externalProcessToken); 6288 return null; 6289 } 6290 6291 boolean decProviderCountLocked(ContentProviderConnection conn, 6292 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6293 if (conn != null) { 6294 cpr = conn.provider; 6295 if (DEBUG_PROVIDER) Slog.v(TAG, 6296 "Removing provider requested by " 6297 + conn.client.processName + " from process " 6298 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6299 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6300 if (stable) { 6301 conn.stableCount--; 6302 } else { 6303 conn.unstableCount--; 6304 } 6305 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6306 cpr.connections.remove(conn); 6307 conn.client.conProviders.remove(conn); 6308 return true; 6309 } 6310 return false; 6311 } 6312 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6313 return false; 6314 } 6315 6316 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6317 String name, IBinder token, boolean stable, int userId) { 6318 ContentProviderRecord cpr; 6319 ContentProviderConnection conn = null; 6320 ProviderInfo cpi = null; 6321 6322 synchronized(this) { 6323 ProcessRecord r = null; 6324 if (caller != null) { 6325 r = getRecordForAppLocked(caller); 6326 if (r == null) { 6327 throw new SecurityException( 6328 "Unable to find app for caller " + caller 6329 + " (pid=" + Binder.getCallingPid() 6330 + ") when getting content provider " + name); 6331 } 6332 if (r.userId != userId) { 6333 throw new SecurityException("Calling requested user " + userId 6334 + " but app is user " + r.userId); 6335 } 6336 } 6337 6338 // First check if this content provider has been published... 6339 cpr = mProviderMap.getProviderByName(name, userId); 6340 boolean providerRunning = cpr != null; 6341 if (providerRunning) { 6342 cpi = cpr.info; 6343 String msg; 6344 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6345 throw new SecurityException(msg); 6346 } 6347 6348 if (r != null && cpr.canRunHere(r)) { 6349 // This provider has been published or is in the process 6350 // of being published... but it is also allowed to run 6351 // in the caller's process, so don't make a connection 6352 // and just let the caller instantiate its own instance. 6353 ContentProviderHolder holder = cpr.newHolder(null); 6354 // don't give caller the provider object, it needs 6355 // to make its own. 6356 holder.provider = null; 6357 return holder; 6358 } 6359 6360 final long origId = Binder.clearCallingIdentity(); 6361 6362 // In this case the provider instance already exists, so we can 6363 // return it right away. 6364 conn = incProviderCountLocked(r, cpr, token, stable); 6365 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6366 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6367 // If this is a perceptible app accessing the provider, 6368 // make sure to count it as being accessed and thus 6369 // back up on the LRU list. This is good because 6370 // content providers are often expensive to start. 6371 updateLruProcessLocked(cpr.proc, false, true); 6372 } 6373 } 6374 6375 if (cpr.proc != null) { 6376 if (false) { 6377 if (cpr.name.flattenToShortString().equals( 6378 "com.android.providers.calendar/.CalendarProvider2")) { 6379 Slog.v(TAG, "****************** KILLING " 6380 + cpr.name.flattenToShortString()); 6381 Process.killProcess(cpr.proc.pid); 6382 } 6383 } 6384 boolean success = updateOomAdjLocked(cpr.proc); 6385 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6386 // NOTE: there is still a race here where a signal could be 6387 // pending on the process even though we managed to update its 6388 // adj level. Not sure what to do about this, but at least 6389 // the race is now smaller. 6390 if (!success) { 6391 // Uh oh... it looks like the provider's process 6392 // has been killed on us. We need to wait for a new 6393 // process to be started, and make sure its death 6394 // doesn't kill our process. 6395 Slog.i(TAG, 6396 "Existing provider " + cpr.name.flattenToShortString() 6397 + " is crashing; detaching " + r); 6398 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6399 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6400 if (!lastRef) { 6401 // This wasn't the last ref our process had on 6402 // the provider... we have now been killed, bail. 6403 return null; 6404 } 6405 providerRunning = false; 6406 conn = null; 6407 } 6408 } 6409 6410 Binder.restoreCallingIdentity(origId); 6411 } 6412 6413 boolean singleton; 6414 if (!providerRunning) { 6415 try { 6416 cpi = AppGlobals.getPackageManager(). 6417 resolveContentProvider(name, 6418 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6419 } catch (RemoteException ex) { 6420 } 6421 if (cpi == null) { 6422 return null; 6423 } 6424 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6425 cpi.name, cpi.flags); 6426 if (singleton) { 6427 userId = 0; 6428 } 6429 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6430 6431 String msg; 6432 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6433 throw new SecurityException(msg); 6434 } 6435 6436 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6437 && !cpi.processName.equals("system")) { 6438 // If this content provider does not run in the system 6439 // process, and the system is not yet ready to run other 6440 // processes, then fail fast instead of hanging. 6441 throw new IllegalArgumentException( 6442 "Attempt to launch content provider before system ready"); 6443 } 6444 6445 // Make sure that the user who owns this provider is started. If not, 6446 // we don't want to allow it to run. 6447 if (mStartedUsers.get(userId) == null) { 6448 Slog.w(TAG, "Unable to launch app " 6449 + cpi.applicationInfo.packageName + "/" 6450 + cpi.applicationInfo.uid + " for provider " 6451 + name + ": user " + userId + " is stopped"); 6452 return null; 6453 } 6454 6455 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6456 cpr = mProviderMap.getProviderByClass(comp, userId); 6457 final boolean firstClass = cpr == null; 6458 if (firstClass) { 6459 try { 6460 ApplicationInfo ai = 6461 AppGlobals.getPackageManager(). 6462 getApplicationInfo( 6463 cpi.applicationInfo.packageName, 6464 STOCK_PM_FLAGS, userId); 6465 if (ai == null) { 6466 Slog.w(TAG, "No package info for content provider " 6467 + cpi.name); 6468 return null; 6469 } 6470 ai = getAppInfoForUser(ai, userId); 6471 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6472 } catch (RemoteException ex) { 6473 // pm is in same process, this will never happen. 6474 } 6475 } 6476 6477 if (r != null && cpr.canRunHere(r)) { 6478 // If this is a multiprocess provider, then just return its 6479 // info and allow the caller to instantiate it. Only do 6480 // this if the provider is the same user as the caller's 6481 // process, or can run as root (so can be in any process). 6482 return cpr.newHolder(null); 6483 } 6484 6485 if (DEBUG_PROVIDER) { 6486 RuntimeException e = new RuntimeException("here"); 6487 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6488 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6489 } 6490 6491 // This is single process, and our app is now connecting to it. 6492 // See if we are already in the process of launching this 6493 // provider. 6494 final int N = mLaunchingProviders.size(); 6495 int i; 6496 for (i=0; i<N; i++) { 6497 if (mLaunchingProviders.get(i) == cpr) { 6498 break; 6499 } 6500 } 6501 6502 // If the provider is not already being launched, then get it 6503 // started. 6504 if (i >= N) { 6505 final long origId = Binder.clearCallingIdentity(); 6506 6507 try { 6508 // Content provider is now in use, its package can't be stopped. 6509 try { 6510 AppGlobals.getPackageManager().setPackageStoppedState( 6511 cpr.appInfo.packageName, false, userId); 6512 } catch (RemoteException e) { 6513 } catch (IllegalArgumentException e) { 6514 Slog.w(TAG, "Failed trying to unstop package " 6515 + cpr.appInfo.packageName + ": " + e); 6516 } 6517 6518 ProcessRecord proc = startProcessLocked(cpi.processName, 6519 cpr.appInfo, false, 0, "content provider", 6520 new ComponentName(cpi.applicationInfo.packageName, 6521 cpi.name), false, false); 6522 if (proc == null) { 6523 Slog.w(TAG, "Unable to launch app " 6524 + cpi.applicationInfo.packageName + "/" 6525 + cpi.applicationInfo.uid + " for provider " 6526 + name + ": process is bad"); 6527 return null; 6528 } 6529 cpr.launchingApp = proc; 6530 mLaunchingProviders.add(cpr); 6531 } finally { 6532 Binder.restoreCallingIdentity(origId); 6533 } 6534 } 6535 6536 // Make sure the provider is published (the same provider class 6537 // may be published under multiple names). 6538 if (firstClass) { 6539 mProviderMap.putProviderByClass(comp, cpr); 6540 } 6541 6542 mProviderMap.putProviderByName(name, cpr); 6543 conn = incProviderCountLocked(r, cpr, token, stable); 6544 if (conn != null) { 6545 conn.waiting = true; 6546 } 6547 } 6548 } 6549 6550 // Wait for the provider to be published... 6551 synchronized (cpr) { 6552 while (cpr.provider == null) { 6553 if (cpr.launchingApp == null) { 6554 Slog.w(TAG, "Unable to launch app " 6555 + cpi.applicationInfo.packageName + "/" 6556 + cpi.applicationInfo.uid + " for provider " 6557 + name + ": launching app became null"); 6558 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6559 cpi.applicationInfo.packageName, 6560 cpi.applicationInfo.uid, name); 6561 return null; 6562 } 6563 try { 6564 if (DEBUG_MU) { 6565 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6566 + cpr.launchingApp); 6567 } 6568 if (conn != null) { 6569 conn.waiting = true; 6570 } 6571 cpr.wait(); 6572 } catch (InterruptedException ex) { 6573 } finally { 6574 if (conn != null) { 6575 conn.waiting = false; 6576 } 6577 } 6578 } 6579 } 6580 return cpr != null ? cpr.newHolder(conn) : null; 6581 } 6582 6583 public final ContentProviderHolder getContentProvider( 6584 IApplicationThread caller, String name, boolean stable) { 6585 enforceNotIsolatedCaller("getContentProvider"); 6586 if (caller == null) { 6587 String msg = "null IApplicationThread when getting content provider " 6588 + name; 6589 Slog.w(TAG, msg); 6590 throw new SecurityException(msg); 6591 } 6592 6593 return getContentProviderImpl(caller, name, null, stable, 6594 UserHandle.getCallingUserId()); 6595 } 6596 6597 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6598 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6599 "Do not have permission in call getContentProviderExternal()"); 6600 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6601 } 6602 6603 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6604 IBinder token, int userId) { 6605 return getContentProviderImpl(null, name, token, true, userId); 6606 } 6607 6608 /** 6609 * Drop a content provider from a ProcessRecord's bookkeeping 6610 * @param cpr 6611 */ 6612 public void removeContentProvider(IBinder connection, boolean stable) { 6613 enforceNotIsolatedCaller("removeContentProvider"); 6614 synchronized (this) { 6615 ContentProviderConnection conn; 6616 try { 6617 conn = (ContentProviderConnection)connection; 6618 } catch (ClassCastException e) { 6619 String msg ="removeContentProvider: " + connection 6620 + " not a ContentProviderConnection"; 6621 Slog.w(TAG, msg); 6622 throw new IllegalArgumentException(msg); 6623 } 6624 if (conn == null) { 6625 throw new NullPointerException("connection is null"); 6626 } 6627 if (decProviderCountLocked(conn, null, null, stable)) { 6628 updateOomAdjLocked(); 6629 } 6630 } 6631 } 6632 6633 public void removeContentProviderExternal(String name, IBinder token) { 6634 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6635 "Do not have permission in call removeContentProviderExternal()"); 6636 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6637 } 6638 6639 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6640 synchronized (this) { 6641 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6642 if(cpr == null) { 6643 //remove from mProvidersByClass 6644 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6645 return; 6646 } 6647 6648 //update content provider record entry info 6649 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6650 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6651 if (localCpr.hasExternalProcessHandles()) { 6652 if (localCpr.removeExternalProcessHandleLocked(token)) { 6653 updateOomAdjLocked(); 6654 } else { 6655 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6656 + " with no external reference for token: " 6657 + token + "."); 6658 } 6659 } else { 6660 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6661 + " with no external references."); 6662 } 6663 } 6664 } 6665 6666 public final void publishContentProviders(IApplicationThread caller, 6667 List<ContentProviderHolder> providers) { 6668 if (providers == null) { 6669 return; 6670 } 6671 6672 enforceNotIsolatedCaller("publishContentProviders"); 6673 synchronized (this) { 6674 final ProcessRecord r = getRecordForAppLocked(caller); 6675 if (DEBUG_MU) 6676 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6677 if (r == null) { 6678 throw new SecurityException( 6679 "Unable to find app for caller " + caller 6680 + " (pid=" + Binder.getCallingPid() 6681 + ") when publishing content providers"); 6682 } 6683 6684 final long origId = Binder.clearCallingIdentity(); 6685 6686 final int N = providers.size(); 6687 for (int i=0; i<N; i++) { 6688 ContentProviderHolder src = providers.get(i); 6689 if (src == null || src.info == null || src.provider == null) { 6690 continue; 6691 } 6692 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6693 if (DEBUG_MU) 6694 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6695 if (dst != null) { 6696 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6697 mProviderMap.putProviderByClass(comp, dst); 6698 String names[] = dst.info.authority.split(";"); 6699 for (int j = 0; j < names.length; j++) { 6700 mProviderMap.putProviderByName(names[j], dst); 6701 } 6702 6703 int NL = mLaunchingProviders.size(); 6704 int j; 6705 for (j=0; j<NL; j++) { 6706 if (mLaunchingProviders.get(j) == dst) { 6707 mLaunchingProviders.remove(j); 6708 j--; 6709 NL--; 6710 } 6711 } 6712 synchronized (dst) { 6713 dst.provider = src.provider; 6714 dst.proc = r; 6715 dst.notifyAll(); 6716 } 6717 updateOomAdjLocked(r); 6718 } 6719 } 6720 6721 Binder.restoreCallingIdentity(origId); 6722 } 6723 } 6724 6725 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6726 ContentProviderConnection conn; 6727 try { 6728 conn = (ContentProviderConnection)connection; 6729 } catch (ClassCastException e) { 6730 String msg ="refContentProvider: " + connection 6731 + " not a ContentProviderConnection"; 6732 Slog.w(TAG, msg); 6733 throw new IllegalArgumentException(msg); 6734 } 6735 if (conn == null) { 6736 throw new NullPointerException("connection is null"); 6737 } 6738 6739 synchronized (this) { 6740 if (stable > 0) { 6741 conn.numStableIncs += stable; 6742 } 6743 stable = conn.stableCount + stable; 6744 if (stable < 0) { 6745 throw new IllegalStateException("stableCount < 0: " + stable); 6746 } 6747 6748 if (unstable > 0) { 6749 conn.numUnstableIncs += unstable; 6750 } 6751 unstable = conn.unstableCount + unstable; 6752 if (unstable < 0) { 6753 throw new IllegalStateException("unstableCount < 0: " + unstable); 6754 } 6755 6756 if ((stable+unstable) <= 0) { 6757 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6758 + stable + " unstable=" + unstable); 6759 } 6760 conn.stableCount = stable; 6761 conn.unstableCount = unstable; 6762 return !conn.dead; 6763 } 6764 } 6765 6766 public void unstableProviderDied(IBinder connection) { 6767 ContentProviderConnection conn; 6768 try { 6769 conn = (ContentProviderConnection)connection; 6770 } catch (ClassCastException e) { 6771 String msg ="refContentProvider: " + connection 6772 + " not a ContentProviderConnection"; 6773 Slog.w(TAG, msg); 6774 throw new IllegalArgumentException(msg); 6775 } 6776 if (conn == null) { 6777 throw new NullPointerException("connection is null"); 6778 } 6779 6780 // Safely retrieve the content provider associated with the connection. 6781 IContentProvider provider; 6782 synchronized (this) { 6783 provider = conn.provider.provider; 6784 } 6785 6786 if (provider == null) { 6787 // Um, yeah, we're way ahead of you. 6788 return; 6789 } 6790 6791 // Make sure the caller is being honest with us. 6792 if (provider.asBinder().pingBinder()) { 6793 // Er, no, still looks good to us. 6794 synchronized (this) { 6795 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6796 + " says " + conn + " died, but we don't agree"); 6797 return; 6798 } 6799 } 6800 6801 // Well look at that! It's dead! 6802 synchronized (this) { 6803 if (conn.provider.provider != provider) { 6804 // But something changed... good enough. 6805 return; 6806 } 6807 6808 ProcessRecord proc = conn.provider.proc; 6809 if (proc == null || proc.thread == null) { 6810 // Seems like the process is already cleaned up. 6811 return; 6812 } 6813 6814 // As far as we're concerned, this is just like receiving a 6815 // death notification... just a bit prematurely. 6816 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6817 + ") early provider death"); 6818 final long ident = Binder.clearCallingIdentity(); 6819 try { 6820 appDiedLocked(proc, proc.pid, proc.thread); 6821 } finally { 6822 Binder.restoreCallingIdentity(ident); 6823 } 6824 } 6825 } 6826 6827 public static final void installSystemProviders() { 6828 List<ProviderInfo> providers; 6829 synchronized (mSelf) { 6830 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6831 providers = mSelf.generateApplicationProvidersLocked(app); 6832 if (providers != null) { 6833 for (int i=providers.size()-1; i>=0; i--) { 6834 ProviderInfo pi = (ProviderInfo)providers.get(i); 6835 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6836 Slog.w(TAG, "Not installing system proc provider " + pi.name 6837 + ": not system .apk"); 6838 providers.remove(i); 6839 } 6840 } 6841 } 6842 } 6843 if (providers != null) { 6844 mSystemThread.installSystemProviders(providers); 6845 } 6846 6847 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6848 6849 mSelf.mUsageStatsService.monitorPackages(); 6850 } 6851 6852 /** 6853 * Allows app to retrieve the MIME type of a URI without having permission 6854 * to access its content provider. 6855 * 6856 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6857 * 6858 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6859 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6860 */ 6861 public String getProviderMimeType(Uri uri, int userId) { 6862 enforceNotIsolatedCaller("getProviderMimeType"); 6863 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6864 userId, false, true, "getProviderMimeType", null); 6865 final String name = uri.getAuthority(); 6866 final long ident = Binder.clearCallingIdentity(); 6867 ContentProviderHolder holder = null; 6868 6869 try { 6870 holder = getContentProviderExternalUnchecked(name, null, userId); 6871 if (holder != null) { 6872 return holder.provider.getType(uri); 6873 } 6874 } catch (RemoteException e) { 6875 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6876 return null; 6877 } finally { 6878 if (holder != null) { 6879 removeContentProviderExternalUnchecked(name, null, userId); 6880 } 6881 Binder.restoreCallingIdentity(ident); 6882 } 6883 6884 return null; 6885 } 6886 6887 // ========================================================= 6888 // GLOBAL MANAGEMENT 6889 // ========================================================= 6890 6891 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6892 ApplicationInfo info, String customProcess, boolean isolated) { 6893 String proc = customProcess != null ? customProcess : info.processName; 6894 BatteryStatsImpl.Uid.Proc ps = null; 6895 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6896 int uid = info.uid; 6897 if (isolated) { 6898 int userId = UserHandle.getUserId(uid); 6899 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6900 uid = 0; 6901 while (true) { 6902 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6903 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6904 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6905 } 6906 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6907 mNextIsolatedProcessUid++; 6908 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6909 // No process for this uid, use it. 6910 break; 6911 } 6912 stepsLeft--; 6913 if (stepsLeft <= 0) { 6914 return null; 6915 } 6916 } 6917 } 6918 synchronized (stats) { 6919 ps = stats.getProcessStatsLocked(info.uid, proc); 6920 } 6921 return new ProcessRecord(ps, thread, info, proc, uid); 6922 } 6923 6924 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6925 ProcessRecord app; 6926 if (!isolated) { 6927 app = getProcessRecordLocked(info.processName, info.uid); 6928 } else { 6929 app = null; 6930 } 6931 6932 if (app == null) { 6933 app = newProcessRecordLocked(null, info, null, isolated); 6934 mProcessNames.put(info.processName, app.uid, app); 6935 if (isolated) { 6936 mIsolatedProcesses.put(app.uid, app); 6937 } 6938 updateLruProcessLocked(app, true, true); 6939 } 6940 6941 // This package really, really can not be stopped. 6942 try { 6943 AppGlobals.getPackageManager().setPackageStoppedState( 6944 info.packageName, false, UserHandle.getUserId(app.uid)); 6945 } catch (RemoteException e) { 6946 } catch (IllegalArgumentException e) { 6947 Slog.w(TAG, "Failed trying to unstop package " 6948 + info.packageName + ": " + e); 6949 } 6950 6951 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6952 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6953 app.persistent = true; 6954 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6955 } 6956 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6957 mPersistentStartingProcesses.add(app); 6958 startProcessLocked(app, "added application", app.processName); 6959 } 6960 6961 return app; 6962 } 6963 6964 public void unhandledBack() { 6965 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6966 "unhandledBack()"); 6967 6968 synchronized(this) { 6969 int count = mMainStack.mHistory.size(); 6970 if (DEBUG_SWITCH) Slog.d( 6971 TAG, "Performing unhandledBack(): stack size = " + count); 6972 if (count > 1) { 6973 final long origId = Binder.clearCallingIdentity(); 6974 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6975 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6976 Binder.restoreCallingIdentity(origId); 6977 } 6978 } 6979 } 6980 6981 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6982 enforceNotIsolatedCaller("openContentUri"); 6983 final int userId = UserHandle.getCallingUserId(); 6984 String name = uri.getAuthority(); 6985 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 6986 ParcelFileDescriptor pfd = null; 6987 if (cph != null) { 6988 // We record the binder invoker's uid in thread-local storage before 6989 // going to the content provider to open the file. Later, in the code 6990 // that handles all permissions checks, we look for this uid and use 6991 // that rather than the Activity Manager's own uid. The effect is that 6992 // we do the check against the caller's permissions even though it looks 6993 // to the content provider like the Activity Manager itself is making 6994 // the request. 6995 sCallerIdentity.set(new Identity( 6996 Binder.getCallingPid(), Binder.getCallingUid())); 6997 try { 6998 pfd = cph.provider.openFile(uri, "r"); 6999 } catch (FileNotFoundException e) { 7000 // do nothing; pfd will be returned null 7001 } finally { 7002 // Ensure that whatever happens, we clean up the identity state 7003 sCallerIdentity.remove(); 7004 } 7005 7006 // We've got the fd now, so we're done with the provider. 7007 removeContentProviderExternalUnchecked(name, null, userId); 7008 } else { 7009 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7010 } 7011 return pfd; 7012 } 7013 7014 // Actually is sleeping or shutting down or whatever else in the future 7015 // is an inactive state. 7016 public boolean isSleeping() { 7017 return mSleeping || mShuttingDown; 7018 } 7019 7020 public void goingToSleep() { 7021 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7022 != PackageManager.PERMISSION_GRANTED) { 7023 throw new SecurityException("Requires permission " 7024 + android.Manifest.permission.DEVICE_POWER); 7025 } 7026 7027 synchronized(this) { 7028 mWentToSleep = true; 7029 updateEventDispatchingLocked(); 7030 7031 if (!mSleeping) { 7032 mSleeping = true; 7033 mMainStack.stopIfSleepingLocked(); 7034 7035 // Initialize the wake times of all processes. 7036 checkExcessivePowerUsageLocked(false); 7037 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7038 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7039 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7040 } 7041 } 7042 } 7043 7044 public boolean shutdown(int timeout) { 7045 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7046 != PackageManager.PERMISSION_GRANTED) { 7047 throw new SecurityException("Requires permission " 7048 + android.Manifest.permission.SHUTDOWN); 7049 } 7050 7051 boolean timedout = false; 7052 7053 synchronized(this) { 7054 mShuttingDown = true; 7055 updateEventDispatchingLocked(); 7056 7057 if (mMainStack.mResumedActivity != null) { 7058 mMainStack.stopIfSleepingLocked(); 7059 final long endTime = System.currentTimeMillis() + timeout; 7060 while (mMainStack.mResumedActivity != null 7061 || mMainStack.mPausingActivity != null) { 7062 long delay = endTime - System.currentTimeMillis(); 7063 if (delay <= 0) { 7064 Slog.w(TAG, "Activity manager shutdown timed out"); 7065 timedout = true; 7066 break; 7067 } 7068 try { 7069 this.wait(); 7070 } catch (InterruptedException e) { 7071 } 7072 } 7073 } 7074 } 7075 7076 mUsageStatsService.shutdown(); 7077 mBatteryStatsService.shutdown(); 7078 7079 return timedout; 7080 } 7081 7082 public final void activitySlept(IBinder token) { 7083 if (localLOGV) Slog.v( 7084 TAG, "Activity slept: token=" + token); 7085 7086 ActivityRecord r = null; 7087 7088 final long origId = Binder.clearCallingIdentity(); 7089 7090 synchronized (this) { 7091 r = mMainStack.isInStackLocked(token); 7092 if (r != null) { 7093 mMainStack.activitySleptLocked(r); 7094 } 7095 } 7096 7097 Binder.restoreCallingIdentity(origId); 7098 } 7099 7100 private void comeOutOfSleepIfNeededLocked() { 7101 if (!mWentToSleep && !mLockScreenShown) { 7102 if (mSleeping) { 7103 mSleeping = false; 7104 mMainStack.awakeFromSleepingLocked(); 7105 mMainStack.resumeTopActivityLocked(null); 7106 } 7107 } 7108 } 7109 7110 public void wakingUp() { 7111 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7112 != PackageManager.PERMISSION_GRANTED) { 7113 throw new SecurityException("Requires permission " 7114 + android.Manifest.permission.DEVICE_POWER); 7115 } 7116 7117 synchronized(this) { 7118 mWentToSleep = false; 7119 updateEventDispatchingLocked(); 7120 comeOutOfSleepIfNeededLocked(); 7121 } 7122 } 7123 7124 private void updateEventDispatchingLocked() { 7125 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7126 } 7127 7128 public void setLockScreenShown(boolean shown) { 7129 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7130 != PackageManager.PERMISSION_GRANTED) { 7131 throw new SecurityException("Requires permission " 7132 + android.Manifest.permission.DEVICE_POWER); 7133 } 7134 7135 synchronized(this) { 7136 mLockScreenShown = shown; 7137 comeOutOfSleepIfNeededLocked(); 7138 } 7139 } 7140 7141 public void stopAppSwitches() { 7142 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7143 != PackageManager.PERMISSION_GRANTED) { 7144 throw new SecurityException("Requires permission " 7145 + android.Manifest.permission.STOP_APP_SWITCHES); 7146 } 7147 7148 synchronized(this) { 7149 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7150 + APP_SWITCH_DELAY_TIME; 7151 mDidAppSwitch = false; 7152 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7153 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7154 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7155 } 7156 } 7157 7158 public void resumeAppSwitches() { 7159 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7160 != PackageManager.PERMISSION_GRANTED) { 7161 throw new SecurityException("Requires permission " 7162 + android.Manifest.permission.STOP_APP_SWITCHES); 7163 } 7164 7165 synchronized(this) { 7166 // Note that we don't execute any pending app switches... we will 7167 // let those wait until either the timeout, or the next start 7168 // activity request. 7169 mAppSwitchesAllowedTime = 0; 7170 } 7171 } 7172 7173 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7174 String name) { 7175 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7176 return true; 7177 } 7178 7179 final int perm = checkComponentPermission( 7180 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7181 callingUid, -1, true); 7182 if (perm == PackageManager.PERMISSION_GRANTED) { 7183 return true; 7184 } 7185 7186 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7187 return false; 7188 } 7189 7190 public void setDebugApp(String packageName, boolean waitForDebugger, 7191 boolean persistent) { 7192 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7193 "setDebugApp()"); 7194 7195 // Note that this is not really thread safe if there are multiple 7196 // callers into it at the same time, but that's not a situation we 7197 // care about. 7198 if (persistent) { 7199 final ContentResolver resolver = mContext.getContentResolver(); 7200 Settings.System.putString( 7201 resolver, Settings.System.DEBUG_APP, 7202 packageName); 7203 Settings.System.putInt( 7204 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7205 waitForDebugger ? 1 : 0); 7206 } 7207 7208 synchronized (this) { 7209 if (!persistent) { 7210 mOrigDebugApp = mDebugApp; 7211 mOrigWaitForDebugger = mWaitForDebugger; 7212 } 7213 mDebugApp = packageName; 7214 mWaitForDebugger = waitForDebugger; 7215 mDebugTransient = !persistent; 7216 if (packageName != null) { 7217 final long origId = Binder.clearCallingIdentity(); 7218 forceStopPackageLocked(packageName, -1, false, false, true, true, 7219 UserHandle.USER_ALL); 7220 Binder.restoreCallingIdentity(origId); 7221 } 7222 } 7223 } 7224 7225 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7226 synchronized (this) { 7227 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7228 if (!isDebuggable) { 7229 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7230 throw new SecurityException("Process not debuggable: " + app.packageName); 7231 } 7232 } 7233 7234 mOpenGlTraceApp = processName; 7235 } 7236 } 7237 7238 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7239 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7240 synchronized (this) { 7241 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7242 if (!isDebuggable) { 7243 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7244 throw new SecurityException("Process not debuggable: " + app.packageName); 7245 } 7246 } 7247 mProfileApp = processName; 7248 mProfileFile = profileFile; 7249 if (mProfileFd != null) { 7250 try { 7251 mProfileFd.close(); 7252 } catch (IOException e) { 7253 } 7254 mProfileFd = null; 7255 } 7256 mProfileFd = profileFd; 7257 mProfileType = 0; 7258 mAutoStopProfiler = autoStopProfiler; 7259 } 7260 } 7261 7262 public void setAlwaysFinish(boolean enabled) { 7263 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7264 "setAlwaysFinish()"); 7265 7266 Settings.System.putInt( 7267 mContext.getContentResolver(), 7268 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7269 7270 synchronized (this) { 7271 mAlwaysFinishActivities = enabled; 7272 } 7273 } 7274 7275 public void setActivityController(IActivityController controller) { 7276 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7277 "setActivityController()"); 7278 synchronized (this) { 7279 mController = controller; 7280 } 7281 } 7282 7283 public boolean isUserAMonkey() { 7284 // For now the fact that there is a controller implies 7285 // we have a monkey. 7286 synchronized (this) { 7287 return mController != null; 7288 } 7289 } 7290 7291 public void registerProcessObserver(IProcessObserver observer) { 7292 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7293 "registerProcessObserver()"); 7294 synchronized (this) { 7295 mProcessObservers.register(observer); 7296 } 7297 } 7298 7299 public void unregisterProcessObserver(IProcessObserver observer) { 7300 synchronized (this) { 7301 mProcessObservers.unregister(observer); 7302 } 7303 } 7304 7305 public void setImmersive(IBinder token, boolean immersive) { 7306 synchronized(this) { 7307 ActivityRecord r = mMainStack.isInStackLocked(token); 7308 if (r == null) { 7309 throw new IllegalArgumentException(); 7310 } 7311 r.immersive = immersive; 7312 } 7313 } 7314 7315 public boolean isImmersive(IBinder token) { 7316 synchronized (this) { 7317 ActivityRecord r = mMainStack.isInStackLocked(token); 7318 if (r == null) { 7319 throw new IllegalArgumentException(); 7320 } 7321 return r.immersive; 7322 } 7323 } 7324 7325 public boolean isTopActivityImmersive() { 7326 enforceNotIsolatedCaller("startActivity"); 7327 synchronized (this) { 7328 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7329 return (r != null) ? r.immersive : false; 7330 } 7331 } 7332 7333 public final void enterSafeMode() { 7334 synchronized(this) { 7335 // It only makes sense to do this before the system is ready 7336 // and started launching other packages. 7337 if (!mSystemReady) { 7338 try { 7339 AppGlobals.getPackageManager().enterSafeMode(); 7340 } catch (RemoteException e) { 7341 } 7342 } 7343 } 7344 } 7345 7346 public final void showSafeModeOverlay() { 7347 View v = LayoutInflater.from(mContext).inflate( 7348 com.android.internal.R.layout.safe_mode, null); 7349 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7350 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7351 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7352 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7353 lp.gravity = Gravity.BOTTOM | Gravity.START; 7354 lp.format = v.getBackground().getOpacity(); 7355 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7356 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7357 ((WindowManager)mContext.getSystemService( 7358 Context.WINDOW_SERVICE)).addView(v, lp); 7359 } 7360 7361 public void noteWakeupAlarm(IIntentSender sender) { 7362 if (!(sender instanceof PendingIntentRecord)) { 7363 return; 7364 } 7365 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7366 synchronized (stats) { 7367 if (mBatteryStatsService.isOnBattery()) { 7368 mBatteryStatsService.enforceCallingPermission(); 7369 PendingIntentRecord rec = (PendingIntentRecord)sender; 7370 int MY_UID = Binder.getCallingUid(); 7371 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7372 BatteryStatsImpl.Uid.Pkg pkg = 7373 stats.getPackageStatsLocked(uid, rec.key.packageName); 7374 pkg.incWakeupsLocked(); 7375 } 7376 } 7377 } 7378 7379 public boolean killPids(int[] pids, String pReason, boolean secure) { 7380 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7381 throw new SecurityException("killPids only available to the system"); 7382 } 7383 String reason = (pReason == null) ? "Unknown" : pReason; 7384 // XXX Note: don't acquire main activity lock here, because the window 7385 // manager calls in with its locks held. 7386 7387 boolean killed = false; 7388 synchronized (mPidsSelfLocked) { 7389 int[] types = new int[pids.length]; 7390 int worstType = 0; 7391 for (int i=0; i<pids.length; i++) { 7392 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7393 if (proc != null) { 7394 int type = proc.setAdj; 7395 types[i] = type; 7396 if (type > worstType) { 7397 worstType = type; 7398 } 7399 } 7400 } 7401 7402 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7403 // then constrain it so we will kill all hidden procs. 7404 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7405 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7406 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7407 } 7408 7409 // If this is not a secure call, don't let it kill processes that 7410 // are important. 7411 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7412 worstType = ProcessList.SERVICE_ADJ; 7413 } 7414 7415 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7416 for (int i=0; i<pids.length; i++) { 7417 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7418 if (proc == null) { 7419 continue; 7420 } 7421 int adj = proc.setAdj; 7422 if (adj >= worstType && !proc.killedBackground) { 7423 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7424 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7425 proc.processName, adj, reason); 7426 killed = true; 7427 proc.killedBackground = true; 7428 Process.killProcessQuiet(pids[i]); 7429 } 7430 } 7431 } 7432 return killed; 7433 } 7434 7435 @Override 7436 public boolean killProcessesBelowForeground(String reason) { 7437 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7438 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7439 } 7440 7441 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7442 } 7443 7444 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7445 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7446 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7447 } 7448 7449 boolean killed = false; 7450 synchronized (mPidsSelfLocked) { 7451 final int size = mPidsSelfLocked.size(); 7452 for (int i = 0; i < size; i++) { 7453 final int pid = mPidsSelfLocked.keyAt(i); 7454 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7455 if (proc == null) continue; 7456 7457 final int adj = proc.setAdj; 7458 if (adj > belowAdj && !proc.killedBackground) { 7459 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7460 EventLog.writeEvent( 7461 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7462 killed = true; 7463 proc.killedBackground = true; 7464 Process.killProcessQuiet(pid); 7465 } 7466 } 7467 } 7468 return killed; 7469 } 7470 7471 public final void startRunning(String pkg, String cls, String action, 7472 String data) { 7473 synchronized(this) { 7474 if (mStartRunning) { 7475 return; 7476 } 7477 mStartRunning = true; 7478 mTopComponent = pkg != null && cls != null 7479 ? new ComponentName(pkg, cls) : null; 7480 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7481 mTopData = data; 7482 if (!mSystemReady) { 7483 return; 7484 } 7485 } 7486 7487 systemReady(null); 7488 } 7489 7490 private void retrieveSettings() { 7491 final ContentResolver resolver = mContext.getContentResolver(); 7492 String debugApp = Settings.System.getString( 7493 resolver, Settings.System.DEBUG_APP); 7494 boolean waitForDebugger = Settings.System.getInt( 7495 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7496 boolean alwaysFinishActivities = Settings.System.getInt( 7497 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7498 7499 Configuration configuration = new Configuration(); 7500 Settings.System.getConfiguration(resolver, configuration); 7501 7502 synchronized (this) { 7503 mDebugApp = mOrigDebugApp = debugApp; 7504 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7505 mAlwaysFinishActivities = alwaysFinishActivities; 7506 // This happens before any activities are started, so we can 7507 // change mConfiguration in-place. 7508 updateConfigurationLocked(configuration, null, false, true); 7509 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7510 } 7511 } 7512 7513 public boolean testIsSystemReady() { 7514 // no need to synchronize(this) just to read & return the value 7515 return mSystemReady; 7516 } 7517 7518 private static File getCalledPreBootReceiversFile() { 7519 File dataDir = Environment.getDataDirectory(); 7520 File systemDir = new File(dataDir, "system"); 7521 File fname = new File(systemDir, "called_pre_boots.dat"); 7522 return fname; 7523 } 7524 7525 static final int LAST_DONE_VERSION = 10000; 7526 7527 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7528 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7529 File file = getCalledPreBootReceiversFile(); 7530 FileInputStream fis = null; 7531 try { 7532 fis = new FileInputStream(file); 7533 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7534 int fvers = dis.readInt(); 7535 if (fvers == LAST_DONE_VERSION) { 7536 String vers = dis.readUTF(); 7537 String codename = dis.readUTF(); 7538 String build = dis.readUTF(); 7539 if (android.os.Build.VERSION.RELEASE.equals(vers) 7540 && android.os.Build.VERSION.CODENAME.equals(codename) 7541 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7542 int num = dis.readInt(); 7543 while (num > 0) { 7544 num--; 7545 String pkg = dis.readUTF(); 7546 String cls = dis.readUTF(); 7547 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7548 } 7549 } 7550 } 7551 } catch (FileNotFoundException e) { 7552 } catch (IOException e) { 7553 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7554 } finally { 7555 if (fis != null) { 7556 try { 7557 fis.close(); 7558 } catch (IOException e) { 7559 } 7560 } 7561 } 7562 return lastDoneReceivers; 7563 } 7564 7565 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7566 File file = getCalledPreBootReceiversFile(); 7567 FileOutputStream fos = null; 7568 DataOutputStream dos = null; 7569 try { 7570 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7571 fos = new FileOutputStream(file); 7572 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7573 dos.writeInt(LAST_DONE_VERSION); 7574 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7575 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7576 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7577 dos.writeInt(list.size()); 7578 for (int i=0; i<list.size(); i++) { 7579 dos.writeUTF(list.get(i).getPackageName()); 7580 dos.writeUTF(list.get(i).getClassName()); 7581 } 7582 } catch (IOException e) { 7583 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7584 file.delete(); 7585 } finally { 7586 FileUtils.sync(fos); 7587 if (dos != null) { 7588 try { 7589 dos.close(); 7590 } catch (IOException e) { 7591 // TODO Auto-generated catch block 7592 e.printStackTrace(); 7593 } 7594 } 7595 } 7596 } 7597 7598 public void systemReady(final Runnable goingCallback) { 7599 synchronized(this) { 7600 if (mSystemReady) { 7601 if (goingCallback != null) goingCallback.run(); 7602 return; 7603 } 7604 7605 // Check to see if there are any update receivers to run. 7606 if (!mDidUpdate) { 7607 if (mWaitingUpdate) { 7608 return; 7609 } 7610 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7611 List<ResolveInfo> ris = null; 7612 try { 7613 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7614 intent, null, 0, 0); 7615 } catch (RemoteException e) { 7616 } 7617 if (ris != null) { 7618 for (int i=ris.size()-1; i>=0; i--) { 7619 if ((ris.get(i).activityInfo.applicationInfo.flags 7620 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7621 ris.remove(i); 7622 } 7623 } 7624 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7625 7626 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7627 7628 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7629 for (int i=0; i<ris.size(); i++) { 7630 ActivityInfo ai = ris.get(i).activityInfo; 7631 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7632 if (lastDoneReceivers.contains(comp)) { 7633 ris.remove(i); 7634 i--; 7635 } 7636 } 7637 7638 for (int i=0; i<ris.size(); i++) { 7639 ActivityInfo ai = ris.get(i).activityInfo; 7640 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7641 doneReceivers.add(comp); 7642 intent.setComponent(comp); 7643 IIntentReceiver finisher = null; 7644 if (i == ris.size()-1) { 7645 finisher = new IIntentReceiver.Stub() { 7646 public void performReceive(Intent intent, int resultCode, 7647 String data, Bundle extras, boolean ordered, 7648 boolean sticky, int sendingUser) { 7649 // The raw IIntentReceiver interface is called 7650 // with the AM lock held, so redispatch to 7651 // execute our code without the lock. 7652 mHandler.post(new Runnable() { 7653 public void run() { 7654 synchronized (ActivityManagerService.this) { 7655 mDidUpdate = true; 7656 } 7657 writeLastDonePreBootReceivers(doneReceivers); 7658 showBootMessage(mContext.getText( 7659 R.string.android_upgrading_complete), 7660 false); 7661 systemReady(goingCallback); 7662 } 7663 }); 7664 } 7665 }; 7666 } 7667 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7668 // XXX also need to send this to stopped users(!!!) 7669 broadcastIntentLocked(null, null, intent, null, finisher, 7670 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7671 UserHandle.USER_ALL); 7672 if (finisher != null) { 7673 mWaitingUpdate = true; 7674 } 7675 } 7676 } 7677 if (mWaitingUpdate) { 7678 return; 7679 } 7680 mDidUpdate = true; 7681 } 7682 7683 mSystemReady = true; 7684 if (!mStartRunning) { 7685 return; 7686 } 7687 } 7688 7689 ArrayList<ProcessRecord> procsToKill = null; 7690 synchronized(mPidsSelfLocked) { 7691 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7692 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7693 if (!isAllowedWhileBooting(proc.info)){ 7694 if (procsToKill == null) { 7695 procsToKill = new ArrayList<ProcessRecord>(); 7696 } 7697 procsToKill.add(proc); 7698 } 7699 } 7700 } 7701 7702 synchronized(this) { 7703 if (procsToKill != null) { 7704 for (int i=procsToKill.size()-1; i>=0; i--) { 7705 ProcessRecord proc = procsToKill.get(i); 7706 Slog.i(TAG, "Removing system update proc: " + proc); 7707 removeProcessLocked(proc, true, false, "system update done"); 7708 } 7709 } 7710 7711 // Now that we have cleaned up any update processes, we 7712 // are ready to start launching real processes and know that 7713 // we won't trample on them any more. 7714 mProcessesReady = true; 7715 } 7716 7717 Slog.i(TAG, "System now ready"); 7718 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7719 SystemClock.uptimeMillis()); 7720 7721 synchronized(this) { 7722 // Make sure we have no pre-ready processes sitting around. 7723 7724 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7725 ResolveInfo ri = mContext.getPackageManager() 7726 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7727 STOCK_PM_FLAGS); 7728 CharSequence errorMsg = null; 7729 if (ri != null) { 7730 ActivityInfo ai = ri.activityInfo; 7731 ApplicationInfo app = ai.applicationInfo; 7732 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7733 mTopAction = Intent.ACTION_FACTORY_TEST; 7734 mTopData = null; 7735 mTopComponent = new ComponentName(app.packageName, 7736 ai.name); 7737 } else { 7738 errorMsg = mContext.getResources().getText( 7739 com.android.internal.R.string.factorytest_not_system); 7740 } 7741 } else { 7742 errorMsg = mContext.getResources().getText( 7743 com.android.internal.R.string.factorytest_no_action); 7744 } 7745 if (errorMsg != null) { 7746 mTopAction = null; 7747 mTopData = null; 7748 mTopComponent = null; 7749 Message msg = Message.obtain(); 7750 msg.what = SHOW_FACTORY_ERROR_MSG; 7751 msg.getData().putCharSequence("msg", errorMsg); 7752 mHandler.sendMessage(msg); 7753 } 7754 } 7755 } 7756 7757 retrieveSettings(); 7758 7759 if (goingCallback != null) goingCallback.run(); 7760 7761 synchronized (this) { 7762 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7763 try { 7764 List apps = AppGlobals.getPackageManager(). 7765 getPersistentApplications(STOCK_PM_FLAGS); 7766 if (apps != null) { 7767 int N = apps.size(); 7768 int i; 7769 for (i=0; i<N; i++) { 7770 ApplicationInfo info 7771 = (ApplicationInfo)apps.get(i); 7772 if (info != null && 7773 !info.packageName.equals("android")) { 7774 addAppLocked(info, false); 7775 } 7776 } 7777 } 7778 } catch (RemoteException ex) { 7779 // pm is in same process, this will never happen. 7780 } 7781 } 7782 7783 // Start up initial activity. 7784 mBooting = true; 7785 7786 try { 7787 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7788 Message msg = Message.obtain(); 7789 msg.what = SHOW_UID_ERROR_MSG; 7790 mHandler.sendMessage(msg); 7791 } 7792 } catch (RemoteException e) { 7793 } 7794 7795 mMainStack.resumeTopActivityLocked(null); 7796 } 7797 } 7798 7799 private boolean makeAppCrashingLocked(ProcessRecord app, 7800 String shortMsg, String longMsg, String stackTrace) { 7801 app.crashing = true; 7802 app.crashingReport = generateProcessError(app, 7803 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7804 startAppProblemLocked(app); 7805 app.stopFreezingAllLocked(); 7806 return handleAppCrashLocked(app); 7807 } 7808 7809 private void makeAppNotRespondingLocked(ProcessRecord app, 7810 String activity, String shortMsg, String longMsg) { 7811 app.notResponding = true; 7812 app.notRespondingReport = generateProcessError(app, 7813 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7814 activity, shortMsg, longMsg, null); 7815 startAppProblemLocked(app); 7816 app.stopFreezingAllLocked(); 7817 } 7818 7819 /** 7820 * Generate a process error record, suitable for attachment to a ProcessRecord. 7821 * 7822 * @param app The ProcessRecord in which the error occurred. 7823 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7824 * ActivityManager.AppErrorStateInfo 7825 * @param activity The activity associated with the crash, if known. 7826 * @param shortMsg Short message describing the crash. 7827 * @param longMsg Long message describing the crash. 7828 * @param stackTrace Full crash stack trace, may be null. 7829 * 7830 * @return Returns a fully-formed AppErrorStateInfo record. 7831 */ 7832 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7833 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7834 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7835 7836 report.condition = condition; 7837 report.processName = app.processName; 7838 report.pid = app.pid; 7839 report.uid = app.info.uid; 7840 report.tag = activity; 7841 report.shortMsg = shortMsg; 7842 report.longMsg = longMsg; 7843 report.stackTrace = stackTrace; 7844 7845 return report; 7846 } 7847 7848 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7849 synchronized (this) { 7850 app.crashing = false; 7851 app.crashingReport = null; 7852 app.notResponding = false; 7853 app.notRespondingReport = null; 7854 if (app.anrDialog == fromDialog) { 7855 app.anrDialog = null; 7856 } 7857 if (app.waitDialog == fromDialog) { 7858 app.waitDialog = null; 7859 } 7860 if (app.pid > 0 && app.pid != MY_PID) { 7861 handleAppCrashLocked(app); 7862 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7863 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7864 app.processName, app.setAdj, "user's request after error"); 7865 Process.killProcessQuiet(app.pid); 7866 } 7867 } 7868 } 7869 7870 private boolean handleAppCrashLocked(ProcessRecord app) { 7871 if (mHeadless) { 7872 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7873 return false; 7874 } 7875 long now = SystemClock.uptimeMillis(); 7876 7877 Long crashTime; 7878 if (!app.isolated) { 7879 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7880 } else { 7881 crashTime = null; 7882 } 7883 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7884 // This process loses! 7885 Slog.w(TAG, "Process " + app.info.processName 7886 + " has crashed too many times: killing!"); 7887 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7888 app.info.processName, app.uid); 7889 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7890 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7891 if (r.app == app) { 7892 Slog.w(TAG, " Force finishing activity " 7893 + r.intent.getComponent().flattenToShortString()); 7894 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7895 } 7896 } 7897 if (!app.persistent) { 7898 // We don't want to start this process again until the user 7899 // explicitly does so... but for persistent process, we really 7900 // need to keep it running. If a persistent process is actually 7901 // repeatedly crashing, then badness for everyone. 7902 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7903 app.info.processName); 7904 if (!app.isolated) { 7905 // XXX We don't have a way to mark isolated processes 7906 // as bad, since they don't have a peristent identity. 7907 mBadProcesses.put(app.info.processName, app.uid, now); 7908 mProcessCrashTimes.remove(app.info.processName, app.uid); 7909 } 7910 app.bad = true; 7911 app.removed = true; 7912 // Don't let services in this process be restarted and potentially 7913 // annoy the user repeatedly. Unless it is persistent, since those 7914 // processes run critical code. 7915 removeProcessLocked(app, false, false, "crash"); 7916 mMainStack.resumeTopActivityLocked(null); 7917 return false; 7918 } 7919 mMainStack.resumeTopActivityLocked(null); 7920 } else { 7921 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7922 if (r != null && r.app == app) { 7923 // If the top running activity is from this crashing 7924 // process, then terminate it to avoid getting in a loop. 7925 Slog.w(TAG, " Force finishing activity " 7926 + r.intent.getComponent().flattenToShortString()); 7927 int index = mMainStack.indexOfActivityLocked(r); 7928 r.stack.finishActivityLocked(r, index, 7929 Activity.RESULT_CANCELED, null, "crashed"); 7930 // Also terminate any activities below it that aren't yet 7931 // stopped, to avoid a situation where one will get 7932 // re-start our crashing activity once it gets resumed again. 7933 index--; 7934 if (index >= 0) { 7935 r = (ActivityRecord)mMainStack.mHistory.get(index); 7936 if (r.state == ActivityState.RESUMED 7937 || r.state == ActivityState.PAUSING 7938 || r.state == ActivityState.PAUSED) { 7939 if (!r.isHomeActivity || mHomeProcess != r.app) { 7940 Slog.w(TAG, " Force finishing activity " 7941 + r.intent.getComponent().flattenToShortString()); 7942 r.stack.finishActivityLocked(r, index, 7943 Activity.RESULT_CANCELED, null, "crashed"); 7944 } 7945 } 7946 } 7947 } 7948 } 7949 7950 // Bump up the crash count of any services currently running in the proc. 7951 if (app.services.size() != 0) { 7952 // Any services running in the application need to be placed 7953 // back in the pending list. 7954 Iterator<ServiceRecord> it = app.services.iterator(); 7955 while (it.hasNext()) { 7956 ServiceRecord sr = it.next(); 7957 sr.crashCount++; 7958 } 7959 } 7960 7961 // If the crashing process is what we consider to be the "home process" and it has been 7962 // replaced by a third-party app, clear the package preferred activities from packages 7963 // with a home activity running in the process to prevent a repeatedly crashing app 7964 // from blocking the user to manually clear the list. 7965 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7966 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7967 Iterator it = mHomeProcess.activities.iterator(); 7968 while (it.hasNext()) { 7969 ActivityRecord r = (ActivityRecord)it.next(); 7970 if (r.isHomeActivity) { 7971 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7972 try { 7973 ActivityThread.getPackageManager() 7974 .clearPackagePreferredActivities(r.packageName); 7975 } catch (RemoteException c) { 7976 // pm is in same process, this will never happen. 7977 } 7978 } 7979 } 7980 } 7981 7982 if (!app.isolated) { 7983 // XXX Can't keep track of crash times for isolated processes, 7984 // because they don't have a perisistent identity. 7985 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7986 } 7987 7988 return true; 7989 } 7990 7991 void startAppProblemLocked(ProcessRecord app) { 7992 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7993 mContext, app.info.packageName, app.info.flags); 7994 skipCurrentReceiverLocked(app); 7995 } 7996 7997 void skipCurrentReceiverLocked(ProcessRecord app) { 7998 for (BroadcastQueue queue : mBroadcastQueues) { 7999 queue.skipCurrentReceiverLocked(app); 8000 } 8001 } 8002 8003 /** 8004 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8005 * The application process will exit immediately after this call returns. 8006 * @param app object of the crashing app, null for the system server 8007 * @param crashInfo describing the exception 8008 */ 8009 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8010 ProcessRecord r = findAppProcess(app, "Crash"); 8011 final String processName = app == null ? "system_server" 8012 : (r == null ? "unknown" : r.processName); 8013 8014 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8015 processName, 8016 r == null ? -1 : r.info.flags, 8017 crashInfo.exceptionClassName, 8018 crashInfo.exceptionMessage, 8019 crashInfo.throwFileName, 8020 crashInfo.throwLineNumber); 8021 8022 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8023 8024 crashApplication(r, crashInfo); 8025 } 8026 8027 public void handleApplicationStrictModeViolation( 8028 IBinder app, 8029 int violationMask, 8030 StrictMode.ViolationInfo info) { 8031 ProcessRecord r = findAppProcess(app, "StrictMode"); 8032 if (r == null) { 8033 return; 8034 } 8035 8036 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8037 Integer stackFingerprint = info.hashCode(); 8038 boolean logIt = true; 8039 synchronized (mAlreadyLoggedViolatedStacks) { 8040 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8041 logIt = false; 8042 // TODO: sub-sample into EventLog for these, with 8043 // the info.durationMillis? Then we'd get 8044 // the relative pain numbers, without logging all 8045 // the stack traces repeatedly. We'd want to do 8046 // likewise in the client code, which also does 8047 // dup suppression, before the Binder call. 8048 } else { 8049 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8050 mAlreadyLoggedViolatedStacks.clear(); 8051 } 8052 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8053 } 8054 } 8055 if (logIt) { 8056 logStrictModeViolationToDropBox(r, info); 8057 } 8058 } 8059 8060 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8061 AppErrorResult result = new AppErrorResult(); 8062 synchronized (this) { 8063 final long origId = Binder.clearCallingIdentity(); 8064 8065 Message msg = Message.obtain(); 8066 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8067 HashMap<String, Object> data = new HashMap<String, Object>(); 8068 data.put("result", result); 8069 data.put("app", r); 8070 data.put("violationMask", violationMask); 8071 data.put("info", info); 8072 msg.obj = data; 8073 mHandler.sendMessage(msg); 8074 8075 Binder.restoreCallingIdentity(origId); 8076 } 8077 int res = result.get(); 8078 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8079 } 8080 } 8081 8082 // Depending on the policy in effect, there could be a bunch of 8083 // these in quick succession so we try to batch these together to 8084 // minimize disk writes, number of dropbox entries, and maximize 8085 // compression, by having more fewer, larger records. 8086 private void logStrictModeViolationToDropBox( 8087 ProcessRecord process, 8088 StrictMode.ViolationInfo info) { 8089 if (info == null) { 8090 return; 8091 } 8092 final boolean isSystemApp = process == null || 8093 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8094 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8095 final String processName = process == null ? "unknown" : process.processName; 8096 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8097 final DropBoxManager dbox = (DropBoxManager) 8098 mContext.getSystemService(Context.DROPBOX_SERVICE); 8099 8100 // Exit early if the dropbox isn't configured to accept this report type. 8101 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8102 8103 boolean bufferWasEmpty; 8104 boolean needsFlush; 8105 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8106 synchronized (sb) { 8107 bufferWasEmpty = sb.length() == 0; 8108 appendDropBoxProcessHeaders(process, processName, sb); 8109 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8110 sb.append("System-App: ").append(isSystemApp).append("\n"); 8111 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8112 if (info.violationNumThisLoop != 0) { 8113 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8114 } 8115 if (info.numAnimationsRunning != 0) { 8116 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8117 } 8118 if (info.broadcastIntentAction != null) { 8119 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8120 } 8121 if (info.durationMillis != -1) { 8122 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8123 } 8124 if (info.numInstances != -1) { 8125 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8126 } 8127 if (info.tags != null) { 8128 for (String tag : info.tags) { 8129 sb.append("Span-Tag: ").append(tag).append("\n"); 8130 } 8131 } 8132 sb.append("\n"); 8133 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8134 sb.append(info.crashInfo.stackTrace); 8135 } 8136 sb.append("\n"); 8137 8138 // Only buffer up to ~64k. Various logging bits truncate 8139 // things at 128k. 8140 needsFlush = (sb.length() > 64 * 1024); 8141 } 8142 8143 // Flush immediately if the buffer's grown too large, or this 8144 // is a non-system app. Non-system apps are isolated with a 8145 // different tag & policy and not batched. 8146 // 8147 // Batching is useful during internal testing with 8148 // StrictMode settings turned up high. Without batching, 8149 // thousands of separate files could be created on boot. 8150 if (!isSystemApp || needsFlush) { 8151 new Thread("Error dump: " + dropboxTag) { 8152 @Override 8153 public void run() { 8154 String report; 8155 synchronized (sb) { 8156 report = sb.toString(); 8157 sb.delete(0, sb.length()); 8158 sb.trimToSize(); 8159 } 8160 if (report.length() != 0) { 8161 dbox.addText(dropboxTag, report); 8162 } 8163 } 8164 }.start(); 8165 return; 8166 } 8167 8168 // System app batching: 8169 if (!bufferWasEmpty) { 8170 // An existing dropbox-writing thread is outstanding, so 8171 // we don't need to start it up. The existing thread will 8172 // catch the buffer appends we just did. 8173 return; 8174 } 8175 8176 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8177 // (After this point, we shouldn't access AMS internal data structures.) 8178 new Thread("Error dump: " + dropboxTag) { 8179 @Override 8180 public void run() { 8181 // 5 second sleep to let stacks arrive and be batched together 8182 try { 8183 Thread.sleep(5000); // 5 seconds 8184 } catch (InterruptedException e) {} 8185 8186 String errorReport; 8187 synchronized (mStrictModeBuffer) { 8188 errorReport = mStrictModeBuffer.toString(); 8189 if (errorReport.length() == 0) { 8190 return; 8191 } 8192 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8193 mStrictModeBuffer.trimToSize(); 8194 } 8195 dbox.addText(dropboxTag, errorReport); 8196 } 8197 }.start(); 8198 } 8199 8200 /** 8201 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8202 * @param app object of the crashing app, null for the system server 8203 * @param tag reported by the caller 8204 * @param crashInfo describing the context of the error 8205 * @return true if the process should exit immediately (WTF is fatal) 8206 */ 8207 public boolean handleApplicationWtf(IBinder app, String tag, 8208 ApplicationErrorReport.CrashInfo crashInfo) { 8209 ProcessRecord r = findAppProcess(app, "WTF"); 8210 final String processName = app == null ? "system_server" 8211 : (r == null ? "unknown" : r.processName); 8212 8213 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8214 processName, 8215 r == null ? -1 : r.info.flags, 8216 tag, crashInfo.exceptionMessage); 8217 8218 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8219 8220 if (r != null && r.pid != Process.myPid() && 8221 Settings.Secure.getInt(mContext.getContentResolver(), 8222 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8223 crashApplication(r, crashInfo); 8224 return true; 8225 } else { 8226 return false; 8227 } 8228 } 8229 8230 /** 8231 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8232 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8233 */ 8234 private ProcessRecord findAppProcess(IBinder app, String reason) { 8235 if (app == null) { 8236 return null; 8237 } 8238 8239 synchronized (this) { 8240 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8241 final int NA = apps.size(); 8242 for (int ia=0; ia<NA; ia++) { 8243 ProcessRecord p = apps.valueAt(ia); 8244 if (p.thread != null && p.thread.asBinder() == app) { 8245 return p; 8246 } 8247 } 8248 } 8249 8250 Slog.w(TAG, "Can't find mystery application for " + reason 8251 + " from pid=" + Binder.getCallingPid() 8252 + " uid=" + Binder.getCallingUid() + ": " + app); 8253 return null; 8254 } 8255 } 8256 8257 /** 8258 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8259 * to append various headers to the dropbox log text. 8260 */ 8261 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8262 StringBuilder sb) { 8263 // Watchdog thread ends up invoking this function (with 8264 // a null ProcessRecord) to add the stack file to dropbox. 8265 // Do not acquire a lock on this (am) in such cases, as it 8266 // could cause a potential deadlock, if and when watchdog 8267 // is invoked due to unavailability of lock on am and it 8268 // would prevent watchdog from killing system_server. 8269 if (process == null) { 8270 sb.append("Process: ").append(processName).append("\n"); 8271 return; 8272 } 8273 // Note: ProcessRecord 'process' is guarded by the service 8274 // instance. (notably process.pkgList, which could otherwise change 8275 // concurrently during execution of this method) 8276 synchronized (this) { 8277 sb.append("Process: ").append(processName).append("\n"); 8278 int flags = process.info.flags; 8279 IPackageManager pm = AppGlobals.getPackageManager(); 8280 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8281 for (String pkg : process.pkgList) { 8282 sb.append("Package: ").append(pkg); 8283 try { 8284 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8285 if (pi != null) { 8286 sb.append(" v").append(pi.versionCode); 8287 if (pi.versionName != null) { 8288 sb.append(" (").append(pi.versionName).append(")"); 8289 } 8290 } 8291 } catch (RemoteException e) { 8292 Slog.e(TAG, "Error getting package info: " + pkg, e); 8293 } 8294 sb.append("\n"); 8295 } 8296 } 8297 } 8298 8299 private static String processClass(ProcessRecord process) { 8300 if (process == null || process.pid == MY_PID) { 8301 return "system_server"; 8302 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8303 return "system_app"; 8304 } else { 8305 return "data_app"; 8306 } 8307 } 8308 8309 /** 8310 * Write a description of an error (crash, WTF, ANR) to the drop box. 8311 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8312 * @param process which caused the error, null means the system server 8313 * @param activity which triggered the error, null if unknown 8314 * @param parent activity related to the error, null if unknown 8315 * @param subject line related to the error, null if absent 8316 * @param report in long form describing the error, null if absent 8317 * @param logFile to include in the report, null if none 8318 * @param crashInfo giving an application stack trace, null if absent 8319 */ 8320 public void addErrorToDropBox(String eventType, 8321 ProcessRecord process, String processName, ActivityRecord activity, 8322 ActivityRecord parent, String subject, 8323 final String report, final File logFile, 8324 final ApplicationErrorReport.CrashInfo crashInfo) { 8325 // NOTE -- this must never acquire the ActivityManagerService lock, 8326 // otherwise the watchdog may be prevented from resetting the system. 8327 8328 final String dropboxTag = processClass(process) + "_" + eventType; 8329 final DropBoxManager dbox = (DropBoxManager) 8330 mContext.getSystemService(Context.DROPBOX_SERVICE); 8331 8332 // Exit early if the dropbox isn't configured to accept this report type. 8333 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8334 8335 final StringBuilder sb = new StringBuilder(1024); 8336 appendDropBoxProcessHeaders(process, processName, sb); 8337 if (activity != null) { 8338 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8339 } 8340 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8341 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8342 } 8343 if (parent != null && parent != activity) { 8344 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8345 } 8346 if (subject != null) { 8347 sb.append("Subject: ").append(subject).append("\n"); 8348 } 8349 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8350 if (Debug.isDebuggerConnected()) { 8351 sb.append("Debugger: Connected\n"); 8352 } 8353 sb.append("\n"); 8354 8355 // Do the rest in a worker thread to avoid blocking the caller on I/O 8356 // (After this point, we shouldn't access AMS internal data structures.) 8357 Thread worker = new Thread("Error dump: " + dropboxTag) { 8358 @Override 8359 public void run() { 8360 if (report != null) { 8361 sb.append(report); 8362 } 8363 if (logFile != null) { 8364 try { 8365 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8366 } catch (IOException e) { 8367 Slog.e(TAG, "Error reading " + logFile, e); 8368 } 8369 } 8370 if (crashInfo != null && crashInfo.stackTrace != null) { 8371 sb.append(crashInfo.stackTrace); 8372 } 8373 8374 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8375 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8376 if (lines > 0) { 8377 sb.append("\n"); 8378 8379 // Merge several logcat streams, and take the last N lines 8380 InputStreamReader input = null; 8381 try { 8382 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8383 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8384 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8385 8386 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8387 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8388 input = new InputStreamReader(logcat.getInputStream()); 8389 8390 int num; 8391 char[] buf = new char[8192]; 8392 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8393 } catch (IOException e) { 8394 Slog.e(TAG, "Error running logcat", e); 8395 } finally { 8396 if (input != null) try { input.close(); } catch (IOException e) {} 8397 } 8398 } 8399 8400 dbox.addText(dropboxTag, sb.toString()); 8401 } 8402 }; 8403 8404 if (process == null) { 8405 // If process is null, we are being called from some internal code 8406 // and may be about to die -- run this synchronously. 8407 worker.run(); 8408 } else { 8409 worker.start(); 8410 } 8411 } 8412 8413 /** 8414 * Bring up the "unexpected error" dialog box for a crashing app. 8415 * Deal with edge cases (intercepts from instrumented applications, 8416 * ActivityController, error intent receivers, that sort of thing). 8417 * @param r the application crashing 8418 * @param crashInfo describing the failure 8419 */ 8420 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8421 long timeMillis = System.currentTimeMillis(); 8422 String shortMsg = crashInfo.exceptionClassName; 8423 String longMsg = crashInfo.exceptionMessage; 8424 String stackTrace = crashInfo.stackTrace; 8425 if (shortMsg != null && longMsg != null) { 8426 longMsg = shortMsg + ": " + longMsg; 8427 } else if (shortMsg != null) { 8428 longMsg = shortMsg; 8429 } 8430 8431 AppErrorResult result = new AppErrorResult(); 8432 synchronized (this) { 8433 if (mController != null) { 8434 try { 8435 String name = r != null ? r.processName : null; 8436 int pid = r != null ? r.pid : Binder.getCallingPid(); 8437 if (!mController.appCrashed(name, pid, 8438 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8439 Slog.w(TAG, "Force-killing crashed app " + name 8440 + " at watcher's request"); 8441 Process.killProcess(pid); 8442 return; 8443 } 8444 } catch (RemoteException e) { 8445 mController = null; 8446 } 8447 } 8448 8449 final long origId = Binder.clearCallingIdentity(); 8450 8451 // If this process is running instrumentation, finish it. 8452 if (r != null && r.instrumentationClass != null) { 8453 Slog.w(TAG, "Error in app " + r.processName 8454 + " running instrumentation " + r.instrumentationClass + ":"); 8455 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8456 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8457 Bundle info = new Bundle(); 8458 info.putString("shortMsg", shortMsg); 8459 info.putString("longMsg", longMsg); 8460 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8461 Binder.restoreCallingIdentity(origId); 8462 return; 8463 } 8464 8465 // If we can't identify the process or it's already exceeded its crash quota, 8466 // quit right away without showing a crash dialog. 8467 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8468 Binder.restoreCallingIdentity(origId); 8469 return; 8470 } 8471 8472 Message msg = Message.obtain(); 8473 msg.what = SHOW_ERROR_MSG; 8474 HashMap data = new HashMap(); 8475 data.put("result", result); 8476 data.put("app", r); 8477 msg.obj = data; 8478 mHandler.sendMessage(msg); 8479 8480 Binder.restoreCallingIdentity(origId); 8481 } 8482 8483 int res = result.get(); 8484 8485 Intent appErrorIntent = null; 8486 synchronized (this) { 8487 if (r != null && !r.isolated) { 8488 // XXX Can't keep track of crash time for isolated processes, 8489 // since they don't have a persistent identity. 8490 mProcessCrashTimes.put(r.info.processName, r.uid, 8491 SystemClock.uptimeMillis()); 8492 } 8493 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8494 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8495 } 8496 } 8497 8498 if (appErrorIntent != null) { 8499 try { 8500 mContext.startActivity(appErrorIntent); 8501 } catch (ActivityNotFoundException e) { 8502 Slog.w(TAG, "bug report receiver dissappeared", e); 8503 } 8504 } 8505 } 8506 8507 Intent createAppErrorIntentLocked(ProcessRecord r, 8508 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8509 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8510 if (report == null) { 8511 return null; 8512 } 8513 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8514 result.setComponent(r.errorReportReceiver); 8515 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8516 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8517 return result; 8518 } 8519 8520 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8521 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8522 if (r.errorReportReceiver == null) { 8523 return null; 8524 } 8525 8526 if (!r.crashing && !r.notResponding) { 8527 return null; 8528 } 8529 8530 ApplicationErrorReport report = new ApplicationErrorReport(); 8531 report.packageName = r.info.packageName; 8532 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8533 report.processName = r.processName; 8534 report.time = timeMillis; 8535 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8536 8537 if (r.crashing) { 8538 report.type = ApplicationErrorReport.TYPE_CRASH; 8539 report.crashInfo = crashInfo; 8540 } else if (r.notResponding) { 8541 report.type = ApplicationErrorReport.TYPE_ANR; 8542 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8543 8544 report.anrInfo.activity = r.notRespondingReport.tag; 8545 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8546 report.anrInfo.info = r.notRespondingReport.longMsg; 8547 } 8548 8549 return report; 8550 } 8551 8552 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8553 enforceNotIsolatedCaller("getProcessesInErrorState"); 8554 // assume our apps are happy - lazy create the list 8555 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8556 8557 final boolean allUsers = ActivityManager.checkUidPermission( 8558 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8559 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8560 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8561 8562 synchronized (this) { 8563 8564 // iterate across all processes 8565 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8566 ProcessRecord app = mLruProcesses.get(i); 8567 if (!allUsers && app.userId != userId) { 8568 continue; 8569 } 8570 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8571 // This one's in trouble, so we'll generate a report for it 8572 // crashes are higher priority (in case there's a crash *and* an anr) 8573 ActivityManager.ProcessErrorStateInfo report = null; 8574 if (app.crashing) { 8575 report = app.crashingReport; 8576 } else if (app.notResponding) { 8577 report = app.notRespondingReport; 8578 } 8579 8580 if (report != null) { 8581 if (errList == null) { 8582 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8583 } 8584 errList.add(report); 8585 } else { 8586 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8587 " crashing = " + app.crashing + 8588 " notResponding = " + app.notResponding); 8589 } 8590 } 8591 } 8592 } 8593 8594 return errList; 8595 } 8596 8597 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8598 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8599 if (currApp != null) { 8600 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8601 } 8602 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8603 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8604 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8605 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8606 if (currApp != null) { 8607 currApp.lru = 0; 8608 } 8609 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8610 } else if (adj >= ProcessList.SERVICE_ADJ) { 8611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8612 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8613 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8614 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8615 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8616 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8618 } else { 8619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8620 } 8621 } 8622 8623 private void fillInProcMemInfo(ProcessRecord app, 8624 ActivityManager.RunningAppProcessInfo outInfo) { 8625 outInfo.pid = app.pid; 8626 outInfo.uid = app.info.uid; 8627 if (mHeavyWeightProcess == app) { 8628 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8629 } 8630 if (app.persistent) { 8631 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8632 } 8633 if (app.hasActivities) { 8634 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8635 } 8636 outInfo.lastTrimLevel = app.trimMemoryLevel; 8637 int adj = app.curAdj; 8638 outInfo.importance = oomAdjToImportance(adj, outInfo); 8639 outInfo.importanceReasonCode = app.adjTypeCode; 8640 } 8641 8642 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8643 enforceNotIsolatedCaller("getRunningAppProcesses"); 8644 // Lazy instantiation of list 8645 List<ActivityManager.RunningAppProcessInfo> runList = null; 8646 final boolean allUsers = ActivityManager.checkUidPermission( 8647 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8648 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8649 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8650 synchronized (this) { 8651 // Iterate across all processes 8652 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8653 ProcessRecord app = mLruProcesses.get(i); 8654 if (!allUsers && app.userId != userId) { 8655 continue; 8656 } 8657 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8658 // Generate process state info for running application 8659 ActivityManager.RunningAppProcessInfo currApp = 8660 new ActivityManager.RunningAppProcessInfo(app.processName, 8661 app.pid, app.getPackageList()); 8662 fillInProcMemInfo(app, currApp); 8663 if (app.adjSource instanceof ProcessRecord) { 8664 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8665 currApp.importanceReasonImportance = oomAdjToImportance( 8666 app.adjSourceOom, null); 8667 } else if (app.adjSource instanceof ActivityRecord) { 8668 ActivityRecord r = (ActivityRecord)app.adjSource; 8669 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8670 } 8671 if (app.adjTarget instanceof ComponentName) { 8672 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8673 } 8674 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8675 // + " lru=" + currApp.lru); 8676 if (runList == null) { 8677 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8678 } 8679 runList.add(currApp); 8680 } 8681 } 8682 } 8683 return runList; 8684 } 8685 8686 public List<ApplicationInfo> getRunningExternalApplications() { 8687 enforceNotIsolatedCaller("getRunningExternalApplications"); 8688 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8689 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8690 if (runningApps != null && runningApps.size() > 0) { 8691 Set<String> extList = new HashSet<String>(); 8692 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8693 if (app.pkgList != null) { 8694 for (String pkg : app.pkgList) { 8695 extList.add(pkg); 8696 } 8697 } 8698 } 8699 IPackageManager pm = AppGlobals.getPackageManager(); 8700 for (String pkg : extList) { 8701 try { 8702 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8703 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8704 retList.add(info); 8705 } 8706 } catch (RemoteException e) { 8707 } 8708 } 8709 } 8710 return retList; 8711 } 8712 8713 @Override 8714 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8715 enforceNotIsolatedCaller("getMyMemoryState"); 8716 synchronized (this) { 8717 ProcessRecord proc; 8718 synchronized (mPidsSelfLocked) { 8719 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8720 } 8721 fillInProcMemInfo(proc, outInfo); 8722 } 8723 } 8724 8725 @Override 8726 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8727 if (checkCallingPermission(android.Manifest.permission.DUMP) 8728 != PackageManager.PERMISSION_GRANTED) { 8729 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8730 + Binder.getCallingPid() 8731 + ", uid=" + Binder.getCallingUid() 8732 + " without permission " 8733 + android.Manifest.permission.DUMP); 8734 return; 8735 } 8736 8737 boolean dumpAll = false; 8738 boolean dumpClient = false; 8739 String dumpPackage = null; 8740 8741 int opti = 0; 8742 while (opti < args.length) { 8743 String opt = args[opti]; 8744 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8745 break; 8746 } 8747 opti++; 8748 if ("-a".equals(opt)) { 8749 dumpAll = true; 8750 } else if ("-c".equals(opt)) { 8751 dumpClient = true; 8752 } else if ("-h".equals(opt)) { 8753 pw.println("Activity manager dump options:"); 8754 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8755 pw.println(" cmd may be one of:"); 8756 pw.println(" a[ctivities]: activity stack state"); 8757 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8758 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8759 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8760 pw.println(" o[om]: out of memory management"); 8761 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8762 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8763 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8764 pw.println(" service [COMP_SPEC]: service client-side state"); 8765 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8766 pw.println(" all: dump all activities"); 8767 pw.println(" top: dump the top activity"); 8768 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8769 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8770 pw.println(" a partial substring in a component name, a"); 8771 pw.println(" hex object identifier."); 8772 pw.println(" -a: include all available server state."); 8773 pw.println(" -c: include client state."); 8774 return; 8775 } else { 8776 pw.println("Unknown argument: " + opt + "; use -h for help"); 8777 } 8778 } 8779 8780 long origId = Binder.clearCallingIdentity(); 8781 boolean more = false; 8782 // Is the caller requesting to dump a particular piece of data? 8783 if (opti < args.length) { 8784 String cmd = args[opti]; 8785 opti++; 8786 if ("activities".equals(cmd) || "a".equals(cmd)) { 8787 synchronized (this) { 8788 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8789 } 8790 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8791 String[] newArgs; 8792 String name; 8793 if (opti >= args.length) { 8794 name = null; 8795 newArgs = EMPTY_STRING_ARRAY; 8796 } else { 8797 name = args[opti]; 8798 opti++; 8799 newArgs = new String[args.length - opti]; 8800 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8801 args.length - opti); 8802 } 8803 synchronized (this) { 8804 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8805 } 8806 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8807 String[] newArgs; 8808 String name; 8809 if (opti >= args.length) { 8810 name = null; 8811 newArgs = EMPTY_STRING_ARRAY; 8812 } else { 8813 name = args[opti]; 8814 opti++; 8815 newArgs = new String[args.length - opti]; 8816 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8817 args.length - opti); 8818 } 8819 synchronized (this) { 8820 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8821 } 8822 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8823 String[] newArgs; 8824 String name; 8825 if (opti >= args.length) { 8826 name = null; 8827 newArgs = EMPTY_STRING_ARRAY; 8828 } else { 8829 name = args[opti]; 8830 opti++; 8831 newArgs = new String[args.length - opti]; 8832 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8833 args.length - opti); 8834 } 8835 synchronized (this) { 8836 dumpProcessesLocked(fd, pw, args, opti, true, name); 8837 } 8838 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8839 synchronized (this) { 8840 dumpOomLocked(fd, pw, args, opti, true); 8841 } 8842 } else if ("provider".equals(cmd)) { 8843 String[] newArgs; 8844 String name; 8845 if (opti >= args.length) { 8846 name = null; 8847 newArgs = EMPTY_STRING_ARRAY; 8848 } else { 8849 name = args[opti]; 8850 opti++; 8851 newArgs = new String[args.length - opti]; 8852 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8853 } 8854 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8855 pw.println("No providers match: " + name); 8856 pw.println("Use -h for help."); 8857 } 8858 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8859 synchronized (this) { 8860 dumpProvidersLocked(fd, pw, args, opti, true, null); 8861 } 8862 } else if ("service".equals(cmd)) { 8863 String[] newArgs; 8864 String name; 8865 if (opti >= args.length) { 8866 name = null; 8867 newArgs = EMPTY_STRING_ARRAY; 8868 } else { 8869 name = args[opti]; 8870 opti++; 8871 newArgs = new String[args.length - opti]; 8872 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8873 args.length - opti); 8874 } 8875 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8876 pw.println("No services match: " + name); 8877 pw.println("Use -h for help."); 8878 } 8879 } else if ("package".equals(cmd)) { 8880 String[] newArgs; 8881 if (opti >= args.length) { 8882 pw.println("package: no package name specified"); 8883 pw.println("Use -h for help."); 8884 } else { 8885 dumpPackage = args[opti]; 8886 opti++; 8887 newArgs = new String[args.length - opti]; 8888 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8889 args.length - opti); 8890 args = newArgs; 8891 opti = 0; 8892 more = true; 8893 } 8894 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8895 synchronized (this) { 8896 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8897 } 8898 } else { 8899 // Dumping a single activity? 8900 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8901 pw.println("Bad activity command, or no activities match: " + cmd); 8902 pw.println("Use -h for help."); 8903 } 8904 } 8905 if (!more) { 8906 Binder.restoreCallingIdentity(origId); 8907 return; 8908 } 8909 } 8910 8911 // No piece of data specified, dump everything. 8912 synchronized (this) { 8913 boolean needSep; 8914 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8915 if (needSep) { 8916 pw.println(" "); 8917 } 8918 if (dumpAll) { 8919 pw.println("-------------------------------------------------------------------------------"); 8920 } 8921 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8922 if (needSep) { 8923 pw.println(" "); 8924 } 8925 if (dumpAll) { 8926 pw.println("-------------------------------------------------------------------------------"); 8927 } 8928 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8929 if (needSep) { 8930 pw.println(" "); 8931 } 8932 if (dumpAll) { 8933 pw.println("-------------------------------------------------------------------------------"); 8934 } 8935 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8936 if (needSep) { 8937 pw.println(" "); 8938 } 8939 if (dumpAll) { 8940 pw.println("-------------------------------------------------------------------------------"); 8941 } 8942 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8943 if (needSep) { 8944 pw.println(" "); 8945 } 8946 if (dumpAll) { 8947 pw.println("-------------------------------------------------------------------------------"); 8948 } 8949 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8950 } 8951 Binder.restoreCallingIdentity(origId); 8952 } 8953 8954 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8955 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8956 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8957 pw.println(" Main stack:"); 8958 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8959 dumpPackage); 8960 pw.println(" "); 8961 pw.println(" Running activities (most recent first):"); 8962 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8963 dumpPackage); 8964 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8965 pw.println(" "); 8966 pw.println(" Activities waiting for another to become visible:"); 8967 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8968 !dumpAll, false, dumpPackage); 8969 } 8970 if (mMainStack.mStoppingActivities.size() > 0) { 8971 pw.println(" "); 8972 pw.println(" Activities waiting to stop:"); 8973 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8974 !dumpAll, false, dumpPackage); 8975 } 8976 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8977 pw.println(" "); 8978 pw.println(" Activities waiting to sleep:"); 8979 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8980 !dumpAll, false, dumpPackage); 8981 } 8982 if (mMainStack.mFinishingActivities.size() > 0) { 8983 pw.println(" "); 8984 pw.println(" Activities waiting to finish:"); 8985 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8986 !dumpAll, false, dumpPackage); 8987 } 8988 8989 pw.println(" "); 8990 if (mMainStack.mPausingActivity != null) { 8991 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8992 } 8993 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8994 pw.println(" mFocusedActivity: " + mFocusedActivity); 8995 if (dumpAll) { 8996 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8997 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8998 pw.println(" mDismissKeyguardOnNextActivity: " 8999 + mMainStack.mDismissKeyguardOnNextActivity); 9000 } 9001 9002 if (mRecentTasks.size() > 0) { 9003 pw.println(); 9004 pw.println(" Recent tasks:"); 9005 9006 final int N = mRecentTasks.size(); 9007 for (int i=0; i<N; i++) { 9008 TaskRecord tr = mRecentTasks.get(i); 9009 if (dumpPackage != null) { 9010 if (tr.realActivity == null || 9011 !dumpPackage.equals(tr.realActivity)) { 9012 continue; 9013 } 9014 } 9015 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9016 pw.println(tr); 9017 if (dumpAll) { 9018 mRecentTasks.get(i).dump(pw, " "); 9019 } 9020 } 9021 } 9022 9023 if (dumpAll) { 9024 pw.println(" "); 9025 pw.println(" mCurTask: " + mCurTask); 9026 } 9027 9028 return true; 9029 } 9030 9031 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9032 int opti, boolean dumpAll, String dumpPackage) { 9033 boolean needSep = false; 9034 int numPers = 0; 9035 9036 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9037 9038 if (dumpAll) { 9039 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9040 final int NA = procs.size(); 9041 for (int ia=0; ia<NA; ia++) { 9042 ProcessRecord r = procs.valueAt(ia); 9043 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9044 continue; 9045 } 9046 if (!needSep) { 9047 pw.println(" All known processes:"); 9048 needSep = true; 9049 } 9050 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9051 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9052 pw.print(" "); pw.println(r); 9053 r.dump(pw, " "); 9054 if (r.persistent) { 9055 numPers++; 9056 } 9057 } 9058 } 9059 } 9060 9061 if (mIsolatedProcesses.size() > 0) { 9062 if (needSep) pw.println(" "); 9063 needSep = true; 9064 pw.println(" Isolated process list (sorted by uid):"); 9065 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9066 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9067 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9068 continue; 9069 } 9070 pw.println(String.format("%sIsolated #%2d: %s", 9071 " ", i, r.toString())); 9072 } 9073 } 9074 9075 if (mLruProcesses.size() > 0) { 9076 if (needSep) pw.println(" "); 9077 needSep = true; 9078 pw.println(" Process LRU list (sorted by oom_adj):"); 9079 dumpProcessOomList(pw, this, mLruProcesses, " ", 9080 "Proc", "PERS", false, dumpPackage); 9081 needSep = true; 9082 } 9083 9084 if (dumpAll) { 9085 synchronized (mPidsSelfLocked) { 9086 boolean printed = false; 9087 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9088 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9089 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9090 continue; 9091 } 9092 if (!printed) { 9093 if (needSep) pw.println(" "); 9094 needSep = true; 9095 pw.println(" PID mappings:"); 9096 printed = true; 9097 } 9098 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9099 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9100 } 9101 } 9102 } 9103 9104 if (mForegroundProcesses.size() > 0) { 9105 synchronized (mPidsSelfLocked) { 9106 boolean printed = false; 9107 for (int i=0; i<mForegroundProcesses.size(); i++) { 9108 ProcessRecord r = mPidsSelfLocked.get( 9109 mForegroundProcesses.valueAt(i).pid); 9110 if (dumpPackage != null && (r == null 9111 || !dumpPackage.equals(r.info.packageName))) { 9112 continue; 9113 } 9114 if (!printed) { 9115 if (needSep) pw.println(" "); 9116 needSep = true; 9117 pw.println(" Foreground Processes:"); 9118 printed = true; 9119 } 9120 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9121 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9122 } 9123 } 9124 } 9125 9126 if (mPersistentStartingProcesses.size() > 0) { 9127 if (needSep) pw.println(" "); 9128 needSep = true; 9129 pw.println(" Persisent processes that are starting:"); 9130 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9131 "Starting Norm", "Restarting PERS", dumpPackage); 9132 } 9133 9134 if (mRemovedProcesses.size() > 0) { 9135 if (needSep) pw.println(" "); 9136 needSep = true; 9137 pw.println(" Processes that are being removed:"); 9138 dumpProcessList(pw, this, mRemovedProcesses, " ", 9139 "Removed Norm", "Removed PERS", dumpPackage); 9140 } 9141 9142 if (mProcessesOnHold.size() > 0) { 9143 if (needSep) pw.println(" "); 9144 needSep = true; 9145 pw.println(" Processes that are on old until the system is ready:"); 9146 dumpProcessList(pw, this, mProcessesOnHold, " ", 9147 "OnHold Norm", "OnHold PERS", dumpPackage); 9148 } 9149 9150 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9151 9152 if (mProcessCrashTimes.getMap().size() > 0) { 9153 boolean printed = false; 9154 long now = SystemClock.uptimeMillis(); 9155 for (Map.Entry<String, SparseArray<Long>> procs 9156 : mProcessCrashTimes.getMap().entrySet()) { 9157 String pname = procs.getKey(); 9158 SparseArray<Long> uids = procs.getValue(); 9159 final int N = uids.size(); 9160 for (int i=0; i<N; i++) { 9161 int puid = uids.keyAt(i); 9162 ProcessRecord r = mProcessNames.get(pname, puid); 9163 if (dumpPackage != null && (r == null 9164 || !dumpPackage.equals(r.info.packageName))) { 9165 continue; 9166 } 9167 if (!printed) { 9168 if (needSep) pw.println(" "); 9169 needSep = true; 9170 pw.println(" Time since processes crashed:"); 9171 printed = true; 9172 } 9173 pw.print(" Process "); pw.print(pname); 9174 pw.print(" uid "); pw.print(puid); 9175 pw.print(": last crashed "); 9176 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9177 pw.println(" ago"); 9178 } 9179 } 9180 } 9181 9182 if (mBadProcesses.getMap().size() > 0) { 9183 boolean printed = false; 9184 for (Map.Entry<String, SparseArray<Long>> procs 9185 : mBadProcesses.getMap().entrySet()) { 9186 String pname = procs.getKey(); 9187 SparseArray<Long> uids = procs.getValue(); 9188 final int N = uids.size(); 9189 for (int i=0; i<N; i++) { 9190 int puid = uids.keyAt(i); 9191 ProcessRecord r = mProcessNames.get(pname, puid); 9192 if (dumpPackage != null && (r == null 9193 || !dumpPackage.equals(r.info.packageName))) { 9194 continue; 9195 } 9196 if (!printed) { 9197 if (needSep) pw.println(" "); 9198 needSep = true; 9199 pw.println(" Bad processes:"); 9200 } 9201 pw.print(" Bad process "); pw.print(pname); 9202 pw.print(" uid "); pw.print(puid); 9203 pw.print(": crashed at time "); 9204 pw.println(uids.valueAt(i)); 9205 } 9206 } 9207 } 9208 9209 pw.println(); 9210 pw.println(" mStartedUsers:"); 9211 for (int i=0; i<mStartedUsers.size(); i++) { 9212 UserStartedState uss = mStartedUsers.valueAt(i); 9213 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9214 pw.print(": "); uss.dump("", pw); 9215 } 9216 pw.print(" mUserLru: ["); 9217 for (int i=0; i<mUserLru.size(); i++) { 9218 if (i > 0) pw.print(", "); 9219 pw.print(mUserLru.get(i)); 9220 } 9221 pw.println("]"); 9222 pw.println(" mHomeProcess: " + mHomeProcess); 9223 pw.println(" mPreviousProcess: " + mPreviousProcess); 9224 if (dumpAll) { 9225 StringBuilder sb = new StringBuilder(128); 9226 sb.append(" mPreviousProcessVisibleTime: "); 9227 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9228 pw.println(sb); 9229 } 9230 if (mHeavyWeightProcess != null) { 9231 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9232 } 9233 pw.println(" mConfiguration: " + mConfiguration); 9234 if (dumpAll) { 9235 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9236 if (mCompatModePackages.getPackages().size() > 0) { 9237 boolean printed = false; 9238 for (Map.Entry<String, Integer> entry 9239 : mCompatModePackages.getPackages().entrySet()) { 9240 String pkg = entry.getKey(); 9241 int mode = entry.getValue(); 9242 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9243 continue; 9244 } 9245 if (!printed) { 9246 pw.println(" mScreenCompatPackages:"); 9247 printed = true; 9248 } 9249 pw.print(" "); pw.print(pkg); pw.print(": "); 9250 pw.print(mode); pw.println(); 9251 } 9252 } 9253 } 9254 if (mSleeping || mWentToSleep || mLockScreenShown) { 9255 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9256 + " mLockScreenShown " + mLockScreenShown); 9257 } 9258 if (mShuttingDown) { 9259 pw.println(" mShuttingDown=" + mShuttingDown); 9260 } 9261 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9262 || mOrigWaitForDebugger) { 9263 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9264 + " mDebugTransient=" + mDebugTransient 9265 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9266 } 9267 if (mOpenGlTraceApp != null) { 9268 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9269 } 9270 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9271 || mProfileFd != null) { 9272 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9273 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9274 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9275 + mAutoStopProfiler); 9276 } 9277 if (mAlwaysFinishActivities || mController != null) { 9278 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9279 + " mController=" + mController); 9280 } 9281 if (dumpAll) { 9282 pw.println(" Total persistent processes: " + numPers); 9283 pw.println(" mStartRunning=" + mStartRunning 9284 + " mProcessesReady=" + mProcessesReady 9285 + " mSystemReady=" + mSystemReady); 9286 pw.println(" mBooting=" + mBooting 9287 + " mBooted=" + mBooted 9288 + " mFactoryTest=" + mFactoryTest); 9289 pw.print(" mLastPowerCheckRealtime="); 9290 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9291 pw.println(""); 9292 pw.print(" mLastPowerCheckUptime="); 9293 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9294 pw.println(""); 9295 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9296 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9297 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9298 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9299 + " mNumHiddenProcs=" + mNumHiddenProcs 9300 + " mNumServiceProcs=" + mNumServiceProcs 9301 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9302 } 9303 9304 return true; 9305 } 9306 9307 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9308 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9309 if (mProcessesToGc.size() > 0) { 9310 boolean printed = false; 9311 long now = SystemClock.uptimeMillis(); 9312 for (int i=0; i<mProcessesToGc.size(); i++) { 9313 ProcessRecord proc = mProcessesToGc.get(i); 9314 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9315 continue; 9316 } 9317 if (!printed) { 9318 if (needSep) pw.println(" "); 9319 needSep = true; 9320 pw.println(" Processes that are waiting to GC:"); 9321 printed = true; 9322 } 9323 pw.print(" Process "); pw.println(proc); 9324 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9325 pw.print(", last gced="); 9326 pw.print(now-proc.lastRequestedGc); 9327 pw.print(" ms ago, last lowMem="); 9328 pw.print(now-proc.lastLowMemory); 9329 pw.println(" ms ago"); 9330 9331 } 9332 } 9333 return needSep; 9334 } 9335 9336 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9337 int opti, boolean dumpAll) { 9338 boolean needSep = false; 9339 9340 if (mLruProcesses.size() > 0) { 9341 if (needSep) pw.println(" "); 9342 needSep = true; 9343 pw.println(" OOM levels:"); 9344 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9345 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9346 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9347 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9348 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9349 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9350 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9351 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9352 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9353 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9354 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9355 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9356 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9357 9358 if (needSep) pw.println(" "); 9359 needSep = true; 9360 pw.println(" Process OOM control:"); 9361 dumpProcessOomList(pw, this, mLruProcesses, " ", 9362 "Proc", "PERS", true, null); 9363 needSep = true; 9364 } 9365 9366 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9367 9368 pw.println(); 9369 pw.println(" mHomeProcess: " + mHomeProcess); 9370 pw.println(" mPreviousProcess: " + mPreviousProcess); 9371 if (mHeavyWeightProcess != null) { 9372 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9373 } 9374 9375 return true; 9376 } 9377 9378 /** 9379 * There are three ways to call this: 9380 * - no provider specified: dump all the providers 9381 * - a flattened component name that matched an existing provider was specified as the 9382 * first arg: dump that one provider 9383 * - the first arg isn't the flattened component name of an existing provider: 9384 * dump all providers whose component contains the first arg as a substring 9385 */ 9386 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9387 int opti, boolean dumpAll) { 9388 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9389 } 9390 9391 static class ItemMatcher { 9392 ArrayList<ComponentName> components; 9393 ArrayList<String> strings; 9394 ArrayList<Integer> objects; 9395 boolean all; 9396 9397 ItemMatcher() { 9398 all = true; 9399 } 9400 9401 void build(String name) { 9402 ComponentName componentName = ComponentName.unflattenFromString(name); 9403 if (componentName != null) { 9404 if (components == null) { 9405 components = new ArrayList<ComponentName>(); 9406 } 9407 components.add(componentName); 9408 all = false; 9409 } else { 9410 int objectId = 0; 9411 // Not a '/' separated full component name; maybe an object ID? 9412 try { 9413 objectId = Integer.parseInt(name, 16); 9414 if (objects == null) { 9415 objects = new ArrayList<Integer>(); 9416 } 9417 objects.add(objectId); 9418 all = false; 9419 } catch (RuntimeException e) { 9420 // Not an integer; just do string match. 9421 if (strings == null) { 9422 strings = new ArrayList<String>(); 9423 } 9424 strings.add(name); 9425 all = false; 9426 } 9427 } 9428 } 9429 9430 int build(String[] args, int opti) { 9431 for (; opti<args.length; opti++) { 9432 String name = args[opti]; 9433 if ("--".equals(name)) { 9434 return opti+1; 9435 } 9436 build(name); 9437 } 9438 return opti; 9439 } 9440 9441 boolean match(Object object, ComponentName comp) { 9442 if (all) { 9443 return true; 9444 } 9445 if (components != null) { 9446 for (int i=0; i<components.size(); i++) { 9447 if (components.get(i).equals(comp)) { 9448 return true; 9449 } 9450 } 9451 } 9452 if (objects != null) { 9453 for (int i=0; i<objects.size(); i++) { 9454 if (System.identityHashCode(object) == objects.get(i)) { 9455 return true; 9456 } 9457 } 9458 } 9459 if (strings != null) { 9460 String flat = comp.flattenToString(); 9461 for (int i=0; i<strings.size(); i++) { 9462 if (flat.contains(strings.get(i))) { 9463 return true; 9464 } 9465 } 9466 } 9467 return false; 9468 } 9469 } 9470 9471 /** 9472 * There are three things that cmd can be: 9473 * - a flattened component name that matches an existing activity 9474 * - the cmd arg isn't the flattened component name of an existing activity: 9475 * dump all activity whose component contains the cmd as a substring 9476 * - A hex number of the ActivityRecord object instance. 9477 */ 9478 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9479 int opti, boolean dumpAll) { 9480 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9481 9482 if ("all".equals(name)) { 9483 synchronized (this) { 9484 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9485 activities.add(r1); 9486 } 9487 } 9488 } else if ("top".equals(name)) { 9489 synchronized (this) { 9490 final int N = mMainStack.mHistory.size(); 9491 if (N > 0) { 9492 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9493 } 9494 } 9495 } else { 9496 ItemMatcher matcher = new ItemMatcher(); 9497 matcher.build(name); 9498 9499 synchronized (this) { 9500 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9501 if (matcher.match(r1, r1.intent.getComponent())) { 9502 activities.add(r1); 9503 } 9504 } 9505 } 9506 } 9507 9508 if (activities.size() <= 0) { 9509 return false; 9510 } 9511 9512 String[] newArgs = new String[args.length - opti]; 9513 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9514 9515 TaskRecord lastTask = null; 9516 boolean needSep = false; 9517 for (int i=activities.size()-1; i>=0; i--) { 9518 ActivityRecord r = (ActivityRecord)activities.get(i); 9519 if (needSep) { 9520 pw.println(); 9521 } 9522 needSep = true; 9523 synchronized (this) { 9524 if (lastTask != r.task) { 9525 lastTask = r.task; 9526 pw.print("TASK "); pw.print(lastTask.affinity); 9527 pw.print(" id="); pw.println(lastTask.taskId); 9528 if (dumpAll) { 9529 lastTask.dump(pw, " "); 9530 } 9531 } 9532 } 9533 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9534 } 9535 return true; 9536 } 9537 9538 /** 9539 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9540 * there is a thread associated with the activity. 9541 */ 9542 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9543 final ActivityRecord r, String[] args, boolean dumpAll) { 9544 String innerPrefix = prefix + " "; 9545 synchronized (this) { 9546 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9547 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9548 pw.print(" pid="); 9549 if (r.app != null) pw.println(r.app.pid); 9550 else pw.println("(not running)"); 9551 if (dumpAll) { 9552 r.dump(pw, innerPrefix); 9553 } 9554 } 9555 if (r.app != null && r.app.thread != null) { 9556 // flush anything that is already in the PrintWriter since the thread is going 9557 // to write to the file descriptor directly 9558 pw.flush(); 9559 try { 9560 TransferPipe tp = new TransferPipe(); 9561 try { 9562 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9563 r.appToken, innerPrefix, args); 9564 tp.go(fd); 9565 } finally { 9566 tp.kill(); 9567 } 9568 } catch (IOException e) { 9569 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9570 } catch (RemoteException e) { 9571 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9572 } 9573 } 9574 } 9575 9576 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9577 int opti, boolean dumpAll, String dumpPackage) { 9578 boolean needSep = false; 9579 boolean onlyHistory = false; 9580 9581 if ("history".equals(dumpPackage)) { 9582 onlyHistory = true; 9583 dumpPackage = null; 9584 } 9585 9586 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9587 if (!onlyHistory && dumpAll) { 9588 if (mRegisteredReceivers.size() > 0) { 9589 boolean printed = false; 9590 Iterator it = mRegisteredReceivers.values().iterator(); 9591 while (it.hasNext()) { 9592 ReceiverList r = (ReceiverList)it.next(); 9593 if (dumpPackage != null && (r.app == null || 9594 !dumpPackage.equals(r.app.info.packageName))) { 9595 continue; 9596 } 9597 if (!printed) { 9598 pw.println(" Registered Receivers:"); 9599 needSep = true; 9600 printed = true; 9601 } 9602 pw.print(" * "); pw.println(r); 9603 r.dump(pw, " "); 9604 } 9605 } 9606 9607 if (mReceiverResolver.dump(pw, needSep ? 9608 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9609 " ", dumpPackage, false)) { 9610 needSep = true; 9611 } 9612 } 9613 9614 for (BroadcastQueue q : mBroadcastQueues) { 9615 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9616 } 9617 9618 needSep = true; 9619 9620 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9621 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9622 if (needSep) { 9623 pw.println(); 9624 } 9625 needSep = true; 9626 pw.print(" Sticky broadcasts for user "); 9627 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9628 StringBuilder sb = new StringBuilder(128); 9629 for (Map.Entry<String, ArrayList<Intent>> ent 9630 : mStickyBroadcasts.valueAt(user).entrySet()) { 9631 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9632 if (dumpAll) { 9633 pw.println(":"); 9634 ArrayList<Intent> intents = ent.getValue(); 9635 final int N = intents.size(); 9636 for (int i=0; i<N; i++) { 9637 sb.setLength(0); 9638 sb.append(" Intent: "); 9639 intents.get(i).toShortString(sb, false, true, false, false); 9640 pw.println(sb.toString()); 9641 Bundle bundle = intents.get(i).getExtras(); 9642 if (bundle != null) { 9643 pw.print(" "); 9644 pw.println(bundle.toString()); 9645 } 9646 } 9647 } else { 9648 pw.println(""); 9649 } 9650 } 9651 } 9652 } 9653 9654 if (!onlyHistory && dumpAll) { 9655 pw.println(); 9656 for (BroadcastQueue queue : mBroadcastQueues) { 9657 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9658 + queue.mBroadcastsScheduled); 9659 } 9660 pw.println(" mHandler:"); 9661 mHandler.dump(new PrintWriterPrinter(pw), " "); 9662 needSep = true; 9663 } 9664 9665 return needSep; 9666 } 9667 9668 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9669 int opti, boolean dumpAll, String dumpPackage) { 9670 boolean needSep = true; 9671 9672 ItemMatcher matcher = new ItemMatcher(); 9673 matcher.build(args, opti); 9674 9675 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9676 9677 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9678 9679 if (mLaunchingProviders.size() > 0) { 9680 boolean printed = false; 9681 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9682 ContentProviderRecord r = mLaunchingProviders.get(i); 9683 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9684 continue; 9685 } 9686 if (!printed) { 9687 if (needSep) pw.println(" "); 9688 needSep = true; 9689 pw.println(" Launching content providers:"); 9690 printed = true; 9691 } 9692 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9693 pw.println(r); 9694 } 9695 } 9696 9697 if (mGrantedUriPermissions.size() > 0) { 9698 if (needSep) pw.println(); 9699 needSep = true; 9700 pw.println("Granted Uri Permissions:"); 9701 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9702 int uid = mGrantedUriPermissions.keyAt(i); 9703 HashMap<Uri, UriPermission> perms 9704 = mGrantedUriPermissions.valueAt(i); 9705 pw.print(" * UID "); pw.print(uid); 9706 pw.println(" holds:"); 9707 for (UriPermission perm : perms.values()) { 9708 pw.print(" "); pw.println(perm); 9709 if (dumpAll) { 9710 perm.dump(pw, " "); 9711 } 9712 } 9713 } 9714 needSep = true; 9715 } 9716 9717 return needSep; 9718 } 9719 9720 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9721 int opti, boolean dumpAll, String dumpPackage) { 9722 boolean needSep = false; 9723 9724 if (mIntentSenderRecords.size() > 0) { 9725 boolean printed = false; 9726 Iterator<WeakReference<PendingIntentRecord>> it 9727 = mIntentSenderRecords.values().iterator(); 9728 while (it.hasNext()) { 9729 WeakReference<PendingIntentRecord> ref = it.next(); 9730 PendingIntentRecord rec = ref != null ? ref.get(): null; 9731 if (dumpPackage != null && (rec == null 9732 || !dumpPackage.equals(rec.key.packageName))) { 9733 continue; 9734 } 9735 if (!printed) { 9736 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9737 printed = true; 9738 } 9739 needSep = true; 9740 if (rec != null) { 9741 pw.print(" * "); pw.println(rec); 9742 if (dumpAll) { 9743 rec.dump(pw, " "); 9744 } 9745 } else { 9746 pw.print(" * "); pw.println(ref); 9747 } 9748 } 9749 } 9750 9751 return needSep; 9752 } 9753 9754 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9755 String prefix, String label, boolean complete, boolean brief, boolean client, 9756 String dumpPackage) { 9757 TaskRecord lastTask = null; 9758 boolean needNL = false; 9759 final String innerPrefix = prefix + " "; 9760 final String[] args = new String[0]; 9761 for (int i=list.size()-1; i>=0; i--) { 9762 final ActivityRecord r = (ActivityRecord)list.get(i); 9763 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9764 continue; 9765 } 9766 final boolean full = !brief && (complete || !r.isInHistory()); 9767 if (needNL) { 9768 pw.println(" "); 9769 needNL = false; 9770 } 9771 if (lastTask != r.task) { 9772 lastTask = r.task; 9773 pw.print(prefix); 9774 pw.print(full ? "* " : " "); 9775 pw.println(lastTask); 9776 if (full) { 9777 lastTask.dump(pw, prefix + " "); 9778 } else if (complete) { 9779 // Complete + brief == give a summary. Isn't that obvious?!? 9780 if (lastTask.intent != null) { 9781 pw.print(prefix); pw.print(" "); 9782 pw.println(lastTask.intent.toInsecureStringWithClip()); 9783 } 9784 } 9785 } 9786 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9787 pw.print(" #"); pw.print(i); pw.print(": "); 9788 pw.println(r); 9789 if (full) { 9790 r.dump(pw, innerPrefix); 9791 } else if (complete) { 9792 // Complete + brief == give a summary. Isn't that obvious?!? 9793 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9794 if (r.app != null) { 9795 pw.print(innerPrefix); pw.println(r.app); 9796 } 9797 } 9798 if (client && r.app != null && r.app.thread != null) { 9799 // flush anything that is already in the PrintWriter since the thread is going 9800 // to write to the file descriptor directly 9801 pw.flush(); 9802 try { 9803 TransferPipe tp = new TransferPipe(); 9804 try { 9805 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9806 r.appToken, innerPrefix, args); 9807 // Short timeout, since blocking here can 9808 // deadlock with the application. 9809 tp.go(fd, 2000); 9810 } finally { 9811 tp.kill(); 9812 } 9813 } catch (IOException e) { 9814 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9815 } catch (RemoteException e) { 9816 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9817 } 9818 needNL = true; 9819 } 9820 } 9821 } 9822 9823 private static String buildOomTag(String prefix, String space, int val, int base) { 9824 if (val == base) { 9825 if (space == null) return prefix; 9826 return prefix + " "; 9827 } 9828 return prefix + "+" + Integer.toString(val-base); 9829 } 9830 9831 private static final int dumpProcessList(PrintWriter pw, 9832 ActivityManagerService service, List list, 9833 String prefix, String normalLabel, String persistentLabel, 9834 String dumpPackage) { 9835 int numPers = 0; 9836 final int N = list.size()-1; 9837 for (int i=N; i>=0; i--) { 9838 ProcessRecord r = (ProcessRecord)list.get(i); 9839 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9840 continue; 9841 } 9842 pw.println(String.format("%s%s #%2d: %s", 9843 prefix, (r.persistent ? persistentLabel : normalLabel), 9844 i, r.toString())); 9845 if (r.persistent) { 9846 numPers++; 9847 } 9848 } 9849 return numPers; 9850 } 9851 9852 private static final boolean dumpProcessOomList(PrintWriter pw, 9853 ActivityManagerService service, List<ProcessRecord> origList, 9854 String prefix, String normalLabel, String persistentLabel, 9855 boolean inclDetails, String dumpPackage) { 9856 9857 ArrayList<Pair<ProcessRecord, Integer>> list 9858 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9859 for (int i=0; i<origList.size(); i++) { 9860 ProcessRecord r = origList.get(i); 9861 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9862 continue; 9863 } 9864 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9865 } 9866 9867 if (list.size() <= 0) { 9868 return false; 9869 } 9870 9871 Comparator<Pair<ProcessRecord, Integer>> comparator 9872 = new Comparator<Pair<ProcessRecord, Integer>>() { 9873 @Override 9874 public int compare(Pair<ProcessRecord, Integer> object1, 9875 Pair<ProcessRecord, Integer> object2) { 9876 if (object1.first.setAdj != object2.first.setAdj) { 9877 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9878 } 9879 if (object1.second.intValue() != object2.second.intValue()) { 9880 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9881 } 9882 return 0; 9883 } 9884 }; 9885 9886 Collections.sort(list, comparator); 9887 9888 final long curRealtime = SystemClock.elapsedRealtime(); 9889 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9890 final long curUptime = SystemClock.uptimeMillis(); 9891 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9892 9893 for (int i=list.size()-1; i>=0; i--) { 9894 ProcessRecord r = list.get(i).first; 9895 String oomAdj; 9896 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9897 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9898 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9899 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9900 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9901 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9902 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9903 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9904 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9905 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9906 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9907 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9908 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9909 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9910 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9911 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9912 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9913 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9914 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9915 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9916 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9917 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9918 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9919 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9920 } else { 9921 oomAdj = Integer.toString(r.setAdj); 9922 } 9923 String schedGroup; 9924 switch (r.setSchedGroup) { 9925 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9926 schedGroup = "B"; 9927 break; 9928 case Process.THREAD_GROUP_DEFAULT: 9929 schedGroup = "F"; 9930 break; 9931 default: 9932 schedGroup = Integer.toString(r.setSchedGroup); 9933 break; 9934 } 9935 String foreground; 9936 if (r.foregroundActivities) { 9937 foreground = "A"; 9938 } else if (r.foregroundServices) { 9939 foreground = "S"; 9940 } else { 9941 foreground = " "; 9942 } 9943 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9944 prefix, (r.persistent ? persistentLabel : normalLabel), 9945 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9946 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9947 if (r.adjSource != null || r.adjTarget != null) { 9948 pw.print(prefix); 9949 pw.print(" "); 9950 if (r.adjTarget instanceof ComponentName) { 9951 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9952 } else if (r.adjTarget != null) { 9953 pw.print(r.adjTarget.toString()); 9954 } else { 9955 pw.print("{null}"); 9956 } 9957 pw.print("<="); 9958 if (r.adjSource instanceof ProcessRecord) { 9959 pw.print("Proc{"); 9960 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9961 pw.println("}"); 9962 } else if (r.adjSource != null) { 9963 pw.println(r.adjSource.toString()); 9964 } else { 9965 pw.println("{null}"); 9966 } 9967 } 9968 if (inclDetails) { 9969 pw.print(prefix); 9970 pw.print(" "); 9971 pw.print("oom: max="); pw.print(r.maxAdj); 9972 pw.print(" hidden="); pw.print(r.hiddenAdj); 9973 pw.print(" empty="); pw.print(r.emptyAdj); 9974 pw.print(" curRaw="); pw.print(r.curRawAdj); 9975 pw.print(" setRaw="); pw.print(r.setRawAdj); 9976 pw.print(" cur="); pw.print(r.curAdj); 9977 pw.print(" set="); pw.println(r.setAdj); 9978 pw.print(prefix); 9979 pw.print(" "); 9980 pw.print("keeping="); pw.print(r.keeping); 9981 pw.print(" hidden="); pw.print(r.hidden); 9982 pw.print(" empty="); pw.print(r.empty); 9983 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9984 9985 if (!r.keeping) { 9986 if (r.lastWakeTime != 0) { 9987 long wtime; 9988 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9989 synchronized (stats) { 9990 wtime = stats.getProcessWakeTime(r.info.uid, 9991 r.pid, curRealtime); 9992 } 9993 long timeUsed = wtime - r.lastWakeTime; 9994 pw.print(prefix); 9995 pw.print(" "); 9996 pw.print("keep awake over "); 9997 TimeUtils.formatDuration(realtimeSince, pw); 9998 pw.print(" used "); 9999 TimeUtils.formatDuration(timeUsed, pw); 10000 pw.print(" ("); 10001 pw.print((timeUsed*100)/realtimeSince); 10002 pw.println("%)"); 10003 } 10004 if (r.lastCpuTime != 0) { 10005 long timeUsed = r.curCpuTime - r.lastCpuTime; 10006 pw.print(prefix); 10007 pw.print(" "); 10008 pw.print("run cpu over "); 10009 TimeUtils.formatDuration(uptimeSince, pw); 10010 pw.print(" used "); 10011 TimeUtils.formatDuration(timeUsed, pw); 10012 pw.print(" ("); 10013 pw.print((timeUsed*100)/uptimeSince); 10014 pw.println("%)"); 10015 } 10016 } 10017 } 10018 } 10019 return true; 10020 } 10021 10022 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10023 ArrayList<ProcessRecord> procs; 10024 synchronized (this) { 10025 if (args != null && args.length > start 10026 && args[start].charAt(0) != '-') { 10027 procs = new ArrayList<ProcessRecord>(); 10028 int pid = -1; 10029 try { 10030 pid = Integer.parseInt(args[start]); 10031 } catch (NumberFormatException e) { 10032 10033 } 10034 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10035 ProcessRecord proc = mLruProcesses.get(i); 10036 if (proc.pid == pid) { 10037 procs.add(proc); 10038 } else if (proc.processName.equals(args[start])) { 10039 procs.add(proc); 10040 } 10041 } 10042 if (procs.size() <= 0) { 10043 pw.println("No process found for: " + args[start]); 10044 return null; 10045 } 10046 } else { 10047 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10048 } 10049 } 10050 return procs; 10051 } 10052 10053 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10054 PrintWriter pw, String[] args) { 10055 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10056 if (procs == null) { 10057 return; 10058 } 10059 10060 long uptime = SystemClock.uptimeMillis(); 10061 long realtime = SystemClock.elapsedRealtime(); 10062 pw.println("Applications Graphics Acceleration Info:"); 10063 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10064 10065 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10066 ProcessRecord r = procs.get(i); 10067 if (r.thread != null) { 10068 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10069 pw.flush(); 10070 try { 10071 TransferPipe tp = new TransferPipe(); 10072 try { 10073 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10074 tp.go(fd); 10075 } finally { 10076 tp.kill(); 10077 } 10078 } catch (IOException e) { 10079 pw.println("Failure while dumping the app: " + r); 10080 pw.flush(); 10081 } catch (RemoteException e) { 10082 pw.println("Got a RemoteException while dumping the app " + r); 10083 pw.flush(); 10084 } 10085 } 10086 } 10087 } 10088 10089 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10090 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10091 if (procs == null) { 10092 return; 10093 } 10094 10095 pw.println("Applications Database Info:"); 10096 10097 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10098 ProcessRecord r = procs.get(i); 10099 if (r.thread != null) { 10100 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10101 pw.flush(); 10102 try { 10103 TransferPipe tp = new TransferPipe(); 10104 try { 10105 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10106 tp.go(fd); 10107 } finally { 10108 tp.kill(); 10109 } 10110 } catch (IOException e) { 10111 pw.println("Failure while dumping the app: " + r); 10112 pw.flush(); 10113 } catch (RemoteException e) { 10114 pw.println("Got a RemoteException while dumping the app " + r); 10115 pw.flush(); 10116 } 10117 } 10118 } 10119 } 10120 10121 final static class MemItem { 10122 final String label; 10123 final String shortLabel; 10124 final long pss; 10125 final int id; 10126 ArrayList<MemItem> subitems; 10127 10128 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10129 label = _label; 10130 shortLabel = _shortLabel; 10131 pss = _pss; 10132 id = _id; 10133 } 10134 } 10135 10136 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10137 boolean sort) { 10138 if (sort) { 10139 Collections.sort(items, new Comparator<MemItem>() { 10140 @Override 10141 public int compare(MemItem lhs, MemItem rhs) { 10142 if (lhs.pss < rhs.pss) { 10143 return 1; 10144 } else if (lhs.pss > rhs.pss) { 10145 return -1; 10146 } 10147 return 0; 10148 } 10149 }); 10150 } 10151 10152 for (int i=0; i<items.size(); i++) { 10153 MemItem mi = items.get(i); 10154 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10155 if (mi.subitems != null) { 10156 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10157 } 10158 } 10159 } 10160 10161 // These are in KB. 10162 static final long[] DUMP_MEM_BUCKETS = new long[] { 10163 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10164 120*1024, 160*1024, 200*1024, 10165 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10166 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10167 }; 10168 10169 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10170 boolean stackLike) { 10171 int start = label.lastIndexOf('.'); 10172 if (start >= 0) start++; 10173 else start = 0; 10174 int end = label.length(); 10175 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10176 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10177 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10178 out.append(bucket); 10179 out.append(stackLike ? "MB." : "MB "); 10180 out.append(label, start, end); 10181 return; 10182 } 10183 } 10184 out.append(memKB/1024); 10185 out.append(stackLike ? "MB." : "MB "); 10186 out.append(label, start, end); 10187 } 10188 10189 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10190 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10191 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10192 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10193 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10194 }; 10195 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10196 "System", "Persistent", "Foreground", 10197 "Visible", "Perceptible", "Heavy Weight", 10198 "Backup", "A Services", "Home", "Previous", 10199 "B Services", "Background" 10200 }; 10201 10202 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10203 PrintWriter pw, String prefix, String[] args, boolean brief, 10204 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10205 boolean dumpAll = false; 10206 boolean oomOnly = false; 10207 10208 int opti = 0; 10209 while (opti < args.length) { 10210 String opt = args[opti]; 10211 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10212 break; 10213 } 10214 opti++; 10215 if ("-a".equals(opt)) { 10216 dumpAll = true; 10217 } else if ("--oom".equals(opt)) { 10218 oomOnly = true; 10219 } else if ("-h".equals(opt)) { 10220 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10221 pw.println(" -a: include all available information for each process."); 10222 pw.println(" --oom: only show processes organized by oom adj."); 10223 pw.println("If [process] is specified it can be the name or "); 10224 pw.println("pid of a specific process to dump."); 10225 return; 10226 } else { 10227 pw.println("Unknown argument: " + opt + "; use -h for help"); 10228 } 10229 } 10230 10231 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10232 if (procs == null) { 10233 return; 10234 } 10235 10236 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10237 long uptime = SystemClock.uptimeMillis(); 10238 long realtime = SystemClock.elapsedRealtime(); 10239 10240 if (procs.size() == 1 || isCheckinRequest) { 10241 dumpAll = true; 10242 } 10243 10244 if (isCheckinRequest) { 10245 // short checkin version 10246 pw.println(uptime + "," + realtime); 10247 pw.flush(); 10248 } else { 10249 pw.println("Applications Memory Usage (kB):"); 10250 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10251 } 10252 10253 String[] innerArgs = new String[args.length-opti]; 10254 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10255 10256 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10257 long nativePss=0, dalvikPss=0, otherPss=0; 10258 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10259 10260 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10261 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10262 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10263 10264 long totalPss = 0; 10265 10266 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10267 ProcessRecord r = procs.get(i); 10268 if (r.thread != null) { 10269 if (!isCheckinRequest && dumpAll) { 10270 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10271 pw.flush(); 10272 } 10273 Debug.MemoryInfo mi = null; 10274 if (dumpAll) { 10275 try { 10276 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10277 } catch (RemoteException e) { 10278 if (!isCheckinRequest) { 10279 pw.println("Got RemoteException!"); 10280 pw.flush(); 10281 } 10282 } 10283 } else { 10284 mi = new Debug.MemoryInfo(); 10285 Debug.getMemoryInfo(r.pid, mi); 10286 } 10287 10288 if (!isCheckinRequest && mi != null) { 10289 long myTotalPss = mi.getTotalPss(); 10290 totalPss += myTotalPss; 10291 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10292 r.processName, myTotalPss, 0); 10293 procMems.add(pssItem); 10294 10295 nativePss += mi.nativePss; 10296 dalvikPss += mi.dalvikPss; 10297 otherPss += mi.otherPss; 10298 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10299 long mem = mi.getOtherPss(j); 10300 miscPss[j] += mem; 10301 otherPss -= mem; 10302 } 10303 10304 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10305 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10306 || oomIndex == (oomPss.length-1)) { 10307 oomPss[oomIndex] += myTotalPss; 10308 if (oomProcs[oomIndex] == null) { 10309 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10310 } 10311 oomProcs[oomIndex].add(pssItem); 10312 break; 10313 } 10314 } 10315 } 10316 } 10317 } 10318 10319 if (!isCheckinRequest && procs.size() > 1) { 10320 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10321 10322 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10323 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10324 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10325 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10326 String label = Debug.MemoryInfo.getOtherLabel(j); 10327 catMems.add(new MemItem(label, label, miscPss[j], j)); 10328 } 10329 10330 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10331 for (int j=0; j<oomPss.length; j++) { 10332 if (oomPss[j] != 0) { 10333 String label = DUMP_MEM_OOM_LABEL[j]; 10334 MemItem item = new MemItem(label, label, oomPss[j], 10335 DUMP_MEM_OOM_ADJ[j]); 10336 item.subitems = oomProcs[j]; 10337 oomMems.add(item); 10338 } 10339 } 10340 10341 if (outTag != null || outStack != null) { 10342 if (outTag != null) { 10343 appendMemBucket(outTag, totalPss, "total", false); 10344 } 10345 if (outStack != null) { 10346 appendMemBucket(outStack, totalPss, "total", true); 10347 } 10348 boolean firstLine = true; 10349 for (int i=0; i<oomMems.size(); i++) { 10350 MemItem miCat = oomMems.get(i); 10351 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10352 continue; 10353 } 10354 if (miCat.id < ProcessList.SERVICE_ADJ 10355 || miCat.id == ProcessList.HOME_APP_ADJ 10356 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10357 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10358 outTag.append(" / "); 10359 } 10360 if (outStack != null) { 10361 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10362 if (firstLine) { 10363 outStack.append(":"); 10364 firstLine = false; 10365 } 10366 outStack.append("\n\t at "); 10367 } else { 10368 outStack.append("$"); 10369 } 10370 } 10371 for (int j=0; j<miCat.subitems.size(); j++) { 10372 MemItem mi = miCat.subitems.get(j); 10373 if (j > 0) { 10374 if (outTag != null) { 10375 outTag.append(" "); 10376 } 10377 if (outStack != null) { 10378 outStack.append("$"); 10379 } 10380 } 10381 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10382 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10383 } 10384 if (outStack != null) { 10385 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10386 } 10387 } 10388 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10389 outStack.append("("); 10390 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10391 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10392 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10393 outStack.append(":"); 10394 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10395 } 10396 } 10397 outStack.append(")"); 10398 } 10399 } 10400 } 10401 } 10402 10403 if (!brief && !oomOnly) { 10404 pw.println(); 10405 pw.println("Total PSS by process:"); 10406 dumpMemItems(pw, " ", procMems, true); 10407 pw.println(); 10408 } 10409 pw.println("Total PSS by OOM adjustment:"); 10410 dumpMemItems(pw, " ", oomMems, false); 10411 if (!oomOnly) { 10412 PrintWriter out = categoryPw != null ? categoryPw : pw; 10413 out.println(); 10414 out.println("Total PSS by category:"); 10415 dumpMemItems(out, " ", catMems, true); 10416 } 10417 pw.println(); 10418 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10419 final int[] SINGLE_LONG_FORMAT = new int[] { 10420 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10421 }; 10422 long[] longOut = new long[1]; 10423 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10424 SINGLE_LONG_FORMAT, null, longOut, null); 10425 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10426 longOut[0] = 0; 10427 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10428 SINGLE_LONG_FORMAT, null, longOut, null); 10429 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10430 longOut[0] = 0; 10431 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10432 SINGLE_LONG_FORMAT, null, longOut, null); 10433 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10434 longOut[0] = 0; 10435 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10436 SINGLE_LONG_FORMAT, null, longOut, null); 10437 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10438 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10439 pw.print(shared); pw.println(" kB"); 10440 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10441 pw.print(voltile); pw.println(" kB volatile"); 10442 } 10443 } 10444 10445 /** 10446 * Searches array of arguments for the specified string 10447 * @param args array of argument strings 10448 * @param value value to search for 10449 * @return true if the value is contained in the array 10450 */ 10451 private static boolean scanArgs(String[] args, String value) { 10452 if (args != null) { 10453 for (String arg : args) { 10454 if (value.equals(arg)) { 10455 return true; 10456 } 10457 } 10458 } 10459 return false; 10460 } 10461 10462 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10463 ContentProviderRecord cpr, boolean always) { 10464 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10465 10466 if (!inLaunching || always) { 10467 synchronized (cpr) { 10468 cpr.launchingApp = null; 10469 cpr.notifyAll(); 10470 } 10471 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10472 String names[] = cpr.info.authority.split(";"); 10473 for (int j = 0; j < names.length; j++) { 10474 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10475 } 10476 } 10477 10478 for (int i=0; i<cpr.connections.size(); i++) { 10479 ContentProviderConnection conn = cpr.connections.get(i); 10480 if (conn.waiting) { 10481 // If this connection is waiting for the provider, then we don't 10482 // need to mess with its process unless we are always removing 10483 // or for some reason the provider is not currently launching. 10484 if (inLaunching && !always) { 10485 continue; 10486 } 10487 } 10488 ProcessRecord capp = conn.client; 10489 conn.dead = true; 10490 if (conn.stableCount > 0) { 10491 if (!capp.persistent && capp.thread != null 10492 && capp.pid != 0 10493 && capp.pid != MY_PID) { 10494 Slog.i(TAG, "Kill " + capp.processName 10495 + " (pid " + capp.pid + "): provider " + cpr.info.name 10496 + " in dying process " + (proc != null ? proc.processName : "??")); 10497 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10498 capp.processName, capp.setAdj, "dying provider " 10499 + cpr.name.toShortString()); 10500 Process.killProcessQuiet(capp.pid); 10501 } 10502 } else if (capp.thread != null && conn.provider.provider != null) { 10503 try { 10504 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10505 } catch (RemoteException e) { 10506 } 10507 // In the protocol here, we don't expect the client to correctly 10508 // clean up this connection, we'll just remove it. 10509 cpr.connections.remove(i); 10510 conn.client.conProviders.remove(conn); 10511 } 10512 } 10513 10514 if (inLaunching && always) { 10515 mLaunchingProviders.remove(cpr); 10516 } 10517 return inLaunching; 10518 } 10519 10520 /** 10521 * Main code for cleaning up a process when it has gone away. This is 10522 * called both as a result of the process dying, or directly when stopping 10523 * a process when running in single process mode. 10524 */ 10525 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10526 boolean restarting, boolean allowRestart, int index) { 10527 if (index >= 0) { 10528 mLruProcesses.remove(index); 10529 } 10530 10531 mProcessesToGc.remove(app); 10532 10533 // Dismiss any open dialogs. 10534 if (app.crashDialog != null) { 10535 app.crashDialog.dismiss(); 10536 app.crashDialog = null; 10537 } 10538 if (app.anrDialog != null) { 10539 app.anrDialog.dismiss(); 10540 app.anrDialog = null; 10541 } 10542 if (app.waitDialog != null) { 10543 app.waitDialog.dismiss(); 10544 app.waitDialog = null; 10545 } 10546 10547 app.crashing = false; 10548 app.notResponding = false; 10549 10550 app.resetPackageList(); 10551 app.unlinkDeathRecipient(); 10552 app.thread = null; 10553 app.forcingToForeground = null; 10554 app.foregroundServices = false; 10555 app.foregroundActivities = false; 10556 app.hasShownUi = false; 10557 app.hasAboveClient = false; 10558 10559 mServices.killServicesLocked(app, allowRestart); 10560 10561 boolean restart = false; 10562 10563 // Remove published content providers. 10564 if (!app.pubProviders.isEmpty()) { 10565 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10566 while (it.hasNext()) { 10567 ContentProviderRecord cpr = it.next(); 10568 10569 final boolean always = app.bad || !allowRestart; 10570 if (removeDyingProviderLocked(app, cpr, always) || always) { 10571 // We left the provider in the launching list, need to 10572 // restart it. 10573 restart = true; 10574 } 10575 10576 cpr.provider = null; 10577 cpr.proc = null; 10578 } 10579 app.pubProviders.clear(); 10580 } 10581 10582 // Take care of any launching providers waiting for this process. 10583 if (checkAppInLaunchingProvidersLocked(app, false)) { 10584 restart = true; 10585 } 10586 10587 // Unregister from connected content providers. 10588 if (!app.conProviders.isEmpty()) { 10589 for (int i=0; i<app.conProviders.size(); i++) { 10590 ContentProviderConnection conn = app.conProviders.get(i); 10591 conn.provider.connections.remove(conn); 10592 } 10593 app.conProviders.clear(); 10594 } 10595 10596 // At this point there may be remaining entries in mLaunchingProviders 10597 // where we were the only one waiting, so they are no longer of use. 10598 // Look for these and clean up if found. 10599 // XXX Commented out for now. Trying to figure out a way to reproduce 10600 // the actual situation to identify what is actually going on. 10601 if (false) { 10602 for (int i=0; i<mLaunchingProviders.size(); i++) { 10603 ContentProviderRecord cpr = (ContentProviderRecord) 10604 mLaunchingProviders.get(i); 10605 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10606 synchronized (cpr) { 10607 cpr.launchingApp = null; 10608 cpr.notifyAll(); 10609 } 10610 } 10611 } 10612 } 10613 10614 skipCurrentReceiverLocked(app); 10615 10616 // Unregister any receivers. 10617 if (app.receivers.size() > 0) { 10618 Iterator<ReceiverList> it = app.receivers.iterator(); 10619 while (it.hasNext()) { 10620 removeReceiverLocked(it.next()); 10621 } 10622 app.receivers.clear(); 10623 } 10624 10625 // If the app is undergoing backup, tell the backup manager about it 10626 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10627 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10628 try { 10629 IBackupManager bm = IBackupManager.Stub.asInterface( 10630 ServiceManager.getService(Context.BACKUP_SERVICE)); 10631 bm.agentDisconnected(app.info.packageName); 10632 } catch (RemoteException e) { 10633 // can't happen; backup manager is local 10634 } 10635 } 10636 10637 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10638 ProcessChangeItem item = mPendingProcessChanges.get(i); 10639 if (item.pid == app.pid) { 10640 mPendingProcessChanges.remove(i); 10641 mAvailProcessChanges.add(item); 10642 } 10643 } 10644 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10645 10646 // If the caller is restarting this app, then leave it in its 10647 // current lists and let the caller take care of it. 10648 if (restarting) { 10649 return; 10650 } 10651 10652 if (!app.persistent || app.isolated) { 10653 if (DEBUG_PROCESSES) Slog.v(TAG, 10654 "Removing non-persistent process during cleanup: " + app); 10655 mProcessNames.remove(app.processName, app.uid); 10656 mIsolatedProcesses.remove(app.uid); 10657 if (mHeavyWeightProcess == app) { 10658 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10659 mHeavyWeightProcess.userId, 0)); 10660 mHeavyWeightProcess = null; 10661 } 10662 } else if (!app.removed) { 10663 // This app is persistent, so we need to keep its record around. 10664 // If it is not already on the pending app list, add it there 10665 // and start a new process for it. 10666 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10667 mPersistentStartingProcesses.add(app); 10668 restart = true; 10669 } 10670 } 10671 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10672 "Clean-up removing on hold: " + app); 10673 mProcessesOnHold.remove(app); 10674 10675 if (app == mHomeProcess) { 10676 mHomeProcess = null; 10677 } 10678 if (app == mPreviousProcess) { 10679 mPreviousProcess = null; 10680 } 10681 10682 if (restart && !app.isolated) { 10683 // We have components that still need to be running in the 10684 // process, so re-launch it. 10685 mProcessNames.put(app.processName, app.uid, app); 10686 startProcessLocked(app, "restart", app.processName); 10687 } else if (app.pid > 0 && app.pid != MY_PID) { 10688 // Goodbye! 10689 synchronized (mPidsSelfLocked) { 10690 mPidsSelfLocked.remove(app.pid); 10691 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10692 } 10693 app.setPid(0); 10694 } 10695 } 10696 10697 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10698 // Look through the content providers we are waiting to have launched, 10699 // and if any run in this process then either schedule a restart of 10700 // the process or kill the client waiting for it if this process has 10701 // gone bad. 10702 int NL = mLaunchingProviders.size(); 10703 boolean restart = false; 10704 for (int i=0; i<NL; i++) { 10705 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10706 if (cpr.launchingApp == app) { 10707 if (!alwaysBad && !app.bad) { 10708 restart = true; 10709 } else { 10710 removeDyingProviderLocked(app, cpr, true); 10711 // cpr should have been removed from mLaunchingProviders 10712 NL = mLaunchingProviders.size(); 10713 i--; 10714 } 10715 } 10716 } 10717 return restart; 10718 } 10719 10720 // ========================================================= 10721 // SERVICES 10722 // ========================================================= 10723 10724 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10725 int flags) { 10726 enforceNotIsolatedCaller("getServices"); 10727 synchronized (this) { 10728 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10729 } 10730 } 10731 10732 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10733 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10734 synchronized (this) { 10735 return mServices.getRunningServiceControlPanelLocked(name); 10736 } 10737 } 10738 10739 public ComponentName startService(IApplicationThread caller, Intent service, 10740 String resolvedType, int userId) { 10741 enforceNotIsolatedCaller("startService"); 10742 // Refuse possible leaked file descriptors 10743 if (service != null && service.hasFileDescriptors() == true) { 10744 throw new IllegalArgumentException("File descriptors passed in Intent"); 10745 } 10746 10747 if (DEBUG_SERVICE) 10748 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10749 synchronized(this) { 10750 final int callingPid = Binder.getCallingPid(); 10751 final int callingUid = Binder.getCallingUid(); 10752 checkValidCaller(callingUid, userId); 10753 final long origId = Binder.clearCallingIdentity(); 10754 ComponentName res = mServices.startServiceLocked(caller, service, 10755 resolvedType, callingPid, callingUid, userId); 10756 Binder.restoreCallingIdentity(origId); 10757 return res; 10758 } 10759 } 10760 10761 ComponentName startServiceInPackage(int uid, 10762 Intent service, String resolvedType, int userId) { 10763 synchronized(this) { 10764 if (DEBUG_SERVICE) 10765 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10766 final long origId = Binder.clearCallingIdentity(); 10767 ComponentName res = mServices.startServiceLocked(null, service, 10768 resolvedType, -1, uid, userId); 10769 Binder.restoreCallingIdentity(origId); 10770 return res; 10771 } 10772 } 10773 10774 public int stopService(IApplicationThread caller, Intent service, 10775 String resolvedType, int userId) { 10776 enforceNotIsolatedCaller("stopService"); 10777 // Refuse possible leaked file descriptors 10778 if (service != null && service.hasFileDescriptors() == true) { 10779 throw new IllegalArgumentException("File descriptors passed in Intent"); 10780 } 10781 10782 checkValidCaller(Binder.getCallingUid(), userId); 10783 10784 synchronized(this) { 10785 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10786 } 10787 } 10788 10789 public IBinder peekService(Intent service, String resolvedType) { 10790 enforceNotIsolatedCaller("peekService"); 10791 // Refuse possible leaked file descriptors 10792 if (service != null && service.hasFileDescriptors() == true) { 10793 throw new IllegalArgumentException("File descriptors passed in Intent"); 10794 } 10795 synchronized(this) { 10796 return mServices.peekServiceLocked(service, resolvedType); 10797 } 10798 } 10799 10800 public boolean stopServiceToken(ComponentName className, IBinder token, 10801 int startId) { 10802 synchronized(this) { 10803 return mServices.stopServiceTokenLocked(className, token, startId); 10804 } 10805 } 10806 10807 public void setServiceForeground(ComponentName className, IBinder token, 10808 int id, Notification notification, boolean removeNotification) { 10809 synchronized(this) { 10810 mServices.setServiceForegroundLocked(className, token, id, notification, 10811 removeNotification); 10812 } 10813 } 10814 10815 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10816 boolean requireFull, String name, String callerPackage) { 10817 synchronized(this) { 10818 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10819 requireFull, name, callerPackage); 10820 } 10821 } 10822 10823 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10824 boolean requireFull, String name, String callerPackage) { 10825 final int callingUserId = UserHandle.getUserId(callingUid); 10826 if (callingUserId != userId) { 10827 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10828 if ((requireFull || checkComponentPermission( 10829 android.Manifest.permission.INTERACT_ACROSS_USERS, 10830 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10831 && checkComponentPermission( 10832 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10833 callingPid, callingUid, -1, true) 10834 != PackageManager.PERMISSION_GRANTED) { 10835 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10836 // In this case, they would like to just execute as their 10837 // owner user instead of failing. 10838 userId = callingUserId; 10839 } else { 10840 StringBuilder builder = new StringBuilder(128); 10841 builder.append("Permission Denial: "); 10842 builder.append(name); 10843 if (callerPackage != null) { 10844 builder.append(" from "); 10845 builder.append(callerPackage); 10846 } 10847 builder.append(" asks to run as user "); 10848 builder.append(userId); 10849 builder.append(" but is calling from user "); 10850 builder.append(UserHandle.getUserId(callingUid)); 10851 builder.append("; this requires "); 10852 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10853 if (!requireFull) { 10854 builder.append(" or "); 10855 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10856 } 10857 String msg = builder.toString(); 10858 Slog.w(TAG, msg); 10859 throw new SecurityException(msg); 10860 } 10861 } 10862 } 10863 if (userId == UserHandle.USER_CURRENT 10864 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10865 userId = mCurrentUserId; 10866 } 10867 if (!allowAll && userId < 0) { 10868 throw new IllegalArgumentException( 10869 "Call does not support special user #" + userId); 10870 } 10871 } 10872 return userId; 10873 } 10874 10875 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10876 String className, int flags) { 10877 boolean result = false; 10878 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10879 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10880 if (ActivityManager.checkUidPermission( 10881 android.Manifest.permission.INTERACT_ACROSS_USERS, 10882 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10883 ComponentName comp = new ComponentName(aInfo.packageName, className); 10884 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10885 + " requests FLAG_SINGLE_USER, but app does not hold " 10886 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10887 Slog.w(TAG, msg); 10888 throw new SecurityException(msg); 10889 } 10890 result = true; 10891 } 10892 } else if (componentProcessName == aInfo.packageName) { 10893 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10894 } else if ("system".equals(componentProcessName)) { 10895 result = true; 10896 } 10897 if (DEBUG_MU) { 10898 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10899 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10900 } 10901 return result; 10902 } 10903 10904 public int bindService(IApplicationThread caller, IBinder token, 10905 Intent service, String resolvedType, 10906 IServiceConnection connection, int flags, int userId) { 10907 enforceNotIsolatedCaller("bindService"); 10908 // Refuse possible leaked file descriptors 10909 if (service != null && service.hasFileDescriptors() == true) { 10910 throw new IllegalArgumentException("File descriptors passed in Intent"); 10911 } 10912 10913 synchronized(this) { 10914 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10915 connection, flags, userId); 10916 } 10917 } 10918 10919 public boolean unbindService(IServiceConnection connection) { 10920 synchronized (this) { 10921 return mServices.unbindServiceLocked(connection); 10922 } 10923 } 10924 10925 public void publishService(IBinder token, Intent intent, IBinder service) { 10926 // Refuse possible leaked file descriptors 10927 if (intent != null && intent.hasFileDescriptors() == true) { 10928 throw new IllegalArgumentException("File descriptors passed in Intent"); 10929 } 10930 10931 synchronized(this) { 10932 if (!(token instanceof ServiceRecord)) { 10933 throw new IllegalArgumentException("Invalid service token"); 10934 } 10935 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10936 } 10937 } 10938 10939 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10940 // Refuse possible leaked file descriptors 10941 if (intent != null && intent.hasFileDescriptors() == true) { 10942 throw new IllegalArgumentException("File descriptors passed in Intent"); 10943 } 10944 10945 synchronized(this) { 10946 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10947 } 10948 } 10949 10950 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10951 synchronized(this) { 10952 if (!(token instanceof ServiceRecord)) { 10953 throw new IllegalArgumentException("Invalid service token"); 10954 } 10955 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10956 } 10957 } 10958 10959 // ========================================================= 10960 // BACKUP AND RESTORE 10961 // ========================================================= 10962 10963 // Cause the target app to be launched if necessary and its backup agent 10964 // instantiated. The backup agent will invoke backupAgentCreated() on the 10965 // activity manager to announce its creation. 10966 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10967 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10968 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10969 10970 synchronized(this) { 10971 // !!! TODO: currently no check here that we're already bound 10972 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10974 synchronized (stats) { 10975 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10976 } 10977 10978 // Backup agent is now in use, its package can't be stopped. 10979 try { 10980 AppGlobals.getPackageManager().setPackageStoppedState( 10981 app.packageName, false, UserHandle.getUserId(app.uid)); 10982 } catch (RemoteException e) { 10983 } catch (IllegalArgumentException e) { 10984 Slog.w(TAG, "Failed trying to unstop package " 10985 + app.packageName + ": " + e); 10986 } 10987 10988 BackupRecord r = new BackupRecord(ss, app, backupMode); 10989 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10990 ? new ComponentName(app.packageName, app.backupAgentName) 10991 : new ComponentName("android", "FullBackupAgent"); 10992 // startProcessLocked() returns existing proc's record if it's already running 10993 ProcessRecord proc = startProcessLocked(app.processName, app, 10994 false, 0, "backup", hostingName, false, false); 10995 if (proc == null) { 10996 Slog.e(TAG, "Unable to start backup agent process " + r); 10997 return false; 10998 } 10999 11000 r.app = proc; 11001 mBackupTarget = r; 11002 mBackupAppName = app.packageName; 11003 11004 // Try not to kill the process during backup 11005 updateOomAdjLocked(proc); 11006 11007 // If the process is already attached, schedule the creation of the backup agent now. 11008 // If it is not yet live, this will be done when it attaches to the framework. 11009 if (proc.thread != null) { 11010 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11011 try { 11012 proc.thread.scheduleCreateBackupAgent(app, 11013 compatibilityInfoForPackageLocked(app), backupMode); 11014 } catch (RemoteException e) { 11015 // Will time out on the backup manager side 11016 } 11017 } else { 11018 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11019 } 11020 // Invariants: at this point, the target app process exists and the application 11021 // is either already running or in the process of coming up. mBackupTarget and 11022 // mBackupAppName describe the app, so that when it binds back to the AM we 11023 // know that it's scheduled for a backup-agent operation. 11024 } 11025 11026 return true; 11027 } 11028 11029 // A backup agent has just come up 11030 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11031 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11032 + " = " + agent); 11033 11034 synchronized(this) { 11035 if (!agentPackageName.equals(mBackupAppName)) { 11036 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11037 return; 11038 } 11039 } 11040 11041 long oldIdent = Binder.clearCallingIdentity(); 11042 try { 11043 IBackupManager bm = IBackupManager.Stub.asInterface( 11044 ServiceManager.getService(Context.BACKUP_SERVICE)); 11045 bm.agentConnected(agentPackageName, agent); 11046 } catch (RemoteException e) { 11047 // can't happen; the backup manager service is local 11048 } catch (Exception e) { 11049 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11050 e.printStackTrace(); 11051 } finally { 11052 Binder.restoreCallingIdentity(oldIdent); 11053 } 11054 } 11055 11056 // done with this agent 11057 public void unbindBackupAgent(ApplicationInfo appInfo) { 11058 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11059 if (appInfo == null) { 11060 Slog.w(TAG, "unbind backup agent for null app"); 11061 return; 11062 } 11063 11064 synchronized(this) { 11065 if (mBackupAppName == null) { 11066 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11067 return; 11068 } 11069 11070 if (!mBackupAppName.equals(appInfo.packageName)) { 11071 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11072 return; 11073 } 11074 11075 ProcessRecord proc = mBackupTarget.app; 11076 mBackupTarget = null; 11077 mBackupAppName = null; 11078 11079 // Not backing this app up any more; reset its OOM adjustment 11080 updateOomAdjLocked(proc); 11081 11082 // If the app crashed during backup, 'thread' will be null here 11083 if (proc.thread != null) { 11084 try { 11085 proc.thread.scheduleDestroyBackupAgent(appInfo, 11086 compatibilityInfoForPackageLocked(appInfo)); 11087 } catch (Exception e) { 11088 Slog.e(TAG, "Exception when unbinding backup agent:"); 11089 e.printStackTrace(); 11090 } 11091 } 11092 } 11093 } 11094 // ========================================================= 11095 // BROADCASTS 11096 // ========================================================= 11097 11098 private final List getStickiesLocked(String action, IntentFilter filter, 11099 List cur, int userId) { 11100 final ContentResolver resolver = mContext.getContentResolver(); 11101 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11102 if (stickies == null) { 11103 return cur; 11104 } 11105 final ArrayList<Intent> list = stickies.get(action); 11106 if (list == null) { 11107 return cur; 11108 } 11109 int N = list.size(); 11110 for (int i=0; i<N; i++) { 11111 Intent intent = list.get(i); 11112 if (filter.match(resolver, intent, true, TAG) >= 0) { 11113 if (cur == null) { 11114 cur = new ArrayList<Intent>(); 11115 } 11116 cur.add(intent); 11117 } 11118 } 11119 return cur; 11120 } 11121 11122 boolean isPendingBroadcastProcessLocked(int pid) { 11123 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11124 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11125 } 11126 11127 void skipPendingBroadcastLocked(int pid) { 11128 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11129 for (BroadcastQueue queue : mBroadcastQueues) { 11130 queue.skipPendingBroadcastLocked(pid); 11131 } 11132 } 11133 11134 // The app just attached; send any pending broadcasts that it should receive 11135 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11136 boolean didSomething = false; 11137 for (BroadcastQueue queue : mBroadcastQueues) { 11138 didSomething |= queue.sendPendingBroadcastsLocked(app); 11139 } 11140 return didSomething; 11141 } 11142 11143 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11144 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11145 enforceNotIsolatedCaller("registerReceiver"); 11146 int callingUid; 11147 int callingPid; 11148 synchronized(this) { 11149 ProcessRecord callerApp = null; 11150 if (caller != null) { 11151 callerApp = getRecordForAppLocked(caller); 11152 if (callerApp == null) { 11153 throw new SecurityException( 11154 "Unable to find app for caller " + caller 11155 + " (pid=" + Binder.getCallingPid() 11156 + ") when registering receiver " + receiver); 11157 } 11158 if (callerApp.info.uid != Process.SYSTEM_UID && 11159 !callerApp.pkgList.contains(callerPackage)) { 11160 throw new SecurityException("Given caller package " + callerPackage 11161 + " is not running in process " + callerApp); 11162 } 11163 callingUid = callerApp.info.uid; 11164 callingPid = callerApp.pid; 11165 } else { 11166 callerPackage = null; 11167 callingUid = Binder.getCallingUid(); 11168 callingPid = Binder.getCallingPid(); 11169 } 11170 11171 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11172 true, true, "registerReceiver", callerPackage); 11173 11174 List allSticky = null; 11175 11176 // Look for any matching sticky broadcasts... 11177 Iterator actions = filter.actionsIterator(); 11178 if (actions != null) { 11179 while (actions.hasNext()) { 11180 String action = (String)actions.next(); 11181 allSticky = getStickiesLocked(action, filter, allSticky, 11182 UserHandle.USER_ALL); 11183 allSticky = getStickiesLocked(action, filter, allSticky, 11184 UserHandle.getUserId(callingUid)); 11185 } 11186 } else { 11187 allSticky = getStickiesLocked(null, filter, allSticky, 11188 UserHandle.USER_ALL); 11189 allSticky = getStickiesLocked(null, filter, allSticky, 11190 UserHandle.getUserId(callingUid)); 11191 } 11192 11193 // The first sticky in the list is returned directly back to 11194 // the client. 11195 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11196 11197 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11198 + ": " + sticky); 11199 11200 if (receiver == null) { 11201 return sticky; 11202 } 11203 11204 ReceiverList rl 11205 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11206 if (rl == null) { 11207 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11208 userId, receiver); 11209 if (rl.app != null) { 11210 rl.app.receivers.add(rl); 11211 } else { 11212 try { 11213 receiver.asBinder().linkToDeath(rl, 0); 11214 } catch (RemoteException e) { 11215 return sticky; 11216 } 11217 rl.linkedToDeath = true; 11218 } 11219 mRegisteredReceivers.put(receiver.asBinder(), rl); 11220 } else if (rl.uid != callingUid) { 11221 throw new IllegalArgumentException( 11222 "Receiver requested to register for uid " + callingUid 11223 + " was previously registered for uid " + rl.uid); 11224 } else if (rl.pid != callingPid) { 11225 throw new IllegalArgumentException( 11226 "Receiver requested to register for pid " + callingPid 11227 + " was previously registered for pid " + rl.pid); 11228 } else if (rl.userId != userId) { 11229 throw new IllegalArgumentException( 11230 "Receiver requested to register for user " + userId 11231 + " was previously registered for user " + rl.userId); 11232 } 11233 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11234 permission, callingUid, userId); 11235 rl.add(bf); 11236 if (!bf.debugCheck()) { 11237 Slog.w(TAG, "==> For Dynamic broadast"); 11238 } 11239 mReceiverResolver.addFilter(bf); 11240 11241 // Enqueue broadcasts for all existing stickies that match 11242 // this filter. 11243 if (allSticky != null) { 11244 ArrayList receivers = new ArrayList(); 11245 receivers.add(bf); 11246 11247 int N = allSticky.size(); 11248 for (int i=0; i<N; i++) { 11249 Intent intent = (Intent)allSticky.get(i); 11250 BroadcastQueue queue = broadcastQueueForIntent(intent); 11251 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11252 null, -1, -1, null, receivers, null, 0, null, null, 11253 false, true, true, -1); 11254 queue.enqueueParallelBroadcastLocked(r); 11255 queue.scheduleBroadcastsLocked(); 11256 } 11257 } 11258 11259 return sticky; 11260 } 11261 } 11262 11263 public void unregisterReceiver(IIntentReceiver receiver) { 11264 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11265 11266 final long origId = Binder.clearCallingIdentity(); 11267 try { 11268 boolean doTrim = false; 11269 11270 synchronized(this) { 11271 ReceiverList rl 11272 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11273 if (rl != null) { 11274 if (rl.curBroadcast != null) { 11275 BroadcastRecord r = rl.curBroadcast; 11276 final boolean doNext = finishReceiverLocked( 11277 receiver.asBinder(), r.resultCode, r.resultData, 11278 r.resultExtras, r.resultAbort, true); 11279 if (doNext) { 11280 doTrim = true; 11281 r.queue.processNextBroadcast(false); 11282 } 11283 } 11284 11285 if (rl.app != null) { 11286 rl.app.receivers.remove(rl); 11287 } 11288 removeReceiverLocked(rl); 11289 if (rl.linkedToDeath) { 11290 rl.linkedToDeath = false; 11291 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11292 } 11293 } 11294 } 11295 11296 // If we actually concluded any broadcasts, we might now be able 11297 // to trim the recipients' apps from our working set 11298 if (doTrim) { 11299 trimApplications(); 11300 return; 11301 } 11302 11303 } finally { 11304 Binder.restoreCallingIdentity(origId); 11305 } 11306 } 11307 11308 void removeReceiverLocked(ReceiverList rl) { 11309 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11310 int N = rl.size(); 11311 for (int i=0; i<N; i++) { 11312 mReceiverResolver.removeFilter(rl.get(i)); 11313 } 11314 } 11315 11316 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11317 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11318 ProcessRecord r = mLruProcesses.get(i); 11319 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11320 try { 11321 r.thread.dispatchPackageBroadcast(cmd, packages); 11322 } catch (RemoteException ex) { 11323 } 11324 } 11325 } 11326 } 11327 11328 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11329 int[] users) { 11330 List<ResolveInfo> receivers = null; 11331 try { 11332 HashSet<ComponentName> singleUserReceivers = null; 11333 boolean scannedFirstReceivers = false; 11334 for (int user : users) { 11335 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11336 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11337 if (newReceivers != null && newReceivers.size() == 0) { 11338 newReceivers = null; 11339 } 11340 if (receivers == null) { 11341 receivers = newReceivers; 11342 } else if (newReceivers != null) { 11343 // We need to concatenate the additional receivers 11344 // found with what we have do far. This would be easy, 11345 // but we also need to de-dup any receivers that are 11346 // singleUser. 11347 if (!scannedFirstReceivers) { 11348 // Collect any single user receivers we had already retrieved. 11349 scannedFirstReceivers = true; 11350 for (int i=0; i<receivers.size(); i++) { 11351 ResolveInfo ri = receivers.get(i); 11352 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11353 ComponentName cn = new ComponentName( 11354 ri.activityInfo.packageName, ri.activityInfo.name); 11355 if (singleUserReceivers == null) { 11356 singleUserReceivers = new HashSet<ComponentName>(); 11357 } 11358 singleUserReceivers.add(cn); 11359 } 11360 } 11361 } 11362 // Add the new results to the existing results, tracking 11363 // and de-dupping single user receivers. 11364 for (int i=0; i<newReceivers.size(); i++) { 11365 ResolveInfo ri = receivers.get(i); 11366 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11367 ComponentName cn = new ComponentName( 11368 ri.activityInfo.packageName, ri.activityInfo.name); 11369 if (singleUserReceivers == null) { 11370 singleUserReceivers = new HashSet<ComponentName>(); 11371 } 11372 if (!singleUserReceivers.contains(cn)) { 11373 singleUserReceivers.add(cn); 11374 receivers.add(ri); 11375 } 11376 } else { 11377 receivers.add(ri); 11378 } 11379 } 11380 } 11381 } 11382 } catch (RemoteException ex) { 11383 // pm is in same process, this will never happen. 11384 } 11385 return receivers; 11386 } 11387 11388 private final int broadcastIntentLocked(ProcessRecord callerApp, 11389 String callerPackage, Intent intent, String resolvedType, 11390 IIntentReceiver resultTo, int resultCode, String resultData, 11391 Bundle map, String requiredPermission, 11392 boolean ordered, boolean sticky, int callingPid, int callingUid, 11393 int userId) { 11394 intent = new Intent(intent); 11395 11396 // By default broadcasts do not go to stopped apps. 11397 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11398 11399 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11400 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11401 + " ordered=" + ordered + " userid=" + userId); 11402 if ((resultTo != null) && !ordered) { 11403 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11404 } 11405 11406 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11407 true, false, "broadcast", callerPackage); 11408 11409 // Make sure that the user who is receiving this broadcast is started 11410 // If not, we will just skip it. 11411 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11412 Slog.w(TAG, "Skipping broadcast of " + intent 11413 + ": user " + userId + " is stopped"); 11414 return ActivityManager.BROADCAST_SUCCESS; 11415 } 11416 11417 /* 11418 * Prevent non-system code (defined here to be non-persistent 11419 * processes) from sending protected broadcasts. 11420 */ 11421 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11422 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11423 callingUid == 0) { 11424 // Always okay. 11425 } else if (callerApp == null || !callerApp.persistent) { 11426 try { 11427 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11428 intent.getAction())) { 11429 String msg = "Permission Denial: not allowed to send broadcast " 11430 + intent.getAction() + " from pid=" 11431 + callingPid + ", uid=" + callingUid; 11432 Slog.w(TAG, msg); 11433 throw new SecurityException(msg); 11434 } 11435 } catch (RemoteException e) { 11436 Slog.w(TAG, "Remote exception", e); 11437 return ActivityManager.BROADCAST_SUCCESS; 11438 } 11439 } 11440 11441 // Handle special intents: if this broadcast is from the package 11442 // manager about a package being removed, we need to remove all of 11443 // its activities from the history stack. 11444 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11445 intent.getAction()); 11446 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11447 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11448 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11449 || uidRemoved) { 11450 if (checkComponentPermission( 11451 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11452 callingPid, callingUid, -1, true) 11453 == PackageManager.PERMISSION_GRANTED) { 11454 if (uidRemoved) { 11455 final Bundle intentExtras = intent.getExtras(); 11456 final int uid = intentExtras != null 11457 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11458 if (uid >= 0) { 11459 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11460 synchronized (bs) { 11461 bs.removeUidStatsLocked(uid); 11462 } 11463 } 11464 } else { 11465 // If resources are unavailable just force stop all 11466 // those packages and flush the attribute cache as well. 11467 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11468 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11469 if (list != null && (list.length > 0)) { 11470 for (String pkg : list) { 11471 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11472 } 11473 sendPackageBroadcastLocked( 11474 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11475 } 11476 } else { 11477 Uri data = intent.getData(); 11478 String ssp; 11479 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11480 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11481 forceStopPackageLocked(ssp, 11482 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11483 false, userId); 11484 } 11485 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11486 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11487 new String[] {ssp}, userId); 11488 } 11489 } 11490 } 11491 } 11492 } else { 11493 String msg = "Permission Denial: " + intent.getAction() 11494 + " broadcast from " + callerPackage + " (pid=" + callingPid 11495 + ", uid=" + callingUid + ")" 11496 + " requires " 11497 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11498 Slog.w(TAG, msg); 11499 throw new SecurityException(msg); 11500 } 11501 11502 // Special case for adding a package: by default turn on compatibility 11503 // mode. 11504 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11505 Uri data = intent.getData(); 11506 String ssp; 11507 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11508 mCompatModePackages.handlePackageAddedLocked(ssp, 11509 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11510 } 11511 } 11512 11513 /* 11514 * If this is the time zone changed action, queue up a message that will reset the timezone 11515 * of all currently running processes. This message will get queued up before the broadcast 11516 * happens. 11517 */ 11518 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11519 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11520 } 11521 11522 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11523 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11524 } 11525 11526 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11527 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11528 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11529 } 11530 11531 // Add to the sticky list if requested. 11532 if (sticky) { 11533 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11534 callingPid, callingUid) 11535 != PackageManager.PERMISSION_GRANTED) { 11536 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11537 + callingPid + ", uid=" + callingUid 11538 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11539 Slog.w(TAG, msg); 11540 throw new SecurityException(msg); 11541 } 11542 if (requiredPermission != null) { 11543 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11544 + " and enforce permission " + requiredPermission); 11545 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11546 } 11547 if (intent.getComponent() != null) { 11548 throw new SecurityException( 11549 "Sticky broadcasts can't target a specific component"); 11550 } 11551 // We use userId directly here, since the "all" target is maintained 11552 // as a separate set of sticky broadcasts. 11553 if (userId != UserHandle.USER_ALL) { 11554 // But first, if this is not a broadcast to all users, then 11555 // make sure it doesn't conflict with an existing broadcast to 11556 // all users. 11557 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11558 UserHandle.USER_ALL); 11559 if (stickies != null) { 11560 ArrayList<Intent> list = stickies.get(intent.getAction()); 11561 if (list != null) { 11562 int N = list.size(); 11563 int i; 11564 for (i=0; i<N; i++) { 11565 if (intent.filterEquals(list.get(i))) { 11566 throw new IllegalArgumentException( 11567 "Sticky broadcast " + intent + " for user " 11568 + userId + " conflicts with existing global broadcast"); 11569 } 11570 } 11571 } 11572 } 11573 } 11574 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11575 if (stickies == null) { 11576 stickies = new HashMap<String, ArrayList<Intent>>(); 11577 mStickyBroadcasts.put(userId, stickies); 11578 } 11579 ArrayList<Intent> list = stickies.get(intent.getAction()); 11580 if (list == null) { 11581 list = new ArrayList<Intent>(); 11582 stickies.put(intent.getAction(), list); 11583 } 11584 int N = list.size(); 11585 int i; 11586 for (i=0; i<N; i++) { 11587 if (intent.filterEquals(list.get(i))) { 11588 // This sticky already exists, replace it. 11589 list.set(i, new Intent(intent)); 11590 break; 11591 } 11592 } 11593 if (i >= N) { 11594 list.add(new Intent(intent)); 11595 } 11596 } 11597 11598 int[] users; 11599 if (userId == UserHandle.USER_ALL) { 11600 // Caller wants broadcast to go to all started users. 11601 users = new int[mStartedUsers.size()]; 11602 for (int i=0; i<mStartedUsers.size(); i++) { 11603 users[i] = mStartedUsers.keyAt(i); 11604 } 11605 } else { 11606 // Caller wants broadcast to go to one specific user. 11607 users = new int[] {userId}; 11608 } 11609 11610 // Figure out who all will receive this broadcast. 11611 List receivers = null; 11612 List<BroadcastFilter> registeredReceivers = null; 11613 // Need to resolve the intent to interested receivers... 11614 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11615 == 0) { 11616 receivers = collectReceiverComponents(intent, resolvedType, users); 11617 } 11618 if (intent.getComponent() == null) { 11619 registeredReceivers = mReceiverResolver.queryIntent(intent, 11620 resolvedType, false, userId); 11621 } 11622 11623 final boolean replacePending = 11624 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11625 11626 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11627 + " replacePending=" + replacePending); 11628 11629 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11630 if (!ordered && NR > 0) { 11631 // If we are not serializing this broadcast, then send the 11632 // registered receivers separately so they don't wait for the 11633 // components to be launched. 11634 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11635 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11636 callerPackage, callingPid, callingUid, requiredPermission, 11637 registeredReceivers, resultTo, resultCode, resultData, map, 11638 ordered, sticky, false, userId); 11639 if (DEBUG_BROADCAST) Slog.v( 11640 TAG, "Enqueueing parallel broadcast " + r); 11641 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11642 if (!replaced) { 11643 queue.enqueueParallelBroadcastLocked(r); 11644 queue.scheduleBroadcastsLocked(); 11645 } 11646 registeredReceivers = null; 11647 NR = 0; 11648 } 11649 11650 // Merge into one list. 11651 int ir = 0; 11652 if (receivers != null) { 11653 // A special case for PACKAGE_ADDED: do not allow the package 11654 // being added to see this broadcast. This prevents them from 11655 // using this as a back door to get run as soon as they are 11656 // installed. Maybe in the future we want to have a special install 11657 // broadcast or such for apps, but we'd like to deliberately make 11658 // this decision. 11659 String skipPackages[] = null; 11660 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11661 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11662 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11663 Uri data = intent.getData(); 11664 if (data != null) { 11665 String pkgName = data.getSchemeSpecificPart(); 11666 if (pkgName != null) { 11667 skipPackages = new String[] { pkgName }; 11668 } 11669 } 11670 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11671 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11672 } 11673 if (skipPackages != null && (skipPackages.length > 0)) { 11674 for (String skipPackage : skipPackages) { 11675 if (skipPackage != null) { 11676 int NT = receivers.size(); 11677 for (int it=0; it<NT; it++) { 11678 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11679 if (curt.activityInfo.packageName.equals(skipPackage)) { 11680 receivers.remove(it); 11681 it--; 11682 NT--; 11683 } 11684 } 11685 } 11686 } 11687 } 11688 11689 int NT = receivers != null ? receivers.size() : 0; 11690 int it = 0; 11691 ResolveInfo curt = null; 11692 BroadcastFilter curr = null; 11693 while (it < NT && ir < NR) { 11694 if (curt == null) { 11695 curt = (ResolveInfo)receivers.get(it); 11696 } 11697 if (curr == null) { 11698 curr = registeredReceivers.get(ir); 11699 } 11700 if (curr.getPriority() >= curt.priority) { 11701 // Insert this broadcast record into the final list. 11702 receivers.add(it, curr); 11703 ir++; 11704 curr = null; 11705 it++; 11706 NT++; 11707 } else { 11708 // Skip to the next ResolveInfo in the final list. 11709 it++; 11710 curt = null; 11711 } 11712 } 11713 } 11714 while (ir < NR) { 11715 if (receivers == null) { 11716 receivers = new ArrayList(); 11717 } 11718 receivers.add(registeredReceivers.get(ir)); 11719 ir++; 11720 } 11721 11722 if ((receivers != null && receivers.size() > 0) 11723 || resultTo != null) { 11724 BroadcastQueue queue = broadcastQueueForIntent(intent); 11725 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11726 callerPackage, callingPid, callingUid, requiredPermission, 11727 receivers, resultTo, resultCode, resultData, map, ordered, 11728 sticky, false, userId); 11729 if (DEBUG_BROADCAST) Slog.v( 11730 TAG, "Enqueueing ordered broadcast " + r 11731 + ": prev had " + queue.mOrderedBroadcasts.size()); 11732 if (DEBUG_BROADCAST) { 11733 int seq = r.intent.getIntExtra("seq", -1); 11734 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11735 } 11736 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11737 if (!replaced) { 11738 queue.enqueueOrderedBroadcastLocked(r); 11739 queue.scheduleBroadcastsLocked(); 11740 } 11741 } 11742 11743 return ActivityManager.BROADCAST_SUCCESS; 11744 } 11745 11746 final Intent verifyBroadcastLocked(Intent intent) { 11747 // Refuse possible leaked file descriptors 11748 if (intent != null && intent.hasFileDescriptors() == true) { 11749 throw new IllegalArgumentException("File descriptors passed in Intent"); 11750 } 11751 11752 int flags = intent.getFlags(); 11753 11754 if (!mProcessesReady) { 11755 // if the caller really truly claims to know what they're doing, go 11756 // ahead and allow the broadcast without launching any receivers 11757 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11758 intent = new Intent(intent); 11759 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11760 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11761 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11762 + " before boot completion"); 11763 throw new IllegalStateException("Cannot broadcast before boot completed"); 11764 } 11765 } 11766 11767 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11768 throw new IllegalArgumentException( 11769 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11770 } 11771 11772 return intent; 11773 } 11774 11775 public final int broadcastIntent(IApplicationThread caller, 11776 Intent intent, String resolvedType, IIntentReceiver resultTo, 11777 int resultCode, String resultData, Bundle map, 11778 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11779 enforceNotIsolatedCaller("broadcastIntent"); 11780 synchronized(this) { 11781 intent = verifyBroadcastLocked(intent); 11782 11783 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11784 final int callingPid = Binder.getCallingPid(); 11785 final int callingUid = Binder.getCallingUid(); 11786 final long origId = Binder.clearCallingIdentity(); 11787 int res = broadcastIntentLocked(callerApp, 11788 callerApp != null ? callerApp.info.packageName : null, 11789 intent, resolvedType, resultTo, 11790 resultCode, resultData, map, requiredPermission, serialized, sticky, 11791 callingPid, callingUid, userId); 11792 Binder.restoreCallingIdentity(origId); 11793 return res; 11794 } 11795 } 11796 11797 int broadcastIntentInPackage(String packageName, int uid, 11798 Intent intent, String resolvedType, IIntentReceiver resultTo, 11799 int resultCode, String resultData, Bundle map, 11800 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11801 synchronized(this) { 11802 intent = verifyBroadcastLocked(intent); 11803 11804 final long origId = Binder.clearCallingIdentity(); 11805 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11806 resultTo, resultCode, resultData, map, requiredPermission, 11807 serialized, sticky, -1, uid, userId); 11808 Binder.restoreCallingIdentity(origId); 11809 return res; 11810 } 11811 } 11812 11813 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11814 // Refuse possible leaked file descriptors 11815 if (intent != null && intent.hasFileDescriptors() == true) { 11816 throw new IllegalArgumentException("File descriptors passed in Intent"); 11817 } 11818 11819 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11820 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11821 11822 synchronized(this) { 11823 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11824 != PackageManager.PERMISSION_GRANTED) { 11825 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11826 + Binder.getCallingPid() 11827 + ", uid=" + Binder.getCallingUid() 11828 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11829 Slog.w(TAG, msg); 11830 throw new SecurityException(msg); 11831 } 11832 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11833 if (stickies != null) { 11834 ArrayList<Intent> list = stickies.get(intent.getAction()); 11835 if (list != null) { 11836 int N = list.size(); 11837 int i; 11838 for (i=0; i<N; i++) { 11839 if (intent.filterEquals(list.get(i))) { 11840 list.remove(i); 11841 break; 11842 } 11843 } 11844 if (list.size() <= 0) { 11845 stickies.remove(intent.getAction()); 11846 } 11847 } 11848 if (stickies.size() <= 0) { 11849 mStickyBroadcasts.remove(userId); 11850 } 11851 } 11852 } 11853 } 11854 11855 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11856 String resultData, Bundle resultExtras, boolean resultAbort, 11857 boolean explicit) { 11858 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11859 if (r == null) { 11860 Slog.w(TAG, "finishReceiver called but not found on queue"); 11861 return false; 11862 } 11863 11864 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11865 explicit); 11866 } 11867 11868 public void finishReceiver(IBinder who, int resultCode, String resultData, 11869 Bundle resultExtras, boolean resultAbort) { 11870 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11871 11872 // Refuse possible leaked file descriptors 11873 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11874 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11875 } 11876 11877 final long origId = Binder.clearCallingIdentity(); 11878 try { 11879 boolean doNext = false; 11880 BroadcastRecord r = null; 11881 11882 synchronized(this) { 11883 r = broadcastRecordForReceiverLocked(who); 11884 if (r != null) { 11885 doNext = r.queue.finishReceiverLocked(r, resultCode, 11886 resultData, resultExtras, resultAbort, true); 11887 } 11888 } 11889 11890 if (doNext) { 11891 r.queue.processNextBroadcast(false); 11892 } 11893 trimApplications(); 11894 } finally { 11895 Binder.restoreCallingIdentity(origId); 11896 } 11897 } 11898 11899 // ========================================================= 11900 // INSTRUMENTATION 11901 // ========================================================= 11902 11903 public boolean startInstrumentation(ComponentName className, 11904 String profileFile, int flags, Bundle arguments, 11905 IInstrumentationWatcher watcher, int userId) { 11906 enforceNotIsolatedCaller("startInstrumentation"); 11907 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 11908 userId, false, true, "startInstrumentation", null); 11909 // Refuse possible leaked file descriptors 11910 if (arguments != null && arguments.hasFileDescriptors()) { 11911 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11912 } 11913 11914 synchronized(this) { 11915 InstrumentationInfo ii = null; 11916 ApplicationInfo ai = null; 11917 try { 11918 ii = mContext.getPackageManager().getInstrumentationInfo( 11919 className, STOCK_PM_FLAGS); 11920 ai = AppGlobals.getPackageManager().getApplicationInfo( 11921 ii.targetPackage, STOCK_PM_FLAGS, userId); 11922 } catch (PackageManager.NameNotFoundException e) { 11923 } catch (RemoteException e) { 11924 } 11925 if (ii == null) { 11926 reportStartInstrumentationFailure(watcher, className, 11927 "Unable to find instrumentation info for: " + className); 11928 return false; 11929 } 11930 if (ai == null) { 11931 reportStartInstrumentationFailure(watcher, className, 11932 "Unable to find instrumentation target package: " + ii.targetPackage); 11933 return false; 11934 } 11935 11936 int match = mContext.getPackageManager().checkSignatures( 11937 ii.targetPackage, ii.packageName); 11938 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11939 String msg = "Permission Denial: starting instrumentation " 11940 + className + " from pid=" 11941 + Binder.getCallingPid() 11942 + ", uid=" + Binder.getCallingPid() 11943 + " not allowed because package " + ii.packageName 11944 + " does not have a signature matching the target " 11945 + ii.targetPackage; 11946 reportStartInstrumentationFailure(watcher, className, msg); 11947 throw new SecurityException(msg); 11948 } 11949 11950 final long origId = Binder.clearCallingIdentity(); 11951 // Instrumentation can kill and relaunch even persistent processes 11952 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11953 ProcessRecord app = addAppLocked(ai, false); 11954 app.instrumentationClass = className; 11955 app.instrumentationInfo = ai; 11956 app.instrumentationProfileFile = profileFile; 11957 app.instrumentationArguments = arguments; 11958 app.instrumentationWatcher = watcher; 11959 app.instrumentationResultClass = className; 11960 Binder.restoreCallingIdentity(origId); 11961 } 11962 11963 return true; 11964 } 11965 11966 /** 11967 * Report errors that occur while attempting to start Instrumentation. Always writes the 11968 * error to the logs, but if somebody is watching, send the report there too. This enables 11969 * the "am" command to report errors with more information. 11970 * 11971 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11972 * @param cn The component name of the instrumentation. 11973 * @param report The error report. 11974 */ 11975 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11976 ComponentName cn, String report) { 11977 Slog.w(TAG, report); 11978 try { 11979 if (watcher != null) { 11980 Bundle results = new Bundle(); 11981 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11982 results.putString("Error", report); 11983 watcher.instrumentationStatus(cn, -1, results); 11984 } 11985 } catch (RemoteException e) { 11986 Slog.w(TAG, e); 11987 } 11988 } 11989 11990 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11991 if (app.instrumentationWatcher != null) { 11992 try { 11993 // NOTE: IInstrumentationWatcher *must* be oneway here 11994 app.instrumentationWatcher.instrumentationFinished( 11995 app.instrumentationClass, 11996 resultCode, 11997 results); 11998 } catch (RemoteException e) { 11999 } 12000 } 12001 app.instrumentationWatcher = null; 12002 app.instrumentationClass = null; 12003 app.instrumentationInfo = null; 12004 app.instrumentationProfileFile = null; 12005 app.instrumentationArguments = null; 12006 12007 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12008 } 12009 12010 public void finishInstrumentation(IApplicationThread target, 12011 int resultCode, Bundle results) { 12012 int userId = UserHandle.getCallingUserId(); 12013 // Refuse possible leaked file descriptors 12014 if (results != null && results.hasFileDescriptors()) { 12015 throw new IllegalArgumentException("File descriptors passed in Intent"); 12016 } 12017 12018 synchronized(this) { 12019 ProcessRecord app = getRecordForAppLocked(target); 12020 if (app == null) { 12021 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12022 return; 12023 } 12024 final long origId = Binder.clearCallingIdentity(); 12025 finishInstrumentationLocked(app, resultCode, results); 12026 Binder.restoreCallingIdentity(origId); 12027 } 12028 } 12029 12030 // ========================================================= 12031 // CONFIGURATION 12032 // ========================================================= 12033 12034 public ConfigurationInfo getDeviceConfigurationInfo() { 12035 ConfigurationInfo config = new ConfigurationInfo(); 12036 synchronized (this) { 12037 config.reqTouchScreen = mConfiguration.touchscreen; 12038 config.reqKeyboardType = mConfiguration.keyboard; 12039 config.reqNavigation = mConfiguration.navigation; 12040 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12041 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12042 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12043 } 12044 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12045 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12046 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12047 } 12048 config.reqGlEsVersion = GL_ES_VERSION; 12049 } 12050 return config; 12051 } 12052 12053 public Configuration getConfiguration() { 12054 Configuration ci; 12055 synchronized(this) { 12056 ci = new Configuration(mConfiguration); 12057 } 12058 return ci; 12059 } 12060 12061 public void updatePersistentConfiguration(Configuration values) { 12062 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12063 "updateConfiguration()"); 12064 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12065 "updateConfiguration()"); 12066 if (values == null) { 12067 throw new NullPointerException("Configuration must not be null"); 12068 } 12069 12070 synchronized(this) { 12071 final long origId = Binder.clearCallingIdentity(); 12072 updateConfigurationLocked(values, null, true, false); 12073 Binder.restoreCallingIdentity(origId); 12074 } 12075 } 12076 12077 public void updateConfiguration(Configuration values) { 12078 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12079 "updateConfiguration()"); 12080 12081 synchronized(this) { 12082 if (values == null && mWindowManager != null) { 12083 // sentinel: fetch the current configuration from the window manager 12084 values = mWindowManager.computeNewConfiguration(); 12085 } 12086 12087 if (mWindowManager != null) { 12088 mProcessList.applyDisplaySize(mWindowManager); 12089 } 12090 12091 final long origId = Binder.clearCallingIdentity(); 12092 if (values != null) { 12093 Settings.System.clearConfiguration(values); 12094 } 12095 updateConfigurationLocked(values, null, false, false); 12096 Binder.restoreCallingIdentity(origId); 12097 } 12098 } 12099 12100 /** 12101 * Do either or both things: (1) change the current configuration, and (2) 12102 * make sure the given activity is running with the (now) current 12103 * configuration. Returns true if the activity has been left running, or 12104 * false if <var>starting</var> is being destroyed to match the new 12105 * configuration. 12106 * @param persistent TODO 12107 */ 12108 boolean updateConfigurationLocked(Configuration values, 12109 ActivityRecord starting, boolean persistent, boolean initLocale) { 12110 // do nothing if we are headless 12111 if (mHeadless) return true; 12112 12113 int changes = 0; 12114 12115 boolean kept = true; 12116 12117 if (values != null) { 12118 Configuration newConfig = new Configuration(mConfiguration); 12119 changes = newConfig.updateFrom(values); 12120 if (changes != 0) { 12121 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12122 Slog.i(TAG, "Updating configuration to: " + values); 12123 } 12124 12125 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12126 12127 if (values.locale != null && !initLocale) { 12128 saveLocaleLocked(values.locale, 12129 !values.locale.equals(mConfiguration.locale), 12130 values.userSetLocale); 12131 } 12132 12133 mConfigurationSeq++; 12134 if (mConfigurationSeq <= 0) { 12135 mConfigurationSeq = 1; 12136 } 12137 newConfig.seq = mConfigurationSeq; 12138 mConfiguration = newConfig; 12139 Slog.i(TAG, "Config changed: " + newConfig); 12140 12141 final Configuration configCopy = new Configuration(mConfiguration); 12142 12143 // TODO: If our config changes, should we auto dismiss any currently 12144 // showing dialogs? 12145 mShowDialogs = shouldShowDialogs(newConfig); 12146 12147 AttributeCache ac = AttributeCache.instance(); 12148 if (ac != null) { 12149 ac.updateConfiguration(configCopy); 12150 } 12151 12152 // Make sure all resources in our process are updated 12153 // right now, so that anyone who is going to retrieve 12154 // resource values after we return will be sure to get 12155 // the new ones. This is especially important during 12156 // boot, where the first config change needs to guarantee 12157 // all resources have that config before following boot 12158 // code is executed. 12159 mSystemThread.applyConfigurationToResources(configCopy); 12160 12161 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12162 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12163 msg.obj = new Configuration(configCopy); 12164 mHandler.sendMessage(msg); 12165 } 12166 12167 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12168 ProcessRecord app = mLruProcesses.get(i); 12169 try { 12170 if (app.thread != null) { 12171 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12172 + app.processName + " new config " + mConfiguration); 12173 app.thread.scheduleConfigurationChanged(configCopy); 12174 } 12175 } catch (Exception e) { 12176 } 12177 } 12178 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12179 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12180 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12181 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12182 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12183 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12184 broadcastIntentLocked(null, null, 12185 new Intent(Intent.ACTION_LOCALE_CHANGED), 12186 null, null, 0, null, null, 12187 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12188 } 12189 } 12190 } 12191 12192 if (changes != 0 && starting == null) { 12193 // If the configuration changed, and the caller is not already 12194 // in the process of starting an activity, then find the top 12195 // activity to check if its configuration needs to change. 12196 starting = mMainStack.topRunningActivityLocked(null); 12197 } 12198 12199 if (starting != null) { 12200 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12201 // And we need to make sure at this point that all other activities 12202 // are made visible with the correct configuration. 12203 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12204 } 12205 12206 if (values != null && mWindowManager != null) { 12207 mWindowManager.setNewConfiguration(mConfiguration); 12208 } 12209 12210 return kept; 12211 } 12212 12213 /** 12214 * Decide based on the configuration whether we should shouw the ANR, 12215 * crash, etc dialogs. The idea is that if there is no affordnace to 12216 * press the on-screen buttons, we shouldn't show the dialog. 12217 * 12218 * A thought: SystemUI might also want to get told about this, the Power 12219 * dialog / global actions also might want different behaviors. 12220 */ 12221 private static final boolean shouldShowDialogs(Configuration config) { 12222 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12223 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12224 } 12225 12226 /** 12227 * Save the locale. You must be inside a synchronized (this) block. 12228 */ 12229 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12230 if(isDiff) { 12231 SystemProperties.set("user.language", l.getLanguage()); 12232 SystemProperties.set("user.region", l.getCountry()); 12233 } 12234 12235 if(isPersist) { 12236 SystemProperties.set("persist.sys.language", l.getLanguage()); 12237 SystemProperties.set("persist.sys.country", l.getCountry()); 12238 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12239 } 12240 } 12241 12242 @Override 12243 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12244 ActivityRecord srec = ActivityRecord.forToken(token); 12245 return srec != null && srec.task.affinity != null && 12246 srec.task.affinity.equals(destAffinity); 12247 } 12248 12249 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12250 Intent resultData) { 12251 ComponentName dest = destIntent.getComponent(); 12252 12253 synchronized (this) { 12254 ActivityRecord srec = ActivityRecord.forToken(token); 12255 if (srec == null) { 12256 return false; 12257 } 12258 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12259 final int start = history.indexOf(srec); 12260 if (start < 0) { 12261 // Current activity is not in history stack; do nothing. 12262 return false; 12263 } 12264 int finishTo = start - 1; 12265 ActivityRecord parent = null; 12266 boolean foundParentInTask = false; 12267 if (dest != null) { 12268 TaskRecord tr = srec.task; 12269 for (int i = start - 1; i >= 0; i--) { 12270 ActivityRecord r = history.get(i); 12271 if (tr != r.task) { 12272 // Couldn't find parent in the same task; stop at the one above this. 12273 // (Root of current task; in-app "home" behavior) 12274 // Always at least finish the current activity. 12275 finishTo = Math.min(start - 1, i + 1); 12276 parent = history.get(finishTo); 12277 break; 12278 } else if (r.info.packageName.equals(dest.getPackageName()) && 12279 r.info.name.equals(dest.getClassName())) { 12280 finishTo = i; 12281 parent = r; 12282 foundParentInTask = true; 12283 break; 12284 } 12285 } 12286 } 12287 12288 if (mController != null) { 12289 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12290 if (next != null) { 12291 // ask watcher if this is allowed 12292 boolean resumeOK = true; 12293 try { 12294 resumeOK = mController.activityResuming(next.packageName); 12295 } catch (RemoteException e) { 12296 mController = null; 12297 } 12298 12299 if (!resumeOK) { 12300 return false; 12301 } 12302 } 12303 } 12304 final long origId = Binder.clearCallingIdentity(); 12305 for (int i = start; i > finishTo; i--) { 12306 ActivityRecord r = history.get(i); 12307 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12308 "navigate-up"); 12309 // Only return the supplied result for the first activity finished 12310 resultCode = Activity.RESULT_CANCELED; 12311 resultData = null; 12312 } 12313 12314 if (parent != null && foundParentInTask) { 12315 final int parentLaunchMode = parent.info.launchMode; 12316 final int destIntentFlags = destIntent.getFlags(); 12317 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12318 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12319 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12320 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12321 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12322 } else { 12323 try { 12324 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12325 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12326 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12327 null, aInfo, parent.appToken, null, 12328 0, -1, parent.launchedFromUid, 0, null, true, null); 12329 foundParentInTask = res == ActivityManager.START_SUCCESS; 12330 } catch (RemoteException e) { 12331 foundParentInTask = false; 12332 } 12333 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12334 resultData, "navigate-up"); 12335 } 12336 } 12337 Binder.restoreCallingIdentity(origId); 12338 return foundParentInTask; 12339 } 12340 } 12341 12342 public int getLaunchedFromUid(IBinder activityToken) { 12343 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12344 if (srec == null) { 12345 return -1; 12346 } 12347 return srec.launchedFromUid; 12348 } 12349 12350 // ========================================================= 12351 // LIFETIME MANAGEMENT 12352 // ========================================================= 12353 12354 // Returns which broadcast queue the app is the current [or imminent] receiver 12355 // on, or 'null' if the app is not an active broadcast recipient. 12356 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12357 BroadcastRecord r = app.curReceiver; 12358 if (r != null) { 12359 return r.queue; 12360 } 12361 12362 // It's not the current receiver, but it might be starting up to become one 12363 synchronized (this) { 12364 for (BroadcastQueue queue : mBroadcastQueues) { 12365 r = queue.mPendingBroadcast; 12366 if (r != null && r.curApp == app) { 12367 // found it; report which queue it's in 12368 return queue; 12369 } 12370 } 12371 } 12372 12373 return null; 12374 } 12375 12376 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12377 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12378 if (mAdjSeq == app.adjSeq) { 12379 // This adjustment has already been computed. If we are calling 12380 // from the top, we may have already computed our adjustment with 12381 // an earlier hidden adjustment that isn't really for us... if 12382 // so, use the new hidden adjustment. 12383 if (!recursed && app.hidden) { 12384 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12385 app.hasActivities ? hiddenAdj : emptyAdj; 12386 } 12387 return app.curRawAdj; 12388 } 12389 12390 if (app.thread == null) { 12391 app.adjSeq = mAdjSeq; 12392 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12393 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12394 } 12395 12396 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12397 app.adjSource = null; 12398 app.adjTarget = null; 12399 app.empty = false; 12400 app.hidden = false; 12401 12402 final int activitiesSize = app.activities.size(); 12403 12404 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12405 // The max adjustment doesn't allow this app to be anything 12406 // below foreground, so it is not worth doing work for it. 12407 app.adjType = "fixed"; 12408 app.adjSeq = mAdjSeq; 12409 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12410 app.hasActivities = false; 12411 app.foregroundActivities = false; 12412 app.keeping = true; 12413 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12414 // System process can do UI, and when they do we want to have 12415 // them trim their memory after the user leaves the UI. To 12416 // facilitate this, here we need to determine whether or not it 12417 // is currently showing UI. 12418 app.systemNoUi = true; 12419 if (app == TOP_APP) { 12420 app.systemNoUi = false; 12421 app.hasActivities = true; 12422 } else if (activitiesSize > 0) { 12423 for (int j = 0; j < activitiesSize; j++) { 12424 final ActivityRecord r = app.activities.get(j); 12425 if (r.visible) { 12426 app.systemNoUi = false; 12427 } 12428 if (r.app == app) { 12429 app.hasActivities = true; 12430 } 12431 } 12432 } 12433 return (app.curAdj=app.maxAdj); 12434 } 12435 12436 app.keeping = false; 12437 app.systemNoUi = false; 12438 app.hasActivities = false; 12439 12440 // Determine the importance of the process, starting with most 12441 // important to least, and assign an appropriate OOM adjustment. 12442 int adj; 12443 int schedGroup; 12444 boolean foregroundActivities = false; 12445 boolean interesting = false; 12446 BroadcastQueue queue; 12447 if (app == TOP_APP) { 12448 // The last app on the list is the foreground app. 12449 adj = ProcessList.FOREGROUND_APP_ADJ; 12450 schedGroup = Process.THREAD_GROUP_DEFAULT; 12451 app.adjType = "top-activity"; 12452 foregroundActivities = true; 12453 interesting = true; 12454 app.hasActivities = true; 12455 } else if (app.instrumentationClass != null) { 12456 // Don't want to kill running instrumentation. 12457 adj = ProcessList.FOREGROUND_APP_ADJ; 12458 schedGroup = Process.THREAD_GROUP_DEFAULT; 12459 app.adjType = "instrumentation"; 12460 interesting = true; 12461 } else if ((queue = isReceivingBroadcast(app)) != null) { 12462 // An app that is currently receiving a broadcast also 12463 // counts as being in the foreground for OOM killer purposes. 12464 // It's placed in a sched group based on the nature of the 12465 // broadcast as reflected by which queue it's active in. 12466 adj = ProcessList.FOREGROUND_APP_ADJ; 12467 schedGroup = (queue == mFgBroadcastQueue) 12468 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12469 app.adjType = "broadcast"; 12470 } else if (app.executingServices.size() > 0) { 12471 // An app that is currently executing a service callback also 12472 // counts as being in the foreground. 12473 adj = ProcessList.FOREGROUND_APP_ADJ; 12474 schedGroup = Process.THREAD_GROUP_DEFAULT; 12475 app.adjType = "exec-service"; 12476 } else { 12477 // Assume process is hidden (has activities); we will correct 12478 // later if this is not the case. 12479 adj = hiddenAdj; 12480 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12481 app.hidden = true; 12482 app.adjType = "bg-activities"; 12483 } 12484 12485 boolean hasStoppingActivities = false; 12486 12487 // Examine all activities if not already foreground. 12488 if (!foregroundActivities && activitiesSize > 0) { 12489 for (int j = 0; j < activitiesSize; j++) { 12490 final ActivityRecord r = app.activities.get(j); 12491 if (r.visible) { 12492 // App has a visible activity; only upgrade adjustment. 12493 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12494 adj = ProcessList.VISIBLE_APP_ADJ; 12495 app.adjType = "visible"; 12496 } 12497 schedGroup = Process.THREAD_GROUP_DEFAULT; 12498 app.hidden = false; 12499 app.hasActivities = true; 12500 foregroundActivities = true; 12501 break; 12502 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12503 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12504 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12505 app.adjType = "pausing"; 12506 } 12507 app.hidden = false; 12508 foregroundActivities = true; 12509 } else if (r.state == ActivityState.STOPPING) { 12510 // We will apply the actual adjustment later, because 12511 // we want to allow this process to immediately go through 12512 // any memory trimming that is in effect. 12513 app.hidden = false; 12514 foregroundActivities = true; 12515 hasStoppingActivities = true; 12516 } 12517 if (r.app == app) { 12518 app.hasActivities = true; 12519 } 12520 } 12521 } 12522 12523 if (adj == hiddenAdj && !app.hasActivities) { 12524 // Whoops, this process is completely empty as far as we know 12525 // at this point. 12526 adj = emptyAdj; 12527 app.empty = true; 12528 app.adjType = "bg-empty"; 12529 } 12530 12531 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12532 if (app.foregroundServices) { 12533 // The user is aware of this app, so make it visible. 12534 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12535 app.hidden = false; 12536 app.adjType = "foreground-service"; 12537 schedGroup = Process.THREAD_GROUP_DEFAULT; 12538 } else if (app.forcingToForeground != null) { 12539 // The user is aware of this app, so make it visible. 12540 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12541 app.hidden = false; 12542 app.adjType = "force-foreground"; 12543 app.adjSource = app.forcingToForeground; 12544 schedGroup = Process.THREAD_GROUP_DEFAULT; 12545 } 12546 } 12547 12548 if (app.foregroundServices) { 12549 interesting = true; 12550 } 12551 12552 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12553 // We don't want to kill the current heavy-weight process. 12554 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12555 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12556 app.hidden = false; 12557 app.adjType = "heavy"; 12558 } 12559 12560 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12561 // This process is hosting what we currently consider to be the 12562 // home app, so we don't want to let it go into the background. 12563 adj = ProcessList.HOME_APP_ADJ; 12564 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12565 app.hidden = false; 12566 app.adjType = "home"; 12567 } 12568 12569 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12570 && app.activities.size() > 0) { 12571 // This was the previous process that showed UI to the user. 12572 // We want to try to keep it around more aggressively, to give 12573 // a good experience around switching between two apps. 12574 adj = ProcessList.PREVIOUS_APP_ADJ; 12575 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12576 app.hidden = false; 12577 app.adjType = "previous"; 12578 } 12579 12580 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12581 + " reason=" + app.adjType); 12582 12583 // By default, we use the computed adjustment. It may be changed if 12584 // there are applications dependent on our services or providers, but 12585 // this gives us a baseline and makes sure we don't get into an 12586 // infinite recursion. 12587 app.adjSeq = mAdjSeq; 12588 app.curRawAdj = app.nonStoppingAdj = adj; 12589 12590 if (mBackupTarget != null && app == mBackupTarget.app) { 12591 // If possible we want to avoid killing apps while they're being backed up 12592 if (adj > ProcessList.BACKUP_APP_ADJ) { 12593 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12594 adj = ProcessList.BACKUP_APP_ADJ; 12595 app.adjType = "backup"; 12596 app.hidden = false; 12597 } 12598 } 12599 12600 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12601 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12602 final long now = SystemClock.uptimeMillis(); 12603 // This process is more important if the top activity is 12604 // bound to the service. 12605 Iterator<ServiceRecord> jt = app.services.iterator(); 12606 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12607 ServiceRecord s = jt.next(); 12608 if (s.startRequested) { 12609 if (app.hasShownUi && app != mHomeProcess) { 12610 // If this process has shown some UI, let it immediately 12611 // go to the LRU list because it may be pretty heavy with 12612 // UI stuff. We'll tag it with a label just to help 12613 // debug and understand what is going on. 12614 if (adj > ProcessList.SERVICE_ADJ) { 12615 app.adjType = "started-bg-ui-services"; 12616 } 12617 } else { 12618 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12619 // This service has seen some activity within 12620 // recent memory, so we will keep its process ahead 12621 // of the background processes. 12622 if (adj > ProcessList.SERVICE_ADJ) { 12623 adj = ProcessList.SERVICE_ADJ; 12624 app.adjType = "started-services"; 12625 app.hidden = false; 12626 } 12627 } 12628 // If we have let the service slide into the background 12629 // state, still have some text describing what it is doing 12630 // even though the service no longer has an impact. 12631 if (adj > ProcessList.SERVICE_ADJ) { 12632 app.adjType = "started-bg-services"; 12633 } 12634 } 12635 // Don't kill this process because it is doing work; it 12636 // has said it is doing work. 12637 app.keeping = true; 12638 } 12639 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12640 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12641 Iterator<ArrayList<ConnectionRecord>> kt 12642 = s.connections.values().iterator(); 12643 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12644 ArrayList<ConnectionRecord> clist = kt.next(); 12645 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12646 // XXX should compute this based on the max of 12647 // all connected clients. 12648 ConnectionRecord cr = clist.get(i); 12649 if (cr.binding.client == app) { 12650 // Binding to ourself is not interesting. 12651 continue; 12652 } 12653 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12654 ProcessRecord client = cr.binding.client; 12655 int clientAdj = adj; 12656 int myHiddenAdj = hiddenAdj; 12657 if (myHiddenAdj > client.hiddenAdj) { 12658 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12659 myHiddenAdj = client.hiddenAdj; 12660 } else { 12661 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12662 } 12663 } 12664 int myEmptyAdj = emptyAdj; 12665 if (myEmptyAdj > client.emptyAdj) { 12666 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12667 myEmptyAdj = client.emptyAdj; 12668 } else { 12669 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12670 } 12671 } 12672 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12673 myEmptyAdj, TOP_APP, true, doingAll); 12674 String adjType = null; 12675 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12676 // Not doing bind OOM management, so treat 12677 // this guy more like a started service. 12678 if (app.hasShownUi && app != mHomeProcess) { 12679 // If this process has shown some UI, let it immediately 12680 // go to the LRU list because it may be pretty heavy with 12681 // UI stuff. We'll tag it with a label just to help 12682 // debug and understand what is going on. 12683 if (adj > clientAdj) { 12684 adjType = "bound-bg-ui-services"; 12685 } 12686 app.hidden = false; 12687 clientAdj = adj; 12688 } else { 12689 if (now >= (s.lastActivity 12690 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12691 // This service has not seen activity within 12692 // recent memory, so allow it to drop to the 12693 // LRU list if there is no other reason to keep 12694 // it around. We'll also tag it with a label just 12695 // to help debug and undertand what is going on. 12696 if (adj > clientAdj) { 12697 adjType = "bound-bg-services"; 12698 } 12699 clientAdj = adj; 12700 } 12701 } 12702 } 12703 if (adj > clientAdj) { 12704 // If this process has recently shown UI, and 12705 // the process that is binding to it is less 12706 // important than being visible, then we don't 12707 // care about the binding as much as we care 12708 // about letting this process get into the LRU 12709 // list to be killed and restarted if needed for 12710 // memory. 12711 if (app.hasShownUi && app != mHomeProcess 12712 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12713 adjType = "bound-bg-ui-services"; 12714 } else { 12715 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12716 |Context.BIND_IMPORTANT)) != 0) { 12717 adj = clientAdj; 12718 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12719 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12720 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12721 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12722 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12723 adj = clientAdj; 12724 } else { 12725 app.pendingUiClean = true; 12726 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12727 adj = ProcessList.VISIBLE_APP_ADJ; 12728 } 12729 } 12730 if (!client.hidden) { 12731 app.hidden = false; 12732 } 12733 if (client.keeping) { 12734 app.keeping = true; 12735 } 12736 adjType = "service"; 12737 } 12738 } 12739 if (adjType != null) { 12740 app.adjType = adjType; 12741 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12742 .REASON_SERVICE_IN_USE; 12743 app.adjSource = cr.binding.client; 12744 app.adjSourceOom = clientAdj; 12745 app.adjTarget = s.name; 12746 } 12747 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12748 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12749 schedGroup = Process.THREAD_GROUP_DEFAULT; 12750 } 12751 } 12752 } 12753 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12754 ActivityRecord a = cr.activity; 12755 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12756 (a.visible || a.state == ActivityState.RESUMED 12757 || a.state == ActivityState.PAUSING)) { 12758 adj = ProcessList.FOREGROUND_APP_ADJ; 12759 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12760 schedGroup = Process.THREAD_GROUP_DEFAULT; 12761 } 12762 app.hidden = false; 12763 app.adjType = "service"; 12764 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12765 .REASON_SERVICE_IN_USE; 12766 app.adjSource = a; 12767 app.adjSourceOom = adj; 12768 app.adjTarget = s.name; 12769 } 12770 } 12771 } 12772 } 12773 } 12774 } 12775 12776 // Finally, if this process has active services running in it, we 12777 // would like to avoid killing it unless it would prevent the current 12778 // application from running. By default we put the process in 12779 // with the rest of the background processes; as we scan through 12780 // its services we may bump it up from there. 12781 if (adj > hiddenAdj) { 12782 adj = hiddenAdj; 12783 app.hidden = false; 12784 app.adjType = "bg-services"; 12785 } 12786 } 12787 12788 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12789 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12790 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12791 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12792 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12793 ContentProviderRecord cpr = jt.next(); 12794 for (int i = cpr.connections.size()-1; 12795 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12796 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12797 i--) { 12798 ContentProviderConnection conn = cpr.connections.get(i); 12799 ProcessRecord client = conn.client; 12800 if (client == app) { 12801 // Being our own client is not interesting. 12802 continue; 12803 } 12804 int myHiddenAdj = hiddenAdj; 12805 if (myHiddenAdj > client.hiddenAdj) { 12806 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12807 myHiddenAdj = client.hiddenAdj; 12808 } else { 12809 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12810 } 12811 } 12812 int myEmptyAdj = emptyAdj; 12813 if (myEmptyAdj > client.emptyAdj) { 12814 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12815 myEmptyAdj = client.emptyAdj; 12816 } else { 12817 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12818 } 12819 } 12820 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12821 myEmptyAdj, TOP_APP, true, doingAll); 12822 if (adj > clientAdj) { 12823 if (app.hasShownUi && app != mHomeProcess 12824 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12825 app.adjType = "bg-ui-provider"; 12826 } else { 12827 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12828 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12829 app.adjType = "provider"; 12830 } 12831 if (!client.hidden) { 12832 app.hidden = false; 12833 } 12834 if (client.keeping) { 12835 app.keeping = true; 12836 } 12837 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12838 .REASON_PROVIDER_IN_USE; 12839 app.adjSource = client; 12840 app.adjSourceOom = clientAdj; 12841 app.adjTarget = cpr.name; 12842 } 12843 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12844 schedGroup = Process.THREAD_GROUP_DEFAULT; 12845 } 12846 } 12847 // If the provider has external (non-framework) process 12848 // dependencies, ensure that its adjustment is at least 12849 // FOREGROUND_APP_ADJ. 12850 if (cpr.hasExternalProcessHandles()) { 12851 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12852 adj = ProcessList.FOREGROUND_APP_ADJ; 12853 schedGroup = Process.THREAD_GROUP_DEFAULT; 12854 app.hidden = false; 12855 app.keeping = true; 12856 app.adjType = "provider"; 12857 app.adjTarget = cpr.name; 12858 } 12859 } 12860 } 12861 } 12862 12863 if (adj == ProcessList.SERVICE_ADJ) { 12864 if (doingAll) { 12865 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12866 mNewNumServiceProcs++; 12867 } 12868 if (app.serviceb) { 12869 adj = ProcessList.SERVICE_B_ADJ; 12870 } 12871 } else { 12872 app.serviceb = false; 12873 } 12874 12875 app.nonStoppingAdj = adj; 12876 12877 if (hasStoppingActivities) { 12878 // Only upgrade adjustment. 12879 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12880 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12881 app.adjType = "stopping"; 12882 } 12883 } 12884 12885 app.curRawAdj = adj; 12886 12887 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12888 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12889 if (adj > app.maxAdj) { 12890 adj = app.maxAdj; 12891 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12892 schedGroup = Process.THREAD_GROUP_DEFAULT; 12893 } 12894 } 12895 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12896 app.keeping = true; 12897 } 12898 12899 if (app.hasAboveClient) { 12900 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12901 // then we need to drop its adjustment to be lower than the service's 12902 // in order to honor the request. We want to drop it by one adjustment 12903 // level... but there is special meaning applied to various levels so 12904 // we will skip some of them. 12905 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12906 // System process will not get dropped, ever 12907 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12908 adj = ProcessList.VISIBLE_APP_ADJ; 12909 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12910 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12911 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12912 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12913 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12914 adj++; 12915 } 12916 } 12917 12918 int importance = app.memImportance; 12919 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12920 app.curAdj = adj; 12921 app.curSchedGroup = schedGroup; 12922 if (!interesting) { 12923 // For this reporting, if there is not something explicitly 12924 // interesting in this process then we will push it to the 12925 // background importance. 12926 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12927 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12928 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12929 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12930 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12931 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12932 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12933 } else if (adj >= ProcessList.SERVICE_ADJ) { 12934 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12935 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12936 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12937 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12938 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12939 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12940 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12941 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12942 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12943 } else { 12944 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12945 } 12946 } 12947 12948 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12949 if (foregroundActivities != app.foregroundActivities) { 12950 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12951 } 12952 if (changes != 0) { 12953 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12954 app.memImportance = importance; 12955 app.foregroundActivities = foregroundActivities; 12956 int i = mPendingProcessChanges.size()-1; 12957 ProcessChangeItem item = null; 12958 while (i >= 0) { 12959 item = mPendingProcessChanges.get(i); 12960 if (item.pid == app.pid) { 12961 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12962 break; 12963 } 12964 i--; 12965 } 12966 if (i < 0) { 12967 // No existing item in pending changes; need a new one. 12968 final int NA = mAvailProcessChanges.size(); 12969 if (NA > 0) { 12970 item = mAvailProcessChanges.remove(NA-1); 12971 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12972 } else { 12973 item = new ProcessChangeItem(); 12974 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12975 } 12976 item.changes = 0; 12977 item.pid = app.pid; 12978 item.uid = app.info.uid; 12979 if (mPendingProcessChanges.size() == 0) { 12980 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12981 "*** Enqueueing dispatch processes changed!"); 12982 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12983 } 12984 mPendingProcessChanges.add(item); 12985 } 12986 item.changes |= changes; 12987 item.importance = importance; 12988 item.foregroundActivities = foregroundActivities; 12989 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12990 + Integer.toHexString(System.identityHashCode(item)) 12991 + " " + app.toShortString() + ": changes=" + item.changes 12992 + " importance=" + item.importance 12993 + " foreground=" + item.foregroundActivities 12994 + " type=" + app.adjType + " source=" + app.adjSource 12995 + " target=" + app.adjTarget); 12996 } 12997 12998 return app.curRawAdj; 12999 } 13000 13001 /** 13002 * Ask a given process to GC right now. 13003 */ 13004 final void performAppGcLocked(ProcessRecord app) { 13005 try { 13006 app.lastRequestedGc = SystemClock.uptimeMillis(); 13007 if (app.thread != null) { 13008 if (app.reportLowMemory) { 13009 app.reportLowMemory = false; 13010 app.thread.scheduleLowMemory(); 13011 } else { 13012 app.thread.processInBackground(); 13013 } 13014 } 13015 } catch (Exception e) { 13016 // whatever. 13017 } 13018 } 13019 13020 /** 13021 * Returns true if things are idle enough to perform GCs. 13022 */ 13023 private final boolean canGcNowLocked() { 13024 boolean processingBroadcasts = false; 13025 for (BroadcastQueue q : mBroadcastQueues) { 13026 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13027 processingBroadcasts = true; 13028 } 13029 } 13030 return !processingBroadcasts 13031 && (mSleeping || (mMainStack.mResumedActivity != null && 13032 mMainStack.mResumedActivity.idle)); 13033 } 13034 13035 /** 13036 * Perform GCs on all processes that are waiting for it, but only 13037 * if things are idle. 13038 */ 13039 final void performAppGcsLocked() { 13040 final int N = mProcessesToGc.size(); 13041 if (N <= 0) { 13042 return; 13043 } 13044 if (canGcNowLocked()) { 13045 while (mProcessesToGc.size() > 0) { 13046 ProcessRecord proc = mProcessesToGc.remove(0); 13047 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13048 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13049 <= SystemClock.uptimeMillis()) { 13050 // To avoid spamming the system, we will GC processes one 13051 // at a time, waiting a few seconds between each. 13052 performAppGcLocked(proc); 13053 scheduleAppGcsLocked(); 13054 return; 13055 } else { 13056 // It hasn't been long enough since we last GCed this 13057 // process... put it in the list to wait for its time. 13058 addProcessToGcListLocked(proc); 13059 break; 13060 } 13061 } 13062 } 13063 13064 scheduleAppGcsLocked(); 13065 } 13066 } 13067 13068 /** 13069 * If all looks good, perform GCs on all processes waiting for them. 13070 */ 13071 final void performAppGcsIfAppropriateLocked() { 13072 if (canGcNowLocked()) { 13073 performAppGcsLocked(); 13074 return; 13075 } 13076 // Still not idle, wait some more. 13077 scheduleAppGcsLocked(); 13078 } 13079 13080 /** 13081 * Schedule the execution of all pending app GCs. 13082 */ 13083 final void scheduleAppGcsLocked() { 13084 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13085 13086 if (mProcessesToGc.size() > 0) { 13087 // Schedule a GC for the time to the next process. 13088 ProcessRecord proc = mProcessesToGc.get(0); 13089 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13090 13091 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13092 long now = SystemClock.uptimeMillis(); 13093 if (when < (now+GC_TIMEOUT)) { 13094 when = now + GC_TIMEOUT; 13095 } 13096 mHandler.sendMessageAtTime(msg, when); 13097 } 13098 } 13099 13100 /** 13101 * Add a process to the array of processes waiting to be GCed. Keeps the 13102 * list in sorted order by the last GC time. The process can't already be 13103 * on the list. 13104 */ 13105 final void addProcessToGcListLocked(ProcessRecord proc) { 13106 boolean added = false; 13107 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13108 if (mProcessesToGc.get(i).lastRequestedGc < 13109 proc.lastRequestedGc) { 13110 added = true; 13111 mProcessesToGc.add(i+1, proc); 13112 break; 13113 } 13114 } 13115 if (!added) { 13116 mProcessesToGc.add(0, proc); 13117 } 13118 } 13119 13120 /** 13121 * Set up to ask a process to GC itself. This will either do it 13122 * immediately, or put it on the list of processes to gc the next 13123 * time things are idle. 13124 */ 13125 final void scheduleAppGcLocked(ProcessRecord app) { 13126 long now = SystemClock.uptimeMillis(); 13127 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13128 return; 13129 } 13130 if (!mProcessesToGc.contains(app)) { 13131 addProcessToGcListLocked(app); 13132 scheduleAppGcsLocked(); 13133 } 13134 } 13135 13136 final void checkExcessivePowerUsageLocked(boolean doKills) { 13137 updateCpuStatsNow(); 13138 13139 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13140 boolean doWakeKills = doKills; 13141 boolean doCpuKills = doKills; 13142 if (mLastPowerCheckRealtime == 0) { 13143 doWakeKills = false; 13144 } 13145 if (mLastPowerCheckUptime == 0) { 13146 doCpuKills = false; 13147 } 13148 if (stats.isScreenOn()) { 13149 doWakeKills = false; 13150 } 13151 final long curRealtime = SystemClock.elapsedRealtime(); 13152 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13153 final long curUptime = SystemClock.uptimeMillis(); 13154 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13155 mLastPowerCheckRealtime = curRealtime; 13156 mLastPowerCheckUptime = curUptime; 13157 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13158 doWakeKills = false; 13159 } 13160 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13161 doCpuKills = false; 13162 } 13163 int i = mLruProcesses.size(); 13164 while (i > 0) { 13165 i--; 13166 ProcessRecord app = mLruProcesses.get(i); 13167 if (!app.keeping) { 13168 long wtime; 13169 synchronized (stats) { 13170 wtime = stats.getProcessWakeTime(app.info.uid, 13171 app.pid, curRealtime); 13172 } 13173 long wtimeUsed = wtime - app.lastWakeTime; 13174 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13175 if (DEBUG_POWER) { 13176 StringBuilder sb = new StringBuilder(128); 13177 sb.append("Wake for "); 13178 app.toShortString(sb); 13179 sb.append(": over "); 13180 TimeUtils.formatDuration(realtimeSince, sb); 13181 sb.append(" used "); 13182 TimeUtils.formatDuration(wtimeUsed, sb); 13183 sb.append(" ("); 13184 sb.append((wtimeUsed*100)/realtimeSince); 13185 sb.append("%)"); 13186 Slog.i(TAG, sb.toString()); 13187 sb.setLength(0); 13188 sb.append("CPU for "); 13189 app.toShortString(sb); 13190 sb.append(": over "); 13191 TimeUtils.formatDuration(uptimeSince, sb); 13192 sb.append(" used "); 13193 TimeUtils.formatDuration(cputimeUsed, sb); 13194 sb.append(" ("); 13195 sb.append((cputimeUsed*100)/uptimeSince); 13196 sb.append("%)"); 13197 Slog.i(TAG, sb.toString()); 13198 } 13199 // If a process has held a wake lock for more 13200 // than 50% of the time during this period, 13201 // that sounds bad. Kill! 13202 if (doWakeKills && realtimeSince > 0 13203 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13204 synchronized (stats) { 13205 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13206 realtimeSince, wtimeUsed); 13207 } 13208 Slog.w(TAG, "Excessive wake lock in " + app.processName 13209 + " (pid " + app.pid + "): held " + wtimeUsed 13210 + " during " + realtimeSince); 13211 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13212 app.processName, app.setAdj, "excessive wake lock"); 13213 Process.killProcessQuiet(app.pid); 13214 } else if (doCpuKills && uptimeSince > 0 13215 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13216 synchronized (stats) { 13217 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13218 uptimeSince, cputimeUsed); 13219 } 13220 Slog.w(TAG, "Excessive CPU in " + app.processName 13221 + " (pid " + app.pid + "): used " + cputimeUsed 13222 + " during " + uptimeSince); 13223 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13224 app.processName, app.setAdj, "excessive cpu"); 13225 Process.killProcessQuiet(app.pid); 13226 } else { 13227 app.lastWakeTime = wtime; 13228 app.lastCpuTime = app.curCpuTime; 13229 } 13230 } 13231 } 13232 } 13233 13234 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13235 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13236 app.hiddenAdj = hiddenAdj; 13237 app.emptyAdj = emptyAdj; 13238 13239 if (app.thread == null) { 13240 return false; 13241 } 13242 13243 final boolean wasKeeping = app.keeping; 13244 13245 boolean success = true; 13246 13247 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13248 13249 if (app.curRawAdj != app.setRawAdj) { 13250 if (wasKeeping && !app.keeping) { 13251 // This app is no longer something we want to keep. Note 13252 // its current wake lock time to later know to kill it if 13253 // it is not behaving well. 13254 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13255 synchronized (stats) { 13256 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13257 app.pid, SystemClock.elapsedRealtime()); 13258 } 13259 app.lastCpuTime = app.curCpuTime; 13260 } 13261 13262 app.setRawAdj = app.curRawAdj; 13263 } 13264 13265 if (app.curAdj != app.setAdj) { 13266 if (Process.setOomAdj(app.pid, app.curAdj)) { 13267 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13268 TAG, "Set " + app.pid + " " + app.processName + 13269 " adj " + app.curAdj + ": " + app.adjType); 13270 app.setAdj = app.curAdj; 13271 } else { 13272 success = false; 13273 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13274 } 13275 } 13276 if (app.setSchedGroup != app.curSchedGroup) { 13277 app.setSchedGroup = app.curSchedGroup; 13278 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13279 "Setting process group of " + app.processName 13280 + " to " + app.curSchedGroup); 13281 if (app.waitingToKill != null && 13282 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13283 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13284 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13285 app.processName, app.setAdj, app.waitingToKill); 13286 app.killedBackground = true; 13287 Process.killProcessQuiet(app.pid); 13288 success = false; 13289 } else { 13290 if (true) { 13291 long oldId = Binder.clearCallingIdentity(); 13292 try { 13293 Process.setProcessGroup(app.pid, app.curSchedGroup); 13294 } catch (Exception e) { 13295 Slog.w(TAG, "Failed setting process group of " + app.pid 13296 + " to " + app.curSchedGroup); 13297 e.printStackTrace(); 13298 } finally { 13299 Binder.restoreCallingIdentity(oldId); 13300 } 13301 } else { 13302 if (app.thread != null) { 13303 try { 13304 app.thread.setSchedulingGroup(app.curSchedGroup); 13305 } catch (RemoteException e) { 13306 } 13307 } 13308 } 13309 } 13310 } 13311 return success; 13312 } 13313 13314 private final ActivityRecord resumedAppLocked() { 13315 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13316 if (resumedActivity == null || resumedActivity.app == null) { 13317 resumedActivity = mMainStack.mPausingActivity; 13318 if (resumedActivity == null || resumedActivity.app == null) { 13319 resumedActivity = mMainStack.topRunningActivityLocked(null); 13320 } 13321 } 13322 return resumedActivity; 13323 } 13324 13325 final boolean updateOomAdjLocked(ProcessRecord app) { 13326 final ActivityRecord TOP_ACT = resumedAppLocked(); 13327 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13328 int curAdj = app.curAdj; 13329 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13330 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13331 13332 mAdjSeq++; 13333 13334 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13335 TOP_APP, false); 13336 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13337 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13338 if (nowHidden != wasHidden) { 13339 // Changed to/from hidden state, so apps after it in the LRU 13340 // list may also be changed. 13341 updateOomAdjLocked(); 13342 } 13343 return success; 13344 } 13345 13346 final void updateOomAdjLocked() { 13347 final ActivityRecord TOP_ACT = resumedAppLocked(); 13348 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13349 13350 if (false) { 13351 RuntimeException e = new RuntimeException(); 13352 e.fillInStackTrace(); 13353 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13354 } 13355 13356 mAdjSeq++; 13357 mNewNumServiceProcs = 0; 13358 13359 // Let's determine how many processes we have running vs. 13360 // how many slots we have for background processes; we may want 13361 // to put multiple processes in a slot of there are enough of 13362 // them. 13363 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13364 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13365 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13366 if (emptyFactor < 1) emptyFactor = 1; 13367 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13368 if (hiddenFactor < 1) hiddenFactor = 1; 13369 int stepHidden = 0; 13370 int stepEmpty = 0; 13371 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13372 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13373 int numHidden = 0; 13374 int numEmpty = 0; 13375 int numTrimming = 0; 13376 13377 mNumNonHiddenProcs = 0; 13378 mNumHiddenProcs = 0; 13379 13380 // First update the OOM adjustment for each of the 13381 // application processes based on their current state. 13382 int i = mLruProcesses.size(); 13383 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13384 int nextHiddenAdj = curHiddenAdj+1; 13385 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13386 int nextEmptyAdj = curEmptyAdj+2; 13387 while (i > 0) { 13388 i--; 13389 ProcessRecord app = mLruProcesses.get(i); 13390 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13391 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13392 if (!app.killedBackground) { 13393 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13394 // This process was assigned as a hidden process... step the 13395 // hidden level. 13396 mNumHiddenProcs++; 13397 if (curHiddenAdj != nextHiddenAdj) { 13398 stepHidden++; 13399 if (stepHidden >= hiddenFactor) { 13400 stepHidden = 0; 13401 curHiddenAdj = nextHiddenAdj; 13402 nextHiddenAdj += 2; 13403 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13404 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13405 } 13406 } 13407 } 13408 numHidden++; 13409 if (numHidden > hiddenProcessLimit) { 13410 Slog.i(TAG, "No longer want " + app.processName 13411 + " (pid " + app.pid + "): hidden #" + numHidden); 13412 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13413 app.processName, app.setAdj, "too many background"); 13414 app.killedBackground = true; 13415 Process.killProcessQuiet(app.pid); 13416 } 13417 } else { 13418 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13419 // This process was assigned as an empty process... step the 13420 // empty level. 13421 if (curEmptyAdj != nextEmptyAdj) { 13422 stepEmpty++; 13423 if (stepEmpty >= emptyFactor) { 13424 stepEmpty = 0; 13425 curEmptyAdj = nextEmptyAdj; 13426 nextEmptyAdj += 2; 13427 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13428 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13429 } 13430 } 13431 } 13432 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13433 mNumNonHiddenProcs++; 13434 } 13435 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13436 numEmpty++; 13437 if (numEmpty > emptyProcessLimit) { 13438 Slog.i(TAG, "No longer want " + app.processName 13439 + " (pid " + app.pid + "): empty #" + numEmpty); 13440 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13441 app.processName, app.setAdj, "too many background"); 13442 app.killedBackground = true; 13443 Process.killProcessQuiet(app.pid); 13444 } 13445 } 13446 } 13447 if (app.isolated && app.services.size() <= 0) { 13448 // If this is an isolated process, and there are no 13449 // services running in it, then the process is no longer 13450 // needed. We agressively kill these because we can by 13451 // definition not re-use the same process again, and it is 13452 // good to avoid having whatever code was running in them 13453 // left sitting around after no longer needed. 13454 Slog.i(TAG, "Isolated process " + app.processName 13455 + " (pid " + app.pid + ") no longer needed"); 13456 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13457 app.processName, app.setAdj, "isolated not needed"); 13458 app.killedBackground = true; 13459 Process.killProcessQuiet(app.pid); 13460 } 13461 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13462 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13463 && !app.killedBackground) { 13464 numTrimming++; 13465 } 13466 } 13467 } 13468 13469 mNumServiceProcs = mNewNumServiceProcs; 13470 13471 // Now determine the memory trimming level of background processes. 13472 // Unfortunately we need to start at the back of the list to do this 13473 // properly. We only do this if the number of background apps we 13474 // are managing to keep around is less than half the maximum we desire; 13475 // if we are keeping a good number around, we'll let them use whatever 13476 // memory they want. 13477 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13478 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13479 final int numHiddenAndEmpty = numHidden + numEmpty; 13480 final int N = mLruProcesses.size(); 13481 int factor = numTrimming/3; 13482 int minFactor = 2; 13483 if (mHomeProcess != null) minFactor++; 13484 if (mPreviousProcess != null) minFactor++; 13485 if (factor < minFactor) factor = minFactor; 13486 int step = 0; 13487 int fgTrimLevel; 13488 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13489 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13490 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13491 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13492 } else { 13493 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13494 } 13495 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13496 for (i=0; i<N; i++) { 13497 ProcessRecord app = mLruProcesses.get(i); 13498 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13499 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13500 && !app.killedBackground) { 13501 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13502 try { 13503 app.thread.scheduleTrimMemory(curLevel); 13504 } catch (RemoteException e) { 13505 } 13506 if (false) { 13507 // For now we won't do this; our memory trimming seems 13508 // to be good enough at this point that destroying 13509 // activities causes more harm than good. 13510 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13511 && app != mHomeProcess && app != mPreviousProcess) { 13512 // Need to do this on its own message because the stack may not 13513 // be in a consistent state at this point. 13514 // For these apps we will also finish their activities 13515 // to help them free memory. 13516 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13517 } 13518 } 13519 } 13520 app.trimMemoryLevel = curLevel; 13521 step++; 13522 if (step >= factor) { 13523 step = 0; 13524 switch (curLevel) { 13525 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13526 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13527 break; 13528 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13529 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13530 break; 13531 } 13532 } 13533 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13534 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13535 && app.thread != null) { 13536 try { 13537 app.thread.scheduleTrimMemory( 13538 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13539 } catch (RemoteException e) { 13540 } 13541 } 13542 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13543 } else { 13544 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13545 && app.pendingUiClean) { 13546 // If this application is now in the background and it 13547 // had done UI, then give it the special trim level to 13548 // have it free UI resources. 13549 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13550 if (app.trimMemoryLevel < level && app.thread != null) { 13551 try { 13552 app.thread.scheduleTrimMemory(level); 13553 } catch (RemoteException e) { 13554 } 13555 } 13556 app.pendingUiClean = false; 13557 } 13558 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13559 try { 13560 app.thread.scheduleTrimMemory(fgTrimLevel); 13561 } catch (RemoteException e) { 13562 } 13563 } 13564 app.trimMemoryLevel = fgTrimLevel; 13565 } 13566 } 13567 } else { 13568 final int N = mLruProcesses.size(); 13569 for (i=0; i<N; i++) { 13570 ProcessRecord app = mLruProcesses.get(i); 13571 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13572 && app.pendingUiClean) { 13573 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13574 && app.thread != null) { 13575 try { 13576 app.thread.scheduleTrimMemory( 13577 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13578 } catch (RemoteException e) { 13579 } 13580 } 13581 app.pendingUiClean = false; 13582 } 13583 app.trimMemoryLevel = 0; 13584 } 13585 } 13586 13587 if (mAlwaysFinishActivities) { 13588 // Need to do this on its own message because the stack may not 13589 // be in a consistent state at this point. 13590 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13591 } 13592 } 13593 13594 final void trimApplications() { 13595 synchronized (this) { 13596 int i; 13597 13598 // First remove any unused application processes whose package 13599 // has been removed. 13600 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13601 final ProcessRecord app = mRemovedProcesses.get(i); 13602 if (app.activities.size() == 0 13603 && app.curReceiver == null && app.services.size() == 0) { 13604 Slog.i( 13605 TAG, "Exiting empty application process " 13606 + app.processName + " (" 13607 + (app.thread != null ? app.thread.asBinder() : null) 13608 + ")\n"); 13609 if (app.pid > 0 && app.pid != MY_PID) { 13610 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13611 app.processName, app.setAdj, "empty"); 13612 Process.killProcessQuiet(app.pid); 13613 } else { 13614 try { 13615 app.thread.scheduleExit(); 13616 } catch (Exception e) { 13617 // Ignore exceptions. 13618 } 13619 } 13620 cleanUpApplicationRecordLocked(app, false, true, -1); 13621 mRemovedProcesses.remove(i); 13622 13623 if (app.persistent) { 13624 if (app.persistent) { 13625 addAppLocked(app.info, false); 13626 } 13627 } 13628 } 13629 } 13630 13631 // Now update the oom adj for all processes. 13632 updateOomAdjLocked(); 13633 } 13634 } 13635 13636 /** This method sends the specified signal to each of the persistent apps */ 13637 public void signalPersistentProcesses(int sig) throws RemoteException { 13638 if (sig != Process.SIGNAL_USR1) { 13639 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13640 } 13641 13642 synchronized (this) { 13643 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13644 != PackageManager.PERMISSION_GRANTED) { 13645 throw new SecurityException("Requires permission " 13646 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13647 } 13648 13649 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13650 ProcessRecord r = mLruProcesses.get(i); 13651 if (r.thread != null && r.persistent) { 13652 Process.sendSignal(r.pid, sig); 13653 } 13654 } 13655 } 13656 } 13657 13658 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13659 if (proc == null || proc == mProfileProc) { 13660 proc = mProfileProc; 13661 path = mProfileFile; 13662 profileType = mProfileType; 13663 clearProfilerLocked(); 13664 } 13665 if (proc == null) { 13666 return; 13667 } 13668 try { 13669 proc.thread.profilerControl(false, path, null, profileType); 13670 } catch (RemoteException e) { 13671 throw new IllegalStateException("Process disappeared"); 13672 } 13673 } 13674 13675 private void clearProfilerLocked() { 13676 if (mProfileFd != null) { 13677 try { 13678 mProfileFd.close(); 13679 } catch (IOException e) { 13680 } 13681 } 13682 mProfileApp = null; 13683 mProfileProc = null; 13684 mProfileFile = null; 13685 mProfileType = 0; 13686 mAutoStopProfiler = false; 13687 } 13688 13689 public boolean profileControl(String process, boolean start, 13690 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13691 13692 try { 13693 synchronized (this) { 13694 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13695 // its own permission. 13696 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13697 != PackageManager.PERMISSION_GRANTED) { 13698 throw new SecurityException("Requires permission " 13699 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13700 } 13701 13702 if (start && fd == null) { 13703 throw new IllegalArgumentException("null fd"); 13704 } 13705 13706 ProcessRecord proc = null; 13707 if (process != null) { 13708 try { 13709 int pid = Integer.parseInt(process); 13710 synchronized (mPidsSelfLocked) { 13711 proc = mPidsSelfLocked.get(pid); 13712 } 13713 } catch (NumberFormatException e) { 13714 } 13715 13716 if (proc == null) { 13717 HashMap<String, SparseArray<ProcessRecord>> all 13718 = mProcessNames.getMap(); 13719 SparseArray<ProcessRecord> procs = all.get(process); 13720 if (procs != null && procs.size() > 0) { 13721 proc = procs.valueAt(0); 13722 } 13723 } 13724 } 13725 13726 if (start && (proc == null || proc.thread == null)) { 13727 throw new IllegalArgumentException("Unknown process: " + process); 13728 } 13729 13730 if (start) { 13731 stopProfilerLocked(null, null, 0); 13732 setProfileApp(proc.info, proc.processName, path, fd, false); 13733 mProfileProc = proc; 13734 mProfileType = profileType; 13735 try { 13736 fd = fd.dup(); 13737 } catch (IOException e) { 13738 fd = null; 13739 } 13740 proc.thread.profilerControl(start, path, fd, profileType); 13741 fd = null; 13742 mProfileFd = null; 13743 } else { 13744 stopProfilerLocked(proc, path, profileType); 13745 if (fd != null) { 13746 try { 13747 fd.close(); 13748 } catch (IOException e) { 13749 } 13750 } 13751 } 13752 13753 return true; 13754 } 13755 } catch (RemoteException e) { 13756 throw new IllegalStateException("Process disappeared"); 13757 } finally { 13758 if (fd != null) { 13759 try { 13760 fd.close(); 13761 } catch (IOException e) { 13762 } 13763 } 13764 } 13765 } 13766 13767 public boolean dumpHeap(String process, boolean managed, 13768 String path, ParcelFileDescriptor fd) throws RemoteException { 13769 13770 try { 13771 synchronized (this) { 13772 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13773 // its own permission (same as profileControl). 13774 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13775 != PackageManager.PERMISSION_GRANTED) { 13776 throw new SecurityException("Requires permission " 13777 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13778 } 13779 13780 if (fd == null) { 13781 throw new IllegalArgumentException("null fd"); 13782 } 13783 13784 ProcessRecord proc = null; 13785 try { 13786 int pid = Integer.parseInt(process); 13787 synchronized (mPidsSelfLocked) { 13788 proc = mPidsSelfLocked.get(pid); 13789 } 13790 } catch (NumberFormatException e) { 13791 } 13792 13793 if (proc == null) { 13794 HashMap<String, SparseArray<ProcessRecord>> all 13795 = mProcessNames.getMap(); 13796 SparseArray<ProcessRecord> procs = all.get(process); 13797 if (procs != null && procs.size() > 0) { 13798 proc = procs.valueAt(0); 13799 } 13800 } 13801 13802 if (proc == null || proc.thread == null) { 13803 throw new IllegalArgumentException("Unknown process: " + process); 13804 } 13805 13806 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13807 if (!isDebuggable) { 13808 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13809 throw new SecurityException("Process not debuggable: " + proc); 13810 } 13811 } 13812 13813 proc.thread.dumpHeap(managed, path, fd); 13814 fd = null; 13815 return true; 13816 } 13817 } catch (RemoteException e) { 13818 throw new IllegalStateException("Process disappeared"); 13819 } finally { 13820 if (fd != null) { 13821 try { 13822 fd.close(); 13823 } catch (IOException e) { 13824 } 13825 } 13826 } 13827 } 13828 13829 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13830 public void monitor() { 13831 synchronized (this) { } 13832 } 13833 13834 void onCoreSettingsChange(Bundle settings) { 13835 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13836 ProcessRecord processRecord = mLruProcesses.get(i); 13837 try { 13838 if (processRecord.thread != null) { 13839 processRecord.thread.setCoreSettings(settings); 13840 } 13841 } catch (RemoteException re) { 13842 /* ignore */ 13843 } 13844 } 13845 } 13846 13847 // Multi-user methods 13848 13849 @Override 13850 public boolean switchUser(int userId) { 13851 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13852 != PackageManager.PERMISSION_GRANTED) { 13853 String msg = "Permission Denial: switchUser() from pid=" 13854 + Binder.getCallingPid() 13855 + ", uid=" + Binder.getCallingUid() 13856 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13857 Slog.w(TAG, msg); 13858 throw new SecurityException(msg); 13859 } 13860 synchronized (this) { 13861 if (mCurrentUserId == userId) { 13862 return true; 13863 } 13864 13865 // If the user we are switching to is not currently started, then 13866 // we need to start it now. 13867 if (mStartedUsers.get(userId) == null) { 13868 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13869 } 13870 13871 mCurrentUserId = userId; 13872 Integer userIdInt = Integer.valueOf(userId); 13873 mUserLru.remove(userIdInt); 13874 mUserLru.add(userIdInt); 13875 boolean haveActivities = mMainStack.switchUser(userId); 13876 if (!haveActivities) { 13877 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13878 } 13879 } 13880 13881 long ident = Binder.clearCallingIdentity(); 13882 try { 13883 // Inform of user switch 13884 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13885 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13886 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 13887 android.Manifest.permission.MANAGE_USERS); 13888 } finally { 13889 Binder.restoreCallingIdentity(ident); 13890 } 13891 13892 return true; 13893 } 13894 13895 void finishUserSwitch(UserStartedState uss) { 13896 synchronized (this) { 13897 if (uss.mState == UserStartedState.STATE_BOOTING 13898 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13899 uss.mState = UserStartedState.STATE_RUNNING; 13900 final int userId = uss.mHandle.getIdentifier(); 13901 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 13902 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13903 broadcastIntentLocked(null, null, intent, 13904 null, null, 0, null, null, 13905 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13906 false, false, MY_PID, Process.SYSTEM_UID, userId); 13907 } 13908 } 13909 } 13910 13911 @Override 13912 public int stopUser(final int userId, final IStopUserCallback callback) { 13913 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13914 != PackageManager.PERMISSION_GRANTED) { 13915 String msg = "Permission Denial: switchUser() from pid=" 13916 + Binder.getCallingPid() 13917 + ", uid=" + Binder.getCallingUid() 13918 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13919 Slog.w(TAG, msg); 13920 throw new SecurityException(msg); 13921 } 13922 if (userId <= 0) { 13923 throw new IllegalArgumentException("Can't stop primary user " + userId); 13924 } 13925 synchronized (this) { 13926 if (mCurrentUserId == userId) { 13927 return ActivityManager.USER_OP_IS_CURRENT; 13928 } 13929 13930 final UserStartedState uss = mStartedUsers.get(userId); 13931 if (uss == null) { 13932 // User is not started, nothing to do... but we do need to 13933 // callback if requested. 13934 if (callback != null) { 13935 mHandler.post(new Runnable() { 13936 @Override 13937 public void run() { 13938 try { 13939 callback.userStopped(userId); 13940 } catch (RemoteException e) { 13941 } 13942 } 13943 }); 13944 } 13945 return ActivityManager.USER_OP_SUCCESS; 13946 } 13947 13948 if (callback != null) { 13949 uss.mStopCallbacks.add(callback); 13950 } 13951 13952 if (uss.mState != UserStartedState.STATE_STOPPING) { 13953 uss.mState = UserStartedState.STATE_STOPPING; 13954 13955 long ident = Binder.clearCallingIdentity(); 13956 try { 13957 // Inform of user switch 13958 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13959 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13960 @Override 13961 public void performReceive(Intent intent, int resultCode, String data, 13962 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 13963 finishUserStop(uss); 13964 } 13965 }; 13966 broadcastIntentLocked(null, null, intent, 13967 null, resultReceiver, 0, null, null, null, 13968 true, false, MY_PID, Process.SYSTEM_UID, userId); 13969 } finally { 13970 Binder.restoreCallingIdentity(ident); 13971 } 13972 } 13973 } 13974 13975 return ActivityManager.USER_OP_SUCCESS; 13976 } 13977 13978 void finishUserStop(UserStartedState uss) { 13979 final int userId = uss.mHandle.getIdentifier(); 13980 boolean stopped; 13981 ArrayList<IStopUserCallback> callbacks; 13982 synchronized (this) { 13983 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13984 if (uss.mState != UserStartedState.STATE_STOPPING 13985 || mStartedUsers.get(userId) != uss) { 13986 stopped = false; 13987 } else { 13988 stopped = true; 13989 // User can no longer run. 13990 mStartedUsers.remove(userId); 13991 13992 // Clean up all state and processes associated with the user. 13993 // Kill all the processes for the user. 13994 forceStopUserLocked(userId); 13995 } 13996 } 13997 13998 for (int i=0; i<callbacks.size(); i++) { 13999 try { 14000 if (stopped) callbacks.get(i).userStopped(userId); 14001 else callbacks.get(i).userStopAborted(userId); 14002 } catch (RemoteException e) { 14003 } 14004 } 14005 } 14006 14007 @Override 14008 public UserInfo getCurrentUser() { 14009 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14010 != PackageManager.PERMISSION_GRANTED) { 14011 String msg = "Permission Denial: getCurrentUser() from pid=" 14012 + Binder.getCallingPid() 14013 + ", uid=" + Binder.getCallingUid() 14014 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14015 Slog.w(TAG, msg); 14016 throw new SecurityException(msg); 14017 } 14018 synchronized (this) { 14019 return getUserManager().getUserInfo(mCurrentUserId); 14020 } 14021 } 14022 14023 @Override 14024 public boolean isUserRunning(int userId) { 14025 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14026 != PackageManager.PERMISSION_GRANTED) { 14027 String msg = "Permission Denial: isUserRunning() from pid=" 14028 + Binder.getCallingPid() 14029 + ", uid=" + Binder.getCallingUid() 14030 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14031 Slog.w(TAG, msg); 14032 throw new SecurityException(msg); 14033 } 14034 synchronized (this) { 14035 UserStartedState state = mStartedUsers.get(userId); 14036 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14037 } 14038 } 14039 14040 private boolean userExists(int userId) { 14041 UserInfo user = getUserManager().getUserInfo(userId); 14042 return user != null; 14043 } 14044 14045 UserManager getUserManager() { 14046 if (mUserManager == null) { 14047 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 14048 } 14049 return mUserManager; 14050 } 14051 14052 private void checkValidCaller(int uid, int userId) { 14053 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14054 14055 throw new SecurityException("Caller uid=" + uid 14056 + " is not privileged to communicate with user=" + userId); 14057 } 14058 14059 private int applyUserId(int uid, int userId) { 14060 return UserHandle.getUid(userId, uid); 14061 } 14062 14063 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14064 if (info == null) return null; 14065 ApplicationInfo newInfo = new ApplicationInfo(info); 14066 newInfo.uid = applyUserId(info.uid, userId); 14067 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14068 + info.packageName; 14069 return newInfo; 14070 } 14071 14072 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14073 if (aInfo == null 14074 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14075 return aInfo; 14076 } 14077 14078 ActivityInfo info = new ActivityInfo(aInfo); 14079 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14080 return info; 14081 } 14082} 14083