ActivityManagerService.java revision 2d1b37819112274f538d1886c379ff337eb0d9ed
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; 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 mProviderMap = new ProviderMap(this); 1515 1516 File dataDir = Environment.getDataDirectory(); 1517 File systemDir = new File(dataDir, "system"); 1518 systemDir.mkdirs(); 1519 mBatteryStatsService = new BatteryStatsService(new File( 1520 systemDir, "batterystats.bin").toString()); 1521 mBatteryStatsService.getActiveStatistics().readLocked(); 1522 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1523 mOnBattery = DEBUG_POWER ? true 1524 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1525 mBatteryStatsService.getActiveStatistics().setCallback(this); 1526 1527 mUsageStatsService = new UsageStatsService(new File( 1528 systemDir, "usagestats").toString()); 1529 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1530 1531 // User 0 is the first and only user that runs at boot. 1532 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1533 mUserLru.add(Integer.valueOf(0)); 1534 1535 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1536 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1537 1538 mConfiguration.setToDefaults(); 1539 mConfiguration.setLocale(Locale.getDefault()); 1540 1541 mConfigurationSeq = mConfiguration.seq = 1; 1542 mProcessStats.init(); 1543 1544 mCompatModePackages = new CompatModePackages(this, systemDir); 1545 1546 // Add ourself to the Watchdog monitors. 1547 Watchdog.getInstance().addMonitor(this); 1548 1549 mProcessStatsThread = new Thread("ProcessStats") { 1550 public void run() { 1551 while (true) { 1552 try { 1553 try { 1554 synchronized(this) { 1555 final long now = SystemClock.uptimeMillis(); 1556 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1557 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1558 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1559 // + ", write delay=" + nextWriteDelay); 1560 if (nextWriteDelay < nextCpuDelay) { 1561 nextCpuDelay = nextWriteDelay; 1562 } 1563 if (nextCpuDelay > 0) { 1564 mProcessStatsMutexFree.set(true); 1565 this.wait(nextCpuDelay); 1566 } 1567 } 1568 } catch (InterruptedException e) { 1569 } 1570 updateCpuStatsNow(); 1571 } catch (Exception e) { 1572 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1573 } 1574 } 1575 } 1576 }; 1577 mProcessStatsThread.start(); 1578 } 1579 1580 @Override 1581 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1582 throws RemoteException { 1583 if (code == SYSPROPS_TRANSACTION) { 1584 // We need to tell all apps about the system property change. 1585 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1586 synchronized(this) { 1587 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1588 final int NA = apps.size(); 1589 for (int ia=0; ia<NA; ia++) { 1590 ProcessRecord app = apps.valueAt(ia); 1591 if (app.thread != null) { 1592 procs.add(app.thread.asBinder()); 1593 } 1594 } 1595 } 1596 } 1597 1598 int N = procs.size(); 1599 for (int i=0; i<N; i++) { 1600 Parcel data2 = Parcel.obtain(); 1601 try { 1602 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1603 } catch (RemoteException e) { 1604 } 1605 data2.recycle(); 1606 } 1607 } 1608 try { 1609 return super.onTransact(code, data, reply, flags); 1610 } catch (RuntimeException e) { 1611 // The activity manager only throws security exceptions, so let's 1612 // log all others. 1613 if (!(e instanceof SecurityException)) { 1614 Slog.e(TAG, "Activity Manager Crash", e); 1615 } 1616 throw e; 1617 } 1618 } 1619 1620 void updateCpuStats() { 1621 final long now = SystemClock.uptimeMillis(); 1622 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1623 return; 1624 } 1625 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1626 synchronized (mProcessStatsThread) { 1627 mProcessStatsThread.notify(); 1628 } 1629 } 1630 } 1631 1632 void updateCpuStatsNow() { 1633 synchronized (mProcessStatsThread) { 1634 mProcessStatsMutexFree.set(false); 1635 final long now = SystemClock.uptimeMillis(); 1636 boolean haveNewCpuStats = false; 1637 1638 if (MONITOR_CPU_USAGE && 1639 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1640 mLastCpuTime.set(now); 1641 haveNewCpuStats = true; 1642 mProcessStats.update(); 1643 //Slog.i(TAG, mProcessStats.printCurrentState()); 1644 //Slog.i(TAG, "Total CPU usage: " 1645 // + mProcessStats.getTotalCpuPercent() + "%"); 1646 1647 // Slog the cpu usage if the property is set. 1648 if ("true".equals(SystemProperties.get("events.cpu"))) { 1649 int user = mProcessStats.getLastUserTime(); 1650 int system = mProcessStats.getLastSystemTime(); 1651 int iowait = mProcessStats.getLastIoWaitTime(); 1652 int irq = mProcessStats.getLastIrqTime(); 1653 int softIrq = mProcessStats.getLastSoftIrqTime(); 1654 int idle = mProcessStats.getLastIdleTime(); 1655 1656 int total = user + system + iowait + irq + softIrq + idle; 1657 if (total == 0) total = 1; 1658 1659 EventLog.writeEvent(EventLogTags.CPU, 1660 ((user+system+iowait+irq+softIrq) * 100) / total, 1661 (user * 100) / total, 1662 (system * 100) / total, 1663 (iowait * 100) / total, 1664 (irq * 100) / total, 1665 (softIrq * 100) / total); 1666 } 1667 } 1668 1669 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1670 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1671 synchronized(bstats) { 1672 synchronized(mPidsSelfLocked) { 1673 if (haveNewCpuStats) { 1674 if (mOnBattery) { 1675 int perc = bstats.startAddingCpuLocked(); 1676 int totalUTime = 0; 1677 int totalSTime = 0; 1678 final int N = mProcessStats.countStats(); 1679 for (int i=0; i<N; i++) { 1680 ProcessStats.Stats st = mProcessStats.getStats(i); 1681 if (!st.working) { 1682 continue; 1683 } 1684 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1685 int otherUTime = (st.rel_utime*perc)/100; 1686 int otherSTime = (st.rel_stime*perc)/100; 1687 totalUTime += otherUTime; 1688 totalSTime += otherSTime; 1689 if (pr != null) { 1690 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1691 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1692 st.rel_stime-otherSTime); 1693 ps.addSpeedStepTimes(cpuSpeedTimes); 1694 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1695 } else { 1696 BatteryStatsImpl.Uid.Proc ps = 1697 bstats.getProcessStatsLocked(st.name, st.pid); 1698 if (ps != null) { 1699 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1700 st.rel_stime-otherSTime); 1701 ps.addSpeedStepTimes(cpuSpeedTimes); 1702 } 1703 } 1704 } 1705 bstats.finishAddingCpuLocked(perc, totalUTime, 1706 totalSTime, cpuSpeedTimes); 1707 } 1708 } 1709 } 1710 1711 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1712 mLastWriteTime = now; 1713 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1714 } 1715 } 1716 } 1717 } 1718 1719 @Override 1720 public void batteryNeedsCpuUpdate() { 1721 updateCpuStatsNow(); 1722 } 1723 1724 @Override 1725 public void batteryPowerChanged(boolean onBattery) { 1726 // When plugging in, update the CPU stats first before changing 1727 // the plug state. 1728 updateCpuStatsNow(); 1729 synchronized (this) { 1730 synchronized(mPidsSelfLocked) { 1731 mOnBattery = DEBUG_POWER ? true : onBattery; 1732 } 1733 } 1734 } 1735 1736 /** 1737 * Initialize the application bind args. These are passed to each 1738 * process when the bindApplication() IPC is sent to the process. They're 1739 * lazily setup to make sure the services are running when they're asked for. 1740 */ 1741 private HashMap<String, IBinder> getCommonServicesLocked() { 1742 if (mAppBindArgs == null) { 1743 mAppBindArgs = new HashMap<String, IBinder>(); 1744 1745 // Setup the application init args 1746 mAppBindArgs.put("package", ServiceManager.getService("package")); 1747 mAppBindArgs.put("window", ServiceManager.getService("window")); 1748 mAppBindArgs.put(Context.ALARM_SERVICE, 1749 ServiceManager.getService(Context.ALARM_SERVICE)); 1750 } 1751 return mAppBindArgs; 1752 } 1753 1754 final void setFocusedActivityLocked(ActivityRecord r) { 1755 if (mFocusedActivity != r) { 1756 mFocusedActivity = r; 1757 if (r != null) { 1758 mWindowManager.setFocusedApp(r.appToken, true); 1759 } 1760 } 1761 } 1762 1763 private final void updateLruProcessInternalLocked(ProcessRecord app, 1764 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1765 // put it on the LRU to keep track of when it should be exited. 1766 int lrui = mLruProcesses.indexOf(app); 1767 if (lrui >= 0) mLruProcesses.remove(lrui); 1768 1769 int i = mLruProcesses.size()-1; 1770 int skipTop = 0; 1771 1772 app.lruSeq = mLruSeq; 1773 1774 // compute the new weight for this process. 1775 if (updateActivityTime) { 1776 app.lastActivityTime = SystemClock.uptimeMillis(); 1777 } 1778 if (app.activities.size() > 0) { 1779 // If this process has activities, we more strongly want to keep 1780 // it around. 1781 app.lruWeight = app.lastActivityTime; 1782 } else if (app.pubProviders.size() > 0) { 1783 // If this process contains content providers, we want to keep 1784 // it a little more strongly. 1785 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1786 // Also don't let it kick out the first few "real" hidden processes. 1787 skipTop = ProcessList.MIN_HIDDEN_APPS; 1788 } else { 1789 // If this process doesn't have activities, we less strongly 1790 // want to keep it around, and generally want to avoid getting 1791 // in front of any very recently used activities. 1792 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1793 // Also don't let it kick out the first few "real" hidden processes. 1794 skipTop = ProcessList.MIN_HIDDEN_APPS; 1795 } 1796 1797 while (i >= 0) { 1798 ProcessRecord p = mLruProcesses.get(i); 1799 // If this app shouldn't be in front of the first N background 1800 // apps, then skip over that many that are currently hidden. 1801 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1802 skipTop--; 1803 } 1804 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1805 mLruProcesses.add(i+1, app); 1806 break; 1807 } 1808 i--; 1809 } 1810 if (i < 0) { 1811 mLruProcesses.add(0, app); 1812 } 1813 1814 // If the app is currently using a content provider or service, 1815 // bump those processes as well. 1816 if (app.connections.size() > 0) { 1817 for (ConnectionRecord cr : app.connections) { 1818 if (cr.binding != null && cr.binding.service != null 1819 && cr.binding.service.app != null 1820 && cr.binding.service.app.lruSeq != mLruSeq) { 1821 updateLruProcessInternalLocked(cr.binding.service.app, false, 1822 updateActivityTime, i+1); 1823 } 1824 } 1825 } 1826 for (int j=app.conProviders.size()-1; j>=0; j--) { 1827 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1828 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1829 updateLruProcessInternalLocked(cpr.proc, false, 1830 updateActivityTime, i+1); 1831 } 1832 } 1833 1834 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1835 if (oomAdj) { 1836 updateOomAdjLocked(); 1837 } 1838 } 1839 1840 final void updateLruProcessLocked(ProcessRecord app, 1841 boolean oomAdj, boolean updateActivityTime) { 1842 mLruSeq++; 1843 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1844 } 1845 1846 final ProcessRecord getProcessRecordLocked( 1847 String processName, int uid) { 1848 if (uid == Process.SYSTEM_UID) { 1849 // The system gets to run in any process. If there are multiple 1850 // processes with the same uid, just pick the first (this 1851 // should never happen). 1852 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1853 processName); 1854 if (procs == null) return null; 1855 final int N = procs.size(); 1856 for (int i = 0; i < N; i++) { 1857 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1858 } 1859 } 1860 ProcessRecord proc = mProcessNames.get(processName, uid); 1861 return proc; 1862 } 1863 1864 void ensurePackageDexOpt(String packageName) { 1865 IPackageManager pm = AppGlobals.getPackageManager(); 1866 try { 1867 if (pm.performDexOpt(packageName)) { 1868 mDidDexOpt = true; 1869 } 1870 } catch (RemoteException e) { 1871 } 1872 } 1873 1874 boolean isNextTransitionForward() { 1875 int transit = mWindowManager.getPendingAppTransition(); 1876 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1877 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1878 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1879 } 1880 1881 final ProcessRecord startProcessLocked(String processName, 1882 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1883 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1884 boolean isolated) { 1885 ProcessRecord app; 1886 if (!isolated) { 1887 app = getProcessRecordLocked(processName, info.uid); 1888 } else { 1889 // If this is an isolated process, it can't re-use an existing process. 1890 app = null; 1891 } 1892 // We don't have to do anything more if: 1893 // (1) There is an existing application record; and 1894 // (2) The caller doesn't think it is dead, OR there is no thread 1895 // object attached to it so we know it couldn't have crashed; and 1896 // (3) There is a pid assigned to it, so it is either starting or 1897 // already running. 1898 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1899 + " app=" + app + " knownToBeDead=" + knownToBeDead 1900 + " thread=" + (app != null ? app.thread : null) 1901 + " pid=" + (app != null ? app.pid : -1)); 1902 if (app != null && app.pid > 0) { 1903 if (!knownToBeDead || app.thread == null) { 1904 // We already have the app running, or are waiting for it to 1905 // come up (we have a pid but not yet its thread), so keep it. 1906 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1907 // If this is a new package in the process, add the package to the list 1908 app.addPackage(info.packageName); 1909 return app; 1910 } else { 1911 // An application record is attached to a previous process, 1912 // clean it up now. 1913 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1914 handleAppDiedLocked(app, true, true); 1915 } 1916 } 1917 1918 String hostingNameStr = hostingName != null 1919 ? hostingName.flattenToShortString() : null; 1920 1921 if (!isolated) { 1922 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1923 // If we are in the background, then check to see if this process 1924 // is bad. If so, we will just silently fail. 1925 if (mBadProcesses.get(info.processName, info.uid) != null) { 1926 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1927 + "/" + info.processName); 1928 return null; 1929 } 1930 } else { 1931 // When the user is explicitly starting a process, then clear its 1932 // crash count so that we won't make it bad until they see at 1933 // least one crash dialog again, and make the process good again 1934 // if it had been bad. 1935 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1936 + "/" + info.processName); 1937 mProcessCrashTimes.remove(info.processName, info.uid); 1938 if (mBadProcesses.get(info.processName, info.uid) != null) { 1939 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1940 info.processName); 1941 mBadProcesses.remove(info.processName, info.uid); 1942 if (app != null) { 1943 app.bad = false; 1944 } 1945 } 1946 } 1947 } 1948 1949 if (app == null) { 1950 app = newProcessRecordLocked(null, info, processName, isolated); 1951 if (app == null) { 1952 Slog.w(TAG, "Failed making new process record for " 1953 + processName + "/" + info.uid + " isolated=" + isolated); 1954 return null; 1955 } 1956 mProcessNames.put(processName, app.uid, app); 1957 if (isolated) { 1958 mIsolatedProcesses.put(app.uid, app); 1959 } 1960 } else { 1961 // If this is a new package in the process, add the package to the list 1962 app.addPackage(info.packageName); 1963 } 1964 1965 // If the system is not ready yet, then hold off on starting this 1966 // process until it is. 1967 if (!mProcessesReady 1968 && !isAllowedWhileBooting(info) 1969 && !allowWhileBooting) { 1970 if (!mProcessesOnHold.contains(app)) { 1971 mProcessesOnHold.add(app); 1972 } 1973 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1974 return app; 1975 } 1976 1977 startProcessLocked(app, hostingType, hostingNameStr); 1978 return (app.pid != 0) ? app : null; 1979 } 1980 1981 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1982 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1983 } 1984 1985 private final void startProcessLocked(ProcessRecord app, 1986 String hostingType, String hostingNameStr) { 1987 if (app.pid > 0 && app.pid != MY_PID) { 1988 synchronized (mPidsSelfLocked) { 1989 mPidsSelfLocked.remove(app.pid); 1990 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1991 } 1992 app.setPid(0); 1993 } 1994 1995 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1996 "startProcessLocked removing on hold: " + app); 1997 mProcessesOnHold.remove(app); 1998 1999 updateCpuStats(); 2000 2001 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2002 mProcDeaths[0] = 0; 2003 2004 try { 2005 int uid = app.uid; 2006 2007 int[] gids = null; 2008 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2009 if (!app.isolated) { 2010 try { 2011 final PackageManager pm = mContext.getPackageManager(); 2012 gids = pm.getPackageGids(app.info.packageName); 2013 2014 if (Environment.isExternalStorageEmulated()) { 2015 if (pm.checkPermission( 2016 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2017 app.info.packageName) == PERMISSION_GRANTED) { 2018 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2019 } else { 2020 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2021 } 2022 } 2023 } catch (PackageManager.NameNotFoundException e) { 2024 Slog.w(TAG, "Unable to retrieve gids", e); 2025 } 2026 } 2027 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2028 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2029 && mTopComponent != null 2030 && app.processName.equals(mTopComponent.getPackageName())) { 2031 uid = 0; 2032 } 2033 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2034 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2035 uid = 0; 2036 } 2037 } 2038 int debugFlags = 0; 2039 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2040 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2041 // Also turn on CheckJNI for debuggable apps. It's quite 2042 // awkward to turn on otherwise. 2043 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2044 } 2045 // Run the app in safe mode if its manifest requests so or the 2046 // system is booted in safe mode. 2047 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2048 Zygote.systemInSafeMode == true) { 2049 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2050 } 2051 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2052 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2053 } 2054 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2055 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2056 } 2057 if ("1".equals(SystemProperties.get("debug.assert"))) { 2058 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2059 } 2060 2061 // Start the process. It will either succeed and return a result containing 2062 // the PID of the new process, or else throw a RuntimeException. 2063 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2064 app.processName, uid, uid, gids, debugFlags, mountExternal, 2065 app.info.targetSdkVersion, null, null); 2066 2067 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2068 synchronized (bs) { 2069 if (bs.isOnBattery()) { 2070 app.batteryStats.incStartsLocked(); 2071 } 2072 } 2073 2074 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2075 app.processName, hostingType, 2076 hostingNameStr != null ? hostingNameStr : ""); 2077 2078 if (app.persistent) { 2079 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2080 } 2081 2082 StringBuilder buf = mStringBuilder; 2083 buf.setLength(0); 2084 buf.append("Start proc "); 2085 buf.append(app.processName); 2086 buf.append(" for "); 2087 buf.append(hostingType); 2088 if (hostingNameStr != null) { 2089 buf.append(" "); 2090 buf.append(hostingNameStr); 2091 } 2092 buf.append(": pid="); 2093 buf.append(startResult.pid); 2094 buf.append(" uid="); 2095 buf.append(uid); 2096 buf.append(" gids={"); 2097 if (gids != null) { 2098 for (int gi=0; gi<gids.length; gi++) { 2099 if (gi != 0) buf.append(", "); 2100 buf.append(gids[gi]); 2101 2102 } 2103 } 2104 buf.append("}"); 2105 Slog.i(TAG, buf.toString()); 2106 app.setPid(startResult.pid); 2107 app.usingWrapper = startResult.usingWrapper; 2108 app.removed = false; 2109 synchronized (mPidsSelfLocked) { 2110 this.mPidsSelfLocked.put(startResult.pid, app); 2111 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2112 msg.obj = app; 2113 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2114 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2115 } 2116 } catch (RuntimeException e) { 2117 // XXX do better error recovery. 2118 app.setPid(0); 2119 Slog.e(TAG, "Failure starting process " + app.processName, e); 2120 } 2121 } 2122 2123 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2124 if (resumed) { 2125 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2126 } else { 2127 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2128 } 2129 } 2130 2131 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2132 if (mHeadless) { 2133 // Added because none of the other calls to ensureBootCompleted seem to fire 2134 // when running headless. 2135 ensureBootCompleted(); 2136 return false; 2137 } 2138 2139 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2140 && mTopAction == null) { 2141 // We are running in factory test mode, but unable to find 2142 // the factory test app, so just sit around displaying the 2143 // error message and don't try to start anything. 2144 return false; 2145 } 2146 Intent intent = new Intent( 2147 mTopAction, 2148 mTopData != null ? Uri.parse(mTopData) : null); 2149 intent.setComponent(mTopComponent); 2150 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2151 intent.addCategory(Intent.CATEGORY_HOME); 2152 } 2153 ActivityInfo aInfo = 2154 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2155 if (aInfo != null) { 2156 intent.setComponent(new ComponentName( 2157 aInfo.applicationInfo.packageName, aInfo.name)); 2158 // Don't do this if the home app is currently being 2159 // instrumented. 2160 aInfo = new ActivityInfo(aInfo); 2161 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2162 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2163 aInfo.applicationInfo.uid); 2164 if (app == null || app.instrumentationClass == null) { 2165 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2166 mMainStack.startActivityLocked(null, intent, null, aInfo, 2167 null, null, 0, 0, 0, 0, null, false, null); 2168 } 2169 } 2170 if (startingUser != null) { 2171 mMainStack.addStartingUserLocked(startingUser); 2172 } 2173 2174 return true; 2175 } 2176 2177 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2178 ActivityInfo ai = null; 2179 ComponentName comp = intent.getComponent(); 2180 try { 2181 if (comp != null) { 2182 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2183 } else { 2184 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2185 intent, 2186 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2187 flags, userId); 2188 2189 if (info != null) { 2190 ai = info.activityInfo; 2191 } 2192 } 2193 } catch (RemoteException e) { 2194 // ignore 2195 } 2196 2197 return ai; 2198 } 2199 2200 /** 2201 * Starts the "new version setup screen" if appropriate. 2202 */ 2203 void startSetupActivityLocked() { 2204 // Only do this once per boot. 2205 if (mCheckedForSetup) { 2206 return; 2207 } 2208 2209 // We will show this screen if the current one is a different 2210 // version than the last one shown, and we are not running in 2211 // low-level factory test mode. 2212 final ContentResolver resolver = mContext.getContentResolver(); 2213 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2214 Settings.Secure.getInt(resolver, 2215 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2216 mCheckedForSetup = true; 2217 2218 // See if we should be showing the platform update setup UI. 2219 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2220 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2221 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2222 2223 // We don't allow third party apps to replace this. 2224 ResolveInfo ri = null; 2225 for (int i=0; ris != null && i<ris.size(); i++) { 2226 if ((ris.get(i).activityInfo.applicationInfo.flags 2227 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2228 ri = ris.get(i); 2229 break; 2230 } 2231 } 2232 2233 if (ri != null) { 2234 String vers = ri.activityInfo.metaData != null 2235 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2236 : null; 2237 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2238 vers = ri.activityInfo.applicationInfo.metaData.getString( 2239 Intent.METADATA_SETUP_VERSION); 2240 } 2241 String lastVers = Settings.Secure.getString( 2242 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2243 if (vers != null && !vers.equals(lastVers)) { 2244 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2245 intent.setComponent(new ComponentName( 2246 ri.activityInfo.packageName, ri.activityInfo.name)); 2247 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2248 null, null, 0, 0, 0, 0, null, false, null); 2249 } 2250 } 2251 } 2252 } 2253 2254 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2255 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2256 } 2257 2258 void enforceNotIsolatedCaller(String caller) { 2259 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2260 throw new SecurityException("Isolated process not allowed to call " + caller); 2261 } 2262 } 2263 2264 public int getFrontActivityScreenCompatMode() { 2265 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2266 synchronized (this) { 2267 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2268 } 2269 } 2270 2271 public void setFrontActivityScreenCompatMode(int mode) { 2272 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2273 "setFrontActivityScreenCompatMode"); 2274 synchronized (this) { 2275 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2276 } 2277 } 2278 2279 public int getPackageScreenCompatMode(String packageName) { 2280 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2281 synchronized (this) { 2282 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2283 } 2284 } 2285 2286 public void setPackageScreenCompatMode(String packageName, int mode) { 2287 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2288 "setPackageScreenCompatMode"); 2289 synchronized (this) { 2290 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2291 } 2292 } 2293 2294 public boolean getPackageAskScreenCompat(String packageName) { 2295 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2296 synchronized (this) { 2297 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2298 } 2299 } 2300 2301 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2302 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2303 "setPackageAskScreenCompat"); 2304 synchronized (this) { 2305 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2306 } 2307 } 2308 2309 void reportResumedActivityLocked(ActivityRecord r) { 2310 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2311 updateUsageStats(r, true); 2312 } 2313 2314 private void dispatchProcessesChanged() { 2315 int N; 2316 synchronized (this) { 2317 N = mPendingProcessChanges.size(); 2318 if (mActiveProcessChanges.length < N) { 2319 mActiveProcessChanges = new ProcessChangeItem[N]; 2320 } 2321 mPendingProcessChanges.toArray(mActiveProcessChanges); 2322 mAvailProcessChanges.addAll(mPendingProcessChanges); 2323 mPendingProcessChanges.clear(); 2324 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2325 } 2326 int i = mProcessObservers.beginBroadcast(); 2327 while (i > 0) { 2328 i--; 2329 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2330 if (observer != null) { 2331 try { 2332 for (int j=0; j<N; j++) { 2333 ProcessChangeItem item = mActiveProcessChanges[j]; 2334 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2335 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2336 + item.pid + " uid=" + item.uid + ": " 2337 + item.foregroundActivities); 2338 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2339 item.foregroundActivities); 2340 } 2341 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2343 + item.pid + " uid=" + item.uid + ": " + item.importance); 2344 observer.onImportanceChanged(item.pid, item.uid, 2345 item.importance); 2346 } 2347 } 2348 } catch (RemoteException e) { 2349 } 2350 } 2351 } 2352 mProcessObservers.finishBroadcast(); 2353 } 2354 2355 private void dispatchProcessDied(int pid, int uid) { 2356 int i = mProcessObservers.beginBroadcast(); 2357 while (i > 0) { 2358 i--; 2359 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2360 if (observer != null) { 2361 try { 2362 observer.onProcessDied(pid, uid); 2363 } catch (RemoteException e) { 2364 } 2365 } 2366 } 2367 mProcessObservers.finishBroadcast(); 2368 } 2369 2370 final void doPendingActivityLaunchesLocked(boolean doResume) { 2371 final int N = mPendingActivityLaunches.size(); 2372 if (N <= 0) { 2373 return; 2374 } 2375 for (int i=0; i<N; i++) { 2376 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2377 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2378 pal.startFlags, doResume && i == (N-1), null); 2379 } 2380 mPendingActivityLaunches.clear(); 2381 } 2382 2383 public final int startActivity(IApplicationThread caller, 2384 Intent intent, String resolvedType, IBinder resultTo, 2385 String resultWho, int requestCode, int startFlags, 2386 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2387 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2388 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2389 } 2390 2391 public final int startActivityAsUser(IApplicationThread caller, 2392 Intent intent, String resolvedType, IBinder resultTo, 2393 String resultWho, int requestCode, int startFlags, 2394 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2395 enforceNotIsolatedCaller("startActivity"); 2396 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2397 false, true, "startActivity", null); 2398 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2399 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2400 null, null, options, userId); 2401 } 2402 2403 public final WaitResult startActivityAndWait(IApplicationThread caller, 2404 Intent intent, String resolvedType, IBinder resultTo, 2405 String resultWho, int requestCode, int startFlags, String profileFile, 2406 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2407 enforceNotIsolatedCaller("startActivityAndWait"); 2408 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2409 false, true, "startActivityAndWait", null); 2410 WaitResult res = new WaitResult(); 2411 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2412 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2413 res, null, options, UserHandle.getCallingUserId()); 2414 return res; 2415 } 2416 2417 public final int startActivityWithConfig(IApplicationThread caller, 2418 Intent intent, String resolvedType, IBinder resultTo, 2419 String resultWho, int requestCode, int startFlags, Configuration config, 2420 Bundle options, int userId) { 2421 enforceNotIsolatedCaller("startActivityWithConfig"); 2422 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2423 false, true, "startActivityWithConfig", null); 2424 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2425 resultTo, resultWho, requestCode, startFlags, 2426 null, null, null, config, options, userId); 2427 return ret; 2428 } 2429 2430 public int startActivityIntentSender(IApplicationThread caller, 2431 IntentSender intent, Intent fillInIntent, String resolvedType, 2432 IBinder resultTo, String resultWho, int requestCode, 2433 int flagsMask, int flagsValues, Bundle options) { 2434 enforceNotIsolatedCaller("startActivityIntentSender"); 2435 // Refuse possible leaked file descriptors 2436 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2437 throw new IllegalArgumentException("File descriptors passed in Intent"); 2438 } 2439 2440 IIntentSender sender = intent.getTarget(); 2441 if (!(sender instanceof PendingIntentRecord)) { 2442 throw new IllegalArgumentException("Bad PendingIntent object"); 2443 } 2444 2445 PendingIntentRecord pir = (PendingIntentRecord)sender; 2446 2447 synchronized (this) { 2448 // If this is coming from the currently resumed activity, it is 2449 // effectively saying that app switches are allowed at this point. 2450 if (mMainStack.mResumedActivity != null 2451 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2452 Binder.getCallingUid()) { 2453 mAppSwitchesAllowedTime = 0; 2454 } 2455 } 2456 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2457 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2458 return ret; 2459 } 2460 2461 public boolean startNextMatchingActivity(IBinder callingActivity, 2462 Intent intent, Bundle options) { 2463 // Refuse possible leaked file descriptors 2464 if (intent != null && intent.hasFileDescriptors() == true) { 2465 throw new IllegalArgumentException("File descriptors passed in Intent"); 2466 } 2467 2468 synchronized (this) { 2469 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2470 if (r == null) { 2471 ActivityOptions.abort(options); 2472 return false; 2473 } 2474 if (r.app == null || r.app.thread == null) { 2475 // The caller is not running... d'oh! 2476 ActivityOptions.abort(options); 2477 return false; 2478 } 2479 intent = new Intent(intent); 2480 // The caller is not allowed to change the data. 2481 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2482 // And we are resetting to find the next component... 2483 intent.setComponent(null); 2484 2485 ActivityInfo aInfo = null; 2486 try { 2487 List<ResolveInfo> resolves = 2488 AppGlobals.getPackageManager().queryIntentActivities( 2489 intent, r.resolvedType, 2490 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2491 UserHandle.getCallingUserId()); 2492 2493 // Look for the original activity in the list... 2494 final int N = resolves != null ? resolves.size() : 0; 2495 for (int i=0; i<N; i++) { 2496 ResolveInfo rInfo = resolves.get(i); 2497 if (rInfo.activityInfo.packageName.equals(r.packageName) 2498 && rInfo.activityInfo.name.equals(r.info.name)) { 2499 // We found the current one... the next matching is 2500 // after it. 2501 i++; 2502 if (i<N) { 2503 aInfo = resolves.get(i).activityInfo; 2504 } 2505 break; 2506 } 2507 } 2508 } catch (RemoteException e) { 2509 } 2510 2511 if (aInfo == null) { 2512 // Nobody who is next! 2513 ActivityOptions.abort(options); 2514 return false; 2515 } 2516 2517 intent.setComponent(new ComponentName( 2518 aInfo.applicationInfo.packageName, aInfo.name)); 2519 intent.setFlags(intent.getFlags()&~( 2520 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2521 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2522 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2523 Intent.FLAG_ACTIVITY_NEW_TASK)); 2524 2525 // Okay now we need to start the new activity, replacing the 2526 // currently running activity. This is a little tricky because 2527 // we want to start the new one as if the current one is finished, 2528 // but not finish the current one first so that there is no flicker. 2529 // And thus... 2530 final boolean wasFinishing = r.finishing; 2531 r.finishing = true; 2532 2533 // Propagate reply information over to the new activity. 2534 final ActivityRecord resultTo = r.resultTo; 2535 final String resultWho = r.resultWho; 2536 final int requestCode = r.requestCode; 2537 r.resultTo = null; 2538 if (resultTo != null) { 2539 resultTo.removeResultsLocked(r, resultWho, requestCode); 2540 } 2541 2542 final long origId = Binder.clearCallingIdentity(); 2543 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2544 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2545 resultWho, requestCode, -1, r.launchedFromUid, 0, 2546 options, false, null); 2547 Binder.restoreCallingIdentity(origId); 2548 2549 r.finishing = wasFinishing; 2550 if (res != ActivityManager.START_SUCCESS) { 2551 return false; 2552 } 2553 return true; 2554 } 2555 } 2556 2557 final int startActivityInPackage(int uid, 2558 Intent intent, String resolvedType, IBinder resultTo, 2559 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2560 2561 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2562 false, true, "startActivityInPackage", null); 2563 2564 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2565 resultTo, resultWho, requestCode, startFlags, 2566 null, null, null, null, options, userId); 2567 return ret; 2568 } 2569 2570 public final int startActivities(IApplicationThread caller, 2571 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2572 enforceNotIsolatedCaller("startActivities"); 2573 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2574 options, UserHandle.getCallingUserId()); 2575 return ret; 2576 } 2577 2578 final int startActivitiesInPackage(int uid, 2579 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2580 Bundle options, int userId) { 2581 2582 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2583 false, true, "startActivityInPackage", null); 2584 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2585 options, userId); 2586 return ret; 2587 } 2588 2589 final void addRecentTaskLocked(TaskRecord task) { 2590 int N = mRecentTasks.size(); 2591 // Quick case: check if the top-most recent task is the same. 2592 if (N > 0 && mRecentTasks.get(0) == task) { 2593 return; 2594 } 2595 // Remove any existing entries that are the same kind of task. 2596 for (int i=0; i<N; i++) { 2597 TaskRecord tr = mRecentTasks.get(i); 2598 if (task.userId == tr.userId 2599 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2600 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2601 mRecentTasks.remove(i); 2602 i--; 2603 N--; 2604 if (task.intent == null) { 2605 // If the new recent task we are adding is not fully 2606 // specified, then replace it with the existing recent task. 2607 task = tr; 2608 } 2609 } 2610 } 2611 if (N >= MAX_RECENT_TASKS) { 2612 mRecentTasks.remove(N-1); 2613 } 2614 mRecentTasks.add(0, task); 2615 } 2616 2617 public void setRequestedOrientation(IBinder token, 2618 int requestedOrientation) { 2619 synchronized (this) { 2620 ActivityRecord r = mMainStack.isInStackLocked(token); 2621 if (r == null) { 2622 return; 2623 } 2624 final long origId = Binder.clearCallingIdentity(); 2625 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2626 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2627 mConfiguration, 2628 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2629 if (config != null) { 2630 r.frozenBeforeDestroy = true; 2631 if (!updateConfigurationLocked(config, r, false, false)) { 2632 mMainStack.resumeTopActivityLocked(null); 2633 } 2634 } 2635 Binder.restoreCallingIdentity(origId); 2636 } 2637 } 2638 2639 public int getRequestedOrientation(IBinder token) { 2640 synchronized (this) { 2641 ActivityRecord r = mMainStack.isInStackLocked(token); 2642 if (r == null) { 2643 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2644 } 2645 return mWindowManager.getAppOrientation(r.appToken); 2646 } 2647 } 2648 2649 /** 2650 * This is the internal entry point for handling Activity.finish(). 2651 * 2652 * @param token The Binder token referencing the Activity we want to finish. 2653 * @param resultCode Result code, if any, from this Activity. 2654 * @param resultData Result data (Intent), if any, from this Activity. 2655 * 2656 * @return Returns true if the activity successfully finished, or false if it is still running. 2657 */ 2658 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2659 // Refuse possible leaked file descriptors 2660 if (resultData != null && resultData.hasFileDescriptors() == true) { 2661 throw new IllegalArgumentException("File descriptors passed in Intent"); 2662 } 2663 2664 synchronized(this) { 2665 if (mController != null) { 2666 // Find the first activity that is not finishing. 2667 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2668 if (next != null) { 2669 // ask watcher if this is allowed 2670 boolean resumeOK = true; 2671 try { 2672 resumeOK = mController.activityResuming(next.packageName); 2673 } catch (RemoteException e) { 2674 mController = null; 2675 } 2676 2677 if (!resumeOK) { 2678 return false; 2679 } 2680 } 2681 } 2682 final long origId = Binder.clearCallingIdentity(); 2683 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2684 resultData, "app-request", true); 2685 Binder.restoreCallingIdentity(origId); 2686 return res; 2687 } 2688 } 2689 2690 public final void finishHeavyWeightApp() { 2691 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2692 != PackageManager.PERMISSION_GRANTED) { 2693 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2694 + Binder.getCallingPid() 2695 + ", uid=" + Binder.getCallingUid() 2696 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2697 Slog.w(TAG, msg); 2698 throw new SecurityException(msg); 2699 } 2700 2701 synchronized(this) { 2702 if (mHeavyWeightProcess == null) { 2703 return; 2704 } 2705 2706 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2707 mHeavyWeightProcess.activities); 2708 for (int i=0; i<activities.size(); i++) { 2709 ActivityRecord r = activities.get(i); 2710 if (!r.finishing) { 2711 int index = mMainStack.indexOfTokenLocked(r.appToken); 2712 if (index >= 0) { 2713 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2714 null, "finish-heavy", true); 2715 } 2716 } 2717 } 2718 2719 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2720 mHeavyWeightProcess.userId, 0)); 2721 mHeavyWeightProcess = null; 2722 } 2723 } 2724 2725 public void crashApplication(int uid, int initialPid, String packageName, 2726 String message) { 2727 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2728 != PackageManager.PERMISSION_GRANTED) { 2729 String msg = "Permission Denial: crashApplication() from pid=" 2730 + Binder.getCallingPid() 2731 + ", uid=" + Binder.getCallingUid() 2732 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2733 Slog.w(TAG, msg); 2734 throw new SecurityException(msg); 2735 } 2736 2737 synchronized(this) { 2738 ProcessRecord proc = null; 2739 2740 // Figure out which process to kill. We don't trust that initialPid 2741 // still has any relation to current pids, so must scan through the 2742 // list. 2743 synchronized (mPidsSelfLocked) { 2744 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2745 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2746 if (p.uid != uid) { 2747 continue; 2748 } 2749 if (p.pid == initialPid) { 2750 proc = p; 2751 break; 2752 } 2753 for (String str : p.pkgList) { 2754 if (str.equals(packageName)) { 2755 proc = p; 2756 } 2757 } 2758 } 2759 } 2760 2761 if (proc == null) { 2762 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2763 + " initialPid=" + initialPid 2764 + " packageName=" + packageName); 2765 return; 2766 } 2767 2768 if (proc.thread != null) { 2769 if (proc.pid == Process.myPid()) { 2770 Log.w(TAG, "crashApplication: trying to crash self!"); 2771 return; 2772 } 2773 long ident = Binder.clearCallingIdentity(); 2774 try { 2775 proc.thread.scheduleCrash(message); 2776 } catch (RemoteException e) { 2777 } 2778 Binder.restoreCallingIdentity(ident); 2779 } 2780 } 2781 } 2782 2783 public final void finishSubActivity(IBinder token, String resultWho, 2784 int requestCode) { 2785 synchronized(this) { 2786 final long origId = Binder.clearCallingIdentity(); 2787 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2788 Binder.restoreCallingIdentity(origId); 2789 } 2790 } 2791 2792 public boolean finishActivityAffinity(IBinder token) { 2793 synchronized(this) { 2794 final long origId = Binder.clearCallingIdentity(); 2795 boolean res = mMainStack.finishActivityAffinityLocked(token); 2796 Binder.restoreCallingIdentity(origId); 2797 return res; 2798 } 2799 } 2800 2801 public boolean willActivityBeVisible(IBinder token) { 2802 synchronized(this) { 2803 int i; 2804 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2805 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2806 if (r.appToken == token) { 2807 return true; 2808 } 2809 if (r.fullscreen && !r.finishing) { 2810 return false; 2811 } 2812 } 2813 return true; 2814 } 2815 } 2816 2817 public void overridePendingTransition(IBinder token, String packageName, 2818 int enterAnim, int exitAnim) { 2819 synchronized(this) { 2820 ActivityRecord self = mMainStack.isInStackLocked(token); 2821 if (self == null) { 2822 return; 2823 } 2824 2825 final long origId = Binder.clearCallingIdentity(); 2826 2827 if (self.state == ActivityState.RESUMED 2828 || self.state == ActivityState.PAUSING) { 2829 mWindowManager.overridePendingAppTransition(packageName, 2830 enterAnim, exitAnim, null); 2831 } 2832 2833 Binder.restoreCallingIdentity(origId); 2834 } 2835 } 2836 2837 /** 2838 * Main function for removing an existing process from the activity manager 2839 * as a result of that process going away. Clears out all connections 2840 * to the process. 2841 */ 2842 private final void handleAppDiedLocked(ProcessRecord app, 2843 boolean restarting, boolean allowRestart) { 2844 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2845 if (!restarting) { 2846 mLruProcesses.remove(app); 2847 } 2848 2849 if (mProfileProc == app) { 2850 clearProfilerLocked(); 2851 } 2852 2853 // Just in case... 2854 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2855 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2856 mMainStack.mPausingActivity = null; 2857 } 2858 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2859 mMainStack.mLastPausedActivity = null; 2860 } 2861 2862 // Remove this application's activities from active lists. 2863 mMainStack.removeHistoryRecordsForAppLocked(app); 2864 2865 boolean atTop = true; 2866 boolean hasVisibleActivities = false; 2867 2868 // Clean out the history list. 2869 int i = mMainStack.mHistory.size(); 2870 if (localLOGV) Slog.v( 2871 TAG, "Removing app " + app + " from history with " + i + " entries"); 2872 while (i > 0) { 2873 i--; 2874 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2875 if (localLOGV) Slog.v( 2876 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2877 if (r.app == app) { 2878 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2879 if (ActivityStack.DEBUG_ADD_REMOVE) { 2880 RuntimeException here = new RuntimeException("here"); 2881 here.fillInStackTrace(); 2882 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2883 + ": haveState=" + r.haveState 2884 + " stateNotNeeded=" + r.stateNotNeeded 2885 + " finishing=" + r.finishing 2886 + " state=" + r.state, here); 2887 } 2888 if (!r.finishing) { 2889 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2890 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2891 System.identityHashCode(r), 2892 r.task.taskId, r.shortComponentName, 2893 "proc died without state saved"); 2894 } 2895 mMainStack.removeActivityFromHistoryLocked(r); 2896 2897 } else { 2898 // We have the current state for this activity, so 2899 // it can be restarted later when needed. 2900 if (localLOGV) Slog.v( 2901 TAG, "Keeping entry, setting app to null"); 2902 if (r.visible) { 2903 hasVisibleActivities = true; 2904 } 2905 r.app = null; 2906 r.nowVisible = false; 2907 if (!r.haveState) { 2908 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2909 "App died, clearing saved state of " + r); 2910 r.icicle = null; 2911 } 2912 } 2913 2914 r.stack.cleanUpActivityLocked(r, true, true); 2915 } 2916 atTop = false; 2917 } 2918 2919 app.activities.clear(); 2920 2921 if (app.instrumentationClass != null) { 2922 Slog.w(TAG, "Crash of app " + app.processName 2923 + " running instrumentation " + app.instrumentationClass); 2924 Bundle info = new Bundle(); 2925 info.putString("shortMsg", "Process crashed."); 2926 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2927 } 2928 2929 if (!restarting) { 2930 if (!mMainStack.resumeTopActivityLocked(null)) { 2931 // If there was nothing to resume, and we are not already 2932 // restarting this process, but there is a visible activity that 2933 // is hosted by the process... then make sure all visible 2934 // activities are running, taking care of restarting this 2935 // process. 2936 if (hasVisibleActivities) { 2937 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2938 } 2939 } 2940 } 2941 } 2942 2943 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2944 IBinder threadBinder = thread.asBinder(); 2945 // Find the application record. 2946 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2947 ProcessRecord rec = mLruProcesses.get(i); 2948 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2949 return i; 2950 } 2951 } 2952 return -1; 2953 } 2954 2955 final ProcessRecord getRecordForAppLocked( 2956 IApplicationThread thread) { 2957 if (thread == null) { 2958 return null; 2959 } 2960 2961 int appIndex = getLRURecordIndexForAppLocked(thread); 2962 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2963 } 2964 2965 final void appDiedLocked(ProcessRecord app, int pid, 2966 IApplicationThread thread) { 2967 2968 mProcDeaths[0]++; 2969 2970 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2971 synchronized (stats) { 2972 stats.noteProcessDiedLocked(app.info.uid, pid); 2973 } 2974 2975 // Clean up already done if the process has been re-started. 2976 if (app.pid == pid && app.thread != null && 2977 app.thread.asBinder() == thread.asBinder()) { 2978 if (!app.killedBackground) { 2979 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2980 + ") has died."); 2981 } 2982 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2983 if (localLOGV) Slog.v( 2984 TAG, "Dying app: " + app + ", pid: " + pid 2985 + ", thread: " + thread.asBinder()); 2986 boolean doLowMem = app.instrumentationClass == null; 2987 handleAppDiedLocked(app, false, true); 2988 2989 if (doLowMem) { 2990 // If there are no longer any background processes running, 2991 // and the app that died was not running instrumentation, 2992 // then tell everyone we are now low on memory. 2993 boolean haveBg = false; 2994 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2995 ProcessRecord rec = mLruProcesses.get(i); 2996 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2997 haveBg = true; 2998 break; 2999 } 3000 } 3001 3002 if (!haveBg) { 3003 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3004 long now = SystemClock.uptimeMillis(); 3005 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3006 ProcessRecord rec = mLruProcesses.get(i); 3007 if (rec != app && rec.thread != null && 3008 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3009 // The low memory report is overriding any current 3010 // state for a GC request. Make sure to do 3011 // heavy/important/visible/foreground processes first. 3012 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3013 rec.lastRequestedGc = 0; 3014 } else { 3015 rec.lastRequestedGc = rec.lastLowMemory; 3016 } 3017 rec.reportLowMemory = true; 3018 rec.lastLowMemory = now; 3019 mProcessesToGc.remove(rec); 3020 addProcessToGcListLocked(rec); 3021 } 3022 } 3023 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3024 scheduleAppGcsLocked(); 3025 } 3026 } 3027 } else if (app.pid != pid) { 3028 // A new process has already been started. 3029 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3030 + ") has died and restarted (pid " + app.pid + ")."); 3031 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3032 } else if (DEBUG_PROCESSES) { 3033 Slog.d(TAG, "Received spurious death notification for thread " 3034 + thread.asBinder()); 3035 } 3036 } 3037 3038 /** 3039 * If a stack trace dump file is configured, dump process stack traces. 3040 * @param clearTraces causes the dump file to be erased prior to the new 3041 * traces being written, if true; when false, the new traces will be 3042 * appended to any existing file content. 3043 * @param firstPids of dalvik VM processes to dump stack traces for first 3044 * @param lastPids of dalvik VM processes to dump stack traces for last 3045 * @param nativeProcs optional list of native process names to dump stack crawls 3046 * @return file containing stack traces, or null if no dump file is configured 3047 */ 3048 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3049 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3050 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3051 if (tracesPath == null || tracesPath.length() == 0) { 3052 return null; 3053 } 3054 3055 File tracesFile = new File(tracesPath); 3056 try { 3057 File tracesDir = tracesFile.getParentFile(); 3058 if (!tracesDir.exists()) { 3059 tracesFile.mkdirs(); 3060 if (!SELinux.restorecon(tracesDir)) { 3061 return null; 3062 } 3063 } 3064 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3065 3066 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3067 tracesFile.createNewFile(); 3068 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3069 } catch (IOException e) { 3070 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3071 return null; 3072 } 3073 3074 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3075 return tracesFile; 3076 } 3077 3078 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3079 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3080 // Use a FileObserver to detect when traces finish writing. 3081 // The order of traces is considered important to maintain for legibility. 3082 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3083 public synchronized void onEvent(int event, String path) { notify(); } 3084 }; 3085 3086 try { 3087 observer.startWatching(); 3088 3089 // First collect all of the stacks of the most important pids. 3090 if (firstPids != null) { 3091 try { 3092 int num = firstPids.size(); 3093 for (int i = 0; i < num; i++) { 3094 synchronized (observer) { 3095 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3096 observer.wait(200); // Wait for write-close, give up after 200msec 3097 } 3098 } 3099 } catch (InterruptedException e) { 3100 Log.wtf(TAG, e); 3101 } 3102 } 3103 3104 // Next measure CPU usage. 3105 if (processStats != null) { 3106 processStats.init(); 3107 System.gc(); 3108 processStats.update(); 3109 try { 3110 synchronized (processStats) { 3111 processStats.wait(500); // measure over 1/2 second. 3112 } 3113 } catch (InterruptedException e) { 3114 } 3115 processStats.update(); 3116 3117 // We'll take the stack crawls of just the top apps using CPU. 3118 final int N = processStats.countWorkingStats(); 3119 int numProcs = 0; 3120 for (int i=0; i<N && numProcs<5; i++) { 3121 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3122 if (lastPids.indexOfKey(stats.pid) >= 0) { 3123 numProcs++; 3124 try { 3125 synchronized (observer) { 3126 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3127 observer.wait(200); // Wait for write-close, give up after 200msec 3128 } 3129 } catch (InterruptedException e) { 3130 Log.wtf(TAG, e); 3131 } 3132 3133 } 3134 } 3135 } 3136 3137 } finally { 3138 observer.stopWatching(); 3139 } 3140 3141 if (nativeProcs != null) { 3142 int[] pids = Process.getPidsForCommands(nativeProcs); 3143 if (pids != null) { 3144 for (int pid : pids) { 3145 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3146 } 3147 } 3148 } 3149 } 3150 3151 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3152 if (true || IS_USER_BUILD) { 3153 return; 3154 } 3155 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3156 if (tracesPath == null || tracesPath.length() == 0) { 3157 return; 3158 } 3159 3160 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3161 StrictMode.allowThreadDiskWrites(); 3162 try { 3163 final File tracesFile = new File(tracesPath); 3164 final File tracesDir = tracesFile.getParentFile(); 3165 final File tracesTmp = new File(tracesDir, "__tmp__"); 3166 try { 3167 if (!tracesDir.exists()) { 3168 tracesFile.mkdirs(); 3169 if (!SELinux.restorecon(tracesDir.getPath())) { 3170 return; 3171 } 3172 } 3173 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3174 3175 if (tracesFile.exists()) { 3176 tracesTmp.delete(); 3177 tracesFile.renameTo(tracesTmp); 3178 } 3179 StringBuilder sb = new StringBuilder(); 3180 Time tobj = new Time(); 3181 tobj.set(System.currentTimeMillis()); 3182 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3183 sb.append(": "); 3184 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3185 sb.append(" since "); 3186 sb.append(msg); 3187 FileOutputStream fos = new FileOutputStream(tracesFile); 3188 fos.write(sb.toString().getBytes()); 3189 if (app == null) { 3190 fos.write("\n*** No application process!".getBytes()); 3191 } 3192 fos.close(); 3193 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3194 } catch (IOException e) { 3195 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3196 return; 3197 } 3198 3199 if (app != null) { 3200 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3201 firstPids.add(app.pid); 3202 dumpStackTraces(tracesPath, firstPids, null, null, null); 3203 } 3204 3205 File lastTracesFile = null; 3206 File curTracesFile = null; 3207 for (int i=9; i>=0; i--) { 3208 String name = String.format("slow%02d.txt", i); 3209 curTracesFile = new File(tracesDir, name); 3210 if (curTracesFile.exists()) { 3211 if (lastTracesFile != null) { 3212 curTracesFile.renameTo(lastTracesFile); 3213 } else { 3214 curTracesFile.delete(); 3215 } 3216 } 3217 lastTracesFile = curTracesFile; 3218 } 3219 tracesFile.renameTo(curTracesFile); 3220 if (tracesTmp.exists()) { 3221 tracesTmp.renameTo(tracesFile); 3222 } 3223 } finally { 3224 StrictMode.setThreadPolicy(oldPolicy); 3225 } 3226 } 3227 3228 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3229 ActivityRecord parent, final String annotation) { 3230 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3231 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3232 3233 if (mController != null) { 3234 try { 3235 // 0 == continue, -1 = kill process immediately 3236 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3237 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3238 } catch (RemoteException e) { 3239 mController = null; 3240 } 3241 } 3242 3243 long anrTime = SystemClock.uptimeMillis(); 3244 if (MONITOR_CPU_USAGE) { 3245 updateCpuStatsNow(); 3246 } 3247 3248 synchronized (this) { 3249 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3250 if (mShuttingDown) { 3251 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3252 return; 3253 } else if (app.notResponding) { 3254 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3255 return; 3256 } else if (app.crashing) { 3257 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3258 return; 3259 } 3260 3261 // In case we come through here for the same app before completing 3262 // this one, mark as anring now so we will bail out. 3263 app.notResponding = true; 3264 3265 // Log the ANR to the event log. 3266 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3267 annotation); 3268 3269 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3270 firstPids.add(app.pid); 3271 3272 int parentPid = app.pid; 3273 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3274 if (parentPid != app.pid) firstPids.add(parentPid); 3275 3276 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3277 3278 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3279 ProcessRecord r = mLruProcesses.get(i); 3280 if (r != null && r.thread != null) { 3281 int pid = r.pid; 3282 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3283 if (r.persistent) { 3284 firstPids.add(pid); 3285 } else { 3286 lastPids.put(pid, Boolean.TRUE); 3287 } 3288 } 3289 } 3290 } 3291 } 3292 3293 // Log the ANR to the main log. 3294 StringBuilder info = new StringBuilder(); 3295 info.setLength(0); 3296 info.append("ANR in ").append(app.processName); 3297 if (activity != null && activity.shortComponentName != null) { 3298 info.append(" (").append(activity.shortComponentName).append(")"); 3299 } 3300 info.append("\n"); 3301 if (annotation != null) { 3302 info.append("Reason: ").append(annotation).append("\n"); 3303 } 3304 if (parent != null && parent != activity) { 3305 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3306 } 3307 3308 final ProcessStats processStats = new ProcessStats(true); 3309 3310 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3311 3312 String cpuInfo = null; 3313 if (MONITOR_CPU_USAGE) { 3314 updateCpuStatsNow(); 3315 synchronized (mProcessStatsThread) { 3316 cpuInfo = mProcessStats.printCurrentState(anrTime); 3317 } 3318 info.append(processStats.printCurrentLoad()); 3319 info.append(cpuInfo); 3320 } 3321 3322 info.append(processStats.printCurrentState(anrTime)); 3323 3324 Slog.e(TAG, info.toString()); 3325 if (tracesFile == null) { 3326 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3327 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3328 } 3329 3330 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3331 cpuInfo, tracesFile, null); 3332 3333 if (mController != null) { 3334 try { 3335 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3336 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3337 if (res != 0) { 3338 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3339 return; 3340 } 3341 } catch (RemoteException e) { 3342 mController = null; 3343 } 3344 } 3345 3346 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3347 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3348 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3349 3350 synchronized (this) { 3351 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3352 Slog.w(TAG, "Killing " + app + ": background ANR"); 3353 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3354 app.processName, app.setAdj, "background ANR"); 3355 Process.killProcessQuiet(app.pid); 3356 return; 3357 } 3358 3359 // Set the app's notResponding state, and look up the errorReportReceiver 3360 makeAppNotRespondingLocked(app, 3361 activity != null ? activity.shortComponentName : null, 3362 annotation != null ? "ANR " + annotation : "ANR", 3363 info.toString()); 3364 3365 // Bring up the infamous App Not Responding dialog 3366 Message msg = Message.obtain(); 3367 HashMap map = new HashMap(); 3368 msg.what = SHOW_NOT_RESPONDING_MSG; 3369 msg.obj = map; 3370 map.put("app", app); 3371 if (activity != null) { 3372 map.put("activity", activity); 3373 } 3374 3375 mHandler.sendMessage(msg); 3376 } 3377 } 3378 3379 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3380 if (!mLaunchWarningShown) { 3381 mLaunchWarningShown = true; 3382 mHandler.post(new Runnable() { 3383 @Override 3384 public void run() { 3385 synchronized (ActivityManagerService.this) { 3386 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3387 d.show(); 3388 mHandler.postDelayed(new Runnable() { 3389 @Override 3390 public void run() { 3391 synchronized (ActivityManagerService.this) { 3392 d.dismiss(); 3393 mLaunchWarningShown = false; 3394 } 3395 } 3396 }, 4000); 3397 } 3398 } 3399 }); 3400 } 3401 } 3402 3403 public boolean clearApplicationUserData(final String packageName, 3404 final IPackageDataObserver observer, final int userId) { 3405 enforceNotIsolatedCaller("clearApplicationUserData"); 3406 int uid = Binder.getCallingUid(); 3407 int pid = Binder.getCallingPid(); 3408 long callingId = Binder.clearCallingIdentity(); 3409 try { 3410 IPackageManager pm = AppGlobals.getPackageManager(); 3411 int pkgUid = -1; 3412 synchronized(this) { 3413 try { 3414 pkgUid = pm.getPackageUid(packageName, userId); 3415 } catch (RemoteException e) { 3416 } 3417 if (pkgUid == -1) { 3418 Slog.w(TAG, "Invalid packageName:" + packageName); 3419 return false; 3420 } 3421 if (uid == pkgUid || checkComponentPermission( 3422 android.Manifest.permission.CLEAR_APP_USER_DATA, 3423 pid, uid, -1, true) 3424 == PackageManager.PERMISSION_GRANTED) { 3425 forceStopPackageLocked(packageName, pkgUid); 3426 } else { 3427 throw new SecurityException(pid+" does not have permission:"+ 3428 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3429 "for process:"+packageName); 3430 } 3431 } 3432 3433 try { 3434 //clear application user data 3435 pm.clearApplicationUserData(packageName, observer, userId); 3436 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3437 Uri.fromParts("package", packageName, null)); 3438 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3439 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3440 null, null, 0, null, null, null, false, false, userId); 3441 } catch (RemoteException e) { 3442 } 3443 } finally { 3444 Binder.restoreCallingIdentity(callingId); 3445 } 3446 return true; 3447 } 3448 3449 public void killBackgroundProcesses(final String packageName) { 3450 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3451 != PackageManager.PERMISSION_GRANTED && 3452 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 int userId = UserHandle.getCallingUserId(); 3463 long callingId = Binder.clearCallingIdentity(); 3464 try { 3465 IPackageManager pm = AppGlobals.getPackageManager(); 3466 int pkgUid = -1; 3467 synchronized(this) { 3468 try { 3469 pkgUid = pm.getPackageUid(packageName, userId); 3470 } catch (RemoteException e) { 3471 } 3472 if (pkgUid == -1) { 3473 Slog.w(TAG, "Invalid packageName: " + packageName); 3474 return; 3475 } 3476 killPackageProcessesLocked(packageName, pkgUid, -1, 3477 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3478 } 3479 } finally { 3480 Binder.restoreCallingIdentity(callingId); 3481 } 3482 } 3483 3484 public void killAllBackgroundProcesses() { 3485 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3486 != PackageManager.PERMISSION_GRANTED) { 3487 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3488 + Binder.getCallingPid() 3489 + ", uid=" + Binder.getCallingUid() 3490 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3491 Slog.w(TAG, msg); 3492 throw new SecurityException(msg); 3493 } 3494 3495 long callingId = Binder.clearCallingIdentity(); 3496 try { 3497 synchronized(this) { 3498 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3499 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3500 final int NA = apps.size(); 3501 for (int ia=0; ia<NA; ia++) { 3502 ProcessRecord app = apps.valueAt(ia); 3503 if (app.persistent) { 3504 // we don't kill persistent processes 3505 continue; 3506 } 3507 if (app.removed) { 3508 procs.add(app); 3509 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3510 app.removed = true; 3511 procs.add(app); 3512 } 3513 } 3514 } 3515 3516 int N = procs.size(); 3517 for (int i=0; i<N; i++) { 3518 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3519 } 3520 } 3521 } finally { 3522 Binder.restoreCallingIdentity(callingId); 3523 } 3524 } 3525 3526 public void forceStopPackage(final String packageName) { 3527 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3528 != PackageManager.PERMISSION_GRANTED) { 3529 String msg = "Permission Denial: forceStopPackage() from pid=" 3530 + Binder.getCallingPid() 3531 + ", uid=" + Binder.getCallingUid() 3532 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3533 Slog.w(TAG, msg); 3534 throw new SecurityException(msg); 3535 } 3536 final int userId = UserHandle.getCallingUserId(); 3537 long callingId = Binder.clearCallingIdentity(); 3538 try { 3539 IPackageManager pm = AppGlobals.getPackageManager(); 3540 int pkgUid = -1; 3541 synchronized(this) { 3542 try { 3543 pkgUid = pm.getPackageUid(packageName, userId); 3544 } catch (RemoteException e) { 3545 } 3546 if (pkgUid == -1) { 3547 Slog.w(TAG, "Invalid packageName: " + packageName); 3548 return; 3549 } 3550 forceStopPackageLocked(packageName, pkgUid); 3551 try { 3552 pm.setPackageStoppedState(packageName, true, userId); 3553 } catch (RemoteException e) { 3554 } catch (IllegalArgumentException e) { 3555 Slog.w(TAG, "Failed trying to unstop package " 3556 + packageName + ": " + e); 3557 } 3558 } 3559 } finally { 3560 Binder.restoreCallingIdentity(callingId); 3561 } 3562 } 3563 3564 /* 3565 * The pkg name and app id have to be specified. 3566 */ 3567 public void killApplicationWithAppId(String pkg, int appid) { 3568 if (pkg == null) { 3569 return; 3570 } 3571 // Make sure the uid is valid. 3572 if (appid < 0) { 3573 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3574 return; 3575 } 3576 int callerUid = Binder.getCallingUid(); 3577 // Only the system server can kill an application 3578 if (callerUid == Process.SYSTEM_UID) { 3579 // Post an aysnc message to kill the application 3580 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3581 msg.arg1 = appid; 3582 msg.arg2 = 0; 3583 msg.obj = pkg; 3584 mHandler.sendMessage(msg); 3585 } else { 3586 throw new SecurityException(callerUid + " cannot kill pkg: " + 3587 pkg); 3588 } 3589 } 3590 3591 public void closeSystemDialogs(String reason) { 3592 enforceNotIsolatedCaller("closeSystemDialogs"); 3593 3594 final int pid = Binder.getCallingPid(); 3595 final int uid = Binder.getCallingUid(); 3596 final long origId = Binder.clearCallingIdentity(); 3597 try { 3598 synchronized (this) { 3599 // Only allow this from foreground processes, so that background 3600 // applications can't abuse it to prevent system UI from being shown. 3601 if (uid >= Process.FIRST_APPLICATION_UID) { 3602 ProcessRecord proc; 3603 synchronized (mPidsSelfLocked) { 3604 proc = mPidsSelfLocked.get(pid); 3605 } 3606 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3607 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3608 + " from background process " + proc); 3609 return; 3610 } 3611 } 3612 closeSystemDialogsLocked(reason); 3613 } 3614 } finally { 3615 Binder.restoreCallingIdentity(origId); 3616 } 3617 } 3618 3619 void closeSystemDialogsLocked(String reason) { 3620 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3621 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3622 if (reason != null) { 3623 intent.putExtra("reason", reason); 3624 } 3625 mWindowManager.closeSystemDialogs(reason); 3626 3627 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3628 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3629 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3630 r.stack.finishActivityLocked(r, i, 3631 Activity.RESULT_CANCELED, null, "close-sys", true); 3632 } 3633 } 3634 3635 broadcastIntentLocked(null, null, intent, null, 3636 null, 0, null, null, null, false, false, -1, 3637 Process.SYSTEM_UID, UserHandle.USER_ALL); 3638 } 3639 3640 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3641 throws RemoteException { 3642 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3643 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3644 for (int i=pids.length-1; i>=0; i--) { 3645 infos[i] = new Debug.MemoryInfo(); 3646 Debug.getMemoryInfo(pids[i], infos[i]); 3647 } 3648 return infos; 3649 } 3650 3651 public long[] getProcessPss(int[] pids) throws RemoteException { 3652 enforceNotIsolatedCaller("getProcessPss"); 3653 long[] pss = new long[pids.length]; 3654 for (int i=pids.length-1; i>=0; i--) { 3655 pss[i] = Debug.getPss(pids[i]); 3656 } 3657 return pss; 3658 } 3659 3660 public void killApplicationProcess(String processName, int uid) { 3661 if (processName == null) { 3662 return; 3663 } 3664 3665 int callerUid = Binder.getCallingUid(); 3666 // Only the system server can kill an application 3667 if (callerUid == Process.SYSTEM_UID) { 3668 synchronized (this) { 3669 ProcessRecord app = getProcessRecordLocked(processName, uid); 3670 if (app != null && app.thread != null) { 3671 try { 3672 app.thread.scheduleSuicide(); 3673 } catch (RemoteException e) { 3674 // If the other end already died, then our work here is done. 3675 } 3676 } else { 3677 Slog.w(TAG, "Process/uid not found attempting kill of " 3678 + processName + " / " + uid); 3679 } 3680 } 3681 } else { 3682 throw new SecurityException(callerUid + " cannot kill app process: " + 3683 processName); 3684 } 3685 } 3686 3687 private void forceStopPackageLocked(final String packageName, int uid) { 3688 forceStopPackageLocked(packageName, uid, false, false, true, false, 3689 UserHandle.getUserId(uid)); 3690 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3691 Uri.fromParts("package", packageName, null)); 3692 if (!mProcessesReady) { 3693 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3694 } 3695 intent.putExtra(Intent.EXTRA_UID, uid); 3696 broadcastIntentLocked(null, null, intent, 3697 null, null, 0, null, null, null, 3698 false, false, 3699 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3700 } 3701 3702 private void forceStopUserLocked(int userId) { 3703 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3704 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3705 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3706 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3707 broadcastIntentLocked(null, null, intent, 3708 null, null, 0, null, null, null, 3709 false, false, 3710 MY_PID, Process.SYSTEM_UID, userId); 3711 } 3712 3713 private final boolean killPackageProcessesLocked(String packageName, int appId, 3714 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3715 boolean doit, boolean evenPersistent, String reason) { 3716 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3717 3718 // Remove all processes this package may have touched: all with the 3719 // same UID (except for the system or root user), and all whose name 3720 // matches the package name. 3721 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3722 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3723 final int NA = apps.size(); 3724 for (int ia=0; ia<NA; ia++) { 3725 ProcessRecord app = apps.valueAt(ia); 3726 if (app.persistent && !evenPersistent) { 3727 // we don't kill persistent processes 3728 continue; 3729 } 3730 if (app.removed) { 3731 if (doit) { 3732 procs.add(app); 3733 } 3734 continue; 3735 } 3736 3737 // Skip process if it doesn't meet our oom adj requirement. 3738 if (app.setAdj < minOomAdj) { 3739 continue; 3740 } 3741 3742 // If no package is specified, we call all processes under the 3743 // give user id. 3744 if (packageName == null) { 3745 if (app.userId != userId) { 3746 continue; 3747 } 3748 // Package has been specified, we want to hit all processes 3749 // that match it. We need to qualify this by the processes 3750 // that are running under the specified app and user ID. 3751 } else { 3752 if (UserHandle.getAppId(app.uid) != appId) { 3753 continue; 3754 } 3755 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3756 continue; 3757 } 3758 if (!app.pkgList.contains(packageName)) { 3759 continue; 3760 } 3761 } 3762 3763 // Process has passed all conditions, kill it! 3764 if (!doit) { 3765 return true; 3766 } 3767 app.removed = true; 3768 procs.add(app); 3769 } 3770 } 3771 3772 int N = procs.size(); 3773 for (int i=0; i<N; i++) { 3774 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3775 } 3776 return N > 0; 3777 } 3778 3779 private final boolean forceStopPackageLocked(String name, int appId, 3780 boolean callerWillRestart, boolean purgeCache, boolean doit, 3781 boolean evenPersistent, int userId) { 3782 int i; 3783 int N; 3784 3785 if (userId == UserHandle.USER_ALL && name == null) { 3786 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3787 } 3788 3789 if (appId < 0 && name != null) { 3790 try { 3791 appId = UserHandle.getAppId( 3792 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3793 } catch (RemoteException e) { 3794 } 3795 } 3796 3797 if (doit) { 3798 if (name != null) { 3799 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3800 + " user=" + userId); 3801 } else { 3802 Slog.i(TAG, "Force stopping user " + userId); 3803 } 3804 3805 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3806 while (badApps.hasNext()) { 3807 SparseArray<Long> ba = badApps.next(); 3808 for (i=ba.size()-1; i>=0; i--) { 3809 boolean remove = false; 3810 final int entUid = ba.keyAt(i); 3811 if (name != null) { 3812 if (userId == UserHandle.USER_ALL) { 3813 if (UserHandle.getAppId(entUid) == appId) { 3814 remove = true; 3815 } 3816 } else { 3817 if (entUid == UserHandle.getUid(userId, appId)) { 3818 remove = true; 3819 } 3820 } 3821 } else if (UserHandle.getUserId(entUid) == userId) { 3822 remove = true; 3823 } 3824 if (remove) { 3825 ba.removeAt(i); 3826 } 3827 } 3828 if (ba.size() == 0) { 3829 badApps.remove(); 3830 } 3831 } 3832 } 3833 3834 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3835 -100, callerWillRestart, false, doit, evenPersistent, 3836 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3837 3838 TaskRecord lastTask = null; 3839 for (i=0; i<mMainStack.mHistory.size(); i++) { 3840 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3841 final boolean samePackage = r.packageName.equals(name) 3842 || (name == null && r.userId == userId); 3843 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3844 && (samePackage || r.task == lastTask) 3845 && (r.app == null || evenPersistent || !r.app.persistent)) { 3846 if (!doit) { 3847 if (r.finishing) { 3848 // If this activity is just finishing, then it is not 3849 // interesting as far as something to stop. 3850 continue; 3851 } 3852 return true; 3853 } 3854 didSomething = true; 3855 Slog.i(TAG, " Force finishing activity " + r); 3856 if (samePackage) { 3857 if (r.app != null) { 3858 r.app.removed = true; 3859 } 3860 r.app = null; 3861 } 3862 lastTask = r.task; 3863 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3864 null, "force-stop", true)) { 3865 i--; 3866 } 3867 } 3868 } 3869 3870 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3871 if (!doit) { 3872 return true; 3873 } 3874 didSomething = true; 3875 } 3876 3877 if (name == null) { 3878 // Remove all sticky broadcasts from this user. 3879 mStickyBroadcasts.remove(userId); 3880 } 3881 3882 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3883 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3884 userId, providers)) { 3885 if (!doit) { 3886 return true; 3887 } 3888 didSomething = true; 3889 } 3890 N = providers.size(); 3891 for (i=0; i<N; i++) { 3892 removeDyingProviderLocked(null, providers.get(i), true); 3893 } 3894 3895 if (mIntentSenderRecords.size() > 0) { 3896 Iterator<WeakReference<PendingIntentRecord>> it 3897 = mIntentSenderRecords.values().iterator(); 3898 while (it.hasNext()) { 3899 WeakReference<PendingIntentRecord> wpir = it.next(); 3900 if (wpir == null) { 3901 it.remove(); 3902 continue; 3903 } 3904 PendingIntentRecord pir = wpir.get(); 3905 if (pir == null) { 3906 it.remove(); 3907 continue; 3908 } 3909 if (name == null) { 3910 // Stopping user, remove all objects for the user. 3911 if (pir.key.userId != userId) { 3912 // Not the same user, skip it. 3913 continue; 3914 } 3915 } else { 3916 if (UserHandle.getAppId(pir.uid) != appId) { 3917 // Different app id, skip it. 3918 continue; 3919 } 3920 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3921 // Different user, skip it. 3922 continue; 3923 } 3924 if (!pir.key.packageName.equals(name)) { 3925 // Different package, skip it. 3926 continue; 3927 } 3928 } 3929 if (!doit) { 3930 return true; 3931 } 3932 didSomething = true; 3933 it.remove(); 3934 pir.canceled = true; 3935 if (pir.key.activity != null) { 3936 pir.key.activity.pendingResults.remove(pir.ref); 3937 } 3938 } 3939 } 3940 3941 if (doit) { 3942 if (purgeCache && name != null) { 3943 AttributeCache ac = AttributeCache.instance(); 3944 if (ac != null) { 3945 ac.removePackage(name); 3946 } 3947 } 3948 if (mBooted) { 3949 mMainStack.resumeTopActivityLocked(null); 3950 mMainStack.scheduleIdleLocked(); 3951 } 3952 } 3953 3954 return didSomething; 3955 } 3956 3957 private final boolean removeProcessLocked(ProcessRecord app, 3958 boolean callerWillRestart, boolean allowRestart, String reason) { 3959 final String name = app.processName; 3960 final int uid = app.uid; 3961 if (DEBUG_PROCESSES) Slog.d( 3962 TAG, "Force removing proc " + app.toShortString() + " (" + name 3963 + "/" + uid + ")"); 3964 3965 mProcessNames.remove(name, uid); 3966 mIsolatedProcesses.remove(app.uid); 3967 if (mHeavyWeightProcess == app) { 3968 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3969 mHeavyWeightProcess.userId, 0)); 3970 mHeavyWeightProcess = null; 3971 } 3972 boolean needRestart = false; 3973 if (app.pid > 0 && app.pid != MY_PID) { 3974 int pid = app.pid; 3975 synchronized (mPidsSelfLocked) { 3976 mPidsSelfLocked.remove(pid); 3977 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3978 } 3979 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3980 handleAppDiedLocked(app, true, allowRestart); 3981 mLruProcesses.remove(app); 3982 Process.killProcessQuiet(pid); 3983 3984 if (app.persistent && !app.isolated) { 3985 if (!callerWillRestart) { 3986 addAppLocked(app.info, false); 3987 } else { 3988 needRestart = true; 3989 } 3990 } 3991 } else { 3992 mRemovedProcesses.add(app); 3993 } 3994 3995 return needRestart; 3996 } 3997 3998 private final void processStartTimedOutLocked(ProcessRecord app) { 3999 final int pid = app.pid; 4000 boolean gone = false; 4001 synchronized (mPidsSelfLocked) { 4002 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4003 if (knownApp != null && knownApp.thread == null) { 4004 mPidsSelfLocked.remove(pid); 4005 gone = true; 4006 } 4007 } 4008 4009 if (gone) { 4010 Slog.w(TAG, "Process " + app + " failed to attach"); 4011 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4012 app.processName); 4013 mProcessNames.remove(app.processName, app.uid); 4014 mIsolatedProcesses.remove(app.uid); 4015 if (mHeavyWeightProcess == app) { 4016 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4017 mHeavyWeightProcess.userId, 0)); 4018 mHeavyWeightProcess = null; 4019 } 4020 // Take care of any launching providers waiting for this process. 4021 checkAppInLaunchingProvidersLocked(app, true); 4022 // Take care of any services that are waiting for the process. 4023 mServices.processStartTimedOutLocked(app); 4024 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4025 app.processName, app.setAdj, "start timeout"); 4026 Process.killProcessQuiet(pid); 4027 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4028 Slog.w(TAG, "Unattached app died before backup, skipping"); 4029 try { 4030 IBackupManager bm = IBackupManager.Stub.asInterface( 4031 ServiceManager.getService(Context.BACKUP_SERVICE)); 4032 bm.agentDisconnected(app.info.packageName); 4033 } catch (RemoteException e) { 4034 // Can't happen; the backup manager is local 4035 } 4036 } 4037 if (isPendingBroadcastProcessLocked(pid)) { 4038 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4039 skipPendingBroadcastLocked(pid); 4040 } 4041 } else { 4042 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4043 } 4044 } 4045 4046 private final boolean attachApplicationLocked(IApplicationThread thread, 4047 int pid) { 4048 4049 // Find the application record that is being attached... either via 4050 // the pid if we are running in multiple processes, or just pull the 4051 // next app record if we are emulating process with anonymous threads. 4052 ProcessRecord app; 4053 if (pid != MY_PID && pid >= 0) { 4054 synchronized (mPidsSelfLocked) { 4055 app = mPidsSelfLocked.get(pid); 4056 } 4057 } else { 4058 app = null; 4059 } 4060 4061 if (app == null) { 4062 Slog.w(TAG, "No pending application record for pid " + pid 4063 + " (IApplicationThread " + thread + "); dropping process"); 4064 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4065 if (pid > 0 && pid != MY_PID) { 4066 Process.killProcessQuiet(pid); 4067 } else { 4068 try { 4069 thread.scheduleExit(); 4070 } catch (Exception e) { 4071 // Ignore exceptions. 4072 } 4073 } 4074 return false; 4075 } 4076 4077 // If this application record is still attached to a previous 4078 // process, clean it up now. 4079 if (app.thread != null) { 4080 handleAppDiedLocked(app, true, true); 4081 } 4082 4083 // Tell the process all about itself. 4084 4085 if (localLOGV) Slog.v( 4086 TAG, "Binding process pid " + pid + " to record " + app); 4087 4088 String processName = app.processName; 4089 try { 4090 AppDeathRecipient adr = new AppDeathRecipient( 4091 app, pid, thread); 4092 thread.asBinder().linkToDeath(adr, 0); 4093 app.deathRecipient = adr; 4094 } catch (RemoteException e) { 4095 app.resetPackageList(); 4096 startProcessLocked(app, "link fail", processName); 4097 return false; 4098 } 4099 4100 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4101 4102 app.thread = thread; 4103 app.curAdj = app.setAdj = -100; 4104 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4105 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4106 app.forcingToForeground = null; 4107 app.foregroundServices = false; 4108 app.hasShownUi = false; 4109 app.debugging = false; 4110 4111 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4112 4113 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4114 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4115 4116 if (!normalMode) { 4117 Slog.i(TAG, "Launching preboot mode app: " + app); 4118 } 4119 4120 if (localLOGV) Slog.v( 4121 TAG, "New app record " + app 4122 + " thread=" + thread.asBinder() + " pid=" + pid); 4123 try { 4124 int testMode = IApplicationThread.DEBUG_OFF; 4125 if (mDebugApp != null && mDebugApp.equals(processName)) { 4126 testMode = mWaitForDebugger 4127 ? IApplicationThread.DEBUG_WAIT 4128 : IApplicationThread.DEBUG_ON; 4129 app.debugging = true; 4130 if (mDebugTransient) { 4131 mDebugApp = mOrigDebugApp; 4132 mWaitForDebugger = mOrigWaitForDebugger; 4133 } 4134 } 4135 String profileFile = app.instrumentationProfileFile; 4136 ParcelFileDescriptor profileFd = null; 4137 boolean profileAutoStop = false; 4138 if (mProfileApp != null && mProfileApp.equals(processName)) { 4139 mProfileProc = app; 4140 profileFile = mProfileFile; 4141 profileFd = mProfileFd; 4142 profileAutoStop = mAutoStopProfiler; 4143 } 4144 boolean enableOpenGlTrace = false; 4145 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4146 enableOpenGlTrace = true; 4147 mOpenGlTraceApp = null; 4148 } 4149 4150 // If the app is being launched for restore or full backup, set it up specially 4151 boolean isRestrictedBackupMode = false; 4152 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4153 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4154 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4155 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4156 } 4157 4158 ensurePackageDexOpt(app.instrumentationInfo != null 4159 ? app.instrumentationInfo.packageName 4160 : app.info.packageName); 4161 if (app.instrumentationClass != null) { 4162 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4163 } 4164 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4165 + processName + " with config " + mConfiguration); 4166 ApplicationInfo appInfo = app.instrumentationInfo != null 4167 ? app.instrumentationInfo : app.info; 4168 app.compat = compatibilityInfoForPackageLocked(appInfo); 4169 if (profileFd != null) { 4170 profileFd = profileFd.dup(); 4171 } 4172 thread.bindApplication(processName, appInfo, providers, 4173 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4174 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4175 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4176 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4177 mCoreSettingsObserver.getCoreSettingsLocked()); 4178 updateLruProcessLocked(app, false, true); 4179 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4180 } catch (Exception e) { 4181 // todo: Yikes! What should we do? For now we will try to 4182 // start another process, but that could easily get us in 4183 // an infinite loop of restarting processes... 4184 Slog.w(TAG, "Exception thrown during bind!", e); 4185 4186 app.resetPackageList(); 4187 app.unlinkDeathRecipient(); 4188 startProcessLocked(app, "bind fail", processName); 4189 return false; 4190 } 4191 4192 // Remove this record from the list of starting applications. 4193 mPersistentStartingProcesses.remove(app); 4194 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4195 "Attach application locked removing on hold: " + app); 4196 mProcessesOnHold.remove(app); 4197 4198 boolean badApp = false; 4199 boolean didSomething = false; 4200 4201 // See if the top visible activity is waiting to run in this process... 4202 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4203 if (hr != null && normalMode) { 4204 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4205 && processName.equals(hr.processName)) { 4206 try { 4207 if (mHeadless) { 4208 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4209 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4210 didSomething = true; 4211 } 4212 } catch (Exception e) { 4213 Slog.w(TAG, "Exception in new application when starting activity " 4214 + hr.intent.getComponent().flattenToShortString(), e); 4215 badApp = true; 4216 } 4217 } else { 4218 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4219 } 4220 } 4221 4222 // Find any services that should be running in this process... 4223 if (!badApp) { 4224 try { 4225 didSomething |= mServices.attachApplicationLocked(app, processName); 4226 } catch (Exception e) { 4227 badApp = true; 4228 } 4229 } 4230 4231 // Check if a next-broadcast receiver is in this process... 4232 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4233 try { 4234 didSomething = sendPendingBroadcastsLocked(app); 4235 } catch (Exception e) { 4236 // If the app died trying to launch the receiver we declare it 'bad' 4237 badApp = true; 4238 } 4239 } 4240 4241 // Check whether the next backup agent is in this process... 4242 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4243 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4244 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4245 try { 4246 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4247 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4248 mBackupTarget.backupMode); 4249 } catch (Exception e) { 4250 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4251 e.printStackTrace(); 4252 } 4253 } 4254 4255 if (badApp) { 4256 // todo: Also need to kill application to deal with all 4257 // kinds of exceptions. 4258 handleAppDiedLocked(app, false, true); 4259 return false; 4260 } 4261 4262 if (!didSomething) { 4263 updateOomAdjLocked(); 4264 } 4265 4266 return true; 4267 } 4268 4269 public final void attachApplication(IApplicationThread thread) { 4270 synchronized (this) { 4271 int callingPid = Binder.getCallingPid(); 4272 final long origId = Binder.clearCallingIdentity(); 4273 attachApplicationLocked(thread, callingPid); 4274 Binder.restoreCallingIdentity(origId); 4275 } 4276 } 4277 4278 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4279 final long origId = Binder.clearCallingIdentity(); 4280 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4281 if (stopProfiling) { 4282 synchronized (this) { 4283 if (mProfileProc == r.app) { 4284 if (mProfileFd != null) { 4285 try { 4286 mProfileFd.close(); 4287 } catch (IOException e) { 4288 } 4289 clearProfilerLocked(); 4290 } 4291 } 4292 } 4293 } 4294 Binder.restoreCallingIdentity(origId); 4295 } 4296 4297 void enableScreenAfterBoot() { 4298 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4299 SystemClock.uptimeMillis()); 4300 mWindowManager.enableScreenAfterBoot(); 4301 4302 synchronized (this) { 4303 updateEventDispatchingLocked(); 4304 } 4305 } 4306 4307 public void showBootMessage(final CharSequence msg, final boolean always) { 4308 enforceNotIsolatedCaller("showBootMessage"); 4309 mWindowManager.showBootMessage(msg, always); 4310 } 4311 4312 public void dismissKeyguardOnNextActivity() { 4313 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4314 final long token = Binder.clearCallingIdentity(); 4315 try { 4316 synchronized (this) { 4317 if (mLockScreenShown) { 4318 mLockScreenShown = false; 4319 comeOutOfSleepIfNeededLocked(); 4320 } 4321 mMainStack.dismissKeyguardOnNextActivityLocked(); 4322 } 4323 } finally { 4324 Binder.restoreCallingIdentity(token); 4325 } 4326 } 4327 4328 final void finishBooting() { 4329 IntentFilter pkgFilter = new IntentFilter(); 4330 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4331 pkgFilter.addDataScheme("package"); 4332 mContext.registerReceiver(new BroadcastReceiver() { 4333 @Override 4334 public void onReceive(Context context, Intent intent) { 4335 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4336 if (pkgs != null) { 4337 for (String pkg : pkgs) { 4338 synchronized (ActivityManagerService.this) { 4339 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4340 setResultCode(Activity.RESULT_OK); 4341 return; 4342 } 4343 } 4344 } 4345 } 4346 } 4347 }, pkgFilter); 4348 4349 synchronized (this) { 4350 // Ensure that any processes we had put on hold are now started 4351 // up. 4352 final int NP = mProcessesOnHold.size(); 4353 if (NP > 0) { 4354 ArrayList<ProcessRecord> procs = 4355 new ArrayList<ProcessRecord>(mProcessesOnHold); 4356 for (int ip=0; ip<NP; ip++) { 4357 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4358 + procs.get(ip)); 4359 startProcessLocked(procs.get(ip), "on-hold", null); 4360 } 4361 } 4362 4363 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4364 // Start looking for apps that are abusing wake locks. 4365 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4366 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4367 // Tell anyone interested that we are done booting! 4368 SystemProperties.set("sys.boot_completed", "1"); 4369 SystemProperties.set("dev.bootcomplete", "1"); 4370 for (int i=0; i<mStartedUsers.size(); i++) { 4371 UserStartedState uss = mStartedUsers.valueAt(i); 4372 if (uss.mState == UserStartedState.STATE_BOOTING) { 4373 uss.mState = UserStartedState.STATE_RUNNING; 4374 final int userId = mStartedUsers.keyAt(i); 4375 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4376 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4377 broadcastIntentLocked(null, null, intent, 4378 null, null, 0, null, null, 4379 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4380 false, false, MY_PID, Process.SYSTEM_UID, userId); 4381 } 4382 } 4383 } 4384 } 4385 } 4386 4387 final void ensureBootCompleted() { 4388 boolean booting; 4389 boolean enableScreen; 4390 synchronized (this) { 4391 booting = mBooting; 4392 mBooting = false; 4393 enableScreen = !mBooted; 4394 mBooted = true; 4395 } 4396 4397 if (booting) { 4398 finishBooting(); 4399 } 4400 4401 if (enableScreen) { 4402 enableScreenAfterBoot(); 4403 } 4404 } 4405 4406 public final void activityPaused(IBinder token) { 4407 final long origId = Binder.clearCallingIdentity(); 4408 mMainStack.activityPaused(token, false); 4409 Binder.restoreCallingIdentity(origId); 4410 } 4411 4412 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4413 CharSequence description) { 4414 if (localLOGV) Slog.v( 4415 TAG, "Activity stopped: token=" + token); 4416 4417 // Refuse possible leaked file descriptors 4418 if (icicle != null && icicle.hasFileDescriptors()) { 4419 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4420 } 4421 4422 ActivityRecord r = null; 4423 4424 final long origId = Binder.clearCallingIdentity(); 4425 4426 synchronized (this) { 4427 r = mMainStack.isInStackLocked(token); 4428 if (r != null) { 4429 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4430 } 4431 } 4432 4433 if (r != null) { 4434 sendPendingThumbnail(r, null, null, null, false); 4435 } 4436 4437 trimApplications(); 4438 4439 Binder.restoreCallingIdentity(origId); 4440 } 4441 4442 public final void activityDestroyed(IBinder token) { 4443 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4444 mMainStack.activityDestroyed(token); 4445 } 4446 4447 public String getCallingPackage(IBinder token) { 4448 synchronized (this) { 4449 ActivityRecord r = getCallingRecordLocked(token); 4450 return r != null && r.app != null ? r.info.packageName : null; 4451 } 4452 } 4453 4454 public ComponentName getCallingActivity(IBinder token) { 4455 synchronized (this) { 4456 ActivityRecord r = getCallingRecordLocked(token); 4457 return r != null ? r.intent.getComponent() : null; 4458 } 4459 } 4460 4461 private ActivityRecord getCallingRecordLocked(IBinder token) { 4462 ActivityRecord r = mMainStack.isInStackLocked(token); 4463 if (r == null) { 4464 return null; 4465 } 4466 return r.resultTo; 4467 } 4468 4469 public ComponentName getActivityClassForToken(IBinder token) { 4470 synchronized(this) { 4471 ActivityRecord r = mMainStack.isInStackLocked(token); 4472 if (r == null) { 4473 return null; 4474 } 4475 return r.intent.getComponent(); 4476 } 4477 } 4478 4479 public String getPackageForToken(IBinder token) { 4480 synchronized(this) { 4481 ActivityRecord r = mMainStack.isInStackLocked(token); 4482 if (r == null) { 4483 return null; 4484 } 4485 return r.packageName; 4486 } 4487 } 4488 4489 public IIntentSender getIntentSender(int type, 4490 String packageName, IBinder token, String resultWho, 4491 int requestCode, Intent[] intents, String[] resolvedTypes, 4492 int flags, Bundle options, int userId) { 4493 enforceNotIsolatedCaller("getIntentSender"); 4494 // Refuse possible leaked file descriptors 4495 if (intents != null) { 4496 if (intents.length < 1) { 4497 throw new IllegalArgumentException("Intents array length must be >= 1"); 4498 } 4499 for (int i=0; i<intents.length; i++) { 4500 Intent intent = intents[i]; 4501 if (intent != null) { 4502 if (intent.hasFileDescriptors()) { 4503 throw new IllegalArgumentException("File descriptors passed in Intent"); 4504 } 4505 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4506 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4507 throw new IllegalArgumentException( 4508 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4509 } 4510 intents[i] = new Intent(intent); 4511 } 4512 } 4513 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4514 throw new IllegalArgumentException( 4515 "Intent array length does not match resolvedTypes length"); 4516 } 4517 } 4518 if (options != null) { 4519 if (options.hasFileDescriptors()) { 4520 throw new IllegalArgumentException("File descriptors passed in options"); 4521 } 4522 } 4523 4524 synchronized(this) { 4525 int callingUid = Binder.getCallingUid(); 4526 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4527 false, true, "getIntentSender", null); 4528 try { 4529 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4530 int uid = AppGlobals.getPackageManager() 4531 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4532 if (!UserHandle.isSameApp(callingUid, uid)) { 4533 String msg = "Permission Denial: getIntentSender() from pid=" 4534 + Binder.getCallingPid() 4535 + ", uid=" + Binder.getCallingUid() 4536 + ", (need uid=" + uid + ")" 4537 + " is not allowed to send as package " + packageName; 4538 Slog.w(TAG, msg); 4539 throw new SecurityException(msg); 4540 } 4541 } 4542 4543 return getIntentSenderLocked(type, packageName, callingUid, userId, 4544 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4545 4546 } catch (RemoteException e) { 4547 throw new SecurityException(e); 4548 } 4549 } 4550 } 4551 4552 IIntentSender getIntentSenderLocked(int type, String packageName, 4553 int callingUid, int userId, IBinder token, String resultWho, 4554 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4555 Bundle options) { 4556 if (DEBUG_MU) 4557 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4558 ActivityRecord activity = null; 4559 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4560 activity = mMainStack.isInStackLocked(token); 4561 if (activity == null) { 4562 return null; 4563 } 4564 if (activity.finishing) { 4565 return null; 4566 } 4567 } 4568 4569 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4570 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4571 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4572 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4573 |PendingIntent.FLAG_UPDATE_CURRENT); 4574 4575 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4576 type, packageName, activity, resultWho, 4577 requestCode, intents, resolvedTypes, flags, options, userId); 4578 WeakReference<PendingIntentRecord> ref; 4579 ref = mIntentSenderRecords.get(key); 4580 PendingIntentRecord rec = ref != null ? ref.get() : null; 4581 if (rec != null) { 4582 if (!cancelCurrent) { 4583 if (updateCurrent) { 4584 if (rec.key.requestIntent != null) { 4585 rec.key.requestIntent.replaceExtras(intents != null ? 4586 intents[intents.length - 1] : null); 4587 } 4588 if (intents != null) { 4589 intents[intents.length-1] = rec.key.requestIntent; 4590 rec.key.allIntents = intents; 4591 rec.key.allResolvedTypes = resolvedTypes; 4592 } else { 4593 rec.key.allIntents = null; 4594 rec.key.allResolvedTypes = null; 4595 } 4596 } 4597 return rec; 4598 } 4599 rec.canceled = true; 4600 mIntentSenderRecords.remove(key); 4601 } 4602 if (noCreate) { 4603 return rec; 4604 } 4605 rec = new PendingIntentRecord(this, key, callingUid); 4606 mIntentSenderRecords.put(key, rec.ref); 4607 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4608 if (activity.pendingResults == null) { 4609 activity.pendingResults 4610 = new HashSet<WeakReference<PendingIntentRecord>>(); 4611 } 4612 activity.pendingResults.add(rec.ref); 4613 } 4614 return rec; 4615 } 4616 4617 public void cancelIntentSender(IIntentSender sender) { 4618 if (!(sender instanceof PendingIntentRecord)) { 4619 return; 4620 } 4621 synchronized(this) { 4622 PendingIntentRecord rec = (PendingIntentRecord)sender; 4623 try { 4624 int uid = AppGlobals.getPackageManager() 4625 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4626 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4627 String msg = "Permission Denial: cancelIntentSender() from pid=" 4628 + Binder.getCallingPid() 4629 + ", uid=" + Binder.getCallingUid() 4630 + " is not allowed to cancel packges " 4631 + rec.key.packageName; 4632 Slog.w(TAG, msg); 4633 throw new SecurityException(msg); 4634 } 4635 } catch (RemoteException e) { 4636 throw new SecurityException(e); 4637 } 4638 cancelIntentSenderLocked(rec, true); 4639 } 4640 } 4641 4642 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4643 rec.canceled = true; 4644 mIntentSenderRecords.remove(rec.key); 4645 if (cleanActivity && rec.key.activity != null) { 4646 rec.key.activity.pendingResults.remove(rec.ref); 4647 } 4648 } 4649 4650 public String getPackageForIntentSender(IIntentSender pendingResult) { 4651 if (!(pendingResult instanceof PendingIntentRecord)) { 4652 return null; 4653 } 4654 try { 4655 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4656 return res.key.packageName; 4657 } catch (ClassCastException e) { 4658 } 4659 return null; 4660 } 4661 4662 public int getUidForIntentSender(IIntentSender sender) { 4663 if (sender instanceof PendingIntentRecord) { 4664 try { 4665 PendingIntentRecord res = (PendingIntentRecord)sender; 4666 return res.uid; 4667 } catch (ClassCastException e) { 4668 } 4669 } 4670 return -1; 4671 } 4672 4673 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4674 if (!(pendingResult instanceof PendingIntentRecord)) { 4675 return false; 4676 } 4677 try { 4678 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4679 if (res.key.allIntents == null) { 4680 return false; 4681 } 4682 for (int i=0; i<res.key.allIntents.length; i++) { 4683 Intent intent = res.key.allIntents[i]; 4684 if (intent.getPackage() != null && intent.getComponent() != null) { 4685 return false; 4686 } 4687 } 4688 return true; 4689 } catch (ClassCastException e) { 4690 } 4691 return false; 4692 } 4693 4694 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4695 if (!(pendingResult instanceof PendingIntentRecord)) { 4696 return false; 4697 } 4698 try { 4699 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4700 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4701 return true; 4702 } 4703 return false; 4704 } catch (ClassCastException e) { 4705 } 4706 return false; 4707 } 4708 4709 public void setProcessLimit(int max) { 4710 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4711 "setProcessLimit()"); 4712 synchronized (this) { 4713 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4714 mProcessLimitOverride = max; 4715 } 4716 trimApplications(); 4717 } 4718 4719 public int getProcessLimit() { 4720 synchronized (this) { 4721 return mProcessLimitOverride; 4722 } 4723 } 4724 4725 void foregroundTokenDied(ForegroundToken token) { 4726 synchronized (ActivityManagerService.this) { 4727 synchronized (mPidsSelfLocked) { 4728 ForegroundToken cur 4729 = mForegroundProcesses.get(token.pid); 4730 if (cur != token) { 4731 return; 4732 } 4733 mForegroundProcesses.remove(token.pid); 4734 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4735 if (pr == null) { 4736 return; 4737 } 4738 pr.forcingToForeground = null; 4739 pr.foregroundServices = false; 4740 } 4741 updateOomAdjLocked(); 4742 } 4743 } 4744 4745 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4746 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4747 "setProcessForeground()"); 4748 synchronized(this) { 4749 boolean changed = false; 4750 4751 synchronized (mPidsSelfLocked) { 4752 ProcessRecord pr = mPidsSelfLocked.get(pid); 4753 if (pr == null && isForeground) { 4754 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4755 return; 4756 } 4757 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4758 if (oldToken != null) { 4759 oldToken.token.unlinkToDeath(oldToken, 0); 4760 mForegroundProcesses.remove(pid); 4761 if (pr != null) { 4762 pr.forcingToForeground = null; 4763 } 4764 changed = true; 4765 } 4766 if (isForeground && token != null) { 4767 ForegroundToken newToken = new ForegroundToken() { 4768 public void binderDied() { 4769 foregroundTokenDied(this); 4770 } 4771 }; 4772 newToken.pid = pid; 4773 newToken.token = token; 4774 try { 4775 token.linkToDeath(newToken, 0); 4776 mForegroundProcesses.put(pid, newToken); 4777 pr.forcingToForeground = token; 4778 changed = true; 4779 } catch (RemoteException e) { 4780 // If the process died while doing this, we will later 4781 // do the cleanup with the process death link. 4782 } 4783 } 4784 } 4785 4786 if (changed) { 4787 updateOomAdjLocked(); 4788 } 4789 } 4790 } 4791 4792 // ========================================================= 4793 // PERMISSIONS 4794 // ========================================================= 4795 4796 static class PermissionController extends IPermissionController.Stub { 4797 ActivityManagerService mActivityManagerService; 4798 PermissionController(ActivityManagerService activityManagerService) { 4799 mActivityManagerService = activityManagerService; 4800 } 4801 4802 public boolean checkPermission(String permission, int pid, int uid) { 4803 return mActivityManagerService.checkPermission(permission, pid, 4804 uid) == PackageManager.PERMISSION_GRANTED; 4805 } 4806 } 4807 4808 /** 4809 * This can be called with or without the global lock held. 4810 */ 4811 int checkComponentPermission(String permission, int pid, int uid, 4812 int owningUid, boolean exported) { 4813 // We might be performing an operation on behalf of an indirect binder 4814 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4815 // client identity accordingly before proceeding. 4816 Identity tlsIdentity = sCallerIdentity.get(); 4817 if (tlsIdentity != null) { 4818 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4819 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4820 uid = tlsIdentity.uid; 4821 pid = tlsIdentity.pid; 4822 } 4823 4824 if (pid == MY_PID) { 4825 return PackageManager.PERMISSION_GRANTED; 4826 } 4827 4828 return ActivityManager.checkComponentPermission(permission, uid, 4829 owningUid, exported); 4830 } 4831 4832 /** 4833 * As the only public entry point for permissions checking, this method 4834 * can enforce the semantic that requesting a check on a null global 4835 * permission is automatically denied. (Internally a null permission 4836 * string is used when calling {@link #checkComponentPermission} in cases 4837 * when only uid-based security is needed.) 4838 * 4839 * This can be called with or without the global lock held. 4840 */ 4841 public int checkPermission(String permission, int pid, int uid) { 4842 if (permission == null) { 4843 return PackageManager.PERMISSION_DENIED; 4844 } 4845 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4846 } 4847 4848 /** 4849 * Binder IPC calls go through the public entry point. 4850 * This can be called with or without the global lock held. 4851 */ 4852 int checkCallingPermission(String permission) { 4853 return checkPermission(permission, 4854 Binder.getCallingPid(), 4855 UserHandle.getAppId(Binder.getCallingUid())); 4856 } 4857 4858 /** 4859 * This can be called with or without the global lock held. 4860 */ 4861 void enforceCallingPermission(String permission, String func) { 4862 if (checkCallingPermission(permission) 4863 == PackageManager.PERMISSION_GRANTED) { 4864 return; 4865 } 4866 4867 String msg = "Permission Denial: " + func + " from pid=" 4868 + Binder.getCallingPid() 4869 + ", uid=" + Binder.getCallingUid() 4870 + " requires " + permission; 4871 Slog.w(TAG, msg); 4872 throw new SecurityException(msg); 4873 } 4874 4875 /** 4876 * Determine if UID is holding permissions required to access {@link Uri} in 4877 * the given {@link ProviderInfo}. Final permission checking is always done 4878 * in {@link ContentProvider}. 4879 */ 4880 private final boolean checkHoldingPermissionsLocked( 4881 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4882 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4883 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4884 4885 if (pi.applicationInfo.uid == uid) { 4886 return true; 4887 } else if (!pi.exported) { 4888 return false; 4889 } 4890 4891 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4892 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4893 try { 4894 // check if target holds top-level <provider> permissions 4895 if (!readMet && pi.readPermission != null 4896 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4897 readMet = true; 4898 } 4899 if (!writeMet && pi.writePermission != null 4900 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4901 writeMet = true; 4902 } 4903 4904 // track if unprotected read/write is allowed; any denied 4905 // <path-permission> below removes this ability 4906 boolean allowDefaultRead = pi.readPermission == null; 4907 boolean allowDefaultWrite = pi.writePermission == null; 4908 4909 // check if target holds any <path-permission> that match uri 4910 final PathPermission[] pps = pi.pathPermissions; 4911 if (pps != null) { 4912 final String path = uri.getPath(); 4913 int i = pps.length; 4914 while (i > 0 && (!readMet || !writeMet)) { 4915 i--; 4916 PathPermission pp = pps[i]; 4917 if (pp.match(path)) { 4918 if (!readMet) { 4919 final String pprperm = pp.getReadPermission(); 4920 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4921 + pprperm + " for " + pp.getPath() 4922 + ": match=" + pp.match(path) 4923 + " check=" + pm.checkUidPermission(pprperm, uid)); 4924 if (pprperm != null) { 4925 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4926 readMet = true; 4927 } else { 4928 allowDefaultRead = false; 4929 } 4930 } 4931 } 4932 if (!writeMet) { 4933 final String ppwperm = pp.getWritePermission(); 4934 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4935 + ppwperm + " for " + pp.getPath() 4936 + ": match=" + pp.match(path) 4937 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4938 if (ppwperm != null) { 4939 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4940 writeMet = true; 4941 } else { 4942 allowDefaultWrite = false; 4943 } 4944 } 4945 } 4946 } 4947 } 4948 } 4949 4950 // grant unprotected <provider> read/write, if not blocked by 4951 // <path-permission> above 4952 if (allowDefaultRead) readMet = true; 4953 if (allowDefaultWrite) writeMet = true; 4954 4955 } catch (RemoteException e) { 4956 return false; 4957 } 4958 4959 return readMet && writeMet; 4960 } 4961 4962 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4963 int modeFlags) { 4964 // Root gets to do everything. 4965 if (uid == 0) { 4966 return true; 4967 } 4968 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4969 if (perms == null) return false; 4970 UriPermission perm = perms.get(uri); 4971 if (perm == null) return false; 4972 return (modeFlags&perm.modeFlags) == modeFlags; 4973 } 4974 4975 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4976 enforceNotIsolatedCaller("checkUriPermission"); 4977 4978 // Another redirected-binder-call permissions check as in 4979 // {@link checkComponentPermission}. 4980 Identity tlsIdentity = sCallerIdentity.get(); 4981 if (tlsIdentity != null) { 4982 uid = tlsIdentity.uid; 4983 pid = tlsIdentity.pid; 4984 } 4985 4986 uid = UserHandle.getAppId(uid); 4987 // Our own process gets to do everything. 4988 if (pid == MY_PID) { 4989 return PackageManager.PERMISSION_GRANTED; 4990 } 4991 synchronized(this) { 4992 return checkUriPermissionLocked(uri, uid, modeFlags) 4993 ? PackageManager.PERMISSION_GRANTED 4994 : PackageManager.PERMISSION_DENIED; 4995 } 4996 } 4997 4998 /** 4999 * Check if the targetPkg can be granted permission to access uri by 5000 * the callingUid using the given modeFlags. Throws a security exception 5001 * if callingUid is not allowed to do this. Returns the uid of the target 5002 * if the URI permission grant should be performed; returns -1 if it is not 5003 * needed (for example targetPkg already has permission to access the URI). 5004 * If you already know the uid of the target, you can supply it in 5005 * lastTargetUid else set that to -1. 5006 */ 5007 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5008 Uri uri, int modeFlags, int lastTargetUid) { 5009 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5010 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5011 if (modeFlags == 0) { 5012 return -1; 5013 } 5014 5015 if (targetPkg != null) { 5016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5017 "Checking grant " + targetPkg + " permission to " + uri); 5018 } 5019 5020 final IPackageManager pm = AppGlobals.getPackageManager(); 5021 5022 // If this is not a content: uri, we can't do anything with it. 5023 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5025 "Can't grant URI permission for non-content URI: " + uri); 5026 return -1; 5027 } 5028 5029 String name = uri.getAuthority(); 5030 ProviderInfo pi = null; 5031 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5032 UserHandle.getUserId(callingUid)); 5033 if (cpr != null) { 5034 pi = cpr.info; 5035 } else { 5036 try { 5037 pi = pm.resolveContentProvider(name, 5038 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 5039 } catch (RemoteException ex) { 5040 } 5041 } 5042 if (pi == null) { 5043 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5044 return -1; 5045 } 5046 5047 int targetUid = lastTargetUid; 5048 if (targetUid < 0 && targetPkg != null) { 5049 try { 5050 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5051 if (targetUid < 0) { 5052 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5053 "Can't grant URI permission no uid for: " + targetPkg); 5054 return -1; 5055 } 5056 } catch (RemoteException ex) { 5057 return -1; 5058 } 5059 } 5060 5061 if (targetUid >= 0) { 5062 // First... does the target actually need this permission? 5063 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5064 // No need to grant the target this permission. 5065 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5066 "Target " + targetPkg + " already has full permission to " + uri); 5067 return -1; 5068 } 5069 } else { 5070 // First... there is no target package, so can anyone access it? 5071 boolean allowed = pi.exported; 5072 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5073 if (pi.readPermission != null) { 5074 allowed = false; 5075 } 5076 } 5077 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5078 if (pi.writePermission != null) { 5079 allowed = false; 5080 } 5081 } 5082 if (allowed) { 5083 return -1; 5084 } 5085 } 5086 5087 // Second... is the provider allowing granting of URI permissions? 5088 if (!pi.grantUriPermissions) { 5089 throw new SecurityException("Provider " + pi.packageName 5090 + "/" + pi.name 5091 + " does not allow granting of Uri permissions (uri " 5092 + uri + ")"); 5093 } 5094 if (pi.uriPermissionPatterns != null) { 5095 final int N = pi.uriPermissionPatterns.length; 5096 boolean allowed = false; 5097 for (int i=0; i<N; i++) { 5098 if (pi.uriPermissionPatterns[i] != null 5099 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5100 allowed = true; 5101 break; 5102 } 5103 } 5104 if (!allowed) { 5105 throw new SecurityException("Provider " + pi.packageName 5106 + "/" + pi.name 5107 + " does not allow granting of permission to path of Uri " 5108 + uri); 5109 } 5110 } 5111 5112 // Third... does the caller itself have permission to access 5113 // this uri? 5114 if (callingUid != Process.myUid()) { 5115 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5116 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5117 throw new SecurityException("Uid " + callingUid 5118 + " does not have permission to uri " + uri); 5119 } 5120 } 5121 } 5122 5123 return targetUid; 5124 } 5125 5126 public int checkGrantUriPermission(int callingUid, String targetPkg, 5127 Uri uri, int modeFlags) { 5128 enforceNotIsolatedCaller("checkGrantUriPermission"); 5129 synchronized(this) { 5130 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5131 } 5132 } 5133 5134 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5135 Uri uri, int modeFlags, UriPermissionOwner owner) { 5136 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5137 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5138 if (modeFlags == 0) { 5139 return; 5140 } 5141 5142 // So here we are: the caller has the assumed permission 5143 // to the uri, and the target doesn't. Let's now give this to 5144 // the target. 5145 5146 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5147 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5148 5149 HashMap<Uri, UriPermission> targetUris 5150 = mGrantedUriPermissions.get(targetUid); 5151 if (targetUris == null) { 5152 targetUris = new HashMap<Uri, UriPermission>(); 5153 mGrantedUriPermissions.put(targetUid, targetUris); 5154 } 5155 5156 UriPermission perm = targetUris.get(uri); 5157 if (perm == null) { 5158 perm = new UriPermission(targetUid, uri); 5159 targetUris.put(uri, perm); 5160 } 5161 5162 perm.modeFlags |= modeFlags; 5163 if (owner == null) { 5164 perm.globalModeFlags |= modeFlags; 5165 } else { 5166 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5167 perm.readOwners.add(owner); 5168 owner.addReadPermission(perm); 5169 } 5170 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5171 perm.writeOwners.add(owner); 5172 owner.addWritePermission(perm); 5173 } 5174 } 5175 } 5176 5177 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5178 int modeFlags, UriPermissionOwner owner) { 5179 if (targetPkg == null) { 5180 throw new NullPointerException("targetPkg"); 5181 } 5182 5183 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5184 if (targetUid < 0) { 5185 return; 5186 } 5187 5188 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5189 } 5190 5191 static class NeededUriGrants extends ArrayList<Uri> { 5192 final String targetPkg; 5193 final int targetUid; 5194 final int flags; 5195 5196 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5197 targetPkg = _targetPkg; 5198 targetUid = _targetUid; 5199 flags = _flags; 5200 } 5201 } 5202 5203 /** 5204 * Like checkGrantUriPermissionLocked, but takes an Intent. 5205 */ 5206 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5207 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5208 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5209 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5210 + " clip=" + (intent != null ? intent.getClipData() : null) 5211 + " from " + intent + "; flags=0x" 5212 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5213 5214 if (targetPkg == null) { 5215 throw new NullPointerException("targetPkg"); 5216 } 5217 5218 if (intent == null) { 5219 return null; 5220 } 5221 Uri data = intent.getData(); 5222 ClipData clip = intent.getClipData(); 5223 if (data == null && clip == null) { 5224 return null; 5225 } 5226 if (data != null) { 5227 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5228 mode, needed != null ? needed.targetUid : -1); 5229 if (target > 0) { 5230 if (needed == null) { 5231 needed = new NeededUriGrants(targetPkg, target, mode); 5232 } 5233 needed.add(data); 5234 } 5235 } 5236 if (clip != null) { 5237 for (int i=0; i<clip.getItemCount(); i++) { 5238 Uri uri = clip.getItemAt(i).getUri(); 5239 if (uri != null) { 5240 int target = -1; 5241 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5242 mode, needed != null ? needed.targetUid : -1); 5243 if (target > 0) { 5244 if (needed == null) { 5245 needed = new NeededUriGrants(targetPkg, target, mode); 5246 } 5247 needed.add(uri); 5248 } 5249 } else { 5250 Intent clipIntent = clip.getItemAt(i).getIntent(); 5251 if (clipIntent != null) { 5252 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5253 callingUid, targetPkg, clipIntent, mode, needed); 5254 if (newNeeded != null) { 5255 needed = newNeeded; 5256 } 5257 } 5258 } 5259 } 5260 } 5261 5262 return needed; 5263 } 5264 5265 /** 5266 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5267 */ 5268 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5269 UriPermissionOwner owner) { 5270 if (needed != null) { 5271 for (int i=0; i<needed.size(); i++) { 5272 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5273 needed.get(i), needed.flags, owner); 5274 } 5275 } 5276 } 5277 5278 void grantUriPermissionFromIntentLocked(int callingUid, 5279 String targetPkg, Intent intent, UriPermissionOwner owner) { 5280 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5281 intent, intent != null ? intent.getFlags() : 0, null); 5282 if (needed == null) { 5283 return; 5284 } 5285 5286 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5287 } 5288 5289 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5290 Uri uri, int modeFlags) { 5291 enforceNotIsolatedCaller("grantUriPermission"); 5292 synchronized(this) { 5293 final ProcessRecord r = getRecordForAppLocked(caller); 5294 if (r == null) { 5295 throw new SecurityException("Unable to find app for caller " 5296 + caller 5297 + " when granting permission to uri " + uri); 5298 } 5299 if (targetPkg == null) { 5300 throw new IllegalArgumentException("null target"); 5301 } 5302 if (uri == null) { 5303 throw new IllegalArgumentException("null uri"); 5304 } 5305 5306 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5307 null); 5308 } 5309 } 5310 5311 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5312 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5313 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5314 HashMap<Uri, UriPermission> perms 5315 = mGrantedUriPermissions.get(perm.uid); 5316 if (perms != null) { 5317 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5318 "Removing " + perm.uid + " permission to " + perm.uri); 5319 perms.remove(perm.uri); 5320 if (perms.size() == 0) { 5321 mGrantedUriPermissions.remove(perm.uid); 5322 } 5323 } 5324 } 5325 } 5326 5327 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5328 int modeFlags) { 5329 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5330 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5331 if (modeFlags == 0) { 5332 return; 5333 } 5334 5335 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5336 "Revoking all granted permissions to " + uri); 5337 5338 final IPackageManager pm = AppGlobals.getPackageManager(); 5339 5340 final String authority = uri.getAuthority(); 5341 ProviderInfo pi = null; 5342 int userId = UserHandle.getUserId(callingUid); 5343 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5344 if (cpr != null) { 5345 pi = cpr.info; 5346 } else { 5347 try { 5348 pi = pm.resolveContentProvider(authority, 5349 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5350 } catch (RemoteException ex) { 5351 } 5352 } 5353 if (pi == null) { 5354 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5355 return; 5356 } 5357 5358 // Does the caller have this permission on the URI? 5359 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5360 // Right now, if you are not the original owner of the permission, 5361 // you are not allowed to revoke it. 5362 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5363 throw new SecurityException("Uid " + callingUid 5364 + " does not have permission to uri " + uri); 5365 //} 5366 } 5367 5368 // Go through all of the permissions and remove any that match. 5369 final List<String> SEGMENTS = uri.getPathSegments(); 5370 if (SEGMENTS != null) { 5371 final int NS = SEGMENTS.size(); 5372 int N = mGrantedUriPermissions.size(); 5373 for (int i=0; i<N; i++) { 5374 HashMap<Uri, UriPermission> perms 5375 = mGrantedUriPermissions.valueAt(i); 5376 Iterator<UriPermission> it = perms.values().iterator(); 5377 toploop: 5378 while (it.hasNext()) { 5379 UriPermission perm = it.next(); 5380 Uri targetUri = perm.uri; 5381 if (!authority.equals(targetUri.getAuthority())) { 5382 continue; 5383 } 5384 List<String> targetSegments = targetUri.getPathSegments(); 5385 if (targetSegments == null) { 5386 continue; 5387 } 5388 if (targetSegments.size() < NS) { 5389 continue; 5390 } 5391 for (int j=0; j<NS; j++) { 5392 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5393 continue toploop; 5394 } 5395 } 5396 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5397 "Revoking " + perm.uid + " permission to " + perm.uri); 5398 perm.clearModes(modeFlags); 5399 if (perm.modeFlags == 0) { 5400 it.remove(); 5401 } 5402 } 5403 if (perms.size() == 0) { 5404 mGrantedUriPermissions.remove( 5405 mGrantedUriPermissions.keyAt(i)); 5406 N--; 5407 i--; 5408 } 5409 } 5410 } 5411 } 5412 5413 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5414 int modeFlags) { 5415 enforceNotIsolatedCaller("revokeUriPermission"); 5416 synchronized(this) { 5417 final ProcessRecord r = getRecordForAppLocked(caller); 5418 if (r == null) { 5419 throw new SecurityException("Unable to find app for caller " 5420 + caller 5421 + " when revoking permission to uri " + uri); 5422 } 5423 if (uri == null) { 5424 Slog.w(TAG, "revokeUriPermission: null uri"); 5425 return; 5426 } 5427 5428 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5429 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5430 if (modeFlags == 0) { 5431 return; 5432 } 5433 5434 final IPackageManager pm = AppGlobals.getPackageManager(); 5435 5436 final String authority = uri.getAuthority(); 5437 ProviderInfo pi = null; 5438 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5439 if (cpr != null) { 5440 pi = cpr.info; 5441 } else { 5442 try { 5443 pi = pm.resolveContentProvider(authority, 5444 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5445 } catch (RemoteException ex) { 5446 } 5447 } 5448 if (pi == null) { 5449 Slog.w(TAG, "No content provider found for permission revoke: " 5450 + uri.toSafeString()); 5451 return; 5452 } 5453 5454 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5455 } 5456 } 5457 5458 @Override 5459 public IBinder newUriPermissionOwner(String name) { 5460 enforceNotIsolatedCaller("newUriPermissionOwner"); 5461 synchronized(this) { 5462 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5463 return owner.getExternalTokenLocked(); 5464 } 5465 } 5466 5467 @Override 5468 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5469 Uri uri, int modeFlags) { 5470 synchronized(this) { 5471 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5472 if (owner == null) { 5473 throw new IllegalArgumentException("Unknown owner: " + token); 5474 } 5475 if (fromUid != Binder.getCallingUid()) { 5476 if (Binder.getCallingUid() != Process.myUid()) { 5477 // Only system code can grant URI permissions on behalf 5478 // of other users. 5479 throw new SecurityException("nice try"); 5480 } 5481 } 5482 if (targetPkg == null) { 5483 throw new IllegalArgumentException("null target"); 5484 } 5485 if (uri == null) { 5486 throw new IllegalArgumentException("null uri"); 5487 } 5488 5489 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5490 } 5491 } 5492 5493 @Override 5494 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5495 synchronized(this) { 5496 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5497 if (owner == null) { 5498 throw new IllegalArgumentException("Unknown owner: " + token); 5499 } 5500 5501 if (uri == null) { 5502 owner.removeUriPermissionsLocked(mode); 5503 } else { 5504 owner.removeUriPermissionLocked(uri, mode); 5505 } 5506 } 5507 } 5508 5509 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5510 synchronized (this) { 5511 ProcessRecord app = 5512 who != null ? getRecordForAppLocked(who) : null; 5513 if (app == null) return; 5514 5515 Message msg = Message.obtain(); 5516 msg.what = WAIT_FOR_DEBUGGER_MSG; 5517 msg.obj = app; 5518 msg.arg1 = waiting ? 1 : 0; 5519 mHandler.sendMessage(msg); 5520 } 5521 } 5522 5523 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5524 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5525 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5526 outInfo.availMem = Process.getFreeMemory(); 5527 outInfo.totalMem = Process.getTotalMemory(); 5528 outInfo.threshold = homeAppMem; 5529 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5530 outInfo.hiddenAppThreshold = hiddenAppMem; 5531 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5532 ProcessList.SERVICE_ADJ); 5533 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5534 ProcessList.VISIBLE_APP_ADJ); 5535 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5536 ProcessList.FOREGROUND_APP_ADJ); 5537 } 5538 5539 // ========================================================= 5540 // TASK MANAGEMENT 5541 // ========================================================= 5542 5543 public List getTasks(int maxNum, int flags, 5544 IThumbnailReceiver receiver) { 5545 ArrayList list = new ArrayList(); 5546 5547 PendingThumbnailsRecord pending = null; 5548 IApplicationThread topThumbnail = null; 5549 ActivityRecord topRecord = null; 5550 5551 synchronized(this) { 5552 if (localLOGV) Slog.v( 5553 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5554 + ", receiver=" + receiver); 5555 5556 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5557 != PackageManager.PERMISSION_GRANTED) { 5558 if (receiver != null) { 5559 // If the caller wants to wait for pending thumbnails, 5560 // it ain't gonna get them. 5561 try { 5562 receiver.finished(); 5563 } catch (RemoteException ex) { 5564 } 5565 } 5566 String msg = "Permission Denial: getTasks() from pid=" 5567 + Binder.getCallingPid() 5568 + ", uid=" + Binder.getCallingUid() 5569 + " requires " + android.Manifest.permission.GET_TASKS; 5570 Slog.w(TAG, msg); 5571 throw new SecurityException(msg); 5572 } 5573 5574 int pos = mMainStack.mHistory.size()-1; 5575 ActivityRecord next = 5576 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5577 ActivityRecord top = null; 5578 TaskRecord curTask = null; 5579 int numActivities = 0; 5580 int numRunning = 0; 5581 while (pos >= 0 && maxNum > 0) { 5582 final ActivityRecord r = next; 5583 pos--; 5584 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5585 5586 // Initialize state for next task if needed. 5587 if (top == null || 5588 (top.state == ActivityState.INITIALIZING 5589 && top.task == r.task)) { 5590 top = r; 5591 curTask = r.task; 5592 numActivities = numRunning = 0; 5593 } 5594 5595 // Add 'r' into the current task. 5596 numActivities++; 5597 if (r.app != null && r.app.thread != null) { 5598 numRunning++; 5599 } 5600 5601 if (localLOGV) Slog.v( 5602 TAG, r.intent.getComponent().flattenToShortString() 5603 + ": task=" + r.task); 5604 5605 // If the next one is a different task, generate a new 5606 // TaskInfo entry for what we have. 5607 if (next == null || next.task != curTask) { 5608 ActivityManager.RunningTaskInfo ci 5609 = new ActivityManager.RunningTaskInfo(); 5610 ci.id = curTask.taskId; 5611 ci.baseActivity = r.intent.getComponent(); 5612 ci.topActivity = top.intent.getComponent(); 5613 if (top.thumbHolder != null) { 5614 ci.description = top.thumbHolder.lastDescription; 5615 } 5616 ci.numActivities = numActivities; 5617 ci.numRunning = numRunning; 5618 //System.out.println( 5619 // "#" + maxNum + ": " + " descr=" + ci.description); 5620 if (ci.thumbnail == null && receiver != null) { 5621 if (localLOGV) Slog.v( 5622 TAG, "State=" + top.state + "Idle=" + top.idle 5623 + " app=" + top.app 5624 + " thr=" + (top.app != null ? top.app.thread : null)); 5625 if (top.state == ActivityState.RESUMED 5626 || top.state == ActivityState.PAUSING) { 5627 if (top.idle && top.app != null 5628 && top.app.thread != null) { 5629 topRecord = top; 5630 topThumbnail = top.app.thread; 5631 } else { 5632 top.thumbnailNeeded = true; 5633 } 5634 } 5635 if (pending == null) { 5636 pending = new PendingThumbnailsRecord(receiver); 5637 } 5638 pending.pendingRecords.add(top); 5639 } 5640 list.add(ci); 5641 maxNum--; 5642 top = null; 5643 } 5644 } 5645 5646 if (pending != null) { 5647 mPendingThumbnails.add(pending); 5648 } 5649 } 5650 5651 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5652 5653 if (topThumbnail != null) { 5654 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5655 try { 5656 topThumbnail.requestThumbnail(topRecord.appToken); 5657 } catch (Exception e) { 5658 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5659 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5660 } 5661 } 5662 5663 if (pending == null && receiver != null) { 5664 // In this case all thumbnails were available and the client 5665 // is being asked to be told when the remaining ones come in... 5666 // which is unusually, since the top-most currently running 5667 // activity should never have a canned thumbnail! Oh well. 5668 try { 5669 receiver.finished(); 5670 } catch (RemoteException ex) { 5671 } 5672 } 5673 5674 return list; 5675 } 5676 5677 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5678 int flags, int userId) { 5679 final int callingUid = Binder.getCallingUid(); 5680 if (userId != UserHandle.getCallingUserId()) { 5681 // Check if the caller is holding permissions for cross-user requests. 5682 if (checkComponentPermission( 5683 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5684 Binder.getCallingPid(), callingUid, -1, true) 5685 != PackageManager.PERMISSION_GRANTED) { 5686 String msg = "Permission Denial: " 5687 + "Request to get recent tasks for user " + userId 5688 + " but is calling from user " + UserHandle.getUserId(callingUid) 5689 + "; this requires " 5690 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5691 Slog.w(TAG, msg); 5692 throw new SecurityException(msg); 5693 } else { 5694 if (userId == UserHandle.USER_CURRENT) { 5695 userId = mCurrentUserId; 5696 } 5697 } 5698 } 5699 5700 synchronized (this) { 5701 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5702 "getRecentTasks()"); 5703 final boolean detailed = checkCallingPermission( 5704 android.Manifest.permission.GET_DETAILED_TASKS) 5705 == PackageManager.PERMISSION_GRANTED; 5706 5707 IPackageManager pm = AppGlobals.getPackageManager(); 5708 5709 final int N = mRecentTasks.size(); 5710 ArrayList<ActivityManager.RecentTaskInfo> res 5711 = new ArrayList<ActivityManager.RecentTaskInfo>( 5712 maxNum < N ? maxNum : N); 5713 for (int i=0; i<N && maxNum > 0; i++) { 5714 TaskRecord tr = mRecentTasks.get(i); 5715 // Only add calling user's recent tasks 5716 if (tr.userId != userId) continue; 5717 // Return the entry if desired by the caller. We always return 5718 // the first entry, because callers always expect this to be the 5719 // foreground app. We may filter others if the caller has 5720 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5721 // we should exclude the entry. 5722 5723 if (i == 0 5724 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5725 || (tr.intent == null) 5726 || ((tr.intent.getFlags() 5727 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5728 ActivityManager.RecentTaskInfo rti 5729 = new ActivityManager.RecentTaskInfo(); 5730 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5731 rti.persistentId = tr.taskId; 5732 rti.baseIntent = new Intent( 5733 tr.intent != null ? tr.intent : tr.affinityIntent); 5734 if (!detailed) { 5735 rti.baseIntent.replaceExtras((Bundle)null); 5736 } 5737 rti.origActivity = tr.origActivity; 5738 rti.description = tr.lastDescription; 5739 5740 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5741 // Check whether this activity is currently available. 5742 try { 5743 if (rti.origActivity != null) { 5744 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5745 == null) { 5746 continue; 5747 } 5748 } else if (rti.baseIntent != null) { 5749 if (pm.queryIntentActivities(rti.baseIntent, 5750 null, 0, userId) == null) { 5751 continue; 5752 } 5753 } 5754 } catch (RemoteException e) { 5755 // Will never happen. 5756 } 5757 } 5758 5759 res.add(rti); 5760 maxNum--; 5761 } 5762 } 5763 return res; 5764 } 5765 } 5766 5767 private TaskRecord taskForIdLocked(int id) { 5768 final int N = mRecentTasks.size(); 5769 for (int i=0; i<N; i++) { 5770 TaskRecord tr = mRecentTasks.get(i); 5771 if (tr.taskId == id) { 5772 return tr; 5773 } 5774 } 5775 return null; 5776 } 5777 5778 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5779 synchronized (this) { 5780 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5781 "getTaskThumbnails()"); 5782 TaskRecord tr = taskForIdLocked(id); 5783 if (tr != null) { 5784 return mMainStack.getTaskThumbnailsLocked(tr); 5785 } 5786 } 5787 return null; 5788 } 5789 5790 public boolean removeSubTask(int taskId, int subTaskIndex) { 5791 synchronized (this) { 5792 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5793 "removeSubTask()"); 5794 long ident = Binder.clearCallingIdentity(); 5795 try { 5796 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5797 true) != null; 5798 } finally { 5799 Binder.restoreCallingIdentity(ident); 5800 } 5801 } 5802 } 5803 5804 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5805 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5806 Intent baseIntent = new Intent( 5807 tr.intent != null ? tr.intent : tr.affinityIntent); 5808 ComponentName component = baseIntent.getComponent(); 5809 if (component == null) { 5810 Slog.w(TAG, "Now component for base intent of task: " + tr); 5811 return; 5812 } 5813 5814 // Find any running services associated with this app. 5815 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5816 5817 if (killProcesses) { 5818 // Find any running processes associated with this app. 5819 final String pkg = component.getPackageName(); 5820 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5821 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5822 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5823 for (int i=0; i<uids.size(); i++) { 5824 ProcessRecord proc = uids.valueAt(i); 5825 if (proc.userId != tr.userId) { 5826 continue; 5827 } 5828 if (!proc.pkgList.contains(pkg)) { 5829 continue; 5830 } 5831 procs.add(proc); 5832 } 5833 } 5834 5835 // Kill the running processes. 5836 for (int i=0; i<procs.size(); i++) { 5837 ProcessRecord pr = procs.get(i); 5838 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5839 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5840 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5841 pr.processName, pr.setAdj, "remove task"); 5842 pr.killedBackground = true; 5843 Process.killProcessQuiet(pr.pid); 5844 } else { 5845 pr.waitingToKill = "remove task"; 5846 } 5847 } 5848 } 5849 } 5850 5851 public boolean removeTask(int taskId, int flags) { 5852 synchronized (this) { 5853 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5854 "removeTask()"); 5855 long ident = Binder.clearCallingIdentity(); 5856 try { 5857 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5858 false); 5859 if (r != null) { 5860 mRecentTasks.remove(r.task); 5861 cleanUpRemovedTaskLocked(r.task, flags); 5862 return true; 5863 } else { 5864 TaskRecord tr = null; 5865 int i=0; 5866 while (i < mRecentTasks.size()) { 5867 TaskRecord t = mRecentTasks.get(i); 5868 if (t.taskId == taskId) { 5869 tr = t; 5870 break; 5871 } 5872 i++; 5873 } 5874 if (tr != null) { 5875 if (tr.numActivities <= 0) { 5876 // Caller is just removing a recent task that is 5877 // not actively running. That is easy! 5878 mRecentTasks.remove(i); 5879 cleanUpRemovedTaskLocked(tr, flags); 5880 return true; 5881 } else { 5882 Slog.w(TAG, "removeTask: task " + taskId 5883 + " does not have activities to remove, " 5884 + " but numActivities=" + tr.numActivities 5885 + ": " + tr); 5886 } 5887 } 5888 } 5889 } finally { 5890 Binder.restoreCallingIdentity(ident); 5891 } 5892 } 5893 return false; 5894 } 5895 5896 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5897 int j; 5898 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5899 TaskRecord jt = startTask; 5900 5901 // First look backwards 5902 for (j=startIndex-1; j>=0; j--) { 5903 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5904 if (r.task != jt) { 5905 jt = r.task; 5906 if (affinity.equals(jt.affinity)) { 5907 return j; 5908 } 5909 } 5910 } 5911 5912 // Now look forwards 5913 final int N = mMainStack.mHistory.size(); 5914 jt = startTask; 5915 for (j=startIndex+1; j<N; j++) { 5916 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5917 if (r.task != jt) { 5918 if (affinity.equals(jt.affinity)) { 5919 return j; 5920 } 5921 jt = r.task; 5922 } 5923 } 5924 5925 // Might it be at the top? 5926 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5927 return N-1; 5928 } 5929 5930 return -1; 5931 } 5932 5933 /** 5934 * TODO: Add mController hook 5935 */ 5936 public void moveTaskToFront(int task, int flags, Bundle options) { 5937 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5938 "moveTaskToFront()"); 5939 5940 synchronized(this) { 5941 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5942 Binder.getCallingUid(), "Task to front")) { 5943 ActivityOptions.abort(options); 5944 return; 5945 } 5946 final long origId = Binder.clearCallingIdentity(); 5947 try { 5948 TaskRecord tr = taskForIdLocked(task); 5949 if (tr != null) { 5950 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5951 mMainStack.mUserLeaving = true; 5952 } 5953 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5954 // Caller wants the home activity moved with it. To accomplish this, 5955 // we'll just move the home task to the top first. 5956 mMainStack.moveHomeToFrontLocked(); 5957 } 5958 mMainStack.moveTaskToFrontLocked(tr, null, options); 5959 return; 5960 } 5961 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5962 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5963 if (hr.task.taskId == task) { 5964 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5965 mMainStack.mUserLeaving = true; 5966 } 5967 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5968 // Caller wants the home activity moved with it. To accomplish this, 5969 // we'll just move the home task to the top first. 5970 mMainStack.moveHomeToFrontLocked(); 5971 } 5972 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5973 return; 5974 } 5975 } 5976 } finally { 5977 Binder.restoreCallingIdentity(origId); 5978 } 5979 ActivityOptions.abort(options); 5980 } 5981 } 5982 5983 public void moveTaskToBack(int task) { 5984 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5985 "moveTaskToBack()"); 5986 5987 synchronized(this) { 5988 if (mMainStack.mResumedActivity != null 5989 && mMainStack.mResumedActivity.task.taskId == task) { 5990 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5991 Binder.getCallingUid(), "Task to back")) { 5992 return; 5993 } 5994 } 5995 final long origId = Binder.clearCallingIdentity(); 5996 mMainStack.moveTaskToBackLocked(task, null); 5997 Binder.restoreCallingIdentity(origId); 5998 } 5999 } 6000 6001 /** 6002 * Moves an activity, and all of the other activities within the same task, to the bottom 6003 * of the history stack. The activity's order within the task is unchanged. 6004 * 6005 * @param token A reference to the activity we wish to move 6006 * @param nonRoot If false then this only works if the activity is the root 6007 * of a task; if true it will work for any activity in a task. 6008 * @return Returns true if the move completed, false if not. 6009 */ 6010 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6011 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6012 synchronized(this) { 6013 final long origId = Binder.clearCallingIdentity(); 6014 int taskId = getTaskForActivityLocked(token, !nonRoot); 6015 if (taskId >= 0) { 6016 return mMainStack.moveTaskToBackLocked(taskId, null); 6017 } 6018 Binder.restoreCallingIdentity(origId); 6019 } 6020 return false; 6021 } 6022 6023 public void moveTaskBackwards(int task) { 6024 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6025 "moveTaskBackwards()"); 6026 6027 synchronized(this) { 6028 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6029 Binder.getCallingUid(), "Task backwards")) { 6030 return; 6031 } 6032 final long origId = Binder.clearCallingIdentity(); 6033 moveTaskBackwardsLocked(task); 6034 Binder.restoreCallingIdentity(origId); 6035 } 6036 } 6037 6038 private final void moveTaskBackwardsLocked(int task) { 6039 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6040 } 6041 6042 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6043 synchronized(this) { 6044 return getTaskForActivityLocked(token, onlyRoot); 6045 } 6046 } 6047 6048 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6049 final int N = mMainStack.mHistory.size(); 6050 TaskRecord lastTask = null; 6051 for (int i=0; i<N; i++) { 6052 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6053 if (r.appToken == token) { 6054 if (!onlyRoot || lastTask != r.task) { 6055 return r.task.taskId; 6056 } 6057 return -1; 6058 } 6059 lastTask = r.task; 6060 } 6061 6062 return -1; 6063 } 6064 6065 // ========================================================= 6066 // THUMBNAILS 6067 // ========================================================= 6068 6069 public void reportThumbnail(IBinder token, 6070 Bitmap thumbnail, CharSequence description) { 6071 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6072 final long origId = Binder.clearCallingIdentity(); 6073 sendPendingThumbnail(null, token, thumbnail, description, true); 6074 Binder.restoreCallingIdentity(origId); 6075 } 6076 6077 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6078 Bitmap thumbnail, CharSequence description, boolean always) { 6079 TaskRecord task = null; 6080 ArrayList receivers = null; 6081 6082 //System.out.println("Send pending thumbnail: " + r); 6083 6084 synchronized(this) { 6085 if (r == null) { 6086 r = mMainStack.isInStackLocked(token); 6087 if (r == null) { 6088 return; 6089 } 6090 } 6091 if (thumbnail == null && r.thumbHolder != null) { 6092 thumbnail = r.thumbHolder.lastThumbnail; 6093 description = r.thumbHolder.lastDescription; 6094 } 6095 if (thumbnail == null && !always) { 6096 // If there is no thumbnail, and this entry is not actually 6097 // going away, then abort for now and pick up the next 6098 // thumbnail we get. 6099 return; 6100 } 6101 task = r.task; 6102 6103 int N = mPendingThumbnails.size(); 6104 int i=0; 6105 while (i<N) { 6106 PendingThumbnailsRecord pr = 6107 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6108 //System.out.println("Looking in " + pr.pendingRecords); 6109 if (pr.pendingRecords.remove(r)) { 6110 if (receivers == null) { 6111 receivers = new ArrayList(); 6112 } 6113 receivers.add(pr); 6114 if (pr.pendingRecords.size() == 0) { 6115 pr.finished = true; 6116 mPendingThumbnails.remove(i); 6117 N--; 6118 continue; 6119 } 6120 } 6121 i++; 6122 } 6123 } 6124 6125 if (receivers != null) { 6126 final int N = receivers.size(); 6127 for (int i=0; i<N; i++) { 6128 try { 6129 PendingThumbnailsRecord pr = 6130 (PendingThumbnailsRecord)receivers.get(i); 6131 pr.receiver.newThumbnail( 6132 task != null ? task.taskId : -1, thumbnail, description); 6133 if (pr.finished) { 6134 pr.receiver.finished(); 6135 } 6136 } catch (Exception e) { 6137 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6138 } 6139 } 6140 } 6141 } 6142 6143 // ========================================================= 6144 // CONTENT PROVIDERS 6145 // ========================================================= 6146 6147 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6148 List<ProviderInfo> providers = null; 6149 try { 6150 providers = AppGlobals.getPackageManager(). 6151 queryContentProviders(app.processName, app.uid, 6152 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6153 } catch (RemoteException ex) { 6154 } 6155 if (DEBUG_MU) 6156 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6157 int userId = app.userId; 6158 if (providers != null) { 6159 int N = providers.size(); 6160 for (int i=0; i<N; i++) { 6161 ProviderInfo cpi = 6162 (ProviderInfo)providers.get(i); 6163 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6164 cpi.name, cpi.flags); 6165 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6166 // This is a singleton provider, but a user besides the 6167 // default user is asking to initialize a process it runs 6168 // in... well, no, it doesn't actually run in this process, 6169 // it runs in the process of the default user. Get rid of it. 6170 providers.remove(i); 6171 N--; 6172 continue; 6173 } 6174 6175 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6176 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6177 if (cpr == null) { 6178 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6179 mProviderMap.putProviderByClass(comp, cpr); 6180 } 6181 if (DEBUG_MU) 6182 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6183 app.pubProviders.put(cpi.name, cpr); 6184 app.addPackage(cpi.applicationInfo.packageName); 6185 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6186 } 6187 } 6188 return providers; 6189 } 6190 6191 /** 6192 * Check if {@link ProcessRecord} has a possible chance at accessing the 6193 * given {@link ProviderInfo}. Final permission checking is always done 6194 * in {@link ContentProvider}. 6195 */ 6196 private final String checkContentProviderPermissionLocked( 6197 ProviderInfo cpi, ProcessRecord r) { 6198 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6199 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6200 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6201 cpi.applicationInfo.uid, cpi.exported) 6202 == PackageManager.PERMISSION_GRANTED) { 6203 return null; 6204 } 6205 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6206 cpi.applicationInfo.uid, cpi.exported) 6207 == PackageManager.PERMISSION_GRANTED) { 6208 return null; 6209 } 6210 6211 PathPermission[] pps = cpi.pathPermissions; 6212 if (pps != null) { 6213 int i = pps.length; 6214 while (i > 0) { 6215 i--; 6216 PathPermission pp = pps[i]; 6217 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6218 cpi.applicationInfo.uid, cpi.exported) 6219 == PackageManager.PERMISSION_GRANTED) { 6220 return null; 6221 } 6222 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6223 cpi.applicationInfo.uid, cpi.exported) 6224 == PackageManager.PERMISSION_GRANTED) { 6225 return null; 6226 } 6227 } 6228 } 6229 6230 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6231 if (perms != null) { 6232 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6233 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6234 return null; 6235 } 6236 } 6237 } 6238 6239 String msg; 6240 if (!cpi.exported) { 6241 msg = "Permission Denial: opening provider " + cpi.name 6242 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6243 + ", uid=" + callingUid + ") that is not exported from uid " 6244 + cpi.applicationInfo.uid; 6245 } else { 6246 msg = "Permission Denial: opening provider " + cpi.name 6247 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6248 + ", uid=" + callingUid + ") requires " 6249 + cpi.readPermission + " or " + cpi.writePermission; 6250 } 6251 Slog.w(TAG, msg); 6252 return msg; 6253 } 6254 6255 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6256 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6257 if (r != null) { 6258 for (int i=0; i<r.conProviders.size(); i++) { 6259 ContentProviderConnection conn = r.conProviders.get(i); 6260 if (conn.provider == cpr) { 6261 if (DEBUG_PROVIDER) Slog.v(TAG, 6262 "Adding provider requested by " 6263 + r.processName + " from process " 6264 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6265 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6266 if (stable) { 6267 conn.stableCount++; 6268 conn.numStableIncs++; 6269 } else { 6270 conn.unstableCount++; 6271 conn.numUnstableIncs++; 6272 } 6273 return conn; 6274 } 6275 } 6276 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6277 if (stable) { 6278 conn.stableCount = 1; 6279 conn.numStableIncs = 1; 6280 } else { 6281 conn.unstableCount = 1; 6282 conn.numUnstableIncs = 1; 6283 } 6284 cpr.connections.add(conn); 6285 r.conProviders.add(conn); 6286 return conn; 6287 } 6288 cpr.addExternalProcessHandleLocked(externalProcessToken); 6289 return null; 6290 } 6291 6292 boolean decProviderCountLocked(ContentProviderConnection conn, 6293 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6294 if (conn != null) { 6295 cpr = conn.provider; 6296 if (DEBUG_PROVIDER) Slog.v(TAG, 6297 "Removing provider requested by " 6298 + conn.client.processName + " from process " 6299 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6300 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6301 if (stable) { 6302 conn.stableCount--; 6303 } else { 6304 conn.unstableCount--; 6305 } 6306 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6307 cpr.connections.remove(conn); 6308 conn.client.conProviders.remove(conn); 6309 return true; 6310 } 6311 return false; 6312 } 6313 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6314 return false; 6315 } 6316 6317 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6318 String name, IBinder token, boolean stable, int userId) { 6319 ContentProviderRecord cpr; 6320 ContentProviderConnection conn = null; 6321 ProviderInfo cpi = null; 6322 6323 synchronized(this) { 6324 ProcessRecord r = null; 6325 if (caller != null) { 6326 r = getRecordForAppLocked(caller); 6327 if (r == null) { 6328 throw new SecurityException( 6329 "Unable to find app for caller " + caller 6330 + " (pid=" + Binder.getCallingPid() 6331 + ") when getting content provider " + name); 6332 } 6333 if (r.userId != userId) { 6334 throw new SecurityException("Calling requested user " + userId 6335 + " but app is user " + r.userId); 6336 } 6337 } 6338 6339 // First check if this content provider has been published... 6340 cpr = mProviderMap.getProviderByName(name, userId); 6341 boolean providerRunning = cpr != null; 6342 if (providerRunning) { 6343 cpi = cpr.info; 6344 String msg; 6345 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6346 throw new SecurityException(msg); 6347 } 6348 6349 if (r != null && cpr.canRunHere(r)) { 6350 // This provider has been published or is in the process 6351 // of being published... but it is also allowed to run 6352 // in the caller's process, so don't make a connection 6353 // and just let the caller instantiate its own instance. 6354 ContentProviderHolder holder = cpr.newHolder(null); 6355 // don't give caller the provider object, it needs 6356 // to make its own. 6357 holder.provider = null; 6358 return holder; 6359 } 6360 6361 final long origId = Binder.clearCallingIdentity(); 6362 6363 // In this case the provider instance already exists, so we can 6364 // return it right away. 6365 conn = incProviderCountLocked(r, cpr, token, stable); 6366 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6367 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6368 // If this is a perceptible app accessing the provider, 6369 // make sure to count it as being accessed and thus 6370 // back up on the LRU list. This is good because 6371 // content providers are often expensive to start. 6372 updateLruProcessLocked(cpr.proc, false, true); 6373 } 6374 } 6375 6376 if (cpr.proc != null) { 6377 if (false) { 6378 if (cpr.name.flattenToShortString().equals( 6379 "com.android.providers.calendar/.CalendarProvider2")) { 6380 Slog.v(TAG, "****************** KILLING " 6381 + cpr.name.flattenToShortString()); 6382 Process.killProcess(cpr.proc.pid); 6383 } 6384 } 6385 boolean success = updateOomAdjLocked(cpr.proc); 6386 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6387 // NOTE: there is still a race here where a signal could be 6388 // pending on the process even though we managed to update its 6389 // adj level. Not sure what to do about this, but at least 6390 // the race is now smaller. 6391 if (!success) { 6392 // Uh oh... it looks like the provider's process 6393 // has been killed on us. We need to wait for a new 6394 // process to be started, and make sure its death 6395 // doesn't kill our process. 6396 Slog.i(TAG, 6397 "Existing provider " + cpr.name.flattenToShortString() 6398 + " is crashing; detaching " + r); 6399 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6400 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6401 if (!lastRef) { 6402 // This wasn't the last ref our process had on 6403 // the provider... we have now been killed, bail. 6404 return null; 6405 } 6406 providerRunning = false; 6407 conn = null; 6408 } 6409 } 6410 6411 Binder.restoreCallingIdentity(origId); 6412 } 6413 6414 boolean singleton; 6415 if (!providerRunning) { 6416 try { 6417 cpi = AppGlobals.getPackageManager(). 6418 resolveContentProvider(name, 6419 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6420 } catch (RemoteException ex) { 6421 } 6422 if (cpi == null) { 6423 return null; 6424 } 6425 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6426 cpi.name, cpi.flags); 6427 if (singleton) { 6428 userId = 0; 6429 } 6430 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6431 6432 String msg; 6433 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6434 throw new SecurityException(msg); 6435 } 6436 6437 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6438 && !cpi.processName.equals("system")) { 6439 // If this content provider does not run in the system 6440 // process, and the system is not yet ready to run other 6441 // processes, then fail fast instead of hanging. 6442 throw new IllegalArgumentException( 6443 "Attempt to launch content provider before system ready"); 6444 } 6445 6446 // Make sure that the user who owns this provider is started. If not, 6447 // we don't want to allow it to run. 6448 if (mStartedUsers.get(userId) == null) { 6449 Slog.w(TAG, "Unable to launch app " 6450 + cpi.applicationInfo.packageName + "/" 6451 + cpi.applicationInfo.uid + " for provider " 6452 + name + ": user " + userId + " is stopped"); 6453 return null; 6454 } 6455 6456 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6457 cpr = mProviderMap.getProviderByClass(comp, userId); 6458 final boolean firstClass = cpr == null; 6459 if (firstClass) { 6460 try { 6461 ApplicationInfo ai = 6462 AppGlobals.getPackageManager(). 6463 getApplicationInfo( 6464 cpi.applicationInfo.packageName, 6465 STOCK_PM_FLAGS, userId); 6466 if (ai == null) { 6467 Slog.w(TAG, "No package info for content provider " 6468 + cpi.name); 6469 return null; 6470 } 6471 ai = getAppInfoForUser(ai, userId); 6472 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6473 } catch (RemoteException ex) { 6474 // pm is in same process, this will never happen. 6475 } 6476 } 6477 6478 if (r != null && cpr.canRunHere(r)) { 6479 // If this is a multiprocess provider, then just return its 6480 // info and allow the caller to instantiate it. Only do 6481 // this if the provider is the same user as the caller's 6482 // process, or can run as root (so can be in any process). 6483 return cpr.newHolder(null); 6484 } 6485 6486 if (DEBUG_PROVIDER) { 6487 RuntimeException e = new RuntimeException("here"); 6488 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6489 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6490 } 6491 6492 // This is single process, and our app is now connecting to it. 6493 // See if we are already in the process of launching this 6494 // provider. 6495 final int N = mLaunchingProviders.size(); 6496 int i; 6497 for (i=0; i<N; i++) { 6498 if (mLaunchingProviders.get(i) == cpr) { 6499 break; 6500 } 6501 } 6502 6503 // If the provider is not already being launched, then get it 6504 // started. 6505 if (i >= N) { 6506 final long origId = Binder.clearCallingIdentity(); 6507 6508 try { 6509 // Content provider is now in use, its package can't be stopped. 6510 try { 6511 AppGlobals.getPackageManager().setPackageStoppedState( 6512 cpr.appInfo.packageName, false, userId); 6513 } catch (RemoteException e) { 6514 } catch (IllegalArgumentException e) { 6515 Slog.w(TAG, "Failed trying to unstop package " 6516 + cpr.appInfo.packageName + ": " + e); 6517 } 6518 6519 ProcessRecord proc = startProcessLocked(cpi.processName, 6520 cpr.appInfo, false, 0, "content provider", 6521 new ComponentName(cpi.applicationInfo.packageName, 6522 cpi.name), false, false); 6523 if (proc == null) { 6524 Slog.w(TAG, "Unable to launch app " 6525 + cpi.applicationInfo.packageName + "/" 6526 + cpi.applicationInfo.uid + " for provider " 6527 + name + ": process is bad"); 6528 return null; 6529 } 6530 cpr.launchingApp = proc; 6531 mLaunchingProviders.add(cpr); 6532 } finally { 6533 Binder.restoreCallingIdentity(origId); 6534 } 6535 } 6536 6537 // Make sure the provider is published (the same provider class 6538 // may be published under multiple names). 6539 if (firstClass) { 6540 mProviderMap.putProviderByClass(comp, cpr); 6541 } 6542 6543 mProviderMap.putProviderByName(name, cpr); 6544 conn = incProviderCountLocked(r, cpr, token, stable); 6545 if (conn != null) { 6546 conn.waiting = true; 6547 } 6548 } 6549 } 6550 6551 // Wait for the provider to be published... 6552 synchronized (cpr) { 6553 while (cpr.provider == null) { 6554 if (cpr.launchingApp == null) { 6555 Slog.w(TAG, "Unable to launch app " 6556 + cpi.applicationInfo.packageName + "/" 6557 + cpi.applicationInfo.uid + " for provider " 6558 + name + ": launching app became null"); 6559 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6560 cpi.applicationInfo.packageName, 6561 cpi.applicationInfo.uid, name); 6562 return null; 6563 } 6564 try { 6565 if (DEBUG_MU) { 6566 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6567 + cpr.launchingApp); 6568 } 6569 if (conn != null) { 6570 conn.waiting = true; 6571 } 6572 cpr.wait(); 6573 } catch (InterruptedException ex) { 6574 } finally { 6575 if (conn != null) { 6576 conn.waiting = false; 6577 } 6578 } 6579 } 6580 } 6581 return cpr != null ? cpr.newHolder(conn) : null; 6582 } 6583 6584 public final ContentProviderHolder getContentProvider( 6585 IApplicationThread caller, String name, boolean stable) { 6586 enforceNotIsolatedCaller("getContentProvider"); 6587 if (caller == null) { 6588 String msg = "null IApplicationThread when getting content provider " 6589 + name; 6590 Slog.w(TAG, msg); 6591 throw new SecurityException(msg); 6592 } 6593 6594 return getContentProviderImpl(caller, name, null, stable, 6595 UserHandle.getCallingUserId()); 6596 } 6597 6598 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6599 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6600 "Do not have permission in call getContentProviderExternal()"); 6601 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6602 } 6603 6604 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6605 IBinder token, int userId) { 6606 return getContentProviderImpl(null, name, token, true, userId); 6607 } 6608 6609 /** 6610 * Drop a content provider from a ProcessRecord's bookkeeping 6611 * @param cpr 6612 */ 6613 public void removeContentProvider(IBinder connection, boolean stable) { 6614 enforceNotIsolatedCaller("removeContentProvider"); 6615 synchronized (this) { 6616 ContentProviderConnection conn; 6617 try { 6618 conn = (ContentProviderConnection)connection; 6619 } catch (ClassCastException e) { 6620 String msg ="removeContentProvider: " + connection 6621 + " not a ContentProviderConnection"; 6622 Slog.w(TAG, msg); 6623 throw new IllegalArgumentException(msg); 6624 } 6625 if (conn == null) { 6626 throw new NullPointerException("connection is null"); 6627 } 6628 if (decProviderCountLocked(conn, null, null, stable)) { 6629 updateOomAdjLocked(); 6630 } 6631 } 6632 } 6633 6634 public void removeContentProviderExternal(String name, IBinder token) { 6635 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6636 "Do not have permission in call removeContentProviderExternal()"); 6637 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6638 } 6639 6640 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6641 synchronized (this) { 6642 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6643 if(cpr == null) { 6644 //remove from mProvidersByClass 6645 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6646 return; 6647 } 6648 6649 //update content provider record entry info 6650 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6651 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6652 if (localCpr.hasExternalProcessHandles()) { 6653 if (localCpr.removeExternalProcessHandleLocked(token)) { 6654 updateOomAdjLocked(); 6655 } else { 6656 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6657 + " with no external reference for token: " 6658 + token + "."); 6659 } 6660 } else { 6661 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6662 + " with no external references."); 6663 } 6664 } 6665 } 6666 6667 public final void publishContentProviders(IApplicationThread caller, 6668 List<ContentProviderHolder> providers) { 6669 if (providers == null) { 6670 return; 6671 } 6672 6673 enforceNotIsolatedCaller("publishContentProviders"); 6674 synchronized (this) { 6675 final ProcessRecord r = getRecordForAppLocked(caller); 6676 if (DEBUG_MU) 6677 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6678 if (r == null) { 6679 throw new SecurityException( 6680 "Unable to find app for caller " + caller 6681 + " (pid=" + Binder.getCallingPid() 6682 + ") when publishing content providers"); 6683 } 6684 6685 final long origId = Binder.clearCallingIdentity(); 6686 6687 final int N = providers.size(); 6688 for (int i=0; i<N; i++) { 6689 ContentProviderHolder src = providers.get(i); 6690 if (src == null || src.info == null || src.provider == null) { 6691 continue; 6692 } 6693 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6694 if (DEBUG_MU) 6695 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6696 if (dst != null) { 6697 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6698 mProviderMap.putProviderByClass(comp, dst); 6699 String names[] = dst.info.authority.split(";"); 6700 for (int j = 0; j < names.length; j++) { 6701 mProviderMap.putProviderByName(names[j], dst); 6702 } 6703 6704 int NL = mLaunchingProviders.size(); 6705 int j; 6706 for (j=0; j<NL; j++) { 6707 if (mLaunchingProviders.get(j) == dst) { 6708 mLaunchingProviders.remove(j); 6709 j--; 6710 NL--; 6711 } 6712 } 6713 synchronized (dst) { 6714 dst.provider = src.provider; 6715 dst.proc = r; 6716 dst.notifyAll(); 6717 } 6718 updateOomAdjLocked(r); 6719 } 6720 } 6721 6722 Binder.restoreCallingIdentity(origId); 6723 } 6724 } 6725 6726 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6727 ContentProviderConnection conn; 6728 try { 6729 conn = (ContentProviderConnection)connection; 6730 } catch (ClassCastException e) { 6731 String msg ="refContentProvider: " + connection 6732 + " not a ContentProviderConnection"; 6733 Slog.w(TAG, msg); 6734 throw new IllegalArgumentException(msg); 6735 } 6736 if (conn == null) { 6737 throw new NullPointerException("connection is null"); 6738 } 6739 6740 synchronized (this) { 6741 if (stable > 0) { 6742 conn.numStableIncs += stable; 6743 } 6744 stable = conn.stableCount + stable; 6745 if (stable < 0) { 6746 throw new IllegalStateException("stableCount < 0: " + stable); 6747 } 6748 6749 if (unstable > 0) { 6750 conn.numUnstableIncs += unstable; 6751 } 6752 unstable = conn.unstableCount + unstable; 6753 if (unstable < 0) { 6754 throw new IllegalStateException("unstableCount < 0: " + unstable); 6755 } 6756 6757 if ((stable+unstable) <= 0) { 6758 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6759 + stable + " unstable=" + unstable); 6760 } 6761 conn.stableCount = stable; 6762 conn.unstableCount = unstable; 6763 return !conn.dead; 6764 } 6765 } 6766 6767 public void unstableProviderDied(IBinder connection) { 6768 ContentProviderConnection conn; 6769 try { 6770 conn = (ContentProviderConnection)connection; 6771 } catch (ClassCastException e) { 6772 String msg ="refContentProvider: " + connection 6773 + " not a ContentProviderConnection"; 6774 Slog.w(TAG, msg); 6775 throw new IllegalArgumentException(msg); 6776 } 6777 if (conn == null) { 6778 throw new NullPointerException("connection is null"); 6779 } 6780 6781 // Safely retrieve the content provider associated with the connection. 6782 IContentProvider provider; 6783 synchronized (this) { 6784 provider = conn.provider.provider; 6785 } 6786 6787 if (provider == null) { 6788 // Um, yeah, we're way ahead of you. 6789 return; 6790 } 6791 6792 // Make sure the caller is being honest with us. 6793 if (provider.asBinder().pingBinder()) { 6794 // Er, no, still looks good to us. 6795 synchronized (this) { 6796 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6797 + " says " + conn + " died, but we don't agree"); 6798 return; 6799 } 6800 } 6801 6802 // Well look at that! It's dead! 6803 synchronized (this) { 6804 if (conn.provider.provider != provider) { 6805 // But something changed... good enough. 6806 return; 6807 } 6808 6809 ProcessRecord proc = conn.provider.proc; 6810 if (proc == null || proc.thread == null) { 6811 // Seems like the process is already cleaned up. 6812 return; 6813 } 6814 6815 // As far as we're concerned, this is just like receiving a 6816 // death notification... just a bit prematurely. 6817 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6818 + ") early provider death"); 6819 final long ident = Binder.clearCallingIdentity(); 6820 try { 6821 appDiedLocked(proc, proc.pid, proc.thread); 6822 } finally { 6823 Binder.restoreCallingIdentity(ident); 6824 } 6825 } 6826 } 6827 6828 public static final void installSystemProviders() { 6829 List<ProviderInfo> providers; 6830 synchronized (mSelf) { 6831 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6832 providers = mSelf.generateApplicationProvidersLocked(app); 6833 if (providers != null) { 6834 for (int i=providers.size()-1; i>=0; i--) { 6835 ProviderInfo pi = (ProviderInfo)providers.get(i); 6836 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6837 Slog.w(TAG, "Not installing system proc provider " + pi.name 6838 + ": not system .apk"); 6839 providers.remove(i); 6840 } 6841 } 6842 } 6843 } 6844 if (providers != null) { 6845 mSystemThread.installSystemProviders(providers); 6846 } 6847 6848 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6849 6850 mSelf.mUsageStatsService.monitorPackages(); 6851 } 6852 6853 /** 6854 * Allows app to retrieve the MIME type of a URI without having permission 6855 * to access its content provider. 6856 * 6857 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6858 * 6859 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6860 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6861 */ 6862 public String getProviderMimeType(Uri uri, int userId) { 6863 enforceNotIsolatedCaller("getProviderMimeType"); 6864 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6865 userId, false, true, "getProviderMimeType", null); 6866 final String name = uri.getAuthority(); 6867 final long ident = Binder.clearCallingIdentity(); 6868 ContentProviderHolder holder = null; 6869 6870 try { 6871 holder = getContentProviderExternalUnchecked(name, null, userId); 6872 if (holder != null) { 6873 return holder.provider.getType(uri); 6874 } 6875 } catch (RemoteException e) { 6876 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6877 return null; 6878 } finally { 6879 if (holder != null) { 6880 removeContentProviderExternalUnchecked(name, null, userId); 6881 } 6882 Binder.restoreCallingIdentity(ident); 6883 } 6884 6885 return null; 6886 } 6887 6888 // ========================================================= 6889 // GLOBAL MANAGEMENT 6890 // ========================================================= 6891 6892 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6893 ApplicationInfo info, String customProcess, boolean isolated) { 6894 String proc = customProcess != null ? customProcess : info.processName; 6895 BatteryStatsImpl.Uid.Proc ps = null; 6896 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6897 int uid = info.uid; 6898 if (isolated) { 6899 int userId = UserHandle.getUserId(uid); 6900 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6901 uid = 0; 6902 while (true) { 6903 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6904 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6905 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6906 } 6907 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6908 mNextIsolatedProcessUid++; 6909 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6910 // No process for this uid, use it. 6911 break; 6912 } 6913 stepsLeft--; 6914 if (stepsLeft <= 0) { 6915 return null; 6916 } 6917 } 6918 } 6919 synchronized (stats) { 6920 ps = stats.getProcessStatsLocked(info.uid, proc); 6921 } 6922 return new ProcessRecord(ps, thread, info, proc, uid); 6923 } 6924 6925 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6926 ProcessRecord app; 6927 if (!isolated) { 6928 app = getProcessRecordLocked(info.processName, info.uid); 6929 } else { 6930 app = null; 6931 } 6932 6933 if (app == null) { 6934 app = newProcessRecordLocked(null, info, null, isolated); 6935 mProcessNames.put(info.processName, app.uid, app); 6936 if (isolated) { 6937 mIsolatedProcesses.put(app.uid, app); 6938 } 6939 updateLruProcessLocked(app, true, true); 6940 } 6941 6942 // This package really, really can not be stopped. 6943 try { 6944 AppGlobals.getPackageManager().setPackageStoppedState( 6945 info.packageName, false, UserHandle.getUserId(app.uid)); 6946 } catch (RemoteException e) { 6947 } catch (IllegalArgumentException e) { 6948 Slog.w(TAG, "Failed trying to unstop package " 6949 + info.packageName + ": " + e); 6950 } 6951 6952 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6953 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6954 app.persistent = true; 6955 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6956 } 6957 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6958 mPersistentStartingProcesses.add(app); 6959 startProcessLocked(app, "added application", app.processName); 6960 } 6961 6962 return app; 6963 } 6964 6965 public void unhandledBack() { 6966 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6967 "unhandledBack()"); 6968 6969 synchronized(this) { 6970 int count = mMainStack.mHistory.size(); 6971 if (DEBUG_SWITCH) Slog.d( 6972 TAG, "Performing unhandledBack(): stack size = " + count); 6973 if (count > 1) { 6974 final long origId = Binder.clearCallingIdentity(); 6975 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6976 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 6977 Binder.restoreCallingIdentity(origId); 6978 } 6979 } 6980 } 6981 6982 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6983 enforceNotIsolatedCaller("openContentUri"); 6984 final int userId = UserHandle.getCallingUserId(); 6985 String name = uri.getAuthority(); 6986 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 6987 ParcelFileDescriptor pfd = null; 6988 if (cph != null) { 6989 // We record the binder invoker's uid in thread-local storage before 6990 // going to the content provider to open the file. Later, in the code 6991 // that handles all permissions checks, we look for this uid and use 6992 // that rather than the Activity Manager's own uid. The effect is that 6993 // we do the check against the caller's permissions even though it looks 6994 // to the content provider like the Activity Manager itself is making 6995 // the request. 6996 sCallerIdentity.set(new Identity( 6997 Binder.getCallingPid(), Binder.getCallingUid())); 6998 try { 6999 pfd = cph.provider.openFile(uri, "r"); 7000 } catch (FileNotFoundException e) { 7001 // do nothing; pfd will be returned null 7002 } finally { 7003 // Ensure that whatever happens, we clean up the identity state 7004 sCallerIdentity.remove(); 7005 } 7006 7007 // We've got the fd now, so we're done with the provider. 7008 removeContentProviderExternalUnchecked(name, null, userId); 7009 } else { 7010 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7011 } 7012 return pfd; 7013 } 7014 7015 // Actually is sleeping or shutting down or whatever else in the future 7016 // is an inactive state. 7017 public boolean isSleeping() { 7018 return mSleeping || mShuttingDown; 7019 } 7020 7021 public void goingToSleep() { 7022 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7023 != PackageManager.PERMISSION_GRANTED) { 7024 throw new SecurityException("Requires permission " 7025 + android.Manifest.permission.DEVICE_POWER); 7026 } 7027 7028 synchronized(this) { 7029 mWentToSleep = true; 7030 updateEventDispatchingLocked(); 7031 7032 if (!mSleeping) { 7033 mSleeping = true; 7034 mMainStack.stopIfSleepingLocked(); 7035 7036 // Initialize the wake times of all processes. 7037 checkExcessivePowerUsageLocked(false); 7038 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7039 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7040 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7041 } 7042 } 7043 } 7044 7045 public boolean shutdown(int timeout) { 7046 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7047 != PackageManager.PERMISSION_GRANTED) { 7048 throw new SecurityException("Requires permission " 7049 + android.Manifest.permission.SHUTDOWN); 7050 } 7051 7052 boolean timedout = false; 7053 7054 synchronized(this) { 7055 mShuttingDown = true; 7056 updateEventDispatchingLocked(); 7057 7058 if (mMainStack.mResumedActivity != null) { 7059 mMainStack.stopIfSleepingLocked(); 7060 final long endTime = System.currentTimeMillis() + timeout; 7061 while (mMainStack.mResumedActivity != null 7062 || mMainStack.mPausingActivity != null) { 7063 long delay = endTime - System.currentTimeMillis(); 7064 if (delay <= 0) { 7065 Slog.w(TAG, "Activity manager shutdown timed out"); 7066 timedout = true; 7067 break; 7068 } 7069 try { 7070 this.wait(); 7071 } catch (InterruptedException e) { 7072 } 7073 } 7074 } 7075 } 7076 7077 mUsageStatsService.shutdown(); 7078 mBatteryStatsService.shutdown(); 7079 7080 return timedout; 7081 } 7082 7083 public final void activitySlept(IBinder token) { 7084 if (localLOGV) Slog.v( 7085 TAG, "Activity slept: token=" + token); 7086 7087 ActivityRecord r = null; 7088 7089 final long origId = Binder.clearCallingIdentity(); 7090 7091 synchronized (this) { 7092 r = mMainStack.isInStackLocked(token); 7093 if (r != null) { 7094 mMainStack.activitySleptLocked(r); 7095 } 7096 } 7097 7098 Binder.restoreCallingIdentity(origId); 7099 } 7100 7101 private void comeOutOfSleepIfNeededLocked() { 7102 if (!mWentToSleep && !mLockScreenShown) { 7103 if (mSleeping) { 7104 mSleeping = false; 7105 mMainStack.awakeFromSleepingLocked(); 7106 mMainStack.resumeTopActivityLocked(null); 7107 } 7108 } 7109 } 7110 7111 public void wakingUp() { 7112 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7113 != PackageManager.PERMISSION_GRANTED) { 7114 throw new SecurityException("Requires permission " 7115 + android.Manifest.permission.DEVICE_POWER); 7116 } 7117 7118 synchronized(this) { 7119 mWentToSleep = false; 7120 updateEventDispatchingLocked(); 7121 comeOutOfSleepIfNeededLocked(); 7122 } 7123 } 7124 7125 private void updateEventDispatchingLocked() { 7126 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7127 } 7128 7129 public void setLockScreenShown(boolean shown) { 7130 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7131 != PackageManager.PERMISSION_GRANTED) { 7132 throw new SecurityException("Requires permission " 7133 + android.Manifest.permission.DEVICE_POWER); 7134 } 7135 7136 synchronized(this) { 7137 mLockScreenShown = shown; 7138 comeOutOfSleepIfNeededLocked(); 7139 } 7140 } 7141 7142 public void stopAppSwitches() { 7143 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7144 != PackageManager.PERMISSION_GRANTED) { 7145 throw new SecurityException("Requires permission " 7146 + android.Manifest.permission.STOP_APP_SWITCHES); 7147 } 7148 7149 synchronized(this) { 7150 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7151 + APP_SWITCH_DELAY_TIME; 7152 mDidAppSwitch = false; 7153 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7154 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7155 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7156 } 7157 } 7158 7159 public void resumeAppSwitches() { 7160 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7161 != PackageManager.PERMISSION_GRANTED) { 7162 throw new SecurityException("Requires permission " 7163 + android.Manifest.permission.STOP_APP_SWITCHES); 7164 } 7165 7166 synchronized(this) { 7167 // Note that we don't execute any pending app switches... we will 7168 // let those wait until either the timeout, or the next start 7169 // activity request. 7170 mAppSwitchesAllowedTime = 0; 7171 } 7172 } 7173 7174 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7175 String name) { 7176 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7177 return true; 7178 } 7179 7180 final int perm = checkComponentPermission( 7181 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7182 callingUid, -1, true); 7183 if (perm == PackageManager.PERMISSION_GRANTED) { 7184 return true; 7185 } 7186 7187 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7188 return false; 7189 } 7190 7191 public void setDebugApp(String packageName, boolean waitForDebugger, 7192 boolean persistent) { 7193 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7194 "setDebugApp()"); 7195 7196 // Note that this is not really thread safe if there are multiple 7197 // callers into it at the same time, but that's not a situation we 7198 // care about. 7199 if (persistent) { 7200 final ContentResolver resolver = mContext.getContentResolver(); 7201 Settings.System.putString( 7202 resolver, Settings.System.DEBUG_APP, 7203 packageName); 7204 Settings.System.putInt( 7205 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7206 waitForDebugger ? 1 : 0); 7207 } 7208 7209 synchronized (this) { 7210 if (!persistent) { 7211 mOrigDebugApp = mDebugApp; 7212 mOrigWaitForDebugger = mWaitForDebugger; 7213 } 7214 mDebugApp = packageName; 7215 mWaitForDebugger = waitForDebugger; 7216 mDebugTransient = !persistent; 7217 if (packageName != null) { 7218 final long origId = Binder.clearCallingIdentity(); 7219 forceStopPackageLocked(packageName, -1, false, false, true, true, 7220 UserHandle.USER_ALL); 7221 Binder.restoreCallingIdentity(origId); 7222 } 7223 } 7224 } 7225 7226 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7227 synchronized (this) { 7228 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7229 if (!isDebuggable) { 7230 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7231 throw new SecurityException("Process not debuggable: " + app.packageName); 7232 } 7233 } 7234 7235 mOpenGlTraceApp = processName; 7236 } 7237 } 7238 7239 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7240 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7241 synchronized (this) { 7242 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7243 if (!isDebuggable) { 7244 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7245 throw new SecurityException("Process not debuggable: " + app.packageName); 7246 } 7247 } 7248 mProfileApp = processName; 7249 mProfileFile = profileFile; 7250 if (mProfileFd != null) { 7251 try { 7252 mProfileFd.close(); 7253 } catch (IOException e) { 7254 } 7255 mProfileFd = null; 7256 } 7257 mProfileFd = profileFd; 7258 mProfileType = 0; 7259 mAutoStopProfiler = autoStopProfiler; 7260 } 7261 } 7262 7263 public void setAlwaysFinish(boolean enabled) { 7264 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7265 "setAlwaysFinish()"); 7266 7267 Settings.System.putInt( 7268 mContext.getContentResolver(), 7269 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7270 7271 synchronized (this) { 7272 mAlwaysFinishActivities = enabled; 7273 } 7274 } 7275 7276 public void setActivityController(IActivityController controller) { 7277 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7278 "setActivityController()"); 7279 synchronized (this) { 7280 mController = controller; 7281 } 7282 } 7283 7284 public boolean isUserAMonkey() { 7285 // For now the fact that there is a controller implies 7286 // we have a monkey. 7287 synchronized (this) { 7288 return mController != null; 7289 } 7290 } 7291 7292 public void registerProcessObserver(IProcessObserver observer) { 7293 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7294 "registerProcessObserver()"); 7295 synchronized (this) { 7296 mProcessObservers.register(observer); 7297 } 7298 } 7299 7300 public void unregisterProcessObserver(IProcessObserver observer) { 7301 synchronized (this) { 7302 mProcessObservers.unregister(observer); 7303 } 7304 } 7305 7306 public void setImmersive(IBinder token, boolean immersive) { 7307 synchronized(this) { 7308 ActivityRecord r = mMainStack.isInStackLocked(token); 7309 if (r == null) { 7310 throw new IllegalArgumentException(); 7311 } 7312 r.immersive = immersive; 7313 } 7314 } 7315 7316 public boolean isImmersive(IBinder token) { 7317 synchronized (this) { 7318 ActivityRecord r = mMainStack.isInStackLocked(token); 7319 if (r == null) { 7320 throw new IllegalArgumentException(); 7321 } 7322 return r.immersive; 7323 } 7324 } 7325 7326 public boolean isTopActivityImmersive() { 7327 enforceNotIsolatedCaller("startActivity"); 7328 synchronized (this) { 7329 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7330 return (r != null) ? r.immersive : false; 7331 } 7332 } 7333 7334 public final void enterSafeMode() { 7335 synchronized(this) { 7336 // It only makes sense to do this before the system is ready 7337 // and started launching other packages. 7338 if (!mSystemReady) { 7339 try { 7340 AppGlobals.getPackageManager().enterSafeMode(); 7341 } catch (RemoteException e) { 7342 } 7343 } 7344 } 7345 } 7346 7347 public final void showSafeModeOverlay() { 7348 View v = LayoutInflater.from(mContext).inflate( 7349 com.android.internal.R.layout.safe_mode, null); 7350 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7351 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7352 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7353 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7354 lp.gravity = Gravity.BOTTOM | Gravity.START; 7355 lp.format = v.getBackground().getOpacity(); 7356 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7357 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7358 ((WindowManager)mContext.getSystemService( 7359 Context.WINDOW_SERVICE)).addView(v, lp); 7360 } 7361 7362 public void noteWakeupAlarm(IIntentSender sender) { 7363 if (!(sender instanceof PendingIntentRecord)) { 7364 return; 7365 } 7366 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7367 synchronized (stats) { 7368 if (mBatteryStatsService.isOnBattery()) { 7369 mBatteryStatsService.enforceCallingPermission(); 7370 PendingIntentRecord rec = (PendingIntentRecord)sender; 7371 int MY_UID = Binder.getCallingUid(); 7372 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7373 BatteryStatsImpl.Uid.Pkg pkg = 7374 stats.getPackageStatsLocked(uid, rec.key.packageName); 7375 pkg.incWakeupsLocked(); 7376 } 7377 } 7378 } 7379 7380 public boolean killPids(int[] pids, String pReason, boolean secure) { 7381 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7382 throw new SecurityException("killPids only available to the system"); 7383 } 7384 String reason = (pReason == null) ? "Unknown" : pReason; 7385 // XXX Note: don't acquire main activity lock here, because the window 7386 // manager calls in with its locks held. 7387 7388 boolean killed = false; 7389 synchronized (mPidsSelfLocked) { 7390 int[] types = new int[pids.length]; 7391 int worstType = 0; 7392 for (int i=0; i<pids.length; i++) { 7393 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7394 if (proc != null) { 7395 int type = proc.setAdj; 7396 types[i] = type; 7397 if (type > worstType) { 7398 worstType = type; 7399 } 7400 } 7401 } 7402 7403 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7404 // then constrain it so we will kill all hidden procs. 7405 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7406 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7407 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7408 } 7409 7410 // If this is not a secure call, don't let it kill processes that 7411 // are important. 7412 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7413 worstType = ProcessList.SERVICE_ADJ; 7414 } 7415 7416 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7417 for (int i=0; i<pids.length; i++) { 7418 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7419 if (proc == null) { 7420 continue; 7421 } 7422 int adj = proc.setAdj; 7423 if (adj >= worstType && !proc.killedBackground) { 7424 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7425 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7426 proc.processName, adj, reason); 7427 killed = true; 7428 proc.killedBackground = true; 7429 Process.killProcessQuiet(pids[i]); 7430 } 7431 } 7432 } 7433 return killed; 7434 } 7435 7436 @Override 7437 public boolean killProcessesBelowForeground(String reason) { 7438 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7439 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7440 } 7441 7442 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7443 } 7444 7445 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7446 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7447 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7448 } 7449 7450 boolean killed = false; 7451 synchronized (mPidsSelfLocked) { 7452 final int size = mPidsSelfLocked.size(); 7453 for (int i = 0; i < size; i++) { 7454 final int pid = mPidsSelfLocked.keyAt(i); 7455 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7456 if (proc == null) continue; 7457 7458 final int adj = proc.setAdj; 7459 if (adj > belowAdj && !proc.killedBackground) { 7460 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7461 EventLog.writeEvent( 7462 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7463 killed = true; 7464 proc.killedBackground = true; 7465 Process.killProcessQuiet(pid); 7466 } 7467 } 7468 } 7469 return killed; 7470 } 7471 7472 public final void startRunning(String pkg, String cls, String action, 7473 String data) { 7474 synchronized(this) { 7475 if (mStartRunning) { 7476 return; 7477 } 7478 mStartRunning = true; 7479 mTopComponent = pkg != null && cls != null 7480 ? new ComponentName(pkg, cls) : null; 7481 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7482 mTopData = data; 7483 if (!mSystemReady) { 7484 return; 7485 } 7486 } 7487 7488 systemReady(null); 7489 } 7490 7491 private void retrieveSettings() { 7492 final ContentResolver resolver = mContext.getContentResolver(); 7493 String debugApp = Settings.System.getString( 7494 resolver, Settings.System.DEBUG_APP); 7495 boolean waitForDebugger = Settings.System.getInt( 7496 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7497 boolean alwaysFinishActivities = Settings.System.getInt( 7498 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7499 7500 Configuration configuration = new Configuration(); 7501 Settings.System.getConfiguration(resolver, configuration); 7502 7503 synchronized (this) { 7504 mDebugApp = mOrigDebugApp = debugApp; 7505 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7506 mAlwaysFinishActivities = alwaysFinishActivities; 7507 // This happens before any activities are started, so we can 7508 // change mConfiguration in-place. 7509 updateConfigurationLocked(configuration, null, false, true); 7510 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7511 } 7512 } 7513 7514 public boolean testIsSystemReady() { 7515 // no need to synchronize(this) just to read & return the value 7516 return mSystemReady; 7517 } 7518 7519 private static File getCalledPreBootReceiversFile() { 7520 File dataDir = Environment.getDataDirectory(); 7521 File systemDir = new File(dataDir, "system"); 7522 File fname = new File(systemDir, "called_pre_boots.dat"); 7523 return fname; 7524 } 7525 7526 static final int LAST_DONE_VERSION = 10000; 7527 7528 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7529 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7530 File file = getCalledPreBootReceiversFile(); 7531 FileInputStream fis = null; 7532 try { 7533 fis = new FileInputStream(file); 7534 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7535 int fvers = dis.readInt(); 7536 if (fvers == LAST_DONE_VERSION) { 7537 String vers = dis.readUTF(); 7538 String codename = dis.readUTF(); 7539 String build = dis.readUTF(); 7540 if (android.os.Build.VERSION.RELEASE.equals(vers) 7541 && android.os.Build.VERSION.CODENAME.equals(codename) 7542 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7543 int num = dis.readInt(); 7544 while (num > 0) { 7545 num--; 7546 String pkg = dis.readUTF(); 7547 String cls = dis.readUTF(); 7548 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7549 } 7550 } 7551 } 7552 } catch (FileNotFoundException e) { 7553 } catch (IOException e) { 7554 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7555 } finally { 7556 if (fis != null) { 7557 try { 7558 fis.close(); 7559 } catch (IOException e) { 7560 } 7561 } 7562 } 7563 return lastDoneReceivers; 7564 } 7565 7566 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7567 File file = getCalledPreBootReceiversFile(); 7568 FileOutputStream fos = null; 7569 DataOutputStream dos = null; 7570 try { 7571 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7572 fos = new FileOutputStream(file); 7573 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7574 dos.writeInt(LAST_DONE_VERSION); 7575 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7576 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7577 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7578 dos.writeInt(list.size()); 7579 for (int i=0; i<list.size(); i++) { 7580 dos.writeUTF(list.get(i).getPackageName()); 7581 dos.writeUTF(list.get(i).getClassName()); 7582 } 7583 } catch (IOException e) { 7584 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7585 file.delete(); 7586 } finally { 7587 FileUtils.sync(fos); 7588 if (dos != null) { 7589 try { 7590 dos.close(); 7591 } catch (IOException e) { 7592 // TODO Auto-generated catch block 7593 e.printStackTrace(); 7594 } 7595 } 7596 } 7597 } 7598 7599 public void systemReady(final Runnable goingCallback) { 7600 synchronized(this) { 7601 if (mSystemReady) { 7602 if (goingCallback != null) goingCallback.run(); 7603 return; 7604 } 7605 7606 // Check to see if there are any update receivers to run. 7607 if (!mDidUpdate) { 7608 if (mWaitingUpdate) { 7609 return; 7610 } 7611 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7612 List<ResolveInfo> ris = null; 7613 try { 7614 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7615 intent, null, 0, 0); 7616 } catch (RemoteException e) { 7617 } 7618 if (ris != null) { 7619 for (int i=ris.size()-1; i>=0; i--) { 7620 if ((ris.get(i).activityInfo.applicationInfo.flags 7621 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7622 ris.remove(i); 7623 } 7624 } 7625 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7626 7627 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7628 7629 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7630 for (int i=0; i<ris.size(); i++) { 7631 ActivityInfo ai = ris.get(i).activityInfo; 7632 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7633 if (lastDoneReceivers.contains(comp)) { 7634 ris.remove(i); 7635 i--; 7636 } 7637 } 7638 7639 for (int i=0; i<ris.size(); i++) { 7640 ActivityInfo ai = ris.get(i).activityInfo; 7641 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7642 doneReceivers.add(comp); 7643 intent.setComponent(comp); 7644 IIntentReceiver finisher = null; 7645 if (i == ris.size()-1) { 7646 finisher = new IIntentReceiver.Stub() { 7647 public void performReceive(Intent intent, int resultCode, 7648 String data, Bundle extras, boolean ordered, 7649 boolean sticky, int sendingUser) { 7650 // The raw IIntentReceiver interface is called 7651 // with the AM lock held, so redispatch to 7652 // execute our code without the lock. 7653 mHandler.post(new Runnable() { 7654 public void run() { 7655 synchronized (ActivityManagerService.this) { 7656 mDidUpdate = true; 7657 } 7658 writeLastDonePreBootReceivers(doneReceivers); 7659 showBootMessage(mContext.getText( 7660 R.string.android_upgrading_complete), 7661 false); 7662 systemReady(goingCallback); 7663 } 7664 }); 7665 } 7666 }; 7667 } 7668 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7669 // XXX also need to send this to stopped users(!!!) 7670 broadcastIntentLocked(null, null, intent, null, finisher, 7671 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7672 UserHandle.USER_ALL); 7673 if (finisher != null) { 7674 mWaitingUpdate = true; 7675 } 7676 } 7677 } 7678 if (mWaitingUpdate) { 7679 return; 7680 } 7681 mDidUpdate = true; 7682 } 7683 7684 mSystemReady = true; 7685 if (!mStartRunning) { 7686 return; 7687 } 7688 } 7689 7690 ArrayList<ProcessRecord> procsToKill = null; 7691 synchronized(mPidsSelfLocked) { 7692 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7693 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7694 if (!isAllowedWhileBooting(proc.info)){ 7695 if (procsToKill == null) { 7696 procsToKill = new ArrayList<ProcessRecord>(); 7697 } 7698 procsToKill.add(proc); 7699 } 7700 } 7701 } 7702 7703 synchronized(this) { 7704 if (procsToKill != null) { 7705 for (int i=procsToKill.size()-1; i>=0; i--) { 7706 ProcessRecord proc = procsToKill.get(i); 7707 Slog.i(TAG, "Removing system update proc: " + proc); 7708 removeProcessLocked(proc, true, false, "system update done"); 7709 } 7710 } 7711 7712 // Now that we have cleaned up any update processes, we 7713 // are ready to start launching real processes and know that 7714 // we won't trample on them any more. 7715 mProcessesReady = true; 7716 } 7717 7718 Slog.i(TAG, "System now ready"); 7719 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7720 SystemClock.uptimeMillis()); 7721 7722 synchronized(this) { 7723 // Make sure we have no pre-ready processes sitting around. 7724 7725 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7726 ResolveInfo ri = mContext.getPackageManager() 7727 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7728 STOCK_PM_FLAGS); 7729 CharSequence errorMsg = null; 7730 if (ri != null) { 7731 ActivityInfo ai = ri.activityInfo; 7732 ApplicationInfo app = ai.applicationInfo; 7733 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7734 mTopAction = Intent.ACTION_FACTORY_TEST; 7735 mTopData = null; 7736 mTopComponent = new ComponentName(app.packageName, 7737 ai.name); 7738 } else { 7739 errorMsg = mContext.getResources().getText( 7740 com.android.internal.R.string.factorytest_not_system); 7741 } 7742 } else { 7743 errorMsg = mContext.getResources().getText( 7744 com.android.internal.R.string.factorytest_no_action); 7745 } 7746 if (errorMsg != null) { 7747 mTopAction = null; 7748 mTopData = null; 7749 mTopComponent = null; 7750 Message msg = Message.obtain(); 7751 msg.what = SHOW_FACTORY_ERROR_MSG; 7752 msg.getData().putCharSequence("msg", errorMsg); 7753 mHandler.sendMessage(msg); 7754 } 7755 } 7756 } 7757 7758 retrieveSettings(); 7759 7760 if (goingCallback != null) goingCallback.run(); 7761 7762 synchronized (this) { 7763 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7764 try { 7765 List apps = AppGlobals.getPackageManager(). 7766 getPersistentApplications(STOCK_PM_FLAGS); 7767 if (apps != null) { 7768 int N = apps.size(); 7769 int i; 7770 for (i=0; i<N; i++) { 7771 ApplicationInfo info 7772 = (ApplicationInfo)apps.get(i); 7773 if (info != null && 7774 !info.packageName.equals("android")) { 7775 addAppLocked(info, false); 7776 } 7777 } 7778 } 7779 } catch (RemoteException ex) { 7780 // pm is in same process, this will never happen. 7781 } 7782 } 7783 7784 // Start up initial activity. 7785 mBooting = true; 7786 7787 try { 7788 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7789 Message msg = Message.obtain(); 7790 msg.what = SHOW_UID_ERROR_MSG; 7791 mHandler.sendMessage(msg); 7792 } 7793 } catch (RemoteException e) { 7794 } 7795 7796 mMainStack.resumeTopActivityLocked(null); 7797 } 7798 } 7799 7800 private boolean makeAppCrashingLocked(ProcessRecord app, 7801 String shortMsg, String longMsg, String stackTrace) { 7802 app.crashing = true; 7803 app.crashingReport = generateProcessError(app, 7804 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7805 startAppProblemLocked(app); 7806 app.stopFreezingAllLocked(); 7807 return handleAppCrashLocked(app); 7808 } 7809 7810 private void makeAppNotRespondingLocked(ProcessRecord app, 7811 String activity, String shortMsg, String longMsg) { 7812 app.notResponding = true; 7813 app.notRespondingReport = generateProcessError(app, 7814 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7815 activity, shortMsg, longMsg, null); 7816 startAppProblemLocked(app); 7817 app.stopFreezingAllLocked(); 7818 } 7819 7820 /** 7821 * Generate a process error record, suitable for attachment to a ProcessRecord. 7822 * 7823 * @param app The ProcessRecord in which the error occurred. 7824 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7825 * ActivityManager.AppErrorStateInfo 7826 * @param activity The activity associated with the crash, if known. 7827 * @param shortMsg Short message describing the crash. 7828 * @param longMsg Long message describing the crash. 7829 * @param stackTrace Full crash stack trace, may be null. 7830 * 7831 * @return Returns a fully-formed AppErrorStateInfo record. 7832 */ 7833 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7834 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7835 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7836 7837 report.condition = condition; 7838 report.processName = app.processName; 7839 report.pid = app.pid; 7840 report.uid = app.info.uid; 7841 report.tag = activity; 7842 report.shortMsg = shortMsg; 7843 report.longMsg = longMsg; 7844 report.stackTrace = stackTrace; 7845 7846 return report; 7847 } 7848 7849 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7850 synchronized (this) { 7851 app.crashing = false; 7852 app.crashingReport = null; 7853 app.notResponding = false; 7854 app.notRespondingReport = null; 7855 if (app.anrDialog == fromDialog) { 7856 app.anrDialog = null; 7857 } 7858 if (app.waitDialog == fromDialog) { 7859 app.waitDialog = null; 7860 } 7861 if (app.pid > 0 && app.pid != MY_PID) { 7862 handleAppCrashLocked(app); 7863 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7864 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7865 app.processName, app.setAdj, "user's request after error"); 7866 Process.killProcessQuiet(app.pid); 7867 } 7868 } 7869 } 7870 7871 private boolean handleAppCrashLocked(ProcessRecord app) { 7872 if (mHeadless) { 7873 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7874 return false; 7875 } 7876 long now = SystemClock.uptimeMillis(); 7877 7878 Long crashTime; 7879 if (!app.isolated) { 7880 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7881 } else { 7882 crashTime = null; 7883 } 7884 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7885 // This process loses! 7886 Slog.w(TAG, "Process " + app.info.processName 7887 + " has crashed too many times: killing!"); 7888 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7889 app.info.processName, app.uid); 7890 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7891 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7892 if (r.app == app) { 7893 Slog.w(TAG, " Force finishing activity " 7894 + r.intent.getComponent().flattenToShortString()); 7895 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7896 null, "crashed", false); 7897 } 7898 } 7899 if (!app.persistent) { 7900 // We don't want to start this process again until the user 7901 // explicitly does so... but for persistent process, we really 7902 // need to keep it running. If a persistent process is actually 7903 // repeatedly crashing, then badness for everyone. 7904 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7905 app.info.processName); 7906 if (!app.isolated) { 7907 // XXX We don't have a way to mark isolated processes 7908 // as bad, since they don't have a peristent identity. 7909 mBadProcesses.put(app.info.processName, app.uid, now); 7910 mProcessCrashTimes.remove(app.info.processName, app.uid); 7911 } 7912 app.bad = true; 7913 app.removed = true; 7914 // Don't let services in this process be restarted and potentially 7915 // annoy the user repeatedly. Unless it is persistent, since those 7916 // processes run critical code. 7917 removeProcessLocked(app, false, false, "crash"); 7918 mMainStack.resumeTopActivityLocked(null); 7919 return false; 7920 } 7921 mMainStack.resumeTopActivityLocked(null); 7922 } else { 7923 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7924 if (r != null && r.app == app) { 7925 // If the top running activity is from this crashing 7926 // process, then terminate it to avoid getting in a loop. 7927 Slog.w(TAG, " Force finishing activity " 7928 + r.intent.getComponent().flattenToShortString()); 7929 int index = mMainStack.indexOfActivityLocked(r); 7930 r.stack.finishActivityLocked(r, index, 7931 Activity.RESULT_CANCELED, null, "crashed", false); 7932 // Also terminate any activities below it that aren't yet 7933 // stopped, to avoid a situation where one will get 7934 // re-start our crashing activity once it gets resumed again. 7935 index--; 7936 if (index >= 0) { 7937 r = (ActivityRecord)mMainStack.mHistory.get(index); 7938 if (r.state == ActivityState.RESUMED 7939 || r.state == ActivityState.PAUSING 7940 || r.state == ActivityState.PAUSED) { 7941 if (!r.isHomeActivity || mHomeProcess != r.app) { 7942 Slog.w(TAG, " Force finishing activity " 7943 + r.intent.getComponent().flattenToShortString()); 7944 r.stack.finishActivityLocked(r, index, 7945 Activity.RESULT_CANCELED, null, "crashed", false); 7946 } 7947 } 7948 } 7949 } 7950 } 7951 7952 // Bump up the crash count of any services currently running in the proc. 7953 if (app.services.size() != 0) { 7954 // Any services running in the application need to be placed 7955 // back in the pending list. 7956 Iterator<ServiceRecord> it = app.services.iterator(); 7957 while (it.hasNext()) { 7958 ServiceRecord sr = it.next(); 7959 sr.crashCount++; 7960 } 7961 } 7962 7963 // If the crashing process is what we consider to be the "home process" and it has been 7964 // replaced by a third-party app, clear the package preferred activities from packages 7965 // with a home activity running in the process to prevent a repeatedly crashing app 7966 // from blocking the user to manually clear the list. 7967 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7968 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7969 Iterator it = mHomeProcess.activities.iterator(); 7970 while (it.hasNext()) { 7971 ActivityRecord r = (ActivityRecord)it.next(); 7972 if (r.isHomeActivity) { 7973 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7974 try { 7975 ActivityThread.getPackageManager() 7976 .clearPackagePreferredActivities(r.packageName); 7977 } catch (RemoteException c) { 7978 // pm is in same process, this will never happen. 7979 } 7980 } 7981 } 7982 } 7983 7984 if (!app.isolated) { 7985 // XXX Can't keep track of crash times for isolated processes, 7986 // because they don't have a perisistent identity. 7987 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7988 } 7989 7990 return true; 7991 } 7992 7993 void startAppProblemLocked(ProcessRecord app) { 7994 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7995 mContext, app.info.packageName, app.info.flags); 7996 skipCurrentReceiverLocked(app); 7997 } 7998 7999 void skipCurrentReceiverLocked(ProcessRecord app) { 8000 for (BroadcastQueue queue : mBroadcastQueues) { 8001 queue.skipCurrentReceiverLocked(app); 8002 } 8003 } 8004 8005 /** 8006 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8007 * The application process will exit immediately after this call returns. 8008 * @param app object of the crashing app, null for the system server 8009 * @param crashInfo describing the exception 8010 */ 8011 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8012 ProcessRecord r = findAppProcess(app, "Crash"); 8013 final String processName = app == null ? "system_server" 8014 : (r == null ? "unknown" : r.processName); 8015 8016 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8017 processName, 8018 r == null ? -1 : r.info.flags, 8019 crashInfo.exceptionClassName, 8020 crashInfo.exceptionMessage, 8021 crashInfo.throwFileName, 8022 crashInfo.throwLineNumber); 8023 8024 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8025 8026 crashApplication(r, crashInfo); 8027 } 8028 8029 public void handleApplicationStrictModeViolation( 8030 IBinder app, 8031 int violationMask, 8032 StrictMode.ViolationInfo info) { 8033 ProcessRecord r = findAppProcess(app, "StrictMode"); 8034 if (r == null) { 8035 return; 8036 } 8037 8038 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8039 Integer stackFingerprint = info.hashCode(); 8040 boolean logIt = true; 8041 synchronized (mAlreadyLoggedViolatedStacks) { 8042 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8043 logIt = false; 8044 // TODO: sub-sample into EventLog for these, with 8045 // the info.durationMillis? Then we'd get 8046 // the relative pain numbers, without logging all 8047 // the stack traces repeatedly. We'd want to do 8048 // likewise in the client code, which also does 8049 // dup suppression, before the Binder call. 8050 } else { 8051 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8052 mAlreadyLoggedViolatedStacks.clear(); 8053 } 8054 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8055 } 8056 } 8057 if (logIt) { 8058 logStrictModeViolationToDropBox(r, info); 8059 } 8060 } 8061 8062 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8063 AppErrorResult result = new AppErrorResult(); 8064 synchronized (this) { 8065 final long origId = Binder.clearCallingIdentity(); 8066 8067 Message msg = Message.obtain(); 8068 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8069 HashMap<String, Object> data = new HashMap<String, Object>(); 8070 data.put("result", result); 8071 data.put("app", r); 8072 data.put("violationMask", violationMask); 8073 data.put("info", info); 8074 msg.obj = data; 8075 mHandler.sendMessage(msg); 8076 8077 Binder.restoreCallingIdentity(origId); 8078 } 8079 int res = result.get(); 8080 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8081 } 8082 } 8083 8084 // Depending on the policy in effect, there could be a bunch of 8085 // these in quick succession so we try to batch these together to 8086 // minimize disk writes, number of dropbox entries, and maximize 8087 // compression, by having more fewer, larger records. 8088 private void logStrictModeViolationToDropBox( 8089 ProcessRecord process, 8090 StrictMode.ViolationInfo info) { 8091 if (info == null) { 8092 return; 8093 } 8094 final boolean isSystemApp = process == null || 8095 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8096 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8097 final String processName = process == null ? "unknown" : process.processName; 8098 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8099 final DropBoxManager dbox = (DropBoxManager) 8100 mContext.getSystemService(Context.DROPBOX_SERVICE); 8101 8102 // Exit early if the dropbox isn't configured to accept this report type. 8103 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8104 8105 boolean bufferWasEmpty; 8106 boolean needsFlush; 8107 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8108 synchronized (sb) { 8109 bufferWasEmpty = sb.length() == 0; 8110 appendDropBoxProcessHeaders(process, processName, sb); 8111 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8112 sb.append("System-App: ").append(isSystemApp).append("\n"); 8113 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8114 if (info.violationNumThisLoop != 0) { 8115 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8116 } 8117 if (info.numAnimationsRunning != 0) { 8118 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8119 } 8120 if (info.broadcastIntentAction != null) { 8121 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8122 } 8123 if (info.durationMillis != -1) { 8124 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8125 } 8126 if (info.numInstances != -1) { 8127 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8128 } 8129 if (info.tags != null) { 8130 for (String tag : info.tags) { 8131 sb.append("Span-Tag: ").append(tag).append("\n"); 8132 } 8133 } 8134 sb.append("\n"); 8135 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8136 sb.append(info.crashInfo.stackTrace); 8137 } 8138 sb.append("\n"); 8139 8140 // Only buffer up to ~64k. Various logging bits truncate 8141 // things at 128k. 8142 needsFlush = (sb.length() > 64 * 1024); 8143 } 8144 8145 // Flush immediately if the buffer's grown too large, or this 8146 // is a non-system app. Non-system apps are isolated with a 8147 // different tag & policy and not batched. 8148 // 8149 // Batching is useful during internal testing with 8150 // StrictMode settings turned up high. Without batching, 8151 // thousands of separate files could be created on boot. 8152 if (!isSystemApp || needsFlush) { 8153 new Thread("Error dump: " + dropboxTag) { 8154 @Override 8155 public void run() { 8156 String report; 8157 synchronized (sb) { 8158 report = sb.toString(); 8159 sb.delete(0, sb.length()); 8160 sb.trimToSize(); 8161 } 8162 if (report.length() != 0) { 8163 dbox.addText(dropboxTag, report); 8164 } 8165 } 8166 }.start(); 8167 return; 8168 } 8169 8170 // System app batching: 8171 if (!bufferWasEmpty) { 8172 // An existing dropbox-writing thread is outstanding, so 8173 // we don't need to start it up. The existing thread will 8174 // catch the buffer appends we just did. 8175 return; 8176 } 8177 8178 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8179 // (After this point, we shouldn't access AMS internal data structures.) 8180 new Thread("Error dump: " + dropboxTag) { 8181 @Override 8182 public void run() { 8183 // 5 second sleep to let stacks arrive and be batched together 8184 try { 8185 Thread.sleep(5000); // 5 seconds 8186 } catch (InterruptedException e) {} 8187 8188 String errorReport; 8189 synchronized (mStrictModeBuffer) { 8190 errorReport = mStrictModeBuffer.toString(); 8191 if (errorReport.length() == 0) { 8192 return; 8193 } 8194 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8195 mStrictModeBuffer.trimToSize(); 8196 } 8197 dbox.addText(dropboxTag, errorReport); 8198 } 8199 }.start(); 8200 } 8201 8202 /** 8203 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8204 * @param app object of the crashing app, null for the system server 8205 * @param tag reported by the caller 8206 * @param crashInfo describing the context of the error 8207 * @return true if the process should exit immediately (WTF is fatal) 8208 */ 8209 public boolean handleApplicationWtf(IBinder app, String tag, 8210 ApplicationErrorReport.CrashInfo crashInfo) { 8211 ProcessRecord r = findAppProcess(app, "WTF"); 8212 final String processName = app == null ? "system_server" 8213 : (r == null ? "unknown" : r.processName); 8214 8215 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8216 processName, 8217 r == null ? -1 : r.info.flags, 8218 tag, crashInfo.exceptionMessage); 8219 8220 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8221 8222 if (r != null && r.pid != Process.myPid() && 8223 Settings.Secure.getInt(mContext.getContentResolver(), 8224 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8225 crashApplication(r, crashInfo); 8226 return true; 8227 } else { 8228 return false; 8229 } 8230 } 8231 8232 /** 8233 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8234 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8235 */ 8236 private ProcessRecord findAppProcess(IBinder app, String reason) { 8237 if (app == null) { 8238 return null; 8239 } 8240 8241 synchronized (this) { 8242 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8243 final int NA = apps.size(); 8244 for (int ia=0; ia<NA; ia++) { 8245 ProcessRecord p = apps.valueAt(ia); 8246 if (p.thread != null && p.thread.asBinder() == app) { 8247 return p; 8248 } 8249 } 8250 } 8251 8252 Slog.w(TAG, "Can't find mystery application for " + reason 8253 + " from pid=" + Binder.getCallingPid() 8254 + " uid=" + Binder.getCallingUid() + ": " + app); 8255 return null; 8256 } 8257 } 8258 8259 /** 8260 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8261 * to append various headers to the dropbox log text. 8262 */ 8263 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8264 StringBuilder sb) { 8265 // Watchdog thread ends up invoking this function (with 8266 // a null ProcessRecord) to add the stack file to dropbox. 8267 // Do not acquire a lock on this (am) in such cases, as it 8268 // could cause a potential deadlock, if and when watchdog 8269 // is invoked due to unavailability of lock on am and it 8270 // would prevent watchdog from killing system_server. 8271 if (process == null) { 8272 sb.append("Process: ").append(processName).append("\n"); 8273 return; 8274 } 8275 // Note: ProcessRecord 'process' is guarded by the service 8276 // instance. (notably process.pkgList, which could otherwise change 8277 // concurrently during execution of this method) 8278 synchronized (this) { 8279 sb.append("Process: ").append(processName).append("\n"); 8280 int flags = process.info.flags; 8281 IPackageManager pm = AppGlobals.getPackageManager(); 8282 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8283 for (String pkg : process.pkgList) { 8284 sb.append("Package: ").append(pkg); 8285 try { 8286 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8287 if (pi != null) { 8288 sb.append(" v").append(pi.versionCode); 8289 if (pi.versionName != null) { 8290 sb.append(" (").append(pi.versionName).append(")"); 8291 } 8292 } 8293 } catch (RemoteException e) { 8294 Slog.e(TAG, "Error getting package info: " + pkg, e); 8295 } 8296 sb.append("\n"); 8297 } 8298 } 8299 } 8300 8301 private static String processClass(ProcessRecord process) { 8302 if (process == null || process.pid == MY_PID) { 8303 return "system_server"; 8304 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8305 return "system_app"; 8306 } else { 8307 return "data_app"; 8308 } 8309 } 8310 8311 /** 8312 * Write a description of an error (crash, WTF, ANR) to the drop box. 8313 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8314 * @param process which caused the error, null means the system server 8315 * @param activity which triggered the error, null if unknown 8316 * @param parent activity related to the error, null if unknown 8317 * @param subject line related to the error, null if absent 8318 * @param report in long form describing the error, null if absent 8319 * @param logFile to include in the report, null if none 8320 * @param crashInfo giving an application stack trace, null if absent 8321 */ 8322 public void addErrorToDropBox(String eventType, 8323 ProcessRecord process, String processName, ActivityRecord activity, 8324 ActivityRecord parent, String subject, 8325 final String report, final File logFile, 8326 final ApplicationErrorReport.CrashInfo crashInfo) { 8327 // NOTE -- this must never acquire the ActivityManagerService lock, 8328 // otherwise the watchdog may be prevented from resetting the system. 8329 8330 final String dropboxTag = processClass(process) + "_" + eventType; 8331 final DropBoxManager dbox = (DropBoxManager) 8332 mContext.getSystemService(Context.DROPBOX_SERVICE); 8333 8334 // Exit early if the dropbox isn't configured to accept this report type. 8335 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8336 8337 final StringBuilder sb = new StringBuilder(1024); 8338 appendDropBoxProcessHeaders(process, processName, sb); 8339 if (activity != null) { 8340 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8341 } 8342 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8343 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8344 } 8345 if (parent != null && parent != activity) { 8346 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8347 } 8348 if (subject != null) { 8349 sb.append("Subject: ").append(subject).append("\n"); 8350 } 8351 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8352 if (Debug.isDebuggerConnected()) { 8353 sb.append("Debugger: Connected\n"); 8354 } 8355 sb.append("\n"); 8356 8357 // Do the rest in a worker thread to avoid blocking the caller on I/O 8358 // (After this point, we shouldn't access AMS internal data structures.) 8359 Thread worker = new Thread("Error dump: " + dropboxTag) { 8360 @Override 8361 public void run() { 8362 if (report != null) { 8363 sb.append(report); 8364 } 8365 if (logFile != null) { 8366 try { 8367 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8368 } catch (IOException e) { 8369 Slog.e(TAG, "Error reading " + logFile, e); 8370 } 8371 } 8372 if (crashInfo != null && crashInfo.stackTrace != null) { 8373 sb.append(crashInfo.stackTrace); 8374 } 8375 8376 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8377 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8378 if (lines > 0) { 8379 sb.append("\n"); 8380 8381 // Merge several logcat streams, and take the last N lines 8382 InputStreamReader input = null; 8383 try { 8384 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8385 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8386 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8387 8388 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8389 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8390 input = new InputStreamReader(logcat.getInputStream()); 8391 8392 int num; 8393 char[] buf = new char[8192]; 8394 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8395 } catch (IOException e) { 8396 Slog.e(TAG, "Error running logcat", e); 8397 } finally { 8398 if (input != null) try { input.close(); } catch (IOException e) {} 8399 } 8400 } 8401 8402 dbox.addText(dropboxTag, sb.toString()); 8403 } 8404 }; 8405 8406 if (process == null) { 8407 // If process is null, we are being called from some internal code 8408 // and may be about to die -- run this synchronously. 8409 worker.run(); 8410 } else { 8411 worker.start(); 8412 } 8413 } 8414 8415 /** 8416 * Bring up the "unexpected error" dialog box for a crashing app. 8417 * Deal with edge cases (intercepts from instrumented applications, 8418 * ActivityController, error intent receivers, that sort of thing). 8419 * @param r the application crashing 8420 * @param crashInfo describing the failure 8421 */ 8422 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8423 long timeMillis = System.currentTimeMillis(); 8424 String shortMsg = crashInfo.exceptionClassName; 8425 String longMsg = crashInfo.exceptionMessage; 8426 String stackTrace = crashInfo.stackTrace; 8427 if (shortMsg != null && longMsg != null) { 8428 longMsg = shortMsg + ": " + longMsg; 8429 } else if (shortMsg != null) { 8430 longMsg = shortMsg; 8431 } 8432 8433 AppErrorResult result = new AppErrorResult(); 8434 synchronized (this) { 8435 if (mController != null) { 8436 try { 8437 String name = r != null ? r.processName : null; 8438 int pid = r != null ? r.pid : Binder.getCallingPid(); 8439 if (!mController.appCrashed(name, pid, 8440 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8441 Slog.w(TAG, "Force-killing crashed app " + name 8442 + " at watcher's request"); 8443 Process.killProcess(pid); 8444 return; 8445 } 8446 } catch (RemoteException e) { 8447 mController = null; 8448 } 8449 } 8450 8451 final long origId = Binder.clearCallingIdentity(); 8452 8453 // If this process is running instrumentation, finish it. 8454 if (r != null && r.instrumentationClass != null) { 8455 Slog.w(TAG, "Error in app " + r.processName 8456 + " running instrumentation " + r.instrumentationClass + ":"); 8457 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8458 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8459 Bundle info = new Bundle(); 8460 info.putString("shortMsg", shortMsg); 8461 info.putString("longMsg", longMsg); 8462 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8463 Binder.restoreCallingIdentity(origId); 8464 return; 8465 } 8466 8467 // If we can't identify the process or it's already exceeded its crash quota, 8468 // quit right away without showing a crash dialog. 8469 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8470 Binder.restoreCallingIdentity(origId); 8471 return; 8472 } 8473 8474 Message msg = Message.obtain(); 8475 msg.what = SHOW_ERROR_MSG; 8476 HashMap data = new HashMap(); 8477 data.put("result", result); 8478 data.put("app", r); 8479 msg.obj = data; 8480 mHandler.sendMessage(msg); 8481 8482 Binder.restoreCallingIdentity(origId); 8483 } 8484 8485 int res = result.get(); 8486 8487 Intent appErrorIntent = null; 8488 synchronized (this) { 8489 if (r != null && !r.isolated) { 8490 // XXX Can't keep track of crash time for isolated processes, 8491 // since they don't have a persistent identity. 8492 mProcessCrashTimes.put(r.info.processName, r.uid, 8493 SystemClock.uptimeMillis()); 8494 } 8495 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8496 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8497 } 8498 } 8499 8500 if (appErrorIntent != null) { 8501 try { 8502 mContext.startActivity(appErrorIntent); 8503 } catch (ActivityNotFoundException e) { 8504 Slog.w(TAG, "bug report receiver dissappeared", e); 8505 } 8506 } 8507 } 8508 8509 Intent createAppErrorIntentLocked(ProcessRecord r, 8510 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8511 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8512 if (report == null) { 8513 return null; 8514 } 8515 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8516 result.setComponent(r.errorReportReceiver); 8517 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8518 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8519 return result; 8520 } 8521 8522 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8523 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8524 if (r.errorReportReceiver == null) { 8525 return null; 8526 } 8527 8528 if (!r.crashing && !r.notResponding) { 8529 return null; 8530 } 8531 8532 ApplicationErrorReport report = new ApplicationErrorReport(); 8533 report.packageName = r.info.packageName; 8534 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8535 report.processName = r.processName; 8536 report.time = timeMillis; 8537 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8538 8539 if (r.crashing) { 8540 report.type = ApplicationErrorReport.TYPE_CRASH; 8541 report.crashInfo = crashInfo; 8542 } else if (r.notResponding) { 8543 report.type = ApplicationErrorReport.TYPE_ANR; 8544 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8545 8546 report.anrInfo.activity = r.notRespondingReport.tag; 8547 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8548 report.anrInfo.info = r.notRespondingReport.longMsg; 8549 } 8550 8551 return report; 8552 } 8553 8554 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8555 enforceNotIsolatedCaller("getProcessesInErrorState"); 8556 // assume our apps are happy - lazy create the list 8557 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8558 8559 final boolean allUsers = ActivityManager.checkUidPermission( 8560 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8561 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8562 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8563 8564 synchronized (this) { 8565 8566 // iterate across all processes 8567 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8568 ProcessRecord app = mLruProcesses.get(i); 8569 if (!allUsers && app.userId != userId) { 8570 continue; 8571 } 8572 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8573 // This one's in trouble, so we'll generate a report for it 8574 // crashes are higher priority (in case there's a crash *and* an anr) 8575 ActivityManager.ProcessErrorStateInfo report = null; 8576 if (app.crashing) { 8577 report = app.crashingReport; 8578 } else if (app.notResponding) { 8579 report = app.notRespondingReport; 8580 } 8581 8582 if (report != null) { 8583 if (errList == null) { 8584 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8585 } 8586 errList.add(report); 8587 } else { 8588 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8589 " crashing = " + app.crashing + 8590 " notResponding = " + app.notResponding); 8591 } 8592 } 8593 } 8594 } 8595 8596 return errList; 8597 } 8598 8599 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8600 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8601 if (currApp != null) { 8602 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8603 } 8604 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8605 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8606 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8607 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8608 if (currApp != null) { 8609 currApp.lru = 0; 8610 } 8611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8612 } else if (adj >= ProcessList.SERVICE_ADJ) { 8613 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8614 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8615 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8616 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8618 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8620 } else { 8621 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8622 } 8623 } 8624 8625 private void fillInProcMemInfo(ProcessRecord app, 8626 ActivityManager.RunningAppProcessInfo outInfo) { 8627 outInfo.pid = app.pid; 8628 outInfo.uid = app.info.uid; 8629 if (mHeavyWeightProcess == app) { 8630 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8631 } 8632 if (app.persistent) { 8633 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8634 } 8635 if (app.hasActivities) { 8636 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8637 } 8638 outInfo.lastTrimLevel = app.trimMemoryLevel; 8639 int adj = app.curAdj; 8640 outInfo.importance = oomAdjToImportance(adj, outInfo); 8641 outInfo.importanceReasonCode = app.adjTypeCode; 8642 } 8643 8644 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8645 enforceNotIsolatedCaller("getRunningAppProcesses"); 8646 // Lazy instantiation of list 8647 List<ActivityManager.RunningAppProcessInfo> runList = null; 8648 final boolean allUsers = ActivityManager.checkUidPermission( 8649 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8650 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8651 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8652 synchronized (this) { 8653 // Iterate across all processes 8654 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8655 ProcessRecord app = mLruProcesses.get(i); 8656 if (!allUsers && app.userId != userId) { 8657 continue; 8658 } 8659 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8660 // Generate process state info for running application 8661 ActivityManager.RunningAppProcessInfo currApp = 8662 new ActivityManager.RunningAppProcessInfo(app.processName, 8663 app.pid, app.getPackageList()); 8664 fillInProcMemInfo(app, currApp); 8665 if (app.adjSource instanceof ProcessRecord) { 8666 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8667 currApp.importanceReasonImportance = oomAdjToImportance( 8668 app.adjSourceOom, null); 8669 } else if (app.adjSource instanceof ActivityRecord) { 8670 ActivityRecord r = (ActivityRecord)app.adjSource; 8671 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8672 } 8673 if (app.adjTarget instanceof ComponentName) { 8674 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8675 } 8676 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8677 // + " lru=" + currApp.lru); 8678 if (runList == null) { 8679 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8680 } 8681 runList.add(currApp); 8682 } 8683 } 8684 } 8685 return runList; 8686 } 8687 8688 public List<ApplicationInfo> getRunningExternalApplications() { 8689 enforceNotIsolatedCaller("getRunningExternalApplications"); 8690 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8691 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8692 if (runningApps != null && runningApps.size() > 0) { 8693 Set<String> extList = new HashSet<String>(); 8694 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8695 if (app.pkgList != null) { 8696 for (String pkg : app.pkgList) { 8697 extList.add(pkg); 8698 } 8699 } 8700 } 8701 IPackageManager pm = AppGlobals.getPackageManager(); 8702 for (String pkg : extList) { 8703 try { 8704 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8705 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8706 retList.add(info); 8707 } 8708 } catch (RemoteException e) { 8709 } 8710 } 8711 } 8712 return retList; 8713 } 8714 8715 @Override 8716 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8717 enforceNotIsolatedCaller("getMyMemoryState"); 8718 synchronized (this) { 8719 ProcessRecord proc; 8720 synchronized (mPidsSelfLocked) { 8721 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8722 } 8723 fillInProcMemInfo(proc, outInfo); 8724 } 8725 } 8726 8727 @Override 8728 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8729 if (checkCallingPermission(android.Manifest.permission.DUMP) 8730 != PackageManager.PERMISSION_GRANTED) { 8731 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8732 + Binder.getCallingPid() 8733 + ", uid=" + Binder.getCallingUid() 8734 + " without permission " 8735 + android.Manifest.permission.DUMP); 8736 return; 8737 } 8738 8739 boolean dumpAll = false; 8740 boolean dumpClient = false; 8741 String dumpPackage = null; 8742 8743 int opti = 0; 8744 while (opti < args.length) { 8745 String opt = args[opti]; 8746 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8747 break; 8748 } 8749 opti++; 8750 if ("-a".equals(opt)) { 8751 dumpAll = true; 8752 } else if ("-c".equals(opt)) { 8753 dumpClient = true; 8754 } else if ("-h".equals(opt)) { 8755 pw.println("Activity manager dump options:"); 8756 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8757 pw.println(" cmd may be one of:"); 8758 pw.println(" a[ctivities]: activity stack state"); 8759 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8760 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8761 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8762 pw.println(" o[om]: out of memory management"); 8763 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8764 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8765 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8766 pw.println(" service [COMP_SPEC]: service client-side state"); 8767 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8768 pw.println(" all: dump all activities"); 8769 pw.println(" top: dump the top activity"); 8770 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8771 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8772 pw.println(" a partial substring in a component name, a"); 8773 pw.println(" hex object identifier."); 8774 pw.println(" -a: include all available server state."); 8775 pw.println(" -c: include client state."); 8776 return; 8777 } else { 8778 pw.println("Unknown argument: " + opt + "; use -h for help"); 8779 } 8780 } 8781 8782 long origId = Binder.clearCallingIdentity(); 8783 boolean more = false; 8784 // Is the caller requesting to dump a particular piece of data? 8785 if (opti < args.length) { 8786 String cmd = args[opti]; 8787 opti++; 8788 if ("activities".equals(cmd) || "a".equals(cmd)) { 8789 synchronized (this) { 8790 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8791 } 8792 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8793 String[] newArgs; 8794 String name; 8795 if (opti >= args.length) { 8796 name = null; 8797 newArgs = EMPTY_STRING_ARRAY; 8798 } else { 8799 name = args[opti]; 8800 opti++; 8801 newArgs = new String[args.length - opti]; 8802 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8803 args.length - opti); 8804 } 8805 synchronized (this) { 8806 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8807 } 8808 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8809 String[] newArgs; 8810 String name; 8811 if (opti >= args.length) { 8812 name = null; 8813 newArgs = EMPTY_STRING_ARRAY; 8814 } else { 8815 name = args[opti]; 8816 opti++; 8817 newArgs = new String[args.length - opti]; 8818 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8819 args.length - opti); 8820 } 8821 synchronized (this) { 8822 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8823 } 8824 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8825 String[] newArgs; 8826 String name; 8827 if (opti >= args.length) { 8828 name = null; 8829 newArgs = EMPTY_STRING_ARRAY; 8830 } else { 8831 name = args[opti]; 8832 opti++; 8833 newArgs = new String[args.length - opti]; 8834 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8835 args.length - opti); 8836 } 8837 synchronized (this) { 8838 dumpProcessesLocked(fd, pw, args, opti, true, name); 8839 } 8840 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8841 synchronized (this) { 8842 dumpOomLocked(fd, pw, args, opti, true); 8843 } 8844 } else if ("provider".equals(cmd)) { 8845 String[] newArgs; 8846 String name; 8847 if (opti >= args.length) { 8848 name = null; 8849 newArgs = EMPTY_STRING_ARRAY; 8850 } else { 8851 name = args[opti]; 8852 opti++; 8853 newArgs = new String[args.length - opti]; 8854 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8855 } 8856 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8857 pw.println("No providers match: " + name); 8858 pw.println("Use -h for help."); 8859 } 8860 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8861 synchronized (this) { 8862 dumpProvidersLocked(fd, pw, args, opti, true, null); 8863 } 8864 } else if ("service".equals(cmd)) { 8865 String[] newArgs; 8866 String name; 8867 if (opti >= args.length) { 8868 name = null; 8869 newArgs = EMPTY_STRING_ARRAY; 8870 } else { 8871 name = args[opti]; 8872 opti++; 8873 newArgs = new String[args.length - opti]; 8874 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8875 args.length - opti); 8876 } 8877 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8878 pw.println("No services match: " + name); 8879 pw.println("Use -h for help."); 8880 } 8881 } else if ("package".equals(cmd)) { 8882 String[] newArgs; 8883 if (opti >= args.length) { 8884 pw.println("package: no package name specified"); 8885 pw.println("Use -h for help."); 8886 } else { 8887 dumpPackage = args[opti]; 8888 opti++; 8889 newArgs = new String[args.length - opti]; 8890 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8891 args.length - opti); 8892 args = newArgs; 8893 opti = 0; 8894 more = true; 8895 } 8896 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8897 synchronized (this) { 8898 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8899 } 8900 } else { 8901 // Dumping a single activity? 8902 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8903 pw.println("Bad activity command, or no activities match: " + cmd); 8904 pw.println("Use -h for help."); 8905 } 8906 } 8907 if (!more) { 8908 Binder.restoreCallingIdentity(origId); 8909 return; 8910 } 8911 } 8912 8913 // No piece of data specified, dump everything. 8914 synchronized (this) { 8915 boolean needSep; 8916 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8917 if (needSep) { 8918 pw.println(" "); 8919 } 8920 if (dumpAll) { 8921 pw.println("-------------------------------------------------------------------------------"); 8922 } 8923 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8924 if (needSep) { 8925 pw.println(" "); 8926 } 8927 if (dumpAll) { 8928 pw.println("-------------------------------------------------------------------------------"); 8929 } 8930 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8931 if (needSep) { 8932 pw.println(" "); 8933 } 8934 if (dumpAll) { 8935 pw.println("-------------------------------------------------------------------------------"); 8936 } 8937 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8938 if (needSep) { 8939 pw.println(" "); 8940 } 8941 if (dumpAll) { 8942 pw.println("-------------------------------------------------------------------------------"); 8943 } 8944 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8945 if (needSep) { 8946 pw.println(" "); 8947 } 8948 if (dumpAll) { 8949 pw.println("-------------------------------------------------------------------------------"); 8950 } 8951 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8952 } 8953 Binder.restoreCallingIdentity(origId); 8954 } 8955 8956 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8957 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8958 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8959 pw.println(" Main stack:"); 8960 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8961 dumpPackage); 8962 pw.println(" "); 8963 pw.println(" Running activities (most recent first):"); 8964 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8965 dumpPackage); 8966 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8967 pw.println(" "); 8968 pw.println(" Activities waiting for another to become visible:"); 8969 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8970 !dumpAll, false, dumpPackage); 8971 } 8972 if (mMainStack.mStoppingActivities.size() > 0) { 8973 pw.println(" "); 8974 pw.println(" Activities waiting to stop:"); 8975 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8976 !dumpAll, false, dumpPackage); 8977 } 8978 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8979 pw.println(" "); 8980 pw.println(" Activities waiting to sleep:"); 8981 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8982 !dumpAll, false, dumpPackage); 8983 } 8984 if (mMainStack.mFinishingActivities.size() > 0) { 8985 pw.println(" "); 8986 pw.println(" Activities waiting to finish:"); 8987 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8988 !dumpAll, false, dumpPackage); 8989 } 8990 8991 pw.println(" "); 8992 if (mMainStack.mPausingActivity != null) { 8993 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8994 } 8995 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8996 pw.println(" mFocusedActivity: " + mFocusedActivity); 8997 if (dumpAll) { 8998 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8999 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9000 pw.println(" mDismissKeyguardOnNextActivity: " 9001 + mMainStack.mDismissKeyguardOnNextActivity); 9002 } 9003 9004 if (mRecentTasks.size() > 0) { 9005 pw.println(); 9006 pw.println(" Recent tasks:"); 9007 9008 final int N = mRecentTasks.size(); 9009 for (int i=0; i<N; i++) { 9010 TaskRecord tr = mRecentTasks.get(i); 9011 if (dumpPackage != null) { 9012 if (tr.realActivity == null || 9013 !dumpPackage.equals(tr.realActivity)) { 9014 continue; 9015 } 9016 } 9017 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9018 pw.println(tr); 9019 if (dumpAll) { 9020 mRecentTasks.get(i).dump(pw, " "); 9021 } 9022 } 9023 } 9024 9025 if (dumpAll) { 9026 pw.println(" "); 9027 pw.println(" mCurTask: " + mCurTask); 9028 } 9029 9030 return true; 9031 } 9032 9033 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9034 int opti, boolean dumpAll, String dumpPackage) { 9035 boolean needSep = false; 9036 int numPers = 0; 9037 9038 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9039 9040 if (dumpAll) { 9041 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9042 final int NA = procs.size(); 9043 for (int ia=0; ia<NA; ia++) { 9044 ProcessRecord r = procs.valueAt(ia); 9045 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9046 continue; 9047 } 9048 if (!needSep) { 9049 pw.println(" All known processes:"); 9050 needSep = true; 9051 } 9052 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9053 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9054 pw.print(" "); pw.println(r); 9055 r.dump(pw, " "); 9056 if (r.persistent) { 9057 numPers++; 9058 } 9059 } 9060 } 9061 } 9062 9063 if (mIsolatedProcesses.size() > 0) { 9064 if (needSep) pw.println(" "); 9065 needSep = true; 9066 pw.println(" Isolated process list (sorted by uid):"); 9067 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9068 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9069 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9070 continue; 9071 } 9072 pw.println(String.format("%sIsolated #%2d: %s", 9073 " ", i, r.toString())); 9074 } 9075 } 9076 9077 if (mLruProcesses.size() > 0) { 9078 if (needSep) pw.println(" "); 9079 needSep = true; 9080 pw.println(" Process LRU list (sorted by oom_adj):"); 9081 dumpProcessOomList(pw, this, mLruProcesses, " ", 9082 "Proc", "PERS", false, dumpPackage); 9083 needSep = true; 9084 } 9085 9086 if (dumpAll) { 9087 synchronized (mPidsSelfLocked) { 9088 boolean printed = false; 9089 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9090 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9091 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9092 continue; 9093 } 9094 if (!printed) { 9095 if (needSep) pw.println(" "); 9096 needSep = true; 9097 pw.println(" PID mappings:"); 9098 printed = true; 9099 } 9100 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9101 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9102 } 9103 } 9104 } 9105 9106 if (mForegroundProcesses.size() > 0) { 9107 synchronized (mPidsSelfLocked) { 9108 boolean printed = false; 9109 for (int i=0; i<mForegroundProcesses.size(); i++) { 9110 ProcessRecord r = mPidsSelfLocked.get( 9111 mForegroundProcesses.valueAt(i).pid); 9112 if (dumpPackage != null && (r == null 9113 || !dumpPackage.equals(r.info.packageName))) { 9114 continue; 9115 } 9116 if (!printed) { 9117 if (needSep) pw.println(" "); 9118 needSep = true; 9119 pw.println(" Foreground Processes:"); 9120 printed = true; 9121 } 9122 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9123 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9124 } 9125 } 9126 } 9127 9128 if (mPersistentStartingProcesses.size() > 0) { 9129 if (needSep) pw.println(" "); 9130 needSep = true; 9131 pw.println(" Persisent processes that are starting:"); 9132 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9133 "Starting Norm", "Restarting PERS", dumpPackage); 9134 } 9135 9136 if (mRemovedProcesses.size() > 0) { 9137 if (needSep) pw.println(" "); 9138 needSep = true; 9139 pw.println(" Processes that are being removed:"); 9140 dumpProcessList(pw, this, mRemovedProcesses, " ", 9141 "Removed Norm", "Removed PERS", dumpPackage); 9142 } 9143 9144 if (mProcessesOnHold.size() > 0) { 9145 if (needSep) pw.println(" "); 9146 needSep = true; 9147 pw.println(" Processes that are on old until the system is ready:"); 9148 dumpProcessList(pw, this, mProcessesOnHold, " ", 9149 "OnHold Norm", "OnHold PERS", dumpPackage); 9150 } 9151 9152 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9153 9154 if (mProcessCrashTimes.getMap().size() > 0) { 9155 boolean printed = false; 9156 long now = SystemClock.uptimeMillis(); 9157 for (Map.Entry<String, SparseArray<Long>> procs 9158 : mProcessCrashTimes.getMap().entrySet()) { 9159 String pname = procs.getKey(); 9160 SparseArray<Long> uids = procs.getValue(); 9161 final int N = uids.size(); 9162 for (int i=0; i<N; i++) { 9163 int puid = uids.keyAt(i); 9164 ProcessRecord r = mProcessNames.get(pname, puid); 9165 if (dumpPackage != null && (r == null 9166 || !dumpPackage.equals(r.info.packageName))) { 9167 continue; 9168 } 9169 if (!printed) { 9170 if (needSep) pw.println(" "); 9171 needSep = true; 9172 pw.println(" Time since processes crashed:"); 9173 printed = true; 9174 } 9175 pw.print(" Process "); pw.print(pname); 9176 pw.print(" uid "); pw.print(puid); 9177 pw.print(": last crashed "); 9178 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9179 pw.println(" ago"); 9180 } 9181 } 9182 } 9183 9184 if (mBadProcesses.getMap().size() > 0) { 9185 boolean printed = false; 9186 for (Map.Entry<String, SparseArray<Long>> procs 9187 : mBadProcesses.getMap().entrySet()) { 9188 String pname = procs.getKey(); 9189 SparseArray<Long> uids = procs.getValue(); 9190 final int N = uids.size(); 9191 for (int i=0; i<N; i++) { 9192 int puid = uids.keyAt(i); 9193 ProcessRecord r = mProcessNames.get(pname, puid); 9194 if (dumpPackage != null && (r == null 9195 || !dumpPackage.equals(r.info.packageName))) { 9196 continue; 9197 } 9198 if (!printed) { 9199 if (needSep) pw.println(" "); 9200 needSep = true; 9201 pw.println(" Bad processes:"); 9202 } 9203 pw.print(" Bad process "); pw.print(pname); 9204 pw.print(" uid "); pw.print(puid); 9205 pw.print(": crashed at time "); 9206 pw.println(uids.valueAt(i)); 9207 } 9208 } 9209 } 9210 9211 pw.println(); 9212 pw.println(" mStartedUsers:"); 9213 for (int i=0; i<mStartedUsers.size(); i++) { 9214 UserStartedState uss = mStartedUsers.valueAt(i); 9215 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9216 pw.print(": "); uss.dump("", pw); 9217 } 9218 pw.print(" mUserLru: ["); 9219 for (int i=0; i<mUserLru.size(); i++) { 9220 if (i > 0) pw.print(", "); 9221 pw.print(mUserLru.get(i)); 9222 } 9223 pw.println("]"); 9224 pw.println(" mHomeProcess: " + mHomeProcess); 9225 pw.println(" mPreviousProcess: " + mPreviousProcess); 9226 if (dumpAll) { 9227 StringBuilder sb = new StringBuilder(128); 9228 sb.append(" mPreviousProcessVisibleTime: "); 9229 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9230 pw.println(sb); 9231 } 9232 if (mHeavyWeightProcess != null) { 9233 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9234 } 9235 pw.println(" mConfiguration: " + mConfiguration); 9236 if (dumpAll) { 9237 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9238 if (mCompatModePackages.getPackages().size() > 0) { 9239 boolean printed = false; 9240 for (Map.Entry<String, Integer> entry 9241 : mCompatModePackages.getPackages().entrySet()) { 9242 String pkg = entry.getKey(); 9243 int mode = entry.getValue(); 9244 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9245 continue; 9246 } 9247 if (!printed) { 9248 pw.println(" mScreenCompatPackages:"); 9249 printed = true; 9250 } 9251 pw.print(" "); pw.print(pkg); pw.print(": "); 9252 pw.print(mode); pw.println(); 9253 } 9254 } 9255 } 9256 if (mSleeping || mWentToSleep || mLockScreenShown) { 9257 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9258 + " mLockScreenShown " + mLockScreenShown); 9259 } 9260 if (mShuttingDown) { 9261 pw.println(" mShuttingDown=" + mShuttingDown); 9262 } 9263 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9264 || mOrigWaitForDebugger) { 9265 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9266 + " mDebugTransient=" + mDebugTransient 9267 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9268 } 9269 if (mOpenGlTraceApp != null) { 9270 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9271 } 9272 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9273 || mProfileFd != null) { 9274 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9275 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9276 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9277 + mAutoStopProfiler); 9278 } 9279 if (mAlwaysFinishActivities || mController != null) { 9280 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9281 + " mController=" + mController); 9282 } 9283 if (dumpAll) { 9284 pw.println(" Total persistent processes: " + numPers); 9285 pw.println(" mStartRunning=" + mStartRunning 9286 + " mProcessesReady=" + mProcessesReady 9287 + " mSystemReady=" + mSystemReady); 9288 pw.println(" mBooting=" + mBooting 9289 + " mBooted=" + mBooted 9290 + " mFactoryTest=" + mFactoryTest); 9291 pw.print(" mLastPowerCheckRealtime="); 9292 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9293 pw.println(""); 9294 pw.print(" mLastPowerCheckUptime="); 9295 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9296 pw.println(""); 9297 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9298 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9299 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9300 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9301 + " mNumHiddenProcs=" + mNumHiddenProcs 9302 + " mNumServiceProcs=" + mNumServiceProcs 9303 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9304 } 9305 9306 return true; 9307 } 9308 9309 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9310 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9311 if (mProcessesToGc.size() > 0) { 9312 boolean printed = false; 9313 long now = SystemClock.uptimeMillis(); 9314 for (int i=0; i<mProcessesToGc.size(); i++) { 9315 ProcessRecord proc = mProcessesToGc.get(i); 9316 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9317 continue; 9318 } 9319 if (!printed) { 9320 if (needSep) pw.println(" "); 9321 needSep = true; 9322 pw.println(" Processes that are waiting to GC:"); 9323 printed = true; 9324 } 9325 pw.print(" Process "); pw.println(proc); 9326 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9327 pw.print(", last gced="); 9328 pw.print(now-proc.lastRequestedGc); 9329 pw.print(" ms ago, last lowMem="); 9330 pw.print(now-proc.lastLowMemory); 9331 pw.println(" ms ago"); 9332 9333 } 9334 } 9335 return needSep; 9336 } 9337 9338 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9339 int opti, boolean dumpAll) { 9340 boolean needSep = false; 9341 9342 if (mLruProcesses.size() > 0) { 9343 if (needSep) pw.println(" "); 9344 needSep = true; 9345 pw.println(" OOM levels:"); 9346 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9347 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9348 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9349 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9350 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9351 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9352 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9353 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9354 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9355 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9356 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9357 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9358 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9359 9360 if (needSep) pw.println(" "); 9361 needSep = true; 9362 pw.println(" Process OOM control:"); 9363 dumpProcessOomList(pw, this, mLruProcesses, " ", 9364 "Proc", "PERS", true, null); 9365 needSep = true; 9366 } 9367 9368 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9369 9370 pw.println(); 9371 pw.println(" mHomeProcess: " + mHomeProcess); 9372 pw.println(" mPreviousProcess: " + mPreviousProcess); 9373 if (mHeavyWeightProcess != null) { 9374 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9375 } 9376 9377 return true; 9378 } 9379 9380 /** 9381 * There are three ways to call this: 9382 * - no provider specified: dump all the providers 9383 * - a flattened component name that matched an existing provider was specified as the 9384 * first arg: dump that one provider 9385 * - the first arg isn't the flattened component name of an existing provider: 9386 * dump all providers whose component contains the first arg as a substring 9387 */ 9388 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9389 int opti, boolean dumpAll) { 9390 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9391 } 9392 9393 static class ItemMatcher { 9394 ArrayList<ComponentName> components; 9395 ArrayList<String> strings; 9396 ArrayList<Integer> objects; 9397 boolean all; 9398 9399 ItemMatcher() { 9400 all = true; 9401 } 9402 9403 void build(String name) { 9404 ComponentName componentName = ComponentName.unflattenFromString(name); 9405 if (componentName != null) { 9406 if (components == null) { 9407 components = new ArrayList<ComponentName>(); 9408 } 9409 components.add(componentName); 9410 all = false; 9411 } else { 9412 int objectId = 0; 9413 // Not a '/' separated full component name; maybe an object ID? 9414 try { 9415 objectId = Integer.parseInt(name, 16); 9416 if (objects == null) { 9417 objects = new ArrayList<Integer>(); 9418 } 9419 objects.add(objectId); 9420 all = false; 9421 } catch (RuntimeException e) { 9422 // Not an integer; just do string match. 9423 if (strings == null) { 9424 strings = new ArrayList<String>(); 9425 } 9426 strings.add(name); 9427 all = false; 9428 } 9429 } 9430 } 9431 9432 int build(String[] args, int opti) { 9433 for (; opti<args.length; opti++) { 9434 String name = args[opti]; 9435 if ("--".equals(name)) { 9436 return opti+1; 9437 } 9438 build(name); 9439 } 9440 return opti; 9441 } 9442 9443 boolean match(Object object, ComponentName comp) { 9444 if (all) { 9445 return true; 9446 } 9447 if (components != null) { 9448 for (int i=0; i<components.size(); i++) { 9449 if (components.get(i).equals(comp)) { 9450 return true; 9451 } 9452 } 9453 } 9454 if (objects != null) { 9455 for (int i=0; i<objects.size(); i++) { 9456 if (System.identityHashCode(object) == objects.get(i)) { 9457 return true; 9458 } 9459 } 9460 } 9461 if (strings != null) { 9462 String flat = comp.flattenToString(); 9463 for (int i=0; i<strings.size(); i++) { 9464 if (flat.contains(strings.get(i))) { 9465 return true; 9466 } 9467 } 9468 } 9469 return false; 9470 } 9471 } 9472 9473 /** 9474 * There are three things that cmd can be: 9475 * - a flattened component name that matches an existing activity 9476 * - the cmd arg isn't the flattened component name of an existing activity: 9477 * dump all activity whose component contains the cmd as a substring 9478 * - A hex number of the ActivityRecord object instance. 9479 */ 9480 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9481 int opti, boolean dumpAll) { 9482 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9483 9484 if ("all".equals(name)) { 9485 synchronized (this) { 9486 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9487 activities.add(r1); 9488 } 9489 } 9490 } else if ("top".equals(name)) { 9491 synchronized (this) { 9492 final int N = mMainStack.mHistory.size(); 9493 if (N > 0) { 9494 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9495 } 9496 } 9497 } else { 9498 ItemMatcher matcher = new ItemMatcher(); 9499 matcher.build(name); 9500 9501 synchronized (this) { 9502 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9503 if (matcher.match(r1, r1.intent.getComponent())) { 9504 activities.add(r1); 9505 } 9506 } 9507 } 9508 } 9509 9510 if (activities.size() <= 0) { 9511 return false; 9512 } 9513 9514 String[] newArgs = new String[args.length - opti]; 9515 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9516 9517 TaskRecord lastTask = null; 9518 boolean needSep = false; 9519 for (int i=activities.size()-1; i>=0; i--) { 9520 ActivityRecord r = (ActivityRecord)activities.get(i); 9521 if (needSep) { 9522 pw.println(); 9523 } 9524 needSep = true; 9525 synchronized (this) { 9526 if (lastTask != r.task) { 9527 lastTask = r.task; 9528 pw.print("TASK "); pw.print(lastTask.affinity); 9529 pw.print(" id="); pw.println(lastTask.taskId); 9530 if (dumpAll) { 9531 lastTask.dump(pw, " "); 9532 } 9533 } 9534 } 9535 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9536 } 9537 return true; 9538 } 9539 9540 /** 9541 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9542 * there is a thread associated with the activity. 9543 */ 9544 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9545 final ActivityRecord r, String[] args, boolean dumpAll) { 9546 String innerPrefix = prefix + " "; 9547 synchronized (this) { 9548 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9549 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9550 pw.print(" pid="); 9551 if (r.app != null) pw.println(r.app.pid); 9552 else pw.println("(not running)"); 9553 if (dumpAll) { 9554 r.dump(pw, innerPrefix); 9555 } 9556 } 9557 if (r.app != null && r.app.thread != null) { 9558 // flush anything that is already in the PrintWriter since the thread is going 9559 // to write to the file descriptor directly 9560 pw.flush(); 9561 try { 9562 TransferPipe tp = new TransferPipe(); 9563 try { 9564 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9565 r.appToken, innerPrefix, args); 9566 tp.go(fd); 9567 } finally { 9568 tp.kill(); 9569 } 9570 } catch (IOException e) { 9571 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9572 } catch (RemoteException e) { 9573 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9574 } 9575 } 9576 } 9577 9578 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9579 int opti, boolean dumpAll, String dumpPackage) { 9580 boolean needSep = false; 9581 boolean onlyHistory = false; 9582 9583 if ("history".equals(dumpPackage)) { 9584 onlyHistory = true; 9585 dumpPackage = null; 9586 } 9587 9588 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9589 if (!onlyHistory && dumpAll) { 9590 if (mRegisteredReceivers.size() > 0) { 9591 boolean printed = false; 9592 Iterator it = mRegisteredReceivers.values().iterator(); 9593 while (it.hasNext()) { 9594 ReceiverList r = (ReceiverList)it.next(); 9595 if (dumpPackage != null && (r.app == null || 9596 !dumpPackage.equals(r.app.info.packageName))) { 9597 continue; 9598 } 9599 if (!printed) { 9600 pw.println(" Registered Receivers:"); 9601 needSep = true; 9602 printed = true; 9603 } 9604 pw.print(" * "); pw.println(r); 9605 r.dump(pw, " "); 9606 } 9607 } 9608 9609 if (mReceiverResolver.dump(pw, needSep ? 9610 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9611 " ", dumpPackage, false)) { 9612 needSep = true; 9613 } 9614 } 9615 9616 for (BroadcastQueue q : mBroadcastQueues) { 9617 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9618 } 9619 9620 needSep = true; 9621 9622 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9623 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9624 if (needSep) { 9625 pw.println(); 9626 } 9627 needSep = true; 9628 pw.print(" Sticky broadcasts for user "); 9629 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9630 StringBuilder sb = new StringBuilder(128); 9631 for (Map.Entry<String, ArrayList<Intent>> ent 9632 : mStickyBroadcasts.valueAt(user).entrySet()) { 9633 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9634 if (dumpAll) { 9635 pw.println(":"); 9636 ArrayList<Intent> intents = ent.getValue(); 9637 final int N = intents.size(); 9638 for (int i=0; i<N; i++) { 9639 sb.setLength(0); 9640 sb.append(" Intent: "); 9641 intents.get(i).toShortString(sb, false, true, false, false); 9642 pw.println(sb.toString()); 9643 Bundle bundle = intents.get(i).getExtras(); 9644 if (bundle != null) { 9645 pw.print(" "); 9646 pw.println(bundle.toString()); 9647 } 9648 } 9649 } else { 9650 pw.println(""); 9651 } 9652 } 9653 } 9654 } 9655 9656 if (!onlyHistory && dumpAll) { 9657 pw.println(); 9658 for (BroadcastQueue queue : mBroadcastQueues) { 9659 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9660 + queue.mBroadcastsScheduled); 9661 } 9662 pw.println(" mHandler:"); 9663 mHandler.dump(new PrintWriterPrinter(pw), " "); 9664 needSep = true; 9665 } 9666 9667 return needSep; 9668 } 9669 9670 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9671 int opti, boolean dumpAll, String dumpPackage) { 9672 boolean needSep = true; 9673 9674 ItemMatcher matcher = new ItemMatcher(); 9675 matcher.build(args, opti); 9676 9677 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9678 9679 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9680 9681 if (mLaunchingProviders.size() > 0) { 9682 boolean printed = false; 9683 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9684 ContentProviderRecord r = mLaunchingProviders.get(i); 9685 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9686 continue; 9687 } 9688 if (!printed) { 9689 if (needSep) pw.println(" "); 9690 needSep = true; 9691 pw.println(" Launching content providers:"); 9692 printed = true; 9693 } 9694 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9695 pw.println(r); 9696 } 9697 } 9698 9699 if (mGrantedUriPermissions.size() > 0) { 9700 if (needSep) pw.println(); 9701 needSep = true; 9702 pw.println("Granted Uri Permissions:"); 9703 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9704 int uid = mGrantedUriPermissions.keyAt(i); 9705 HashMap<Uri, UriPermission> perms 9706 = mGrantedUriPermissions.valueAt(i); 9707 pw.print(" * UID "); pw.print(uid); 9708 pw.println(" holds:"); 9709 for (UriPermission perm : perms.values()) { 9710 pw.print(" "); pw.println(perm); 9711 if (dumpAll) { 9712 perm.dump(pw, " "); 9713 } 9714 } 9715 } 9716 needSep = true; 9717 } 9718 9719 return needSep; 9720 } 9721 9722 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9723 int opti, boolean dumpAll, String dumpPackage) { 9724 boolean needSep = false; 9725 9726 if (mIntentSenderRecords.size() > 0) { 9727 boolean printed = false; 9728 Iterator<WeakReference<PendingIntentRecord>> it 9729 = mIntentSenderRecords.values().iterator(); 9730 while (it.hasNext()) { 9731 WeakReference<PendingIntentRecord> ref = it.next(); 9732 PendingIntentRecord rec = ref != null ? ref.get(): null; 9733 if (dumpPackage != null && (rec == null 9734 || !dumpPackage.equals(rec.key.packageName))) { 9735 continue; 9736 } 9737 if (!printed) { 9738 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9739 printed = true; 9740 } 9741 needSep = true; 9742 if (rec != null) { 9743 pw.print(" * "); pw.println(rec); 9744 if (dumpAll) { 9745 rec.dump(pw, " "); 9746 } 9747 } else { 9748 pw.print(" * "); pw.println(ref); 9749 } 9750 } 9751 } 9752 9753 return needSep; 9754 } 9755 9756 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9757 String prefix, String label, boolean complete, boolean brief, boolean client, 9758 String dumpPackage) { 9759 TaskRecord lastTask = null; 9760 boolean needNL = false; 9761 final String innerPrefix = prefix + " "; 9762 final String[] args = new String[0]; 9763 for (int i=list.size()-1; i>=0; i--) { 9764 final ActivityRecord r = (ActivityRecord)list.get(i); 9765 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9766 continue; 9767 } 9768 final boolean full = !brief && (complete || !r.isInHistory()); 9769 if (needNL) { 9770 pw.println(" "); 9771 needNL = false; 9772 } 9773 if (lastTask != r.task) { 9774 lastTask = r.task; 9775 pw.print(prefix); 9776 pw.print(full ? "* " : " "); 9777 pw.println(lastTask); 9778 if (full) { 9779 lastTask.dump(pw, prefix + " "); 9780 } else if (complete) { 9781 // Complete + brief == give a summary. Isn't that obvious?!? 9782 if (lastTask.intent != null) { 9783 pw.print(prefix); pw.print(" "); 9784 pw.println(lastTask.intent.toInsecureStringWithClip()); 9785 } 9786 } 9787 } 9788 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9789 pw.print(" #"); pw.print(i); pw.print(": "); 9790 pw.println(r); 9791 if (full) { 9792 r.dump(pw, innerPrefix); 9793 } else if (complete) { 9794 // Complete + brief == give a summary. Isn't that obvious?!? 9795 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9796 if (r.app != null) { 9797 pw.print(innerPrefix); pw.println(r.app); 9798 } 9799 } 9800 if (client && r.app != null && r.app.thread != null) { 9801 // flush anything that is already in the PrintWriter since the thread is going 9802 // to write to the file descriptor directly 9803 pw.flush(); 9804 try { 9805 TransferPipe tp = new TransferPipe(); 9806 try { 9807 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9808 r.appToken, innerPrefix, args); 9809 // Short timeout, since blocking here can 9810 // deadlock with the application. 9811 tp.go(fd, 2000); 9812 } finally { 9813 tp.kill(); 9814 } 9815 } catch (IOException e) { 9816 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9817 } catch (RemoteException e) { 9818 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9819 } 9820 needNL = true; 9821 } 9822 } 9823 } 9824 9825 private static String buildOomTag(String prefix, String space, int val, int base) { 9826 if (val == base) { 9827 if (space == null) return prefix; 9828 return prefix + " "; 9829 } 9830 return prefix + "+" + Integer.toString(val-base); 9831 } 9832 9833 private static final int dumpProcessList(PrintWriter pw, 9834 ActivityManagerService service, List list, 9835 String prefix, String normalLabel, String persistentLabel, 9836 String dumpPackage) { 9837 int numPers = 0; 9838 final int N = list.size()-1; 9839 for (int i=N; i>=0; i--) { 9840 ProcessRecord r = (ProcessRecord)list.get(i); 9841 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9842 continue; 9843 } 9844 pw.println(String.format("%s%s #%2d: %s", 9845 prefix, (r.persistent ? persistentLabel : normalLabel), 9846 i, r.toString())); 9847 if (r.persistent) { 9848 numPers++; 9849 } 9850 } 9851 return numPers; 9852 } 9853 9854 private static final boolean dumpProcessOomList(PrintWriter pw, 9855 ActivityManagerService service, List<ProcessRecord> origList, 9856 String prefix, String normalLabel, String persistentLabel, 9857 boolean inclDetails, String dumpPackage) { 9858 9859 ArrayList<Pair<ProcessRecord, Integer>> list 9860 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9861 for (int i=0; i<origList.size(); i++) { 9862 ProcessRecord r = origList.get(i); 9863 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9864 continue; 9865 } 9866 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9867 } 9868 9869 if (list.size() <= 0) { 9870 return false; 9871 } 9872 9873 Comparator<Pair<ProcessRecord, Integer>> comparator 9874 = new Comparator<Pair<ProcessRecord, Integer>>() { 9875 @Override 9876 public int compare(Pair<ProcessRecord, Integer> object1, 9877 Pair<ProcessRecord, Integer> object2) { 9878 if (object1.first.setAdj != object2.first.setAdj) { 9879 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9880 } 9881 if (object1.second.intValue() != object2.second.intValue()) { 9882 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9883 } 9884 return 0; 9885 } 9886 }; 9887 9888 Collections.sort(list, comparator); 9889 9890 final long curRealtime = SystemClock.elapsedRealtime(); 9891 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9892 final long curUptime = SystemClock.uptimeMillis(); 9893 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9894 9895 for (int i=list.size()-1; i>=0; i--) { 9896 ProcessRecord r = list.get(i).first; 9897 String oomAdj; 9898 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9899 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9900 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9901 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9902 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9903 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9904 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9905 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9906 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9907 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9908 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9909 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9910 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9911 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9912 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9913 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9914 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9915 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9916 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9917 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9918 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9919 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9920 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9921 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9922 } else { 9923 oomAdj = Integer.toString(r.setAdj); 9924 } 9925 String schedGroup; 9926 switch (r.setSchedGroup) { 9927 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9928 schedGroup = "B"; 9929 break; 9930 case Process.THREAD_GROUP_DEFAULT: 9931 schedGroup = "F"; 9932 break; 9933 default: 9934 schedGroup = Integer.toString(r.setSchedGroup); 9935 break; 9936 } 9937 String foreground; 9938 if (r.foregroundActivities) { 9939 foreground = "A"; 9940 } else if (r.foregroundServices) { 9941 foreground = "S"; 9942 } else { 9943 foreground = " "; 9944 } 9945 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9946 prefix, (r.persistent ? persistentLabel : normalLabel), 9947 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9948 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9949 if (r.adjSource != null || r.adjTarget != null) { 9950 pw.print(prefix); 9951 pw.print(" "); 9952 if (r.adjTarget instanceof ComponentName) { 9953 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9954 } else if (r.adjTarget != null) { 9955 pw.print(r.adjTarget.toString()); 9956 } else { 9957 pw.print("{null}"); 9958 } 9959 pw.print("<="); 9960 if (r.adjSource instanceof ProcessRecord) { 9961 pw.print("Proc{"); 9962 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9963 pw.println("}"); 9964 } else if (r.adjSource != null) { 9965 pw.println(r.adjSource.toString()); 9966 } else { 9967 pw.println("{null}"); 9968 } 9969 } 9970 if (inclDetails) { 9971 pw.print(prefix); 9972 pw.print(" "); 9973 pw.print("oom: max="); pw.print(r.maxAdj); 9974 pw.print(" hidden="); pw.print(r.hiddenAdj); 9975 pw.print(" empty="); pw.print(r.emptyAdj); 9976 pw.print(" curRaw="); pw.print(r.curRawAdj); 9977 pw.print(" setRaw="); pw.print(r.setRawAdj); 9978 pw.print(" cur="); pw.print(r.curAdj); 9979 pw.print(" set="); pw.println(r.setAdj); 9980 pw.print(prefix); 9981 pw.print(" "); 9982 pw.print("keeping="); pw.print(r.keeping); 9983 pw.print(" hidden="); pw.print(r.hidden); 9984 pw.print(" empty="); pw.print(r.empty); 9985 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9986 9987 if (!r.keeping) { 9988 if (r.lastWakeTime != 0) { 9989 long wtime; 9990 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9991 synchronized (stats) { 9992 wtime = stats.getProcessWakeTime(r.info.uid, 9993 r.pid, curRealtime); 9994 } 9995 long timeUsed = wtime - r.lastWakeTime; 9996 pw.print(prefix); 9997 pw.print(" "); 9998 pw.print("keep awake over "); 9999 TimeUtils.formatDuration(realtimeSince, pw); 10000 pw.print(" used "); 10001 TimeUtils.formatDuration(timeUsed, pw); 10002 pw.print(" ("); 10003 pw.print((timeUsed*100)/realtimeSince); 10004 pw.println("%)"); 10005 } 10006 if (r.lastCpuTime != 0) { 10007 long timeUsed = r.curCpuTime - r.lastCpuTime; 10008 pw.print(prefix); 10009 pw.print(" "); 10010 pw.print("run cpu over "); 10011 TimeUtils.formatDuration(uptimeSince, pw); 10012 pw.print(" used "); 10013 TimeUtils.formatDuration(timeUsed, pw); 10014 pw.print(" ("); 10015 pw.print((timeUsed*100)/uptimeSince); 10016 pw.println("%)"); 10017 } 10018 } 10019 } 10020 } 10021 return true; 10022 } 10023 10024 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10025 ArrayList<ProcessRecord> procs; 10026 synchronized (this) { 10027 if (args != null && args.length > start 10028 && args[start].charAt(0) != '-') { 10029 procs = new ArrayList<ProcessRecord>(); 10030 int pid = -1; 10031 try { 10032 pid = Integer.parseInt(args[start]); 10033 } catch (NumberFormatException e) { 10034 10035 } 10036 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10037 ProcessRecord proc = mLruProcesses.get(i); 10038 if (proc.pid == pid) { 10039 procs.add(proc); 10040 } else if (proc.processName.equals(args[start])) { 10041 procs.add(proc); 10042 } 10043 } 10044 if (procs.size() <= 0) { 10045 pw.println("No process found for: " + args[start]); 10046 return null; 10047 } 10048 } else { 10049 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10050 } 10051 } 10052 return procs; 10053 } 10054 10055 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10056 PrintWriter pw, String[] args) { 10057 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10058 if (procs == null) { 10059 return; 10060 } 10061 10062 long uptime = SystemClock.uptimeMillis(); 10063 long realtime = SystemClock.elapsedRealtime(); 10064 pw.println("Applications Graphics Acceleration Info:"); 10065 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10066 10067 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10068 ProcessRecord r = procs.get(i); 10069 if (r.thread != null) { 10070 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10071 pw.flush(); 10072 try { 10073 TransferPipe tp = new TransferPipe(); 10074 try { 10075 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10076 tp.go(fd); 10077 } finally { 10078 tp.kill(); 10079 } 10080 } catch (IOException e) { 10081 pw.println("Failure while dumping the app: " + r); 10082 pw.flush(); 10083 } catch (RemoteException e) { 10084 pw.println("Got a RemoteException while dumping the app " + r); 10085 pw.flush(); 10086 } 10087 } 10088 } 10089 } 10090 10091 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10092 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10093 if (procs == null) { 10094 return; 10095 } 10096 10097 pw.println("Applications Database Info:"); 10098 10099 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10100 ProcessRecord r = procs.get(i); 10101 if (r.thread != null) { 10102 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10103 pw.flush(); 10104 try { 10105 TransferPipe tp = new TransferPipe(); 10106 try { 10107 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10108 tp.go(fd); 10109 } finally { 10110 tp.kill(); 10111 } 10112 } catch (IOException e) { 10113 pw.println("Failure while dumping the app: " + r); 10114 pw.flush(); 10115 } catch (RemoteException e) { 10116 pw.println("Got a RemoteException while dumping the app " + r); 10117 pw.flush(); 10118 } 10119 } 10120 } 10121 } 10122 10123 final static class MemItem { 10124 final String label; 10125 final String shortLabel; 10126 final long pss; 10127 final int id; 10128 ArrayList<MemItem> subitems; 10129 10130 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10131 label = _label; 10132 shortLabel = _shortLabel; 10133 pss = _pss; 10134 id = _id; 10135 } 10136 } 10137 10138 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10139 boolean sort) { 10140 if (sort) { 10141 Collections.sort(items, new Comparator<MemItem>() { 10142 @Override 10143 public int compare(MemItem lhs, MemItem rhs) { 10144 if (lhs.pss < rhs.pss) { 10145 return 1; 10146 } else if (lhs.pss > rhs.pss) { 10147 return -1; 10148 } 10149 return 0; 10150 } 10151 }); 10152 } 10153 10154 for (int i=0; i<items.size(); i++) { 10155 MemItem mi = items.get(i); 10156 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10157 if (mi.subitems != null) { 10158 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10159 } 10160 } 10161 } 10162 10163 // These are in KB. 10164 static final long[] DUMP_MEM_BUCKETS = new long[] { 10165 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10166 120*1024, 160*1024, 200*1024, 10167 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10168 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10169 }; 10170 10171 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10172 boolean stackLike) { 10173 int start = label.lastIndexOf('.'); 10174 if (start >= 0) start++; 10175 else start = 0; 10176 int end = label.length(); 10177 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10178 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10179 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10180 out.append(bucket); 10181 out.append(stackLike ? "MB." : "MB "); 10182 out.append(label, start, end); 10183 return; 10184 } 10185 } 10186 out.append(memKB/1024); 10187 out.append(stackLike ? "MB." : "MB "); 10188 out.append(label, start, end); 10189 } 10190 10191 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10192 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10193 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10194 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10195 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10196 }; 10197 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10198 "System", "Persistent", "Foreground", 10199 "Visible", "Perceptible", "Heavy Weight", 10200 "Backup", "A Services", "Home", "Previous", 10201 "B Services", "Background" 10202 }; 10203 10204 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10205 PrintWriter pw, String prefix, String[] args, boolean brief, 10206 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10207 boolean dumpAll = false; 10208 boolean oomOnly = false; 10209 10210 int opti = 0; 10211 while (opti < args.length) { 10212 String opt = args[opti]; 10213 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10214 break; 10215 } 10216 opti++; 10217 if ("-a".equals(opt)) { 10218 dumpAll = true; 10219 } else if ("--oom".equals(opt)) { 10220 oomOnly = true; 10221 } else if ("-h".equals(opt)) { 10222 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10223 pw.println(" -a: include all available information for each process."); 10224 pw.println(" --oom: only show processes organized by oom adj."); 10225 pw.println("If [process] is specified it can be the name or "); 10226 pw.println("pid of a specific process to dump."); 10227 return; 10228 } else { 10229 pw.println("Unknown argument: " + opt + "; use -h for help"); 10230 } 10231 } 10232 10233 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10234 if (procs == null) { 10235 return; 10236 } 10237 10238 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10239 long uptime = SystemClock.uptimeMillis(); 10240 long realtime = SystemClock.elapsedRealtime(); 10241 10242 if (procs.size() == 1 || isCheckinRequest) { 10243 dumpAll = true; 10244 } 10245 10246 if (isCheckinRequest) { 10247 // short checkin version 10248 pw.println(uptime + "," + realtime); 10249 pw.flush(); 10250 } else { 10251 pw.println("Applications Memory Usage (kB):"); 10252 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10253 } 10254 10255 String[] innerArgs = new String[args.length-opti]; 10256 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10257 10258 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10259 long nativePss=0, dalvikPss=0, otherPss=0; 10260 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10261 10262 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10263 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10264 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10265 10266 long totalPss = 0; 10267 10268 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10269 ProcessRecord r = procs.get(i); 10270 if (r.thread != null) { 10271 if (!isCheckinRequest && dumpAll) { 10272 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10273 pw.flush(); 10274 } 10275 Debug.MemoryInfo mi = null; 10276 if (dumpAll) { 10277 try { 10278 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10279 } catch (RemoteException e) { 10280 if (!isCheckinRequest) { 10281 pw.println("Got RemoteException!"); 10282 pw.flush(); 10283 } 10284 } 10285 } else { 10286 mi = new Debug.MemoryInfo(); 10287 Debug.getMemoryInfo(r.pid, mi); 10288 } 10289 10290 if (!isCheckinRequest && mi != null) { 10291 long myTotalPss = mi.getTotalPss(); 10292 totalPss += myTotalPss; 10293 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10294 r.processName, myTotalPss, 0); 10295 procMems.add(pssItem); 10296 10297 nativePss += mi.nativePss; 10298 dalvikPss += mi.dalvikPss; 10299 otherPss += mi.otherPss; 10300 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10301 long mem = mi.getOtherPss(j); 10302 miscPss[j] += mem; 10303 otherPss -= mem; 10304 } 10305 10306 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10307 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10308 || oomIndex == (oomPss.length-1)) { 10309 oomPss[oomIndex] += myTotalPss; 10310 if (oomProcs[oomIndex] == null) { 10311 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10312 } 10313 oomProcs[oomIndex].add(pssItem); 10314 break; 10315 } 10316 } 10317 } 10318 } 10319 } 10320 10321 if (!isCheckinRequest && procs.size() > 1) { 10322 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10323 10324 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10325 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10326 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10327 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10328 String label = Debug.MemoryInfo.getOtherLabel(j); 10329 catMems.add(new MemItem(label, label, miscPss[j], j)); 10330 } 10331 10332 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10333 for (int j=0; j<oomPss.length; j++) { 10334 if (oomPss[j] != 0) { 10335 String label = DUMP_MEM_OOM_LABEL[j]; 10336 MemItem item = new MemItem(label, label, oomPss[j], 10337 DUMP_MEM_OOM_ADJ[j]); 10338 item.subitems = oomProcs[j]; 10339 oomMems.add(item); 10340 } 10341 } 10342 10343 if (outTag != null || outStack != null) { 10344 if (outTag != null) { 10345 appendMemBucket(outTag, totalPss, "total", false); 10346 } 10347 if (outStack != null) { 10348 appendMemBucket(outStack, totalPss, "total", true); 10349 } 10350 boolean firstLine = true; 10351 for (int i=0; i<oomMems.size(); i++) { 10352 MemItem miCat = oomMems.get(i); 10353 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10354 continue; 10355 } 10356 if (miCat.id < ProcessList.SERVICE_ADJ 10357 || miCat.id == ProcessList.HOME_APP_ADJ 10358 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10359 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10360 outTag.append(" / "); 10361 } 10362 if (outStack != null) { 10363 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10364 if (firstLine) { 10365 outStack.append(":"); 10366 firstLine = false; 10367 } 10368 outStack.append("\n\t at "); 10369 } else { 10370 outStack.append("$"); 10371 } 10372 } 10373 for (int j=0; j<miCat.subitems.size(); j++) { 10374 MemItem mi = miCat.subitems.get(j); 10375 if (j > 0) { 10376 if (outTag != null) { 10377 outTag.append(" "); 10378 } 10379 if (outStack != null) { 10380 outStack.append("$"); 10381 } 10382 } 10383 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10384 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10385 } 10386 if (outStack != null) { 10387 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10388 } 10389 } 10390 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10391 outStack.append("("); 10392 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10393 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10394 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10395 outStack.append(":"); 10396 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10397 } 10398 } 10399 outStack.append(")"); 10400 } 10401 } 10402 } 10403 } 10404 10405 if (!brief && !oomOnly) { 10406 pw.println(); 10407 pw.println("Total PSS by process:"); 10408 dumpMemItems(pw, " ", procMems, true); 10409 pw.println(); 10410 } 10411 pw.println("Total PSS by OOM adjustment:"); 10412 dumpMemItems(pw, " ", oomMems, false); 10413 if (!oomOnly) { 10414 PrintWriter out = categoryPw != null ? categoryPw : pw; 10415 out.println(); 10416 out.println("Total PSS by category:"); 10417 dumpMemItems(out, " ", catMems, true); 10418 } 10419 pw.println(); 10420 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10421 final int[] SINGLE_LONG_FORMAT = new int[] { 10422 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10423 }; 10424 long[] longOut = new long[1]; 10425 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10426 SINGLE_LONG_FORMAT, null, longOut, null); 10427 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10428 longOut[0] = 0; 10429 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10430 SINGLE_LONG_FORMAT, null, longOut, null); 10431 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10432 longOut[0] = 0; 10433 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10434 SINGLE_LONG_FORMAT, null, longOut, null); 10435 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10436 longOut[0] = 0; 10437 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10438 SINGLE_LONG_FORMAT, null, longOut, null); 10439 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10440 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10441 pw.print(shared); pw.println(" kB"); 10442 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10443 pw.print(voltile); pw.println(" kB volatile"); 10444 } 10445 } 10446 10447 /** 10448 * Searches array of arguments for the specified string 10449 * @param args array of argument strings 10450 * @param value value to search for 10451 * @return true if the value is contained in the array 10452 */ 10453 private static boolean scanArgs(String[] args, String value) { 10454 if (args != null) { 10455 for (String arg : args) { 10456 if (value.equals(arg)) { 10457 return true; 10458 } 10459 } 10460 } 10461 return false; 10462 } 10463 10464 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10465 ContentProviderRecord cpr, boolean always) { 10466 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10467 10468 if (!inLaunching || always) { 10469 synchronized (cpr) { 10470 cpr.launchingApp = null; 10471 cpr.notifyAll(); 10472 } 10473 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10474 String names[] = cpr.info.authority.split(";"); 10475 for (int j = 0; j < names.length; j++) { 10476 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10477 } 10478 } 10479 10480 for (int i=0; i<cpr.connections.size(); i++) { 10481 ContentProviderConnection conn = cpr.connections.get(i); 10482 if (conn.waiting) { 10483 // If this connection is waiting for the provider, then we don't 10484 // need to mess with its process unless we are always removing 10485 // or for some reason the provider is not currently launching. 10486 if (inLaunching && !always) { 10487 continue; 10488 } 10489 } 10490 ProcessRecord capp = conn.client; 10491 conn.dead = true; 10492 if (conn.stableCount > 0) { 10493 if (!capp.persistent && capp.thread != null 10494 && capp.pid != 0 10495 && capp.pid != MY_PID) { 10496 Slog.i(TAG, "Kill " + capp.processName 10497 + " (pid " + capp.pid + "): provider " + cpr.info.name 10498 + " in dying process " + (proc != null ? proc.processName : "??")); 10499 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10500 capp.processName, capp.setAdj, "dying provider " 10501 + cpr.name.toShortString()); 10502 Process.killProcessQuiet(capp.pid); 10503 } 10504 } else if (capp.thread != null && conn.provider.provider != null) { 10505 try { 10506 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10507 } catch (RemoteException e) { 10508 } 10509 // In the protocol here, we don't expect the client to correctly 10510 // clean up this connection, we'll just remove it. 10511 cpr.connections.remove(i); 10512 conn.client.conProviders.remove(conn); 10513 } 10514 } 10515 10516 if (inLaunching && always) { 10517 mLaunchingProviders.remove(cpr); 10518 } 10519 return inLaunching; 10520 } 10521 10522 /** 10523 * Main code for cleaning up a process when it has gone away. This is 10524 * called both as a result of the process dying, or directly when stopping 10525 * a process when running in single process mode. 10526 */ 10527 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10528 boolean restarting, boolean allowRestart, int index) { 10529 if (index >= 0) { 10530 mLruProcesses.remove(index); 10531 } 10532 10533 mProcessesToGc.remove(app); 10534 10535 // Dismiss any open dialogs. 10536 if (app.crashDialog != null) { 10537 app.crashDialog.dismiss(); 10538 app.crashDialog = null; 10539 } 10540 if (app.anrDialog != null) { 10541 app.anrDialog.dismiss(); 10542 app.anrDialog = null; 10543 } 10544 if (app.waitDialog != null) { 10545 app.waitDialog.dismiss(); 10546 app.waitDialog = null; 10547 } 10548 10549 app.crashing = false; 10550 app.notResponding = false; 10551 10552 app.resetPackageList(); 10553 app.unlinkDeathRecipient(); 10554 app.thread = null; 10555 app.forcingToForeground = null; 10556 app.foregroundServices = false; 10557 app.foregroundActivities = false; 10558 app.hasShownUi = false; 10559 app.hasAboveClient = false; 10560 10561 mServices.killServicesLocked(app, allowRestart); 10562 10563 boolean restart = false; 10564 10565 // Remove published content providers. 10566 if (!app.pubProviders.isEmpty()) { 10567 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10568 while (it.hasNext()) { 10569 ContentProviderRecord cpr = it.next(); 10570 10571 final boolean always = app.bad || !allowRestart; 10572 if (removeDyingProviderLocked(app, cpr, always) || always) { 10573 // We left the provider in the launching list, need to 10574 // restart it. 10575 restart = true; 10576 } 10577 10578 cpr.provider = null; 10579 cpr.proc = null; 10580 } 10581 app.pubProviders.clear(); 10582 } 10583 10584 // Take care of any launching providers waiting for this process. 10585 if (checkAppInLaunchingProvidersLocked(app, false)) { 10586 restart = true; 10587 } 10588 10589 // Unregister from connected content providers. 10590 if (!app.conProviders.isEmpty()) { 10591 for (int i=0; i<app.conProviders.size(); i++) { 10592 ContentProviderConnection conn = app.conProviders.get(i); 10593 conn.provider.connections.remove(conn); 10594 } 10595 app.conProviders.clear(); 10596 } 10597 10598 // At this point there may be remaining entries in mLaunchingProviders 10599 // where we were the only one waiting, so they are no longer of use. 10600 // Look for these and clean up if found. 10601 // XXX Commented out for now. Trying to figure out a way to reproduce 10602 // the actual situation to identify what is actually going on. 10603 if (false) { 10604 for (int i=0; i<mLaunchingProviders.size(); i++) { 10605 ContentProviderRecord cpr = (ContentProviderRecord) 10606 mLaunchingProviders.get(i); 10607 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10608 synchronized (cpr) { 10609 cpr.launchingApp = null; 10610 cpr.notifyAll(); 10611 } 10612 } 10613 } 10614 } 10615 10616 skipCurrentReceiverLocked(app); 10617 10618 // Unregister any receivers. 10619 if (app.receivers.size() > 0) { 10620 Iterator<ReceiverList> it = app.receivers.iterator(); 10621 while (it.hasNext()) { 10622 removeReceiverLocked(it.next()); 10623 } 10624 app.receivers.clear(); 10625 } 10626 10627 // If the app is undergoing backup, tell the backup manager about it 10628 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10629 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10630 try { 10631 IBackupManager bm = IBackupManager.Stub.asInterface( 10632 ServiceManager.getService(Context.BACKUP_SERVICE)); 10633 bm.agentDisconnected(app.info.packageName); 10634 } catch (RemoteException e) { 10635 // can't happen; backup manager is local 10636 } 10637 } 10638 10639 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10640 ProcessChangeItem item = mPendingProcessChanges.get(i); 10641 if (item.pid == app.pid) { 10642 mPendingProcessChanges.remove(i); 10643 mAvailProcessChanges.add(item); 10644 } 10645 } 10646 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10647 10648 // If the caller is restarting this app, then leave it in its 10649 // current lists and let the caller take care of it. 10650 if (restarting) { 10651 return; 10652 } 10653 10654 if (!app.persistent || app.isolated) { 10655 if (DEBUG_PROCESSES) Slog.v(TAG, 10656 "Removing non-persistent process during cleanup: " + app); 10657 mProcessNames.remove(app.processName, app.uid); 10658 mIsolatedProcesses.remove(app.uid); 10659 if (mHeavyWeightProcess == app) { 10660 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10661 mHeavyWeightProcess.userId, 0)); 10662 mHeavyWeightProcess = null; 10663 } 10664 } else if (!app.removed) { 10665 // This app is persistent, so we need to keep its record around. 10666 // If it is not already on the pending app list, add it there 10667 // and start a new process for it. 10668 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10669 mPersistentStartingProcesses.add(app); 10670 restart = true; 10671 } 10672 } 10673 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10674 "Clean-up removing on hold: " + app); 10675 mProcessesOnHold.remove(app); 10676 10677 if (app == mHomeProcess) { 10678 mHomeProcess = null; 10679 } 10680 if (app == mPreviousProcess) { 10681 mPreviousProcess = null; 10682 } 10683 10684 if (restart && !app.isolated) { 10685 // We have components that still need to be running in the 10686 // process, so re-launch it. 10687 mProcessNames.put(app.processName, app.uid, app); 10688 startProcessLocked(app, "restart", app.processName); 10689 } else if (app.pid > 0 && app.pid != MY_PID) { 10690 // Goodbye! 10691 synchronized (mPidsSelfLocked) { 10692 mPidsSelfLocked.remove(app.pid); 10693 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10694 } 10695 app.setPid(0); 10696 } 10697 } 10698 10699 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10700 // Look through the content providers we are waiting to have launched, 10701 // and if any run in this process then either schedule a restart of 10702 // the process or kill the client waiting for it if this process has 10703 // gone bad. 10704 int NL = mLaunchingProviders.size(); 10705 boolean restart = false; 10706 for (int i=0; i<NL; i++) { 10707 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10708 if (cpr.launchingApp == app) { 10709 if (!alwaysBad && !app.bad) { 10710 restart = true; 10711 } else { 10712 removeDyingProviderLocked(app, cpr, true); 10713 // cpr should have been removed from mLaunchingProviders 10714 NL = mLaunchingProviders.size(); 10715 i--; 10716 } 10717 } 10718 } 10719 return restart; 10720 } 10721 10722 // ========================================================= 10723 // SERVICES 10724 // ========================================================= 10725 10726 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10727 int flags) { 10728 enforceNotIsolatedCaller("getServices"); 10729 synchronized (this) { 10730 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10731 } 10732 } 10733 10734 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10735 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10736 synchronized (this) { 10737 return mServices.getRunningServiceControlPanelLocked(name); 10738 } 10739 } 10740 10741 public ComponentName startService(IApplicationThread caller, Intent service, 10742 String resolvedType, int userId) { 10743 enforceNotIsolatedCaller("startService"); 10744 // Refuse possible leaked file descriptors 10745 if (service != null && service.hasFileDescriptors() == true) { 10746 throw new IllegalArgumentException("File descriptors passed in Intent"); 10747 } 10748 10749 if (DEBUG_SERVICE) 10750 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10751 synchronized(this) { 10752 final int callingPid = Binder.getCallingPid(); 10753 final int callingUid = Binder.getCallingUid(); 10754 checkValidCaller(callingUid, userId); 10755 final long origId = Binder.clearCallingIdentity(); 10756 ComponentName res = mServices.startServiceLocked(caller, service, 10757 resolvedType, callingPid, callingUid, userId); 10758 Binder.restoreCallingIdentity(origId); 10759 return res; 10760 } 10761 } 10762 10763 ComponentName startServiceInPackage(int uid, 10764 Intent service, String resolvedType, int userId) { 10765 synchronized(this) { 10766 if (DEBUG_SERVICE) 10767 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10768 final long origId = Binder.clearCallingIdentity(); 10769 ComponentName res = mServices.startServiceLocked(null, service, 10770 resolvedType, -1, uid, userId); 10771 Binder.restoreCallingIdentity(origId); 10772 return res; 10773 } 10774 } 10775 10776 public int stopService(IApplicationThread caller, Intent service, 10777 String resolvedType, int userId) { 10778 enforceNotIsolatedCaller("stopService"); 10779 // Refuse possible leaked file descriptors 10780 if (service != null && service.hasFileDescriptors() == true) { 10781 throw new IllegalArgumentException("File descriptors passed in Intent"); 10782 } 10783 10784 checkValidCaller(Binder.getCallingUid(), userId); 10785 10786 synchronized(this) { 10787 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10788 } 10789 } 10790 10791 public IBinder peekService(Intent service, String resolvedType) { 10792 enforceNotIsolatedCaller("peekService"); 10793 // Refuse possible leaked file descriptors 10794 if (service != null && service.hasFileDescriptors() == true) { 10795 throw new IllegalArgumentException("File descriptors passed in Intent"); 10796 } 10797 synchronized(this) { 10798 return mServices.peekServiceLocked(service, resolvedType); 10799 } 10800 } 10801 10802 public boolean stopServiceToken(ComponentName className, IBinder token, 10803 int startId) { 10804 synchronized(this) { 10805 return mServices.stopServiceTokenLocked(className, token, startId); 10806 } 10807 } 10808 10809 public void setServiceForeground(ComponentName className, IBinder token, 10810 int id, Notification notification, boolean removeNotification) { 10811 synchronized(this) { 10812 mServices.setServiceForegroundLocked(className, token, id, notification, 10813 removeNotification); 10814 } 10815 } 10816 10817 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10818 boolean requireFull, String name, String callerPackage) { 10819 synchronized(this) { 10820 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10821 requireFull, name, callerPackage); 10822 } 10823 } 10824 10825 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10826 boolean requireFull, String name, String callerPackage) { 10827 final int callingUserId = UserHandle.getUserId(callingUid); 10828 if (callingUserId != userId) { 10829 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10830 if ((requireFull || checkComponentPermission( 10831 android.Manifest.permission.INTERACT_ACROSS_USERS, 10832 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10833 && checkComponentPermission( 10834 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10835 callingPid, callingUid, -1, true) 10836 != PackageManager.PERMISSION_GRANTED) { 10837 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10838 // In this case, they would like to just execute as their 10839 // owner user instead of failing. 10840 userId = callingUserId; 10841 } else { 10842 StringBuilder builder = new StringBuilder(128); 10843 builder.append("Permission Denial: "); 10844 builder.append(name); 10845 if (callerPackage != null) { 10846 builder.append(" from "); 10847 builder.append(callerPackage); 10848 } 10849 builder.append(" asks to run as user "); 10850 builder.append(userId); 10851 builder.append(" but is calling from user "); 10852 builder.append(UserHandle.getUserId(callingUid)); 10853 builder.append("; this requires "); 10854 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10855 if (!requireFull) { 10856 builder.append(" or "); 10857 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10858 } 10859 String msg = builder.toString(); 10860 Slog.w(TAG, msg); 10861 throw new SecurityException(msg); 10862 } 10863 } 10864 } 10865 if (userId == UserHandle.USER_CURRENT 10866 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10867 userId = mCurrentUserId; 10868 } 10869 if (!allowAll && userId < 0) { 10870 throw new IllegalArgumentException( 10871 "Call does not support special user #" + userId); 10872 } 10873 } 10874 return userId; 10875 } 10876 10877 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10878 String className, int flags) { 10879 boolean result = false; 10880 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10881 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10882 if (ActivityManager.checkUidPermission( 10883 android.Manifest.permission.INTERACT_ACROSS_USERS, 10884 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10885 ComponentName comp = new ComponentName(aInfo.packageName, className); 10886 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10887 + " requests FLAG_SINGLE_USER, but app does not hold " 10888 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10889 Slog.w(TAG, msg); 10890 throw new SecurityException(msg); 10891 } 10892 result = true; 10893 } 10894 } else if (componentProcessName == aInfo.packageName) { 10895 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10896 } else if ("system".equals(componentProcessName)) { 10897 result = true; 10898 } 10899 if (DEBUG_MU) { 10900 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10901 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10902 } 10903 return result; 10904 } 10905 10906 public int bindService(IApplicationThread caller, IBinder token, 10907 Intent service, String resolvedType, 10908 IServiceConnection connection, int flags, int userId) { 10909 enforceNotIsolatedCaller("bindService"); 10910 // Refuse possible leaked file descriptors 10911 if (service != null && service.hasFileDescriptors() == true) { 10912 throw new IllegalArgumentException("File descriptors passed in Intent"); 10913 } 10914 10915 synchronized(this) { 10916 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10917 connection, flags, userId); 10918 } 10919 } 10920 10921 public boolean unbindService(IServiceConnection connection) { 10922 synchronized (this) { 10923 return mServices.unbindServiceLocked(connection); 10924 } 10925 } 10926 10927 public void publishService(IBinder token, Intent intent, IBinder service) { 10928 // Refuse possible leaked file descriptors 10929 if (intent != null && intent.hasFileDescriptors() == true) { 10930 throw new IllegalArgumentException("File descriptors passed in Intent"); 10931 } 10932 10933 synchronized(this) { 10934 if (!(token instanceof ServiceRecord)) { 10935 throw new IllegalArgumentException("Invalid service token"); 10936 } 10937 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10938 } 10939 } 10940 10941 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10942 // Refuse possible leaked file descriptors 10943 if (intent != null && intent.hasFileDescriptors() == true) { 10944 throw new IllegalArgumentException("File descriptors passed in Intent"); 10945 } 10946 10947 synchronized(this) { 10948 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10949 } 10950 } 10951 10952 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10953 synchronized(this) { 10954 if (!(token instanceof ServiceRecord)) { 10955 throw new IllegalArgumentException("Invalid service token"); 10956 } 10957 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10958 } 10959 } 10960 10961 // ========================================================= 10962 // BACKUP AND RESTORE 10963 // ========================================================= 10964 10965 // Cause the target app to be launched if necessary and its backup agent 10966 // instantiated. The backup agent will invoke backupAgentCreated() on the 10967 // activity manager to announce its creation. 10968 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10969 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10970 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10971 10972 synchronized(this) { 10973 // !!! TODO: currently no check here that we're already bound 10974 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10975 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10976 synchronized (stats) { 10977 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10978 } 10979 10980 // Backup agent is now in use, its package can't be stopped. 10981 try { 10982 AppGlobals.getPackageManager().setPackageStoppedState( 10983 app.packageName, false, UserHandle.getUserId(app.uid)); 10984 } catch (RemoteException e) { 10985 } catch (IllegalArgumentException e) { 10986 Slog.w(TAG, "Failed trying to unstop package " 10987 + app.packageName + ": " + e); 10988 } 10989 10990 BackupRecord r = new BackupRecord(ss, app, backupMode); 10991 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10992 ? new ComponentName(app.packageName, app.backupAgentName) 10993 : new ComponentName("android", "FullBackupAgent"); 10994 // startProcessLocked() returns existing proc's record if it's already running 10995 ProcessRecord proc = startProcessLocked(app.processName, app, 10996 false, 0, "backup", hostingName, false, false); 10997 if (proc == null) { 10998 Slog.e(TAG, "Unable to start backup agent process " + r); 10999 return false; 11000 } 11001 11002 r.app = proc; 11003 mBackupTarget = r; 11004 mBackupAppName = app.packageName; 11005 11006 // Try not to kill the process during backup 11007 updateOomAdjLocked(proc); 11008 11009 // If the process is already attached, schedule the creation of the backup agent now. 11010 // If it is not yet live, this will be done when it attaches to the framework. 11011 if (proc.thread != null) { 11012 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11013 try { 11014 proc.thread.scheduleCreateBackupAgent(app, 11015 compatibilityInfoForPackageLocked(app), backupMode); 11016 } catch (RemoteException e) { 11017 // Will time out on the backup manager side 11018 } 11019 } else { 11020 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11021 } 11022 // Invariants: at this point, the target app process exists and the application 11023 // is either already running or in the process of coming up. mBackupTarget and 11024 // mBackupAppName describe the app, so that when it binds back to the AM we 11025 // know that it's scheduled for a backup-agent operation. 11026 } 11027 11028 return true; 11029 } 11030 11031 // A backup agent has just come up 11032 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11033 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11034 + " = " + agent); 11035 11036 synchronized(this) { 11037 if (!agentPackageName.equals(mBackupAppName)) { 11038 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11039 return; 11040 } 11041 } 11042 11043 long oldIdent = Binder.clearCallingIdentity(); 11044 try { 11045 IBackupManager bm = IBackupManager.Stub.asInterface( 11046 ServiceManager.getService(Context.BACKUP_SERVICE)); 11047 bm.agentConnected(agentPackageName, agent); 11048 } catch (RemoteException e) { 11049 // can't happen; the backup manager service is local 11050 } catch (Exception e) { 11051 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11052 e.printStackTrace(); 11053 } finally { 11054 Binder.restoreCallingIdentity(oldIdent); 11055 } 11056 } 11057 11058 // done with this agent 11059 public void unbindBackupAgent(ApplicationInfo appInfo) { 11060 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11061 if (appInfo == null) { 11062 Slog.w(TAG, "unbind backup agent for null app"); 11063 return; 11064 } 11065 11066 synchronized(this) { 11067 if (mBackupAppName == null) { 11068 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11069 return; 11070 } 11071 11072 if (!mBackupAppName.equals(appInfo.packageName)) { 11073 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11074 return; 11075 } 11076 11077 ProcessRecord proc = mBackupTarget.app; 11078 mBackupTarget = null; 11079 mBackupAppName = null; 11080 11081 // Not backing this app up any more; reset its OOM adjustment 11082 updateOomAdjLocked(proc); 11083 11084 // If the app crashed during backup, 'thread' will be null here 11085 if (proc.thread != null) { 11086 try { 11087 proc.thread.scheduleDestroyBackupAgent(appInfo, 11088 compatibilityInfoForPackageLocked(appInfo)); 11089 } catch (Exception e) { 11090 Slog.e(TAG, "Exception when unbinding backup agent:"); 11091 e.printStackTrace(); 11092 } 11093 } 11094 } 11095 } 11096 // ========================================================= 11097 // BROADCASTS 11098 // ========================================================= 11099 11100 private final List getStickiesLocked(String action, IntentFilter filter, 11101 List cur, int userId) { 11102 final ContentResolver resolver = mContext.getContentResolver(); 11103 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11104 if (stickies == null) { 11105 return cur; 11106 } 11107 final ArrayList<Intent> list = stickies.get(action); 11108 if (list == null) { 11109 return cur; 11110 } 11111 int N = list.size(); 11112 for (int i=0; i<N; i++) { 11113 Intent intent = list.get(i); 11114 if (filter.match(resolver, intent, true, TAG) >= 0) { 11115 if (cur == null) { 11116 cur = new ArrayList<Intent>(); 11117 } 11118 cur.add(intent); 11119 } 11120 } 11121 return cur; 11122 } 11123 11124 boolean isPendingBroadcastProcessLocked(int pid) { 11125 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11126 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11127 } 11128 11129 void skipPendingBroadcastLocked(int pid) { 11130 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11131 for (BroadcastQueue queue : mBroadcastQueues) { 11132 queue.skipPendingBroadcastLocked(pid); 11133 } 11134 } 11135 11136 // The app just attached; send any pending broadcasts that it should receive 11137 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11138 boolean didSomething = false; 11139 for (BroadcastQueue queue : mBroadcastQueues) { 11140 didSomething |= queue.sendPendingBroadcastsLocked(app); 11141 } 11142 return didSomething; 11143 } 11144 11145 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11146 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11147 enforceNotIsolatedCaller("registerReceiver"); 11148 int callingUid; 11149 int callingPid; 11150 synchronized(this) { 11151 ProcessRecord callerApp = null; 11152 if (caller != null) { 11153 callerApp = getRecordForAppLocked(caller); 11154 if (callerApp == null) { 11155 throw new SecurityException( 11156 "Unable to find app for caller " + caller 11157 + " (pid=" + Binder.getCallingPid() 11158 + ") when registering receiver " + receiver); 11159 } 11160 if (callerApp.info.uid != Process.SYSTEM_UID && 11161 !callerApp.pkgList.contains(callerPackage)) { 11162 throw new SecurityException("Given caller package " + callerPackage 11163 + " is not running in process " + callerApp); 11164 } 11165 callingUid = callerApp.info.uid; 11166 callingPid = callerApp.pid; 11167 } else { 11168 callerPackage = null; 11169 callingUid = Binder.getCallingUid(); 11170 callingPid = Binder.getCallingPid(); 11171 } 11172 11173 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11174 true, true, "registerReceiver", callerPackage); 11175 11176 List allSticky = null; 11177 11178 // Look for any matching sticky broadcasts... 11179 Iterator actions = filter.actionsIterator(); 11180 if (actions != null) { 11181 while (actions.hasNext()) { 11182 String action = (String)actions.next(); 11183 allSticky = getStickiesLocked(action, filter, allSticky, 11184 UserHandle.USER_ALL); 11185 allSticky = getStickiesLocked(action, filter, allSticky, 11186 UserHandle.getUserId(callingUid)); 11187 } 11188 } else { 11189 allSticky = getStickiesLocked(null, filter, allSticky, 11190 UserHandle.USER_ALL); 11191 allSticky = getStickiesLocked(null, filter, allSticky, 11192 UserHandle.getUserId(callingUid)); 11193 } 11194 11195 // The first sticky in the list is returned directly back to 11196 // the client. 11197 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11198 11199 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11200 + ": " + sticky); 11201 11202 if (receiver == null) { 11203 return sticky; 11204 } 11205 11206 ReceiverList rl 11207 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11208 if (rl == null) { 11209 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11210 userId, receiver); 11211 if (rl.app != null) { 11212 rl.app.receivers.add(rl); 11213 } else { 11214 try { 11215 receiver.asBinder().linkToDeath(rl, 0); 11216 } catch (RemoteException e) { 11217 return sticky; 11218 } 11219 rl.linkedToDeath = true; 11220 } 11221 mRegisteredReceivers.put(receiver.asBinder(), rl); 11222 } else if (rl.uid != callingUid) { 11223 throw new IllegalArgumentException( 11224 "Receiver requested to register for uid " + callingUid 11225 + " was previously registered for uid " + rl.uid); 11226 } else if (rl.pid != callingPid) { 11227 throw new IllegalArgumentException( 11228 "Receiver requested to register for pid " + callingPid 11229 + " was previously registered for pid " + rl.pid); 11230 } else if (rl.userId != userId) { 11231 throw new IllegalArgumentException( 11232 "Receiver requested to register for user " + userId 11233 + " was previously registered for user " + rl.userId); 11234 } 11235 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11236 permission, callingUid, userId); 11237 rl.add(bf); 11238 if (!bf.debugCheck()) { 11239 Slog.w(TAG, "==> For Dynamic broadast"); 11240 } 11241 mReceiverResolver.addFilter(bf); 11242 11243 // Enqueue broadcasts for all existing stickies that match 11244 // this filter. 11245 if (allSticky != null) { 11246 ArrayList receivers = new ArrayList(); 11247 receivers.add(bf); 11248 11249 int N = allSticky.size(); 11250 for (int i=0; i<N; i++) { 11251 Intent intent = (Intent)allSticky.get(i); 11252 BroadcastQueue queue = broadcastQueueForIntent(intent); 11253 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11254 null, -1, -1, null, receivers, null, 0, null, null, 11255 false, true, true, -1); 11256 queue.enqueueParallelBroadcastLocked(r); 11257 queue.scheduleBroadcastsLocked(); 11258 } 11259 } 11260 11261 return sticky; 11262 } 11263 } 11264 11265 public void unregisterReceiver(IIntentReceiver receiver) { 11266 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11267 11268 final long origId = Binder.clearCallingIdentity(); 11269 try { 11270 boolean doTrim = false; 11271 11272 synchronized(this) { 11273 ReceiverList rl 11274 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11275 if (rl != null) { 11276 if (rl.curBroadcast != null) { 11277 BroadcastRecord r = rl.curBroadcast; 11278 final boolean doNext = finishReceiverLocked( 11279 receiver.asBinder(), r.resultCode, r.resultData, 11280 r.resultExtras, r.resultAbort, true); 11281 if (doNext) { 11282 doTrim = true; 11283 r.queue.processNextBroadcast(false); 11284 } 11285 } 11286 11287 if (rl.app != null) { 11288 rl.app.receivers.remove(rl); 11289 } 11290 removeReceiverLocked(rl); 11291 if (rl.linkedToDeath) { 11292 rl.linkedToDeath = false; 11293 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11294 } 11295 } 11296 } 11297 11298 // If we actually concluded any broadcasts, we might now be able 11299 // to trim the recipients' apps from our working set 11300 if (doTrim) { 11301 trimApplications(); 11302 return; 11303 } 11304 11305 } finally { 11306 Binder.restoreCallingIdentity(origId); 11307 } 11308 } 11309 11310 void removeReceiverLocked(ReceiverList rl) { 11311 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11312 int N = rl.size(); 11313 for (int i=0; i<N; i++) { 11314 mReceiverResolver.removeFilter(rl.get(i)); 11315 } 11316 } 11317 11318 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11319 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11320 ProcessRecord r = mLruProcesses.get(i); 11321 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11322 try { 11323 r.thread.dispatchPackageBroadcast(cmd, packages); 11324 } catch (RemoteException ex) { 11325 } 11326 } 11327 } 11328 } 11329 11330 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11331 int[] users) { 11332 List<ResolveInfo> receivers = null; 11333 try { 11334 HashSet<ComponentName> singleUserReceivers = null; 11335 boolean scannedFirstReceivers = false; 11336 for (int user : users) { 11337 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11338 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11339 if (newReceivers != null && newReceivers.size() == 0) { 11340 newReceivers = null; 11341 } 11342 if (receivers == null) { 11343 receivers = newReceivers; 11344 } else if (newReceivers != null) { 11345 // We need to concatenate the additional receivers 11346 // found with what we have do far. This would be easy, 11347 // but we also need to de-dup any receivers that are 11348 // singleUser. 11349 if (!scannedFirstReceivers) { 11350 // Collect any single user receivers we had already retrieved. 11351 scannedFirstReceivers = true; 11352 for (int i=0; i<receivers.size(); i++) { 11353 ResolveInfo ri = receivers.get(i); 11354 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11355 ComponentName cn = new ComponentName( 11356 ri.activityInfo.packageName, ri.activityInfo.name); 11357 if (singleUserReceivers == null) { 11358 singleUserReceivers = new HashSet<ComponentName>(); 11359 } 11360 singleUserReceivers.add(cn); 11361 } 11362 } 11363 } 11364 // Add the new results to the existing results, tracking 11365 // and de-dupping single user receivers. 11366 for (int i=0; i<newReceivers.size(); i++) { 11367 ResolveInfo ri = receivers.get(i); 11368 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11369 ComponentName cn = new ComponentName( 11370 ri.activityInfo.packageName, ri.activityInfo.name); 11371 if (singleUserReceivers == null) { 11372 singleUserReceivers = new HashSet<ComponentName>(); 11373 } 11374 if (!singleUserReceivers.contains(cn)) { 11375 singleUserReceivers.add(cn); 11376 receivers.add(ri); 11377 } 11378 } else { 11379 receivers.add(ri); 11380 } 11381 } 11382 } 11383 } 11384 } catch (RemoteException ex) { 11385 // pm is in same process, this will never happen. 11386 } 11387 return receivers; 11388 } 11389 11390 private final int broadcastIntentLocked(ProcessRecord callerApp, 11391 String callerPackage, Intent intent, String resolvedType, 11392 IIntentReceiver resultTo, int resultCode, String resultData, 11393 Bundle map, String requiredPermission, 11394 boolean ordered, boolean sticky, int callingPid, int callingUid, 11395 int userId) { 11396 intent = new Intent(intent); 11397 11398 // By default broadcasts do not go to stopped apps. 11399 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11400 11401 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11402 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11403 + " ordered=" + ordered + " userid=" + userId); 11404 if ((resultTo != null) && !ordered) { 11405 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11406 } 11407 11408 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11409 true, false, "broadcast", callerPackage); 11410 11411 // Make sure that the user who is receiving this broadcast is started 11412 // If not, we will just skip it. 11413 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11414 Slog.w(TAG, "Skipping broadcast of " + intent 11415 + ": user " + userId + " is stopped"); 11416 return ActivityManager.BROADCAST_SUCCESS; 11417 } 11418 11419 /* 11420 * Prevent non-system code (defined here to be non-persistent 11421 * processes) from sending protected broadcasts. 11422 */ 11423 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11424 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11425 callingUid == 0) { 11426 // Always okay. 11427 } else if (callerApp == null || !callerApp.persistent) { 11428 try { 11429 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11430 intent.getAction())) { 11431 String msg = "Permission Denial: not allowed to send broadcast " 11432 + intent.getAction() + " from pid=" 11433 + callingPid + ", uid=" + callingUid; 11434 Slog.w(TAG, msg); 11435 throw new SecurityException(msg); 11436 } 11437 } catch (RemoteException e) { 11438 Slog.w(TAG, "Remote exception", e); 11439 return ActivityManager.BROADCAST_SUCCESS; 11440 } 11441 } 11442 11443 // Handle special intents: if this broadcast is from the package 11444 // manager about a package being removed, we need to remove all of 11445 // its activities from the history stack. 11446 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11447 intent.getAction()); 11448 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11449 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11450 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11451 || uidRemoved) { 11452 if (checkComponentPermission( 11453 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11454 callingPid, callingUid, -1, true) 11455 == PackageManager.PERMISSION_GRANTED) { 11456 if (uidRemoved) { 11457 final Bundle intentExtras = intent.getExtras(); 11458 final int uid = intentExtras != null 11459 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11460 if (uid >= 0) { 11461 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11462 synchronized (bs) { 11463 bs.removeUidStatsLocked(uid); 11464 } 11465 } 11466 } else { 11467 // If resources are unavailable just force stop all 11468 // those packages and flush the attribute cache as well. 11469 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11470 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11471 if (list != null && (list.length > 0)) { 11472 for (String pkg : list) { 11473 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11474 } 11475 sendPackageBroadcastLocked( 11476 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11477 } 11478 } else { 11479 Uri data = intent.getData(); 11480 String ssp; 11481 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11482 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11483 forceStopPackageLocked(ssp, 11484 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11485 false, userId); 11486 } 11487 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11488 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11489 new String[] {ssp}, userId); 11490 } 11491 } 11492 } 11493 } 11494 } else { 11495 String msg = "Permission Denial: " + intent.getAction() 11496 + " broadcast from " + callerPackage + " (pid=" + callingPid 11497 + ", uid=" + callingUid + ")" 11498 + " requires " 11499 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11500 Slog.w(TAG, msg); 11501 throw new SecurityException(msg); 11502 } 11503 11504 // Special case for adding a package: by default turn on compatibility 11505 // mode. 11506 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11507 Uri data = intent.getData(); 11508 String ssp; 11509 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11510 mCompatModePackages.handlePackageAddedLocked(ssp, 11511 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11512 } 11513 } 11514 11515 /* 11516 * If this is the time zone changed action, queue up a message that will reset the timezone 11517 * of all currently running processes. This message will get queued up before the broadcast 11518 * happens. 11519 */ 11520 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11521 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11522 } 11523 11524 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11525 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11526 } 11527 11528 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11529 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11530 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11531 } 11532 11533 // Add to the sticky list if requested. 11534 if (sticky) { 11535 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11536 callingPid, callingUid) 11537 != PackageManager.PERMISSION_GRANTED) { 11538 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11539 + callingPid + ", uid=" + callingUid 11540 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11541 Slog.w(TAG, msg); 11542 throw new SecurityException(msg); 11543 } 11544 if (requiredPermission != null) { 11545 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11546 + " and enforce permission " + requiredPermission); 11547 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11548 } 11549 if (intent.getComponent() != null) { 11550 throw new SecurityException( 11551 "Sticky broadcasts can't target a specific component"); 11552 } 11553 // We use userId directly here, since the "all" target is maintained 11554 // as a separate set of sticky broadcasts. 11555 if (userId != UserHandle.USER_ALL) { 11556 // But first, if this is not a broadcast to all users, then 11557 // make sure it doesn't conflict with an existing broadcast to 11558 // all users. 11559 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11560 UserHandle.USER_ALL); 11561 if (stickies != null) { 11562 ArrayList<Intent> list = stickies.get(intent.getAction()); 11563 if (list != null) { 11564 int N = list.size(); 11565 int i; 11566 for (i=0; i<N; i++) { 11567 if (intent.filterEquals(list.get(i))) { 11568 throw new IllegalArgumentException( 11569 "Sticky broadcast " + intent + " for user " 11570 + userId + " conflicts with existing global broadcast"); 11571 } 11572 } 11573 } 11574 } 11575 } 11576 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11577 if (stickies == null) { 11578 stickies = new HashMap<String, ArrayList<Intent>>(); 11579 mStickyBroadcasts.put(userId, stickies); 11580 } 11581 ArrayList<Intent> list = stickies.get(intent.getAction()); 11582 if (list == null) { 11583 list = new ArrayList<Intent>(); 11584 stickies.put(intent.getAction(), list); 11585 } 11586 int N = list.size(); 11587 int i; 11588 for (i=0; i<N; i++) { 11589 if (intent.filterEquals(list.get(i))) { 11590 // This sticky already exists, replace it. 11591 list.set(i, new Intent(intent)); 11592 break; 11593 } 11594 } 11595 if (i >= N) { 11596 list.add(new Intent(intent)); 11597 } 11598 } 11599 11600 int[] users; 11601 if (userId == UserHandle.USER_ALL) { 11602 // Caller wants broadcast to go to all started users. 11603 users = new int[mStartedUsers.size()]; 11604 for (int i=0; i<mStartedUsers.size(); i++) { 11605 users[i] = mStartedUsers.keyAt(i); 11606 } 11607 } else { 11608 // Caller wants broadcast to go to one specific user. 11609 users = new int[] {userId}; 11610 } 11611 11612 // Figure out who all will receive this broadcast. 11613 List receivers = null; 11614 List<BroadcastFilter> registeredReceivers = null; 11615 // Need to resolve the intent to interested receivers... 11616 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11617 == 0) { 11618 receivers = collectReceiverComponents(intent, resolvedType, users); 11619 } 11620 if (intent.getComponent() == null) { 11621 registeredReceivers = mReceiverResolver.queryIntent(intent, 11622 resolvedType, false, userId); 11623 } 11624 11625 final boolean replacePending = 11626 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11627 11628 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11629 + " replacePending=" + replacePending); 11630 11631 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11632 if (!ordered && NR > 0) { 11633 // If we are not serializing this broadcast, then send the 11634 // registered receivers separately so they don't wait for the 11635 // components to be launched. 11636 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11637 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11638 callerPackage, callingPid, callingUid, requiredPermission, 11639 registeredReceivers, resultTo, resultCode, resultData, map, 11640 ordered, sticky, false, userId); 11641 if (DEBUG_BROADCAST) Slog.v( 11642 TAG, "Enqueueing parallel broadcast " + r); 11643 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11644 if (!replaced) { 11645 queue.enqueueParallelBroadcastLocked(r); 11646 queue.scheduleBroadcastsLocked(); 11647 } 11648 registeredReceivers = null; 11649 NR = 0; 11650 } 11651 11652 // Merge into one list. 11653 int ir = 0; 11654 if (receivers != null) { 11655 // A special case for PACKAGE_ADDED: do not allow the package 11656 // being added to see this broadcast. This prevents them from 11657 // using this as a back door to get run as soon as they are 11658 // installed. Maybe in the future we want to have a special install 11659 // broadcast or such for apps, but we'd like to deliberately make 11660 // this decision. 11661 String skipPackages[] = null; 11662 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11663 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11664 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11665 Uri data = intent.getData(); 11666 if (data != null) { 11667 String pkgName = data.getSchemeSpecificPart(); 11668 if (pkgName != null) { 11669 skipPackages = new String[] { pkgName }; 11670 } 11671 } 11672 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11673 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11674 } 11675 if (skipPackages != null && (skipPackages.length > 0)) { 11676 for (String skipPackage : skipPackages) { 11677 if (skipPackage != null) { 11678 int NT = receivers.size(); 11679 for (int it=0; it<NT; it++) { 11680 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11681 if (curt.activityInfo.packageName.equals(skipPackage)) { 11682 receivers.remove(it); 11683 it--; 11684 NT--; 11685 } 11686 } 11687 } 11688 } 11689 } 11690 11691 int NT = receivers != null ? receivers.size() : 0; 11692 int it = 0; 11693 ResolveInfo curt = null; 11694 BroadcastFilter curr = null; 11695 while (it < NT && ir < NR) { 11696 if (curt == null) { 11697 curt = (ResolveInfo)receivers.get(it); 11698 } 11699 if (curr == null) { 11700 curr = registeredReceivers.get(ir); 11701 } 11702 if (curr.getPriority() >= curt.priority) { 11703 // Insert this broadcast record into the final list. 11704 receivers.add(it, curr); 11705 ir++; 11706 curr = null; 11707 it++; 11708 NT++; 11709 } else { 11710 // Skip to the next ResolveInfo in the final list. 11711 it++; 11712 curt = null; 11713 } 11714 } 11715 } 11716 while (ir < NR) { 11717 if (receivers == null) { 11718 receivers = new ArrayList(); 11719 } 11720 receivers.add(registeredReceivers.get(ir)); 11721 ir++; 11722 } 11723 11724 if ((receivers != null && receivers.size() > 0) 11725 || resultTo != null) { 11726 BroadcastQueue queue = broadcastQueueForIntent(intent); 11727 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11728 callerPackage, callingPid, callingUid, requiredPermission, 11729 receivers, resultTo, resultCode, resultData, map, ordered, 11730 sticky, false, userId); 11731 if (DEBUG_BROADCAST) Slog.v( 11732 TAG, "Enqueueing ordered broadcast " + r 11733 + ": prev had " + queue.mOrderedBroadcasts.size()); 11734 if (DEBUG_BROADCAST) { 11735 int seq = r.intent.getIntExtra("seq", -1); 11736 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11737 } 11738 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11739 if (!replaced) { 11740 queue.enqueueOrderedBroadcastLocked(r); 11741 queue.scheduleBroadcastsLocked(); 11742 } 11743 } 11744 11745 return ActivityManager.BROADCAST_SUCCESS; 11746 } 11747 11748 final Intent verifyBroadcastLocked(Intent intent) { 11749 // Refuse possible leaked file descriptors 11750 if (intent != null && intent.hasFileDescriptors() == true) { 11751 throw new IllegalArgumentException("File descriptors passed in Intent"); 11752 } 11753 11754 int flags = intent.getFlags(); 11755 11756 if (!mProcessesReady) { 11757 // if the caller really truly claims to know what they're doing, go 11758 // ahead and allow the broadcast without launching any receivers 11759 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11760 intent = new Intent(intent); 11761 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11762 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11763 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11764 + " before boot completion"); 11765 throw new IllegalStateException("Cannot broadcast before boot completed"); 11766 } 11767 } 11768 11769 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11770 throw new IllegalArgumentException( 11771 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11772 } 11773 11774 return intent; 11775 } 11776 11777 public final int broadcastIntent(IApplicationThread caller, 11778 Intent intent, String resolvedType, IIntentReceiver resultTo, 11779 int resultCode, String resultData, Bundle map, 11780 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11781 enforceNotIsolatedCaller("broadcastIntent"); 11782 synchronized(this) { 11783 intent = verifyBroadcastLocked(intent); 11784 11785 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11786 final int callingPid = Binder.getCallingPid(); 11787 final int callingUid = Binder.getCallingUid(); 11788 final long origId = Binder.clearCallingIdentity(); 11789 int res = broadcastIntentLocked(callerApp, 11790 callerApp != null ? callerApp.info.packageName : null, 11791 intent, resolvedType, resultTo, 11792 resultCode, resultData, map, requiredPermission, serialized, sticky, 11793 callingPid, callingUid, userId); 11794 Binder.restoreCallingIdentity(origId); 11795 return res; 11796 } 11797 } 11798 11799 int broadcastIntentInPackage(String packageName, int uid, 11800 Intent intent, String resolvedType, IIntentReceiver resultTo, 11801 int resultCode, String resultData, Bundle map, 11802 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11803 synchronized(this) { 11804 intent = verifyBroadcastLocked(intent); 11805 11806 final long origId = Binder.clearCallingIdentity(); 11807 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11808 resultTo, resultCode, resultData, map, requiredPermission, 11809 serialized, sticky, -1, uid, userId); 11810 Binder.restoreCallingIdentity(origId); 11811 return res; 11812 } 11813 } 11814 11815 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11816 // Refuse possible leaked file descriptors 11817 if (intent != null && intent.hasFileDescriptors() == true) { 11818 throw new IllegalArgumentException("File descriptors passed in Intent"); 11819 } 11820 11821 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11822 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11823 11824 synchronized(this) { 11825 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11826 != PackageManager.PERMISSION_GRANTED) { 11827 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11828 + Binder.getCallingPid() 11829 + ", uid=" + Binder.getCallingUid() 11830 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11831 Slog.w(TAG, msg); 11832 throw new SecurityException(msg); 11833 } 11834 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11835 if (stickies != null) { 11836 ArrayList<Intent> list = stickies.get(intent.getAction()); 11837 if (list != null) { 11838 int N = list.size(); 11839 int i; 11840 for (i=0; i<N; i++) { 11841 if (intent.filterEquals(list.get(i))) { 11842 list.remove(i); 11843 break; 11844 } 11845 } 11846 if (list.size() <= 0) { 11847 stickies.remove(intent.getAction()); 11848 } 11849 } 11850 if (stickies.size() <= 0) { 11851 mStickyBroadcasts.remove(userId); 11852 } 11853 } 11854 } 11855 } 11856 11857 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11858 String resultData, Bundle resultExtras, boolean resultAbort, 11859 boolean explicit) { 11860 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11861 if (r == null) { 11862 Slog.w(TAG, "finishReceiver called but not found on queue"); 11863 return false; 11864 } 11865 11866 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11867 explicit); 11868 } 11869 11870 public void finishReceiver(IBinder who, int resultCode, String resultData, 11871 Bundle resultExtras, boolean resultAbort) { 11872 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11873 11874 // Refuse possible leaked file descriptors 11875 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11876 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11877 } 11878 11879 final long origId = Binder.clearCallingIdentity(); 11880 try { 11881 boolean doNext = false; 11882 BroadcastRecord r = null; 11883 11884 synchronized(this) { 11885 r = broadcastRecordForReceiverLocked(who); 11886 if (r != null) { 11887 doNext = r.queue.finishReceiverLocked(r, resultCode, 11888 resultData, resultExtras, resultAbort, true); 11889 } 11890 } 11891 11892 if (doNext) { 11893 r.queue.processNextBroadcast(false); 11894 } 11895 trimApplications(); 11896 } finally { 11897 Binder.restoreCallingIdentity(origId); 11898 } 11899 } 11900 11901 // ========================================================= 11902 // INSTRUMENTATION 11903 // ========================================================= 11904 11905 public boolean startInstrumentation(ComponentName className, 11906 String profileFile, int flags, Bundle arguments, 11907 IInstrumentationWatcher watcher, int userId) { 11908 enforceNotIsolatedCaller("startInstrumentation"); 11909 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 11910 userId, false, true, "startInstrumentation", null); 11911 // Refuse possible leaked file descriptors 11912 if (arguments != null && arguments.hasFileDescriptors()) { 11913 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11914 } 11915 11916 synchronized(this) { 11917 InstrumentationInfo ii = null; 11918 ApplicationInfo ai = null; 11919 try { 11920 ii = mContext.getPackageManager().getInstrumentationInfo( 11921 className, STOCK_PM_FLAGS); 11922 ai = AppGlobals.getPackageManager().getApplicationInfo( 11923 ii.targetPackage, STOCK_PM_FLAGS, userId); 11924 } catch (PackageManager.NameNotFoundException e) { 11925 } catch (RemoteException e) { 11926 } 11927 if (ii == null) { 11928 reportStartInstrumentationFailure(watcher, className, 11929 "Unable to find instrumentation info for: " + className); 11930 return false; 11931 } 11932 if (ai == null) { 11933 reportStartInstrumentationFailure(watcher, className, 11934 "Unable to find instrumentation target package: " + ii.targetPackage); 11935 return false; 11936 } 11937 11938 int match = mContext.getPackageManager().checkSignatures( 11939 ii.targetPackage, ii.packageName); 11940 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11941 String msg = "Permission Denial: starting instrumentation " 11942 + className + " from pid=" 11943 + Binder.getCallingPid() 11944 + ", uid=" + Binder.getCallingPid() 11945 + " not allowed because package " + ii.packageName 11946 + " does not have a signature matching the target " 11947 + ii.targetPackage; 11948 reportStartInstrumentationFailure(watcher, className, msg); 11949 throw new SecurityException(msg); 11950 } 11951 11952 final long origId = Binder.clearCallingIdentity(); 11953 // Instrumentation can kill and relaunch even persistent processes 11954 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11955 ProcessRecord app = addAppLocked(ai, false); 11956 app.instrumentationClass = className; 11957 app.instrumentationInfo = ai; 11958 app.instrumentationProfileFile = profileFile; 11959 app.instrumentationArguments = arguments; 11960 app.instrumentationWatcher = watcher; 11961 app.instrumentationResultClass = className; 11962 Binder.restoreCallingIdentity(origId); 11963 } 11964 11965 return true; 11966 } 11967 11968 /** 11969 * Report errors that occur while attempting to start Instrumentation. Always writes the 11970 * error to the logs, but if somebody is watching, send the report there too. This enables 11971 * the "am" command to report errors with more information. 11972 * 11973 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11974 * @param cn The component name of the instrumentation. 11975 * @param report The error report. 11976 */ 11977 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11978 ComponentName cn, String report) { 11979 Slog.w(TAG, report); 11980 try { 11981 if (watcher != null) { 11982 Bundle results = new Bundle(); 11983 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11984 results.putString("Error", report); 11985 watcher.instrumentationStatus(cn, -1, results); 11986 } 11987 } catch (RemoteException e) { 11988 Slog.w(TAG, e); 11989 } 11990 } 11991 11992 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11993 if (app.instrumentationWatcher != null) { 11994 try { 11995 // NOTE: IInstrumentationWatcher *must* be oneway here 11996 app.instrumentationWatcher.instrumentationFinished( 11997 app.instrumentationClass, 11998 resultCode, 11999 results); 12000 } catch (RemoteException e) { 12001 } 12002 } 12003 app.instrumentationWatcher = null; 12004 app.instrumentationClass = null; 12005 app.instrumentationInfo = null; 12006 app.instrumentationProfileFile = null; 12007 app.instrumentationArguments = null; 12008 12009 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12010 } 12011 12012 public void finishInstrumentation(IApplicationThread target, 12013 int resultCode, Bundle results) { 12014 int userId = UserHandle.getCallingUserId(); 12015 // Refuse possible leaked file descriptors 12016 if (results != null && results.hasFileDescriptors()) { 12017 throw new IllegalArgumentException("File descriptors passed in Intent"); 12018 } 12019 12020 synchronized(this) { 12021 ProcessRecord app = getRecordForAppLocked(target); 12022 if (app == null) { 12023 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12024 return; 12025 } 12026 final long origId = Binder.clearCallingIdentity(); 12027 finishInstrumentationLocked(app, resultCode, results); 12028 Binder.restoreCallingIdentity(origId); 12029 } 12030 } 12031 12032 // ========================================================= 12033 // CONFIGURATION 12034 // ========================================================= 12035 12036 public ConfigurationInfo getDeviceConfigurationInfo() { 12037 ConfigurationInfo config = new ConfigurationInfo(); 12038 synchronized (this) { 12039 config.reqTouchScreen = mConfiguration.touchscreen; 12040 config.reqKeyboardType = mConfiguration.keyboard; 12041 config.reqNavigation = mConfiguration.navigation; 12042 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12043 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12044 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12045 } 12046 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12047 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12048 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12049 } 12050 config.reqGlEsVersion = GL_ES_VERSION; 12051 } 12052 return config; 12053 } 12054 12055 public Configuration getConfiguration() { 12056 Configuration ci; 12057 synchronized(this) { 12058 ci = new Configuration(mConfiguration); 12059 } 12060 return ci; 12061 } 12062 12063 public void updatePersistentConfiguration(Configuration values) { 12064 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12065 "updateConfiguration()"); 12066 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12067 "updateConfiguration()"); 12068 if (values == null) { 12069 throw new NullPointerException("Configuration must not be null"); 12070 } 12071 12072 synchronized(this) { 12073 final long origId = Binder.clearCallingIdentity(); 12074 updateConfigurationLocked(values, null, true, false); 12075 Binder.restoreCallingIdentity(origId); 12076 } 12077 } 12078 12079 public void updateConfiguration(Configuration values) { 12080 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12081 "updateConfiguration()"); 12082 12083 synchronized(this) { 12084 if (values == null && mWindowManager != null) { 12085 // sentinel: fetch the current configuration from the window manager 12086 values = mWindowManager.computeNewConfiguration(); 12087 } 12088 12089 if (mWindowManager != null) { 12090 mProcessList.applyDisplaySize(mWindowManager); 12091 } 12092 12093 final long origId = Binder.clearCallingIdentity(); 12094 if (values != null) { 12095 Settings.System.clearConfiguration(values); 12096 } 12097 updateConfigurationLocked(values, null, false, false); 12098 Binder.restoreCallingIdentity(origId); 12099 } 12100 } 12101 12102 /** 12103 * Do either or both things: (1) change the current configuration, and (2) 12104 * make sure the given activity is running with the (now) current 12105 * configuration. Returns true if the activity has been left running, or 12106 * false if <var>starting</var> is being destroyed to match the new 12107 * configuration. 12108 * @param persistent TODO 12109 */ 12110 boolean updateConfigurationLocked(Configuration values, 12111 ActivityRecord starting, boolean persistent, boolean initLocale) { 12112 // do nothing if we are headless 12113 if (mHeadless) return true; 12114 12115 int changes = 0; 12116 12117 boolean kept = true; 12118 12119 if (values != null) { 12120 Configuration newConfig = new Configuration(mConfiguration); 12121 changes = newConfig.updateFrom(values); 12122 if (changes != 0) { 12123 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12124 Slog.i(TAG, "Updating configuration to: " + values); 12125 } 12126 12127 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12128 12129 if (values.locale != null && !initLocale) { 12130 saveLocaleLocked(values.locale, 12131 !values.locale.equals(mConfiguration.locale), 12132 values.userSetLocale); 12133 } 12134 12135 mConfigurationSeq++; 12136 if (mConfigurationSeq <= 0) { 12137 mConfigurationSeq = 1; 12138 } 12139 newConfig.seq = mConfigurationSeq; 12140 mConfiguration = newConfig; 12141 Slog.i(TAG, "Config changed: " + newConfig); 12142 12143 final Configuration configCopy = new Configuration(mConfiguration); 12144 12145 // TODO: If our config changes, should we auto dismiss any currently 12146 // showing dialogs? 12147 mShowDialogs = shouldShowDialogs(newConfig); 12148 12149 AttributeCache ac = AttributeCache.instance(); 12150 if (ac != null) { 12151 ac.updateConfiguration(configCopy); 12152 } 12153 12154 // Make sure all resources in our process are updated 12155 // right now, so that anyone who is going to retrieve 12156 // resource values after we return will be sure to get 12157 // the new ones. This is especially important during 12158 // boot, where the first config change needs to guarantee 12159 // all resources have that config before following boot 12160 // code is executed. 12161 mSystemThread.applyConfigurationToResources(configCopy); 12162 12163 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12164 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12165 msg.obj = new Configuration(configCopy); 12166 mHandler.sendMessage(msg); 12167 } 12168 12169 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12170 ProcessRecord app = mLruProcesses.get(i); 12171 try { 12172 if (app.thread != null) { 12173 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12174 + app.processName + " new config " + mConfiguration); 12175 app.thread.scheduleConfigurationChanged(configCopy); 12176 } 12177 } catch (Exception e) { 12178 } 12179 } 12180 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12181 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12182 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12183 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12184 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12185 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12186 broadcastIntentLocked(null, null, 12187 new Intent(Intent.ACTION_LOCALE_CHANGED), 12188 null, null, 0, null, null, 12189 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12190 } 12191 } 12192 } 12193 12194 if (changes != 0 && starting == null) { 12195 // If the configuration changed, and the caller is not already 12196 // in the process of starting an activity, then find the top 12197 // activity to check if its configuration needs to change. 12198 starting = mMainStack.topRunningActivityLocked(null); 12199 } 12200 12201 if (starting != null) { 12202 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12203 // And we need to make sure at this point that all other activities 12204 // are made visible with the correct configuration. 12205 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12206 } 12207 12208 if (values != null && mWindowManager != null) { 12209 mWindowManager.setNewConfiguration(mConfiguration); 12210 } 12211 12212 return kept; 12213 } 12214 12215 /** 12216 * Decide based on the configuration whether we should shouw the ANR, 12217 * crash, etc dialogs. The idea is that if there is no affordnace to 12218 * press the on-screen buttons, we shouldn't show the dialog. 12219 * 12220 * A thought: SystemUI might also want to get told about this, the Power 12221 * dialog / global actions also might want different behaviors. 12222 */ 12223 private static final boolean shouldShowDialogs(Configuration config) { 12224 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12225 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12226 } 12227 12228 /** 12229 * Save the locale. You must be inside a synchronized (this) block. 12230 */ 12231 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12232 if(isDiff) { 12233 SystemProperties.set("user.language", l.getLanguage()); 12234 SystemProperties.set("user.region", l.getCountry()); 12235 } 12236 12237 if(isPersist) { 12238 SystemProperties.set("persist.sys.language", l.getLanguage()); 12239 SystemProperties.set("persist.sys.country", l.getCountry()); 12240 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12241 } 12242 } 12243 12244 @Override 12245 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12246 ActivityRecord srec = ActivityRecord.forToken(token); 12247 return srec != null && srec.task.affinity != null && 12248 srec.task.affinity.equals(destAffinity); 12249 } 12250 12251 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12252 Intent resultData) { 12253 ComponentName dest = destIntent.getComponent(); 12254 12255 synchronized (this) { 12256 ActivityRecord srec = ActivityRecord.forToken(token); 12257 if (srec == null) { 12258 return false; 12259 } 12260 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12261 final int start = history.indexOf(srec); 12262 if (start < 0) { 12263 // Current activity is not in history stack; do nothing. 12264 return false; 12265 } 12266 int finishTo = start - 1; 12267 ActivityRecord parent = null; 12268 boolean foundParentInTask = false; 12269 if (dest != null) { 12270 TaskRecord tr = srec.task; 12271 for (int i = start - 1; i >= 0; i--) { 12272 ActivityRecord r = history.get(i); 12273 if (tr != r.task) { 12274 // Couldn't find parent in the same task; stop at the one above this. 12275 // (Root of current task; in-app "home" behavior) 12276 // Always at least finish the current activity. 12277 finishTo = Math.min(start - 1, i + 1); 12278 parent = history.get(finishTo); 12279 break; 12280 } else if (r.info.packageName.equals(dest.getPackageName()) && 12281 r.info.name.equals(dest.getClassName())) { 12282 finishTo = i; 12283 parent = r; 12284 foundParentInTask = true; 12285 break; 12286 } 12287 } 12288 } 12289 12290 if (mController != null) { 12291 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12292 if (next != null) { 12293 // ask watcher if this is allowed 12294 boolean resumeOK = true; 12295 try { 12296 resumeOK = mController.activityResuming(next.packageName); 12297 } catch (RemoteException e) { 12298 mController = null; 12299 } 12300 12301 if (!resumeOK) { 12302 return false; 12303 } 12304 } 12305 } 12306 final long origId = Binder.clearCallingIdentity(); 12307 for (int i = start; i > finishTo; i--) { 12308 ActivityRecord r = history.get(i); 12309 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12310 "navigate-up", true); 12311 // Only return the supplied result for the first activity finished 12312 resultCode = Activity.RESULT_CANCELED; 12313 resultData = null; 12314 } 12315 12316 if (parent != null && foundParentInTask) { 12317 final int parentLaunchMode = parent.info.launchMode; 12318 final int destIntentFlags = destIntent.getFlags(); 12319 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12320 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12321 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12322 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12323 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12324 } else { 12325 try { 12326 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12327 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12328 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12329 null, aInfo, parent.appToken, null, 12330 0, -1, parent.launchedFromUid, 0, null, true, null); 12331 foundParentInTask = res == ActivityManager.START_SUCCESS; 12332 } catch (RemoteException e) { 12333 foundParentInTask = false; 12334 } 12335 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12336 resultData, "navigate-up", true); 12337 } 12338 } 12339 Binder.restoreCallingIdentity(origId); 12340 return foundParentInTask; 12341 } 12342 } 12343 12344 public int getLaunchedFromUid(IBinder activityToken) { 12345 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12346 if (srec == null) { 12347 return -1; 12348 } 12349 return srec.launchedFromUid; 12350 } 12351 12352 // ========================================================= 12353 // LIFETIME MANAGEMENT 12354 // ========================================================= 12355 12356 // Returns which broadcast queue the app is the current [or imminent] receiver 12357 // on, or 'null' if the app is not an active broadcast recipient. 12358 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12359 BroadcastRecord r = app.curReceiver; 12360 if (r != null) { 12361 return r.queue; 12362 } 12363 12364 // It's not the current receiver, but it might be starting up to become one 12365 synchronized (this) { 12366 for (BroadcastQueue queue : mBroadcastQueues) { 12367 r = queue.mPendingBroadcast; 12368 if (r != null && r.curApp == app) { 12369 // found it; report which queue it's in 12370 return queue; 12371 } 12372 } 12373 } 12374 12375 return null; 12376 } 12377 12378 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12379 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12380 if (mAdjSeq == app.adjSeq) { 12381 // This adjustment has already been computed. If we are calling 12382 // from the top, we may have already computed our adjustment with 12383 // an earlier hidden adjustment that isn't really for us... if 12384 // so, use the new hidden adjustment. 12385 if (!recursed && app.hidden) { 12386 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12387 app.hasActivities ? hiddenAdj : emptyAdj; 12388 } 12389 return app.curRawAdj; 12390 } 12391 12392 if (app.thread == null) { 12393 app.adjSeq = mAdjSeq; 12394 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12395 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12396 } 12397 12398 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12399 app.adjSource = null; 12400 app.adjTarget = null; 12401 app.empty = false; 12402 app.hidden = false; 12403 12404 final int activitiesSize = app.activities.size(); 12405 12406 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12407 // The max adjustment doesn't allow this app to be anything 12408 // below foreground, so it is not worth doing work for it. 12409 app.adjType = "fixed"; 12410 app.adjSeq = mAdjSeq; 12411 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12412 app.hasActivities = false; 12413 app.foregroundActivities = false; 12414 app.keeping = true; 12415 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12416 // System process can do UI, and when they do we want to have 12417 // them trim their memory after the user leaves the UI. To 12418 // facilitate this, here we need to determine whether or not it 12419 // is currently showing UI. 12420 app.systemNoUi = true; 12421 if (app == TOP_APP) { 12422 app.systemNoUi = false; 12423 app.hasActivities = true; 12424 } else if (activitiesSize > 0) { 12425 for (int j = 0; j < activitiesSize; j++) { 12426 final ActivityRecord r = app.activities.get(j); 12427 if (r.visible) { 12428 app.systemNoUi = false; 12429 } 12430 if (r.app == app) { 12431 app.hasActivities = true; 12432 } 12433 } 12434 } 12435 return (app.curAdj=app.maxAdj); 12436 } 12437 12438 app.keeping = false; 12439 app.systemNoUi = false; 12440 app.hasActivities = false; 12441 12442 // Determine the importance of the process, starting with most 12443 // important to least, and assign an appropriate OOM adjustment. 12444 int adj; 12445 int schedGroup; 12446 boolean foregroundActivities = false; 12447 boolean interesting = false; 12448 BroadcastQueue queue; 12449 if (app == TOP_APP) { 12450 // The last app on the list is the foreground app. 12451 adj = ProcessList.FOREGROUND_APP_ADJ; 12452 schedGroup = Process.THREAD_GROUP_DEFAULT; 12453 app.adjType = "top-activity"; 12454 foregroundActivities = true; 12455 interesting = true; 12456 app.hasActivities = true; 12457 } else if (app.instrumentationClass != null) { 12458 // Don't want to kill running instrumentation. 12459 adj = ProcessList.FOREGROUND_APP_ADJ; 12460 schedGroup = Process.THREAD_GROUP_DEFAULT; 12461 app.adjType = "instrumentation"; 12462 interesting = true; 12463 } else if ((queue = isReceivingBroadcast(app)) != null) { 12464 // An app that is currently receiving a broadcast also 12465 // counts as being in the foreground for OOM killer purposes. 12466 // It's placed in a sched group based on the nature of the 12467 // broadcast as reflected by which queue it's active in. 12468 adj = ProcessList.FOREGROUND_APP_ADJ; 12469 schedGroup = (queue == mFgBroadcastQueue) 12470 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12471 app.adjType = "broadcast"; 12472 } else if (app.executingServices.size() > 0) { 12473 // An app that is currently executing a service callback also 12474 // counts as being in the foreground. 12475 adj = ProcessList.FOREGROUND_APP_ADJ; 12476 schedGroup = Process.THREAD_GROUP_DEFAULT; 12477 app.adjType = "exec-service"; 12478 } else { 12479 // Assume process is hidden (has activities); we will correct 12480 // later if this is not the case. 12481 adj = hiddenAdj; 12482 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12483 app.hidden = true; 12484 app.adjType = "bg-activities"; 12485 } 12486 12487 boolean hasStoppingActivities = false; 12488 12489 // Examine all activities if not already foreground. 12490 if (!foregroundActivities && activitiesSize > 0) { 12491 for (int j = 0; j < activitiesSize; j++) { 12492 final ActivityRecord r = app.activities.get(j); 12493 if (r.visible) { 12494 // App has a visible activity; only upgrade adjustment. 12495 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12496 adj = ProcessList.VISIBLE_APP_ADJ; 12497 app.adjType = "visible"; 12498 } 12499 schedGroup = Process.THREAD_GROUP_DEFAULT; 12500 app.hidden = false; 12501 app.hasActivities = true; 12502 foregroundActivities = true; 12503 break; 12504 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12505 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12506 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12507 app.adjType = "pausing"; 12508 } 12509 app.hidden = false; 12510 foregroundActivities = true; 12511 } else if (r.state == ActivityState.STOPPING) { 12512 // We will apply the actual adjustment later, because 12513 // we want to allow this process to immediately go through 12514 // any memory trimming that is in effect. 12515 app.hidden = false; 12516 foregroundActivities = true; 12517 hasStoppingActivities = true; 12518 } 12519 if (r.app == app) { 12520 app.hasActivities = true; 12521 } 12522 } 12523 } 12524 12525 if (adj == hiddenAdj && !app.hasActivities) { 12526 // Whoops, this process is completely empty as far as we know 12527 // at this point. 12528 adj = emptyAdj; 12529 app.empty = true; 12530 app.adjType = "bg-empty"; 12531 } 12532 12533 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12534 if (app.foregroundServices) { 12535 // The user is aware of this app, so make it visible. 12536 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12537 app.hidden = false; 12538 app.adjType = "foreground-service"; 12539 schedGroup = Process.THREAD_GROUP_DEFAULT; 12540 } else if (app.forcingToForeground != null) { 12541 // The user is aware of this app, so make it visible. 12542 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12543 app.hidden = false; 12544 app.adjType = "force-foreground"; 12545 app.adjSource = app.forcingToForeground; 12546 schedGroup = Process.THREAD_GROUP_DEFAULT; 12547 } 12548 } 12549 12550 if (app.foregroundServices) { 12551 interesting = true; 12552 } 12553 12554 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12555 // We don't want to kill the current heavy-weight process. 12556 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12557 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12558 app.hidden = false; 12559 app.adjType = "heavy"; 12560 } 12561 12562 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12563 // This process is hosting what we currently consider to be the 12564 // home app, so we don't want to let it go into the background. 12565 adj = ProcessList.HOME_APP_ADJ; 12566 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12567 app.hidden = false; 12568 app.adjType = "home"; 12569 } 12570 12571 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12572 && app.activities.size() > 0) { 12573 // This was the previous process that showed UI to the user. 12574 // We want to try to keep it around more aggressively, to give 12575 // a good experience around switching between two apps. 12576 adj = ProcessList.PREVIOUS_APP_ADJ; 12577 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12578 app.hidden = false; 12579 app.adjType = "previous"; 12580 } 12581 12582 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12583 + " reason=" + app.adjType); 12584 12585 // By default, we use the computed adjustment. It may be changed if 12586 // there are applications dependent on our services or providers, but 12587 // this gives us a baseline and makes sure we don't get into an 12588 // infinite recursion. 12589 app.adjSeq = mAdjSeq; 12590 app.curRawAdj = app.nonStoppingAdj = adj; 12591 12592 if (mBackupTarget != null && app == mBackupTarget.app) { 12593 // If possible we want to avoid killing apps while they're being backed up 12594 if (adj > ProcessList.BACKUP_APP_ADJ) { 12595 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12596 adj = ProcessList.BACKUP_APP_ADJ; 12597 app.adjType = "backup"; 12598 app.hidden = false; 12599 } 12600 } 12601 12602 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12603 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12604 final long now = SystemClock.uptimeMillis(); 12605 // This process is more important if the top activity is 12606 // bound to the service. 12607 Iterator<ServiceRecord> jt = app.services.iterator(); 12608 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12609 ServiceRecord s = jt.next(); 12610 if (s.startRequested) { 12611 if (app.hasShownUi && app != mHomeProcess) { 12612 // If this process has shown some UI, let it immediately 12613 // go to the LRU list because it may be pretty heavy with 12614 // UI stuff. We'll tag it with a label just to help 12615 // debug and understand what is going on. 12616 if (adj > ProcessList.SERVICE_ADJ) { 12617 app.adjType = "started-bg-ui-services"; 12618 } 12619 } else { 12620 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12621 // This service has seen some activity within 12622 // recent memory, so we will keep its process ahead 12623 // of the background processes. 12624 if (adj > ProcessList.SERVICE_ADJ) { 12625 adj = ProcessList.SERVICE_ADJ; 12626 app.adjType = "started-services"; 12627 app.hidden = false; 12628 } 12629 } 12630 // If we have let the service slide into the background 12631 // state, still have some text describing what it is doing 12632 // even though the service no longer has an impact. 12633 if (adj > ProcessList.SERVICE_ADJ) { 12634 app.adjType = "started-bg-services"; 12635 } 12636 } 12637 // Don't kill this process because it is doing work; it 12638 // has said it is doing work. 12639 app.keeping = true; 12640 } 12641 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12642 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12643 Iterator<ArrayList<ConnectionRecord>> kt 12644 = s.connections.values().iterator(); 12645 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12646 ArrayList<ConnectionRecord> clist = kt.next(); 12647 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12648 // XXX should compute this based on the max of 12649 // all connected clients. 12650 ConnectionRecord cr = clist.get(i); 12651 if (cr.binding.client == app) { 12652 // Binding to ourself is not interesting. 12653 continue; 12654 } 12655 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12656 ProcessRecord client = cr.binding.client; 12657 int clientAdj = adj; 12658 int myHiddenAdj = hiddenAdj; 12659 if (myHiddenAdj > client.hiddenAdj) { 12660 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12661 myHiddenAdj = client.hiddenAdj; 12662 } else { 12663 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12664 } 12665 } 12666 int myEmptyAdj = emptyAdj; 12667 if (myEmptyAdj > client.emptyAdj) { 12668 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12669 myEmptyAdj = client.emptyAdj; 12670 } else { 12671 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12672 } 12673 } 12674 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12675 myEmptyAdj, TOP_APP, true, doingAll); 12676 String adjType = null; 12677 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12678 // Not doing bind OOM management, so treat 12679 // this guy more like a started service. 12680 if (app.hasShownUi && app != mHomeProcess) { 12681 // If this process has shown some UI, let it immediately 12682 // go to the LRU list because it may be pretty heavy with 12683 // UI stuff. We'll tag it with a label just to help 12684 // debug and understand what is going on. 12685 if (adj > clientAdj) { 12686 adjType = "bound-bg-ui-services"; 12687 } 12688 app.hidden = false; 12689 clientAdj = adj; 12690 } else { 12691 if (now >= (s.lastActivity 12692 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12693 // This service has not seen activity within 12694 // recent memory, so allow it to drop to the 12695 // LRU list if there is no other reason to keep 12696 // it around. We'll also tag it with a label just 12697 // to help debug and undertand what is going on. 12698 if (adj > clientAdj) { 12699 adjType = "bound-bg-services"; 12700 } 12701 clientAdj = adj; 12702 } 12703 } 12704 } 12705 if (adj > clientAdj) { 12706 // If this process has recently shown UI, and 12707 // the process that is binding to it is less 12708 // important than being visible, then we don't 12709 // care about the binding as much as we care 12710 // about letting this process get into the LRU 12711 // list to be killed and restarted if needed for 12712 // memory. 12713 if (app.hasShownUi && app != mHomeProcess 12714 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12715 adjType = "bound-bg-ui-services"; 12716 } else { 12717 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12718 |Context.BIND_IMPORTANT)) != 0) { 12719 adj = clientAdj; 12720 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12721 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12722 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12723 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12724 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12725 adj = clientAdj; 12726 } else { 12727 app.pendingUiClean = true; 12728 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12729 adj = ProcessList.VISIBLE_APP_ADJ; 12730 } 12731 } 12732 if (!client.hidden) { 12733 app.hidden = false; 12734 } 12735 if (client.keeping) { 12736 app.keeping = true; 12737 } 12738 adjType = "service"; 12739 } 12740 } 12741 if (adjType != null) { 12742 app.adjType = adjType; 12743 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12744 .REASON_SERVICE_IN_USE; 12745 app.adjSource = cr.binding.client; 12746 app.adjSourceOom = clientAdj; 12747 app.adjTarget = s.name; 12748 } 12749 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12750 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12751 schedGroup = Process.THREAD_GROUP_DEFAULT; 12752 } 12753 } 12754 } 12755 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12756 ActivityRecord a = cr.activity; 12757 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12758 (a.visible || a.state == ActivityState.RESUMED 12759 || a.state == ActivityState.PAUSING)) { 12760 adj = ProcessList.FOREGROUND_APP_ADJ; 12761 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12762 schedGroup = Process.THREAD_GROUP_DEFAULT; 12763 } 12764 app.hidden = false; 12765 app.adjType = "service"; 12766 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12767 .REASON_SERVICE_IN_USE; 12768 app.adjSource = a; 12769 app.adjSourceOom = adj; 12770 app.adjTarget = s.name; 12771 } 12772 } 12773 } 12774 } 12775 } 12776 } 12777 12778 // Finally, if this process has active services running in it, we 12779 // would like to avoid killing it unless it would prevent the current 12780 // application from running. By default we put the process in 12781 // with the rest of the background processes; as we scan through 12782 // its services we may bump it up from there. 12783 if (adj > hiddenAdj) { 12784 adj = hiddenAdj; 12785 app.hidden = false; 12786 app.adjType = "bg-services"; 12787 } 12788 } 12789 12790 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12791 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12792 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12793 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12794 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12795 ContentProviderRecord cpr = jt.next(); 12796 for (int i = cpr.connections.size()-1; 12797 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12798 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12799 i--) { 12800 ContentProviderConnection conn = cpr.connections.get(i); 12801 ProcessRecord client = conn.client; 12802 if (client == app) { 12803 // Being our own client is not interesting. 12804 continue; 12805 } 12806 int myHiddenAdj = hiddenAdj; 12807 if (myHiddenAdj > client.hiddenAdj) { 12808 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12809 myHiddenAdj = client.hiddenAdj; 12810 } else { 12811 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12812 } 12813 } 12814 int myEmptyAdj = emptyAdj; 12815 if (myEmptyAdj > client.emptyAdj) { 12816 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12817 myEmptyAdj = client.emptyAdj; 12818 } else { 12819 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12820 } 12821 } 12822 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12823 myEmptyAdj, TOP_APP, true, doingAll); 12824 if (adj > clientAdj) { 12825 if (app.hasShownUi && app != mHomeProcess 12826 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12827 app.adjType = "bg-ui-provider"; 12828 } else { 12829 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12830 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12831 app.adjType = "provider"; 12832 } 12833 if (!client.hidden) { 12834 app.hidden = false; 12835 } 12836 if (client.keeping) { 12837 app.keeping = true; 12838 } 12839 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12840 .REASON_PROVIDER_IN_USE; 12841 app.adjSource = client; 12842 app.adjSourceOom = clientAdj; 12843 app.adjTarget = cpr.name; 12844 } 12845 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12846 schedGroup = Process.THREAD_GROUP_DEFAULT; 12847 } 12848 } 12849 // If the provider has external (non-framework) process 12850 // dependencies, ensure that its adjustment is at least 12851 // FOREGROUND_APP_ADJ. 12852 if (cpr.hasExternalProcessHandles()) { 12853 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12854 adj = ProcessList.FOREGROUND_APP_ADJ; 12855 schedGroup = Process.THREAD_GROUP_DEFAULT; 12856 app.hidden = false; 12857 app.keeping = true; 12858 app.adjType = "provider"; 12859 app.adjTarget = cpr.name; 12860 } 12861 } 12862 } 12863 } 12864 12865 if (adj == ProcessList.SERVICE_ADJ) { 12866 if (doingAll) { 12867 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12868 mNewNumServiceProcs++; 12869 } 12870 if (app.serviceb) { 12871 adj = ProcessList.SERVICE_B_ADJ; 12872 } 12873 } else { 12874 app.serviceb = false; 12875 } 12876 12877 app.nonStoppingAdj = adj; 12878 12879 if (hasStoppingActivities) { 12880 // Only upgrade adjustment. 12881 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12882 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12883 app.adjType = "stopping"; 12884 } 12885 } 12886 12887 app.curRawAdj = adj; 12888 12889 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12890 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12891 if (adj > app.maxAdj) { 12892 adj = app.maxAdj; 12893 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12894 schedGroup = Process.THREAD_GROUP_DEFAULT; 12895 } 12896 } 12897 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12898 app.keeping = true; 12899 } 12900 12901 if (app.hasAboveClient) { 12902 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12903 // then we need to drop its adjustment to be lower than the service's 12904 // in order to honor the request. We want to drop it by one adjustment 12905 // level... but there is special meaning applied to various levels so 12906 // we will skip some of them. 12907 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12908 // System process will not get dropped, ever 12909 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12910 adj = ProcessList.VISIBLE_APP_ADJ; 12911 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12912 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12913 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12914 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12915 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12916 adj++; 12917 } 12918 } 12919 12920 int importance = app.memImportance; 12921 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12922 app.curAdj = adj; 12923 app.curSchedGroup = schedGroup; 12924 if (!interesting) { 12925 // For this reporting, if there is not something explicitly 12926 // interesting in this process then we will push it to the 12927 // background importance. 12928 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12929 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12930 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12931 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12932 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12933 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12934 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12935 } else if (adj >= ProcessList.SERVICE_ADJ) { 12936 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12937 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12938 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12939 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12940 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12941 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12942 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12943 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12944 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12945 } else { 12946 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12947 } 12948 } 12949 12950 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12951 if (foregroundActivities != app.foregroundActivities) { 12952 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12953 } 12954 if (changes != 0) { 12955 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12956 app.memImportance = importance; 12957 app.foregroundActivities = foregroundActivities; 12958 int i = mPendingProcessChanges.size()-1; 12959 ProcessChangeItem item = null; 12960 while (i >= 0) { 12961 item = mPendingProcessChanges.get(i); 12962 if (item.pid == app.pid) { 12963 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12964 break; 12965 } 12966 i--; 12967 } 12968 if (i < 0) { 12969 // No existing item in pending changes; need a new one. 12970 final int NA = mAvailProcessChanges.size(); 12971 if (NA > 0) { 12972 item = mAvailProcessChanges.remove(NA-1); 12973 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12974 } else { 12975 item = new ProcessChangeItem(); 12976 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12977 } 12978 item.changes = 0; 12979 item.pid = app.pid; 12980 item.uid = app.info.uid; 12981 if (mPendingProcessChanges.size() == 0) { 12982 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12983 "*** Enqueueing dispatch processes changed!"); 12984 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12985 } 12986 mPendingProcessChanges.add(item); 12987 } 12988 item.changes |= changes; 12989 item.importance = importance; 12990 item.foregroundActivities = foregroundActivities; 12991 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12992 + Integer.toHexString(System.identityHashCode(item)) 12993 + " " + app.toShortString() + ": changes=" + item.changes 12994 + " importance=" + item.importance 12995 + " foreground=" + item.foregroundActivities 12996 + " type=" + app.adjType + " source=" + app.adjSource 12997 + " target=" + app.adjTarget); 12998 } 12999 13000 return app.curRawAdj; 13001 } 13002 13003 /** 13004 * Ask a given process to GC right now. 13005 */ 13006 final void performAppGcLocked(ProcessRecord app) { 13007 try { 13008 app.lastRequestedGc = SystemClock.uptimeMillis(); 13009 if (app.thread != null) { 13010 if (app.reportLowMemory) { 13011 app.reportLowMemory = false; 13012 app.thread.scheduleLowMemory(); 13013 } else { 13014 app.thread.processInBackground(); 13015 } 13016 } 13017 } catch (Exception e) { 13018 // whatever. 13019 } 13020 } 13021 13022 /** 13023 * Returns true if things are idle enough to perform GCs. 13024 */ 13025 private final boolean canGcNowLocked() { 13026 boolean processingBroadcasts = false; 13027 for (BroadcastQueue q : mBroadcastQueues) { 13028 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13029 processingBroadcasts = true; 13030 } 13031 } 13032 return !processingBroadcasts 13033 && (mSleeping || (mMainStack.mResumedActivity != null && 13034 mMainStack.mResumedActivity.idle)); 13035 } 13036 13037 /** 13038 * Perform GCs on all processes that are waiting for it, but only 13039 * if things are idle. 13040 */ 13041 final void performAppGcsLocked() { 13042 final int N = mProcessesToGc.size(); 13043 if (N <= 0) { 13044 return; 13045 } 13046 if (canGcNowLocked()) { 13047 while (mProcessesToGc.size() > 0) { 13048 ProcessRecord proc = mProcessesToGc.remove(0); 13049 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13050 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13051 <= SystemClock.uptimeMillis()) { 13052 // To avoid spamming the system, we will GC processes one 13053 // at a time, waiting a few seconds between each. 13054 performAppGcLocked(proc); 13055 scheduleAppGcsLocked(); 13056 return; 13057 } else { 13058 // It hasn't been long enough since we last GCed this 13059 // process... put it in the list to wait for its time. 13060 addProcessToGcListLocked(proc); 13061 break; 13062 } 13063 } 13064 } 13065 13066 scheduleAppGcsLocked(); 13067 } 13068 } 13069 13070 /** 13071 * If all looks good, perform GCs on all processes waiting for them. 13072 */ 13073 final void performAppGcsIfAppropriateLocked() { 13074 if (canGcNowLocked()) { 13075 performAppGcsLocked(); 13076 return; 13077 } 13078 // Still not idle, wait some more. 13079 scheduleAppGcsLocked(); 13080 } 13081 13082 /** 13083 * Schedule the execution of all pending app GCs. 13084 */ 13085 final void scheduleAppGcsLocked() { 13086 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13087 13088 if (mProcessesToGc.size() > 0) { 13089 // Schedule a GC for the time to the next process. 13090 ProcessRecord proc = mProcessesToGc.get(0); 13091 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13092 13093 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13094 long now = SystemClock.uptimeMillis(); 13095 if (when < (now+GC_TIMEOUT)) { 13096 when = now + GC_TIMEOUT; 13097 } 13098 mHandler.sendMessageAtTime(msg, when); 13099 } 13100 } 13101 13102 /** 13103 * Add a process to the array of processes waiting to be GCed. Keeps the 13104 * list in sorted order by the last GC time. The process can't already be 13105 * on the list. 13106 */ 13107 final void addProcessToGcListLocked(ProcessRecord proc) { 13108 boolean added = false; 13109 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13110 if (mProcessesToGc.get(i).lastRequestedGc < 13111 proc.lastRequestedGc) { 13112 added = true; 13113 mProcessesToGc.add(i+1, proc); 13114 break; 13115 } 13116 } 13117 if (!added) { 13118 mProcessesToGc.add(0, proc); 13119 } 13120 } 13121 13122 /** 13123 * Set up to ask a process to GC itself. This will either do it 13124 * immediately, or put it on the list of processes to gc the next 13125 * time things are idle. 13126 */ 13127 final void scheduleAppGcLocked(ProcessRecord app) { 13128 long now = SystemClock.uptimeMillis(); 13129 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13130 return; 13131 } 13132 if (!mProcessesToGc.contains(app)) { 13133 addProcessToGcListLocked(app); 13134 scheduleAppGcsLocked(); 13135 } 13136 } 13137 13138 final void checkExcessivePowerUsageLocked(boolean doKills) { 13139 updateCpuStatsNow(); 13140 13141 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13142 boolean doWakeKills = doKills; 13143 boolean doCpuKills = doKills; 13144 if (mLastPowerCheckRealtime == 0) { 13145 doWakeKills = false; 13146 } 13147 if (mLastPowerCheckUptime == 0) { 13148 doCpuKills = false; 13149 } 13150 if (stats.isScreenOn()) { 13151 doWakeKills = false; 13152 } 13153 final long curRealtime = SystemClock.elapsedRealtime(); 13154 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13155 final long curUptime = SystemClock.uptimeMillis(); 13156 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13157 mLastPowerCheckRealtime = curRealtime; 13158 mLastPowerCheckUptime = curUptime; 13159 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13160 doWakeKills = false; 13161 } 13162 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13163 doCpuKills = false; 13164 } 13165 int i = mLruProcesses.size(); 13166 while (i > 0) { 13167 i--; 13168 ProcessRecord app = mLruProcesses.get(i); 13169 if (!app.keeping) { 13170 long wtime; 13171 synchronized (stats) { 13172 wtime = stats.getProcessWakeTime(app.info.uid, 13173 app.pid, curRealtime); 13174 } 13175 long wtimeUsed = wtime - app.lastWakeTime; 13176 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13177 if (DEBUG_POWER) { 13178 StringBuilder sb = new StringBuilder(128); 13179 sb.append("Wake for "); 13180 app.toShortString(sb); 13181 sb.append(": over "); 13182 TimeUtils.formatDuration(realtimeSince, sb); 13183 sb.append(" used "); 13184 TimeUtils.formatDuration(wtimeUsed, sb); 13185 sb.append(" ("); 13186 sb.append((wtimeUsed*100)/realtimeSince); 13187 sb.append("%)"); 13188 Slog.i(TAG, sb.toString()); 13189 sb.setLength(0); 13190 sb.append("CPU for "); 13191 app.toShortString(sb); 13192 sb.append(": over "); 13193 TimeUtils.formatDuration(uptimeSince, sb); 13194 sb.append(" used "); 13195 TimeUtils.formatDuration(cputimeUsed, sb); 13196 sb.append(" ("); 13197 sb.append((cputimeUsed*100)/uptimeSince); 13198 sb.append("%)"); 13199 Slog.i(TAG, sb.toString()); 13200 } 13201 // If a process has held a wake lock for more 13202 // than 50% of the time during this period, 13203 // that sounds bad. Kill! 13204 if (doWakeKills && realtimeSince > 0 13205 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13206 synchronized (stats) { 13207 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13208 realtimeSince, wtimeUsed); 13209 } 13210 Slog.w(TAG, "Excessive wake lock in " + app.processName 13211 + " (pid " + app.pid + "): held " + wtimeUsed 13212 + " during " + realtimeSince); 13213 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13214 app.processName, app.setAdj, "excessive wake lock"); 13215 Process.killProcessQuiet(app.pid); 13216 } else if (doCpuKills && uptimeSince > 0 13217 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13218 synchronized (stats) { 13219 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13220 uptimeSince, cputimeUsed); 13221 } 13222 Slog.w(TAG, "Excessive CPU in " + app.processName 13223 + " (pid " + app.pid + "): used " + cputimeUsed 13224 + " during " + uptimeSince); 13225 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13226 app.processName, app.setAdj, "excessive cpu"); 13227 Process.killProcessQuiet(app.pid); 13228 } else { 13229 app.lastWakeTime = wtime; 13230 app.lastCpuTime = app.curCpuTime; 13231 } 13232 } 13233 } 13234 } 13235 13236 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13237 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13238 app.hiddenAdj = hiddenAdj; 13239 app.emptyAdj = emptyAdj; 13240 13241 if (app.thread == null) { 13242 return false; 13243 } 13244 13245 final boolean wasKeeping = app.keeping; 13246 13247 boolean success = true; 13248 13249 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13250 13251 if (app.curRawAdj != app.setRawAdj) { 13252 if (wasKeeping && !app.keeping) { 13253 // This app is no longer something we want to keep. Note 13254 // its current wake lock time to later know to kill it if 13255 // it is not behaving well. 13256 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13257 synchronized (stats) { 13258 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13259 app.pid, SystemClock.elapsedRealtime()); 13260 } 13261 app.lastCpuTime = app.curCpuTime; 13262 } 13263 13264 app.setRawAdj = app.curRawAdj; 13265 } 13266 13267 if (app.curAdj != app.setAdj) { 13268 if (Process.setOomAdj(app.pid, app.curAdj)) { 13269 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13270 TAG, "Set " + app.pid + " " + app.processName + 13271 " adj " + app.curAdj + ": " + app.adjType); 13272 app.setAdj = app.curAdj; 13273 } else { 13274 success = false; 13275 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13276 } 13277 } 13278 if (app.setSchedGroup != app.curSchedGroup) { 13279 app.setSchedGroup = app.curSchedGroup; 13280 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13281 "Setting process group of " + app.processName 13282 + " to " + app.curSchedGroup); 13283 if (app.waitingToKill != null && 13284 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13285 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13286 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13287 app.processName, app.setAdj, app.waitingToKill); 13288 app.killedBackground = true; 13289 Process.killProcessQuiet(app.pid); 13290 success = false; 13291 } else { 13292 if (true) { 13293 long oldId = Binder.clearCallingIdentity(); 13294 try { 13295 Process.setProcessGroup(app.pid, app.curSchedGroup); 13296 } catch (Exception e) { 13297 Slog.w(TAG, "Failed setting process group of " + app.pid 13298 + " to " + app.curSchedGroup); 13299 e.printStackTrace(); 13300 } finally { 13301 Binder.restoreCallingIdentity(oldId); 13302 } 13303 } else { 13304 if (app.thread != null) { 13305 try { 13306 app.thread.setSchedulingGroup(app.curSchedGroup); 13307 } catch (RemoteException e) { 13308 } 13309 } 13310 } 13311 } 13312 } 13313 return success; 13314 } 13315 13316 private final ActivityRecord resumedAppLocked() { 13317 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13318 if (resumedActivity == null || resumedActivity.app == null) { 13319 resumedActivity = mMainStack.mPausingActivity; 13320 if (resumedActivity == null || resumedActivity.app == null) { 13321 resumedActivity = mMainStack.topRunningActivityLocked(null); 13322 } 13323 } 13324 return resumedActivity; 13325 } 13326 13327 final boolean updateOomAdjLocked(ProcessRecord app) { 13328 final ActivityRecord TOP_ACT = resumedAppLocked(); 13329 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13330 int curAdj = app.curAdj; 13331 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13332 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13333 13334 mAdjSeq++; 13335 13336 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13337 TOP_APP, false); 13338 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13339 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13340 if (nowHidden != wasHidden) { 13341 // Changed to/from hidden state, so apps after it in the LRU 13342 // list may also be changed. 13343 updateOomAdjLocked(); 13344 } 13345 return success; 13346 } 13347 13348 final void updateOomAdjLocked() { 13349 final ActivityRecord TOP_ACT = resumedAppLocked(); 13350 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13351 13352 if (false) { 13353 RuntimeException e = new RuntimeException(); 13354 e.fillInStackTrace(); 13355 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13356 } 13357 13358 mAdjSeq++; 13359 mNewNumServiceProcs = 0; 13360 13361 // Let's determine how many processes we have running vs. 13362 // how many slots we have for background processes; we may want 13363 // to put multiple processes in a slot of there are enough of 13364 // them. 13365 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13366 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13367 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13368 if (emptyFactor < 1) emptyFactor = 1; 13369 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13370 if (hiddenFactor < 1) hiddenFactor = 1; 13371 int stepHidden = 0; 13372 int stepEmpty = 0; 13373 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13374 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13375 int numHidden = 0; 13376 int numEmpty = 0; 13377 int numTrimming = 0; 13378 13379 mNumNonHiddenProcs = 0; 13380 mNumHiddenProcs = 0; 13381 13382 // First update the OOM adjustment for each of the 13383 // application processes based on their current state. 13384 int i = mLruProcesses.size(); 13385 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13386 int nextHiddenAdj = curHiddenAdj+1; 13387 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13388 int nextEmptyAdj = curEmptyAdj+2; 13389 while (i > 0) { 13390 i--; 13391 ProcessRecord app = mLruProcesses.get(i); 13392 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13393 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13394 if (!app.killedBackground) { 13395 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13396 // This process was assigned as a hidden process... step the 13397 // hidden level. 13398 mNumHiddenProcs++; 13399 if (curHiddenAdj != nextHiddenAdj) { 13400 stepHidden++; 13401 if (stepHidden >= hiddenFactor) { 13402 stepHidden = 0; 13403 curHiddenAdj = nextHiddenAdj; 13404 nextHiddenAdj += 2; 13405 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13406 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13407 } 13408 } 13409 } 13410 numHidden++; 13411 if (numHidden > hiddenProcessLimit) { 13412 Slog.i(TAG, "No longer want " + app.processName 13413 + " (pid " + app.pid + "): hidden #" + numHidden); 13414 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13415 app.processName, app.setAdj, "too many background"); 13416 app.killedBackground = true; 13417 Process.killProcessQuiet(app.pid); 13418 } 13419 } else { 13420 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13421 // This process was assigned as an empty process... step the 13422 // empty level. 13423 if (curEmptyAdj != nextEmptyAdj) { 13424 stepEmpty++; 13425 if (stepEmpty >= emptyFactor) { 13426 stepEmpty = 0; 13427 curEmptyAdj = nextEmptyAdj; 13428 nextEmptyAdj += 2; 13429 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13430 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13431 } 13432 } 13433 } 13434 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13435 mNumNonHiddenProcs++; 13436 } 13437 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13438 numEmpty++; 13439 if (numEmpty > emptyProcessLimit) { 13440 Slog.i(TAG, "No longer want " + app.processName 13441 + " (pid " + app.pid + "): empty #" + numEmpty); 13442 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13443 app.processName, app.setAdj, "too many background"); 13444 app.killedBackground = true; 13445 Process.killProcessQuiet(app.pid); 13446 } 13447 } 13448 } 13449 if (app.isolated && app.services.size() <= 0) { 13450 // If this is an isolated process, and there are no 13451 // services running in it, then the process is no longer 13452 // needed. We agressively kill these because we can by 13453 // definition not re-use the same process again, and it is 13454 // good to avoid having whatever code was running in them 13455 // left sitting around after no longer needed. 13456 Slog.i(TAG, "Isolated process " + app.processName 13457 + " (pid " + app.pid + ") no longer needed"); 13458 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13459 app.processName, app.setAdj, "isolated not needed"); 13460 app.killedBackground = true; 13461 Process.killProcessQuiet(app.pid); 13462 } 13463 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13464 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13465 && !app.killedBackground) { 13466 numTrimming++; 13467 } 13468 } 13469 } 13470 13471 mNumServiceProcs = mNewNumServiceProcs; 13472 13473 // Now determine the memory trimming level of background processes. 13474 // Unfortunately we need to start at the back of the list to do this 13475 // properly. We only do this if the number of background apps we 13476 // are managing to keep around is less than half the maximum we desire; 13477 // if we are keeping a good number around, we'll let them use whatever 13478 // memory they want. 13479 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13480 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13481 final int numHiddenAndEmpty = numHidden + numEmpty; 13482 final int N = mLruProcesses.size(); 13483 int factor = numTrimming/3; 13484 int minFactor = 2; 13485 if (mHomeProcess != null) minFactor++; 13486 if (mPreviousProcess != null) minFactor++; 13487 if (factor < minFactor) factor = minFactor; 13488 int step = 0; 13489 int fgTrimLevel; 13490 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13491 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13492 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13493 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13494 } else { 13495 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13496 } 13497 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13498 for (i=0; i<N; i++) { 13499 ProcessRecord app = mLruProcesses.get(i); 13500 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13501 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13502 && !app.killedBackground) { 13503 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13504 try { 13505 app.thread.scheduleTrimMemory(curLevel); 13506 } catch (RemoteException e) { 13507 } 13508 if (false) { 13509 // For now we won't do this; our memory trimming seems 13510 // to be good enough at this point that destroying 13511 // activities causes more harm than good. 13512 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13513 && app != mHomeProcess && app != mPreviousProcess) { 13514 // Need to do this on its own message because the stack may not 13515 // be in a consistent state at this point. 13516 // For these apps we will also finish their activities 13517 // to help them free memory. 13518 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13519 } 13520 } 13521 } 13522 app.trimMemoryLevel = curLevel; 13523 step++; 13524 if (step >= factor) { 13525 step = 0; 13526 switch (curLevel) { 13527 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13528 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13529 break; 13530 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13531 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13532 break; 13533 } 13534 } 13535 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13536 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13537 && app.thread != null) { 13538 try { 13539 app.thread.scheduleTrimMemory( 13540 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13541 } catch (RemoteException e) { 13542 } 13543 } 13544 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13545 } else { 13546 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13547 && app.pendingUiClean) { 13548 // If this application is now in the background and it 13549 // had done UI, then give it the special trim level to 13550 // have it free UI resources. 13551 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13552 if (app.trimMemoryLevel < level && app.thread != null) { 13553 try { 13554 app.thread.scheduleTrimMemory(level); 13555 } catch (RemoteException e) { 13556 } 13557 } 13558 app.pendingUiClean = false; 13559 } 13560 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13561 try { 13562 app.thread.scheduleTrimMemory(fgTrimLevel); 13563 } catch (RemoteException e) { 13564 } 13565 } 13566 app.trimMemoryLevel = fgTrimLevel; 13567 } 13568 } 13569 } else { 13570 final int N = mLruProcesses.size(); 13571 for (i=0; i<N; i++) { 13572 ProcessRecord app = mLruProcesses.get(i); 13573 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13574 && app.pendingUiClean) { 13575 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13576 && app.thread != null) { 13577 try { 13578 app.thread.scheduleTrimMemory( 13579 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13580 } catch (RemoteException e) { 13581 } 13582 } 13583 app.pendingUiClean = false; 13584 } 13585 app.trimMemoryLevel = 0; 13586 } 13587 } 13588 13589 if (mAlwaysFinishActivities) { 13590 // Need to do this on its own message because the stack may not 13591 // be in a consistent state at this point. 13592 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13593 } 13594 } 13595 13596 final void trimApplications() { 13597 synchronized (this) { 13598 int i; 13599 13600 // First remove any unused application processes whose package 13601 // has been removed. 13602 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13603 final ProcessRecord app = mRemovedProcesses.get(i); 13604 if (app.activities.size() == 0 13605 && app.curReceiver == null && app.services.size() == 0) { 13606 Slog.i( 13607 TAG, "Exiting empty application process " 13608 + app.processName + " (" 13609 + (app.thread != null ? app.thread.asBinder() : null) 13610 + ")\n"); 13611 if (app.pid > 0 && app.pid != MY_PID) { 13612 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13613 app.processName, app.setAdj, "empty"); 13614 Process.killProcessQuiet(app.pid); 13615 } else { 13616 try { 13617 app.thread.scheduleExit(); 13618 } catch (Exception e) { 13619 // Ignore exceptions. 13620 } 13621 } 13622 cleanUpApplicationRecordLocked(app, false, true, -1); 13623 mRemovedProcesses.remove(i); 13624 13625 if (app.persistent) { 13626 if (app.persistent) { 13627 addAppLocked(app.info, false); 13628 } 13629 } 13630 } 13631 } 13632 13633 // Now update the oom adj for all processes. 13634 updateOomAdjLocked(); 13635 } 13636 } 13637 13638 /** This method sends the specified signal to each of the persistent apps */ 13639 public void signalPersistentProcesses(int sig) throws RemoteException { 13640 if (sig != Process.SIGNAL_USR1) { 13641 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13642 } 13643 13644 synchronized (this) { 13645 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13646 != PackageManager.PERMISSION_GRANTED) { 13647 throw new SecurityException("Requires permission " 13648 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13649 } 13650 13651 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13652 ProcessRecord r = mLruProcesses.get(i); 13653 if (r.thread != null && r.persistent) { 13654 Process.sendSignal(r.pid, sig); 13655 } 13656 } 13657 } 13658 } 13659 13660 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13661 if (proc == null || proc == mProfileProc) { 13662 proc = mProfileProc; 13663 path = mProfileFile; 13664 profileType = mProfileType; 13665 clearProfilerLocked(); 13666 } 13667 if (proc == null) { 13668 return; 13669 } 13670 try { 13671 proc.thread.profilerControl(false, path, null, profileType); 13672 } catch (RemoteException e) { 13673 throw new IllegalStateException("Process disappeared"); 13674 } 13675 } 13676 13677 private void clearProfilerLocked() { 13678 if (mProfileFd != null) { 13679 try { 13680 mProfileFd.close(); 13681 } catch (IOException e) { 13682 } 13683 } 13684 mProfileApp = null; 13685 mProfileProc = null; 13686 mProfileFile = null; 13687 mProfileType = 0; 13688 mAutoStopProfiler = false; 13689 } 13690 13691 public boolean profileControl(String process, boolean start, 13692 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13693 13694 try { 13695 synchronized (this) { 13696 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13697 // its own permission. 13698 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13699 != PackageManager.PERMISSION_GRANTED) { 13700 throw new SecurityException("Requires permission " 13701 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13702 } 13703 13704 if (start && fd == null) { 13705 throw new IllegalArgumentException("null fd"); 13706 } 13707 13708 ProcessRecord proc = null; 13709 if (process != null) { 13710 try { 13711 int pid = Integer.parseInt(process); 13712 synchronized (mPidsSelfLocked) { 13713 proc = mPidsSelfLocked.get(pid); 13714 } 13715 } catch (NumberFormatException e) { 13716 } 13717 13718 if (proc == null) { 13719 HashMap<String, SparseArray<ProcessRecord>> all 13720 = mProcessNames.getMap(); 13721 SparseArray<ProcessRecord> procs = all.get(process); 13722 if (procs != null && procs.size() > 0) { 13723 proc = procs.valueAt(0); 13724 } 13725 } 13726 } 13727 13728 if (start && (proc == null || proc.thread == null)) { 13729 throw new IllegalArgumentException("Unknown process: " + process); 13730 } 13731 13732 if (start) { 13733 stopProfilerLocked(null, null, 0); 13734 setProfileApp(proc.info, proc.processName, path, fd, false); 13735 mProfileProc = proc; 13736 mProfileType = profileType; 13737 try { 13738 fd = fd.dup(); 13739 } catch (IOException e) { 13740 fd = null; 13741 } 13742 proc.thread.profilerControl(start, path, fd, profileType); 13743 fd = null; 13744 mProfileFd = null; 13745 } else { 13746 stopProfilerLocked(proc, path, profileType); 13747 if (fd != null) { 13748 try { 13749 fd.close(); 13750 } catch (IOException e) { 13751 } 13752 } 13753 } 13754 13755 return true; 13756 } 13757 } catch (RemoteException e) { 13758 throw new IllegalStateException("Process disappeared"); 13759 } finally { 13760 if (fd != null) { 13761 try { 13762 fd.close(); 13763 } catch (IOException e) { 13764 } 13765 } 13766 } 13767 } 13768 13769 public boolean dumpHeap(String process, boolean managed, 13770 String path, ParcelFileDescriptor fd) throws RemoteException { 13771 13772 try { 13773 synchronized (this) { 13774 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13775 // its own permission (same as profileControl). 13776 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13777 != PackageManager.PERMISSION_GRANTED) { 13778 throw new SecurityException("Requires permission " 13779 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13780 } 13781 13782 if (fd == null) { 13783 throw new IllegalArgumentException("null fd"); 13784 } 13785 13786 ProcessRecord proc = null; 13787 try { 13788 int pid = Integer.parseInt(process); 13789 synchronized (mPidsSelfLocked) { 13790 proc = mPidsSelfLocked.get(pid); 13791 } 13792 } catch (NumberFormatException e) { 13793 } 13794 13795 if (proc == null) { 13796 HashMap<String, SparseArray<ProcessRecord>> all 13797 = mProcessNames.getMap(); 13798 SparseArray<ProcessRecord> procs = all.get(process); 13799 if (procs != null && procs.size() > 0) { 13800 proc = procs.valueAt(0); 13801 } 13802 } 13803 13804 if (proc == null || proc.thread == null) { 13805 throw new IllegalArgumentException("Unknown process: " + process); 13806 } 13807 13808 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13809 if (!isDebuggable) { 13810 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13811 throw new SecurityException("Process not debuggable: " + proc); 13812 } 13813 } 13814 13815 proc.thread.dumpHeap(managed, path, fd); 13816 fd = null; 13817 return true; 13818 } 13819 } catch (RemoteException e) { 13820 throw new IllegalStateException("Process disappeared"); 13821 } finally { 13822 if (fd != null) { 13823 try { 13824 fd.close(); 13825 } catch (IOException e) { 13826 } 13827 } 13828 } 13829 } 13830 13831 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13832 public void monitor() { 13833 synchronized (this) { } 13834 } 13835 13836 void onCoreSettingsChange(Bundle settings) { 13837 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13838 ProcessRecord processRecord = mLruProcesses.get(i); 13839 try { 13840 if (processRecord.thread != null) { 13841 processRecord.thread.setCoreSettings(settings); 13842 } 13843 } catch (RemoteException re) { 13844 /* ignore */ 13845 } 13846 } 13847 } 13848 13849 // Multi-user methods 13850 13851 @Override 13852 public boolean switchUser(int userId) { 13853 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13854 != PackageManager.PERMISSION_GRANTED) { 13855 String msg = "Permission Denial: switchUser() from pid=" 13856 + Binder.getCallingPid() 13857 + ", uid=" + Binder.getCallingUid() 13858 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13859 Slog.w(TAG, msg); 13860 throw new SecurityException(msg); 13861 } 13862 synchronized (this) { 13863 if (mCurrentUserId == userId) { 13864 return true; 13865 } 13866 13867 // If the user we are switching to is not currently started, then 13868 // we need to start it now. 13869 if (mStartedUsers.get(userId) == null) { 13870 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13871 } 13872 13873 mCurrentUserId = userId; 13874 Integer userIdInt = Integer.valueOf(userId); 13875 mUserLru.remove(userIdInt); 13876 mUserLru.add(userIdInt); 13877 boolean haveActivities = mMainStack.switchUser(userId); 13878 if (!haveActivities) { 13879 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13880 } 13881 } 13882 13883 long ident = Binder.clearCallingIdentity(); 13884 try { 13885 // Inform of user switch 13886 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13887 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13888 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 13889 android.Manifest.permission.MANAGE_USERS); 13890 } finally { 13891 Binder.restoreCallingIdentity(ident); 13892 } 13893 13894 return true; 13895 } 13896 13897 void finishUserSwitch(UserStartedState uss) { 13898 synchronized (this) { 13899 if (uss.mState == UserStartedState.STATE_BOOTING 13900 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13901 uss.mState = UserStartedState.STATE_RUNNING; 13902 final int userId = uss.mHandle.getIdentifier(); 13903 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 13904 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13905 broadcastIntentLocked(null, null, intent, 13906 null, null, 0, null, null, 13907 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13908 false, false, MY_PID, Process.SYSTEM_UID, userId); 13909 } 13910 } 13911 } 13912 13913 @Override 13914 public int stopUser(final int userId, final IStopUserCallback callback) { 13915 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13916 != PackageManager.PERMISSION_GRANTED) { 13917 String msg = "Permission Denial: switchUser() from pid=" 13918 + Binder.getCallingPid() 13919 + ", uid=" + Binder.getCallingUid() 13920 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13921 Slog.w(TAG, msg); 13922 throw new SecurityException(msg); 13923 } 13924 if (userId <= 0) { 13925 throw new IllegalArgumentException("Can't stop primary user " + userId); 13926 } 13927 synchronized (this) { 13928 if (mCurrentUserId == userId) { 13929 return ActivityManager.USER_OP_IS_CURRENT; 13930 } 13931 13932 final UserStartedState uss = mStartedUsers.get(userId); 13933 if (uss == null) { 13934 // User is not started, nothing to do... but we do need to 13935 // callback if requested. 13936 if (callback != null) { 13937 mHandler.post(new Runnable() { 13938 @Override 13939 public void run() { 13940 try { 13941 callback.userStopped(userId); 13942 } catch (RemoteException e) { 13943 } 13944 } 13945 }); 13946 } 13947 return ActivityManager.USER_OP_SUCCESS; 13948 } 13949 13950 if (callback != null) { 13951 uss.mStopCallbacks.add(callback); 13952 } 13953 13954 if (uss.mState != UserStartedState.STATE_STOPPING) { 13955 uss.mState = UserStartedState.STATE_STOPPING; 13956 13957 long ident = Binder.clearCallingIdentity(); 13958 try { 13959 // Inform of user switch 13960 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13961 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13962 @Override 13963 public void performReceive(Intent intent, int resultCode, String data, 13964 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 13965 finishUserStop(uss); 13966 } 13967 }; 13968 broadcastIntentLocked(null, null, intent, 13969 null, resultReceiver, 0, null, null, null, 13970 true, false, MY_PID, Process.SYSTEM_UID, userId); 13971 } finally { 13972 Binder.restoreCallingIdentity(ident); 13973 } 13974 } 13975 } 13976 13977 return ActivityManager.USER_OP_SUCCESS; 13978 } 13979 13980 void finishUserStop(UserStartedState uss) { 13981 final int userId = uss.mHandle.getIdentifier(); 13982 boolean stopped; 13983 ArrayList<IStopUserCallback> callbacks; 13984 synchronized (this) { 13985 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13986 if (uss.mState != UserStartedState.STATE_STOPPING 13987 || mStartedUsers.get(userId) != uss) { 13988 stopped = false; 13989 } else { 13990 stopped = true; 13991 // User can no longer run. 13992 mStartedUsers.remove(userId); 13993 13994 // Clean up all state and processes associated with the user. 13995 // Kill all the processes for the user. 13996 forceStopUserLocked(userId); 13997 } 13998 } 13999 14000 for (int i=0; i<callbacks.size(); i++) { 14001 try { 14002 if (stopped) callbacks.get(i).userStopped(userId); 14003 else callbacks.get(i).userStopAborted(userId); 14004 } catch (RemoteException e) { 14005 } 14006 } 14007 } 14008 14009 @Override 14010 public UserInfo getCurrentUser() { 14011 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14012 != PackageManager.PERMISSION_GRANTED) { 14013 String msg = "Permission Denial: getCurrentUser() from pid=" 14014 + Binder.getCallingPid() 14015 + ", uid=" + Binder.getCallingUid() 14016 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14017 Slog.w(TAG, msg); 14018 throw new SecurityException(msg); 14019 } 14020 synchronized (this) { 14021 return getUserManager().getUserInfo(mCurrentUserId); 14022 } 14023 } 14024 14025 @Override 14026 public boolean isUserRunning(int userId) { 14027 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14028 != PackageManager.PERMISSION_GRANTED) { 14029 String msg = "Permission Denial: isUserRunning() from pid=" 14030 + Binder.getCallingPid() 14031 + ", uid=" + Binder.getCallingUid() 14032 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14033 Slog.w(TAG, msg); 14034 throw new SecurityException(msg); 14035 } 14036 synchronized (this) { 14037 UserStartedState state = mStartedUsers.get(userId); 14038 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14039 } 14040 } 14041 14042 private boolean userExists(int userId) { 14043 UserInfo user = getUserManager().getUserInfo(userId); 14044 return user != null; 14045 } 14046 14047 UserManager getUserManager() { 14048 if (mUserManager == null) { 14049 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 14050 } 14051 return mUserManager; 14052 } 14053 14054 private void checkValidCaller(int uid, int userId) { 14055 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14056 14057 throw new SecurityException("Caller uid=" + uid 14058 + " is not privileged to communicate with user=" + userId); 14059 } 14060 14061 private int applyUserId(int uid, int userId) { 14062 return UserHandle.getUid(userId, uid); 14063 } 14064 14065 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14066 if (info == null) return null; 14067 ApplicationInfo newInfo = new ApplicationInfo(info); 14068 newInfo.uid = applyUserId(info.uid, userId); 14069 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14070 + info.packageName; 14071 return newInfo; 14072 } 14073 14074 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14075 if (aInfo == null 14076 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14077 return aInfo; 14078 } 14079 14080 ActivityInfo info = new ActivityInfo(aInfo); 14081 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14082 return info; 14083 } 14084} 14085