ActivityManagerService.java revision 259d5e56a82d721ccb7e7f514c80de69acae309e
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.LocaleUtil; 120import android.util.Log; 121import android.util.Pair; 122import android.util.PrintWriterPrinter; 123import android.util.Slog; 124import android.util.SparseArray; 125import android.util.SparseIntArray; 126import android.util.TimeUtils; 127import android.view.Gravity; 128import android.view.LayoutInflater; 129import android.view.View; 130import android.view.WindowManager; 131import android.view.WindowManagerPolicy; 132 133import java.io.BufferedInputStream; 134import java.io.BufferedOutputStream; 135import java.io.BufferedReader; 136import java.io.DataInputStream; 137import java.io.DataOutputStream; 138import java.io.File; 139import java.io.FileDescriptor; 140import java.io.FileInputStream; 141import java.io.FileNotFoundException; 142import java.io.FileOutputStream; 143import java.io.IOException; 144import java.io.InputStreamReader; 145import java.io.PrintWriter; 146import java.io.StringWriter; 147import java.lang.ref.WeakReference; 148import java.util.ArrayList; 149import java.util.Collections; 150import java.util.Comparator; 151import java.util.HashMap; 152import java.util.HashSet; 153import java.util.Iterator; 154import java.util.List; 155import java.util.Locale; 156import java.util.Map; 157import java.util.Set; 158import java.util.concurrent.atomic.AtomicBoolean; 159import java.util.concurrent.atomic.AtomicLong; 160 161public final class ActivityManagerService extends ActivityManagerNative 162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 163 private static final String USER_DATA_DIR = "/data/user/"; 164 static final String TAG = "ActivityManager"; 165 static final String TAG_MU = "ActivityManagerServiceMU"; 166 static final boolean DEBUG = false; 167 static final boolean localLOGV = DEBUG; 168 static final boolean DEBUG_SWITCH = localLOGV || false; 169 static final boolean DEBUG_TASKS = localLOGV || false; 170 static final boolean DEBUG_PAUSE = localLOGV || false; 171 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 172 static final boolean DEBUG_TRANSITION = localLOGV || false; 173 static final boolean DEBUG_BROADCAST = localLOGV || false; 174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_SERVICE = localLOGV || false; 177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 178 static final boolean DEBUG_VISBILITY = localLOGV || false; 179 static final boolean DEBUG_PROCESSES = localLOGV || false; 180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 181 static final boolean DEBUG_PROVIDER = localLOGV || false; 182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 183 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 184 static final boolean DEBUG_RESULTS = localLOGV || false; 185 static final boolean DEBUG_BACKUP = localLOGV || false; 186 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 187 static final boolean DEBUG_POWER = localLOGV || false; 188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 189 static final boolean DEBUG_MU = localLOGV || false; 190 static final boolean VALIDATE_TOKENS = false; 191 static final boolean SHOW_ACTIVITY_START_TIME = true; 192 193 // Control over CPU and battery monitoring. 194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 195 static final boolean MONITOR_CPU_USAGE = true; 196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 198 static final boolean MONITOR_THREAD_CPU_USAGE = false; 199 200 // The flags that are set for all calls we make to the package manager. 201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 202 203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 204 205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 206 207 // Maximum number of recent tasks that we can remember. 208 static final int MAX_RECENT_TASKS = 20; 209 210 // Amount of time after a call to stopAppSwitches() during which we will 211 // prevent further untrusted switches from happening. 212 static final long APP_SWITCH_DELAY_TIME = 5*1000; 213 214 // How long we wait for a launched process to attach to the activity manager 215 // before we decide it's never going to come up for real. 216 static final int PROC_START_TIMEOUT = 10*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real, when the process was 220 // started with a wrapper for instrumentation (such as Valgrind) because it 221 // could take much longer than usual. 222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 223 224 // How long to wait after going idle before forcing apps to GC. 225 static final int GC_TIMEOUT = 5*1000; 226 227 // The minimum amount of time between successive GC requests for a process. 228 static final int GC_MIN_INTERVAL = 60*1000; 229 230 // The rate at which we check for apps using excessive power -- 15 mins. 231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 232 233 // The minimum sample duration we will allow before deciding we have 234 // enough data on wake locks to start killing things. 235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on CPU usage to start killing things. 239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // How long we allow a receiver to run before giving up on it. 242 static final int BROADCAST_FG_TIMEOUT = 10*1000; 243 static final int BROADCAST_BG_TIMEOUT = 60*1000; 244 245 // How long we wait until we timeout on key dispatching. 246 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 247 248 // How long we wait until we timeout on key dispatching during instrumentation. 249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 250 251 static final int MY_PID = Process.myPid(); 252 253 static final String[] EMPTY_STRING_ARRAY = new String[0]; 254 255 public ActivityStack mMainStack; 256 257 private final boolean mHeadless; 258 259 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 260 // default actuion automatically. Important for devices without direct input 261 // devices. 262 private boolean mShowDialogs = true; 263 264 /** 265 * Description of a request to start a new activity, which has been held 266 * due to app switches being disabled. 267 */ 268 static class PendingActivityLaunch { 269 ActivityRecord r; 270 ActivityRecord sourceRecord; 271 int startFlags; 272 } 273 274 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 275 = new ArrayList<PendingActivityLaunch>(); 276 277 278 BroadcastQueue mFgBroadcastQueue; 279 BroadcastQueue mBgBroadcastQueue; 280 // Convenient for easy iteration over the queues. Foreground is first 281 // so that dispatch of foreground broadcasts gets precedence. 282 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 283 284 BroadcastQueue broadcastQueueForIntent(Intent intent) { 285 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 286 if (DEBUG_BACKGROUND_BROADCAST) { 287 Slog.i(TAG, "Broadcast intent " + intent + " on " 288 + (isFg ? "foreground" : "background") 289 + " queue"); 290 } 291 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 292 } 293 294 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 295 for (BroadcastQueue queue : mBroadcastQueues) { 296 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 297 if (r != null) { 298 return r; 299 } 300 } 301 return null; 302 } 303 304 /** 305 * Activity we have told the window manager to have key focus. 306 */ 307 ActivityRecord mFocusedActivity = null; 308 /** 309 * List of intents that were used to start the most recent tasks. 310 */ 311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 312 313 /** 314 * Process management. 315 */ 316 final ProcessList mProcessList = new ProcessList(); 317 318 /** 319 * All of the applications we currently have running organized by name. 320 * The keys are strings of the application package name (as 321 * returned by the package manager), and the keys are ApplicationRecord 322 * objects. 323 */ 324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 325 326 /** 327 * The currently running isolated processes. 328 */ 329 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 330 331 /** 332 * Counter for assigning isolated process uids, to avoid frequently reusing the 333 * same ones. 334 */ 335 int mNextIsolatedProcessUid = 0; 336 337 /** 338 * The currently running heavy-weight process, if any. 339 */ 340 ProcessRecord mHeavyWeightProcess = null; 341 342 /** 343 * The last time that various processes have crashed. 344 */ 345 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 346 347 /** 348 * Set of applications that we consider to be bad, and will reject 349 * incoming broadcasts from (which the user has no control over). 350 * Processes are added to this set when they have crashed twice within 351 * a minimum amount of time; they are removed from it when they are 352 * later restarted (hopefully due to some user action). The value is the 353 * time it was added to the list. 354 */ 355 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 356 357 /** 358 * All of the processes we currently have running organized by pid. 359 * The keys are the pid running the application. 360 * 361 * <p>NOTE: This object is protected by its own lock, NOT the global 362 * activity manager lock! 363 */ 364 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 365 366 /** 367 * All of the processes that have been forced to be foreground. The key 368 * is the pid of the caller who requested it (we hold a death 369 * link on it). 370 */ 371 abstract class ForegroundToken implements IBinder.DeathRecipient { 372 int pid; 373 IBinder token; 374 } 375 final SparseArray<ForegroundToken> mForegroundProcesses 376 = new SparseArray<ForegroundToken>(); 377 378 /** 379 * List of records for processes that someone had tried to start before the 380 * system was ready. We don't start them at that point, but ensure they 381 * are started by the time booting is complete. 382 */ 383 final ArrayList<ProcessRecord> mProcessesOnHold 384 = new ArrayList<ProcessRecord>(); 385 386 /** 387 * List of persistent applications that are in the process 388 * of being started. 389 */ 390 final ArrayList<ProcessRecord> mPersistentStartingProcesses 391 = new ArrayList<ProcessRecord>(); 392 393 /** 394 * Processes that are being forcibly torn down. 395 */ 396 final ArrayList<ProcessRecord> mRemovedProcesses 397 = new ArrayList<ProcessRecord>(); 398 399 /** 400 * List of running applications, sorted by recent usage. 401 * The first entry in the list is the least recently used. 402 * It contains ApplicationRecord objects. This list does NOT include 403 * any persistent application records (since we never want to exit them). 404 */ 405 final ArrayList<ProcessRecord> mLruProcesses 406 = new ArrayList<ProcessRecord>(); 407 408 /** 409 * List of processes that should gc as soon as things are idle. 410 */ 411 final ArrayList<ProcessRecord> mProcessesToGc 412 = new ArrayList<ProcessRecord>(); 413 414 /** 415 * This is the process holding what we currently consider to be 416 * the "home" activity. 417 */ 418 ProcessRecord mHomeProcess; 419 420 /** 421 * This is the process holding the activity the user last visited that 422 * is in a different process from the one they are currently in. 423 */ 424 ProcessRecord mPreviousProcess; 425 426 /** 427 * The time at which the previous process was last visible. 428 */ 429 long mPreviousProcessVisibleTime; 430 431 /** 432 * Which uses have been started, so are allowed to run code. 433 */ 434 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 435 436 /** 437 * Packages that the user has asked to have run in screen size 438 * compatibility mode instead of filling the screen. 439 */ 440 final CompatModePackages mCompatModePackages; 441 442 /** 443 * Set of PendingResultRecord objects that are currently active. 444 */ 445 final HashSet mPendingResultRecords = new HashSet(); 446 447 /** 448 * Set of IntentSenderRecord objects that are currently active. 449 */ 450 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 451 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 452 453 /** 454 * Fingerprints (hashCode()) of stack traces that we've 455 * already logged DropBox entries for. Guarded by itself. If 456 * something (rogue user app) forces this over 457 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 458 */ 459 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 460 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 461 462 /** 463 * Strict Mode background batched logging state. 464 * 465 * The string buffer is guarded by itself, and its lock is also 466 * used to determine if another batched write is already 467 * in-flight. 468 */ 469 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 470 471 /** 472 * Keeps track of all IIntentReceivers that have been registered for 473 * broadcasts. Hash keys are the receiver IBinder, hash value is 474 * a ReceiverList. 475 */ 476 final HashMap mRegisteredReceivers = new HashMap(); 477 478 /** 479 * Resolver for broadcast intents to registered receivers. 480 * Holds BroadcastFilter (subclass of IntentFilter). 481 */ 482 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 483 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 484 @Override 485 protected boolean allowFilterResult( 486 BroadcastFilter filter, List<BroadcastFilter> dest) { 487 IBinder target = filter.receiverList.receiver.asBinder(); 488 for (int i=dest.size()-1; i>=0; i--) { 489 if (dest.get(i).receiverList.receiver.asBinder() == target) { 490 return false; 491 } 492 } 493 return true; 494 } 495 496 @Override 497 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 498 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 499 || userId == filter.owningUserId) { 500 return super.newResult(filter, match, userId); 501 } 502 return null; 503 } 504 505 @Override 506 protected BroadcastFilter[] newArray(int size) { 507 return new BroadcastFilter[size]; 508 } 509 510 @Override 511 protected String packageForFilter(BroadcastFilter filter) { 512 return filter.packageName; 513 } 514 }; 515 516 /** 517 * State of all active sticky broadcasts per user. Keys are the action of the 518 * sticky Intent, values are an ArrayList of all broadcasted intents with 519 * that action (which should usually be one). The SparseArray is keyed 520 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 521 * for stickies that are sent to all users. 522 */ 523 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 524 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 525 526 final ActiveServices mServices; 527 528 /** 529 * Backup/restore process management 530 */ 531 String mBackupAppName = null; 532 BackupRecord mBackupTarget = null; 533 534 /** 535 * List of PendingThumbnailsRecord objects of clients who are still 536 * waiting to receive all of the thumbnails for a task. 537 */ 538 final ArrayList mPendingThumbnails = new ArrayList(); 539 540 /** 541 * List of HistoryRecord objects that have been finished and must 542 * still report back to a pending thumbnail receiver. 543 */ 544 final ArrayList mCancelledThumbnails = new ArrayList(); 545 546 final ProviderMap mProviderMap = new ProviderMap(); 547 548 /** 549 * List of content providers who have clients waiting for them. The 550 * application is currently being launched and the provider will be 551 * removed from this list once it is published. 552 */ 553 final ArrayList<ContentProviderRecord> mLaunchingProviders 554 = new ArrayList<ContentProviderRecord>(); 555 556 /** 557 * Global set of specific Uri permissions that have been granted. 558 */ 559 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 560 = new SparseArray<HashMap<Uri, UriPermission>>(); 561 562 CoreSettingsObserver mCoreSettingsObserver; 563 564 /** 565 * Thread-local storage used to carry caller permissions over through 566 * indirect content-provider access. 567 * @see #ActivityManagerService.openContentUri() 568 */ 569 private class Identity { 570 public int pid; 571 public int uid; 572 573 Identity(int _pid, int _uid) { 574 pid = _pid; 575 uid = _uid; 576 } 577 } 578 579 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 580 581 /** 582 * All information we have collected about the runtime performance of 583 * any user id that can impact battery performance. 584 */ 585 final BatteryStatsService mBatteryStatsService; 586 587 /** 588 * information about component usage 589 */ 590 final UsageStatsService mUsageStatsService; 591 592 /** 593 * Current configuration information. HistoryRecord objects are given 594 * a reference to this object to indicate which configuration they are 595 * currently running in, so this object must be kept immutable. 596 */ 597 Configuration mConfiguration = new Configuration(); 598 599 /** 600 * Current sequencing integer of the configuration, for skipping old 601 * configurations. 602 */ 603 int mConfigurationSeq = 0; 604 605 /** 606 * Hardware-reported OpenGLES version. 607 */ 608 final int GL_ES_VERSION; 609 610 /** 611 * List of initialization arguments to pass to all processes when binding applications to them. 612 * For example, references to the commonly used services. 613 */ 614 HashMap<String, IBinder> mAppBindArgs; 615 616 /** 617 * Temporary to avoid allocations. Protected by main lock. 618 */ 619 final StringBuilder mStringBuilder = new StringBuilder(256); 620 621 /** 622 * Used to control how we initialize the service. 623 */ 624 boolean mStartRunning = false; 625 ComponentName mTopComponent; 626 String mTopAction; 627 String mTopData; 628 boolean mProcessesReady = false; 629 boolean mSystemReady = false; 630 boolean mBooting = false; 631 boolean mWaitingUpdate = false; 632 boolean mDidUpdate = false; 633 boolean mOnBattery = false; 634 boolean mLaunchWarningShown = false; 635 636 Context mContext; 637 638 int mFactoryTest; 639 640 boolean mCheckedForSetup; 641 642 /** 643 * The time at which we will allow normal application switches again, 644 * after a call to {@link #stopAppSwitches()}. 645 */ 646 long mAppSwitchesAllowedTime; 647 648 /** 649 * This is set to true after the first switch after mAppSwitchesAllowedTime 650 * is set; any switches after that will clear the time. 651 */ 652 boolean mDidAppSwitch; 653 654 /** 655 * Last time (in realtime) at which we checked for power usage. 656 */ 657 long mLastPowerCheckRealtime; 658 659 /** 660 * Last time (in uptime) at which we checked for power usage. 661 */ 662 long mLastPowerCheckUptime; 663 664 /** 665 * Set while we are wanting to sleep, to prevent any 666 * activities from being started/resumed. 667 */ 668 boolean mSleeping = false; 669 670 /** 671 * State of external calls telling us if the device is asleep. 672 */ 673 boolean mWentToSleep = false; 674 675 /** 676 * State of external call telling us if the lock screen is shown. 677 */ 678 boolean mLockScreenShown = false; 679 680 /** 681 * Set if we are shutting down the system, similar to sleeping. 682 */ 683 boolean mShuttingDown = false; 684 685 /** 686 * Task identifier that activities are currently being started 687 * in. Incremented each time a new task is created. 688 * todo: Replace this with a TokenSpace class that generates non-repeating 689 * integers that won't wrap. 690 */ 691 int mCurTask = 1; 692 693 /** 694 * Current sequence id for oom_adj computation traversal. 695 */ 696 int mAdjSeq = 0; 697 698 /** 699 * Current sequence id for process LRU updating. 700 */ 701 int mLruSeq = 0; 702 703 /** 704 * Keep track of the non-hidden/empty process we last found, to help 705 * determine how to distribute hidden/empty processes next time. 706 */ 707 int mNumNonHiddenProcs = 0; 708 709 /** 710 * Keep track of the number of hidden procs, to balance oom adj 711 * distribution between those and empty procs. 712 */ 713 int mNumHiddenProcs = 0; 714 715 /** 716 * Keep track of the number of service processes we last found, to 717 * determine on the next iteration which should be B services. 718 */ 719 int mNumServiceProcs = 0; 720 int mNewNumServiceProcs = 0; 721 722 /** 723 * System monitoring: number of processes that died since the last 724 * N procs were started. 725 */ 726 int[] mProcDeaths = new int[20]; 727 728 /** 729 * This is set if we had to do a delayed dexopt of an app before launching 730 * it, to increasing the ANR timeouts in that case. 731 */ 732 boolean mDidDexOpt; 733 734 String mDebugApp = null; 735 boolean mWaitForDebugger = false; 736 boolean mDebugTransient = false; 737 String mOrigDebugApp = null; 738 boolean mOrigWaitForDebugger = false; 739 boolean mAlwaysFinishActivities = false; 740 IActivityController mController = null; 741 String mProfileApp = null; 742 ProcessRecord mProfileProc = null; 743 String mProfileFile; 744 ParcelFileDescriptor mProfileFd; 745 int mProfileType = 0; 746 boolean mAutoStopProfiler = false; 747 String mOpenGlTraceApp = null; 748 749 static class ProcessChangeItem { 750 static final int CHANGE_ACTIVITIES = 1<<0; 751 static final int CHANGE_IMPORTANCE= 1<<1; 752 int changes; 753 int uid; 754 int pid; 755 int importance; 756 boolean foregroundActivities; 757 } 758 759 final RemoteCallbackList<IProcessObserver> mProcessObservers 760 = new RemoteCallbackList<IProcessObserver>(); 761 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 762 763 final ArrayList<ProcessChangeItem> mPendingProcessChanges 764 = new ArrayList<ProcessChangeItem>(); 765 final ArrayList<ProcessChangeItem> mAvailProcessChanges 766 = new ArrayList<ProcessChangeItem>(); 767 768 /** 769 * Callback of last caller to {@link #requestPss}. 770 */ 771 Runnable mRequestPssCallback; 772 773 /** 774 * Remaining processes for which we are waiting results from the last 775 * call to {@link #requestPss}. 776 */ 777 final ArrayList<ProcessRecord> mRequestPssList 778 = new ArrayList<ProcessRecord>(); 779 780 /** 781 * Runtime statistics collection thread. This object's lock is used to 782 * protect all related state. 783 */ 784 final Thread mProcessStatsThread; 785 786 /** 787 * Used to collect process stats when showing not responding dialog. 788 * Protected by mProcessStatsThread. 789 */ 790 final ProcessStats mProcessStats = new ProcessStats( 791 MONITOR_THREAD_CPU_USAGE); 792 final AtomicLong mLastCpuTime = new AtomicLong(0); 793 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 794 795 long mLastWriteTime = 0; 796 797 /** 798 * Set to true after the system has finished booting. 799 */ 800 boolean mBooted = false; 801 802 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 803 int mProcessLimitOverride = -1; 804 805 WindowManagerService mWindowManager; 806 807 static ActivityManagerService mSelf; 808 static ActivityThread mSystemThread; 809 810 private int mCurrentUserId; 811 private UserManager mUserManager; 812 813 private final class AppDeathRecipient implements IBinder.DeathRecipient { 814 final ProcessRecord mApp; 815 final int mPid; 816 final IApplicationThread mAppThread; 817 818 AppDeathRecipient(ProcessRecord app, int pid, 819 IApplicationThread thread) { 820 if (localLOGV) Slog.v( 821 TAG, "New death recipient " + this 822 + " for thread " + thread.asBinder()); 823 mApp = app; 824 mPid = pid; 825 mAppThread = thread; 826 } 827 828 public void binderDied() { 829 if (localLOGV) Slog.v( 830 TAG, "Death received in " + this 831 + " for thread " + mAppThread.asBinder()); 832 synchronized(ActivityManagerService.this) { 833 appDiedLocked(mApp, mPid, mAppThread); 834 } 835 } 836 } 837 838 static final int SHOW_ERROR_MSG = 1; 839 static final int SHOW_NOT_RESPONDING_MSG = 2; 840 static final int SHOW_FACTORY_ERROR_MSG = 3; 841 static final int UPDATE_CONFIGURATION_MSG = 4; 842 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 843 static final int WAIT_FOR_DEBUGGER_MSG = 6; 844 static final int SERVICE_TIMEOUT_MSG = 12; 845 static final int UPDATE_TIME_ZONE = 13; 846 static final int SHOW_UID_ERROR_MSG = 14; 847 static final int IM_FEELING_LUCKY_MSG = 15; 848 static final int PROC_START_TIMEOUT_MSG = 20; 849 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 850 static final int KILL_APPLICATION_MSG = 22; 851 static final int FINALIZE_PENDING_INTENT_MSG = 23; 852 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 853 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 854 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 855 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 856 static final int CLEAR_DNS_CACHE = 28; 857 static final int UPDATE_HTTP_PROXY = 29; 858 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 859 static final int DISPATCH_PROCESSES_CHANGED = 31; 860 static final int DISPATCH_PROCESS_DIED = 32; 861 static final int REPORT_MEM_USAGE = 33; 862 863 static final int FIRST_ACTIVITY_STACK_MSG = 100; 864 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 865 static final int FIRST_COMPAT_MODE_MSG = 300; 866 867 AlertDialog mUidAlert; 868 CompatModeDialog mCompatModeDialog; 869 long mLastMemUsageReportTime = 0; 870 871 final Handler mHandler = new Handler() { 872 //public Handler() { 873 // if (localLOGV) Slog.v(TAG, "Handler started!"); 874 //} 875 876 public void handleMessage(Message msg) { 877 switch (msg.what) { 878 case SHOW_ERROR_MSG: { 879 HashMap data = (HashMap) msg.obj; 880 synchronized (ActivityManagerService.this) { 881 ProcessRecord proc = (ProcessRecord)data.get("app"); 882 if (proc != null && proc.crashDialog != null) { 883 Slog.e(TAG, "App already has crash dialog: " + proc); 884 return; 885 } 886 AppErrorResult res = (AppErrorResult) data.get("result"); 887 if (mShowDialogs && !mSleeping && !mShuttingDown) { 888 Dialog d = new AppErrorDialog(mContext, res, proc); 889 d.show(); 890 proc.crashDialog = d; 891 } else { 892 // The device is asleep, so just pretend that the user 893 // saw a crash dialog and hit "force quit". 894 res.set(0); 895 } 896 } 897 898 ensureBootCompleted(); 899 } break; 900 case SHOW_NOT_RESPONDING_MSG: { 901 synchronized (ActivityManagerService.this) { 902 HashMap data = (HashMap) msg.obj; 903 ProcessRecord proc = (ProcessRecord)data.get("app"); 904 if (proc != null && proc.anrDialog != null) { 905 Slog.e(TAG, "App already has anr dialog: " + proc); 906 return; 907 } 908 909 Intent intent = new Intent("android.intent.action.ANR"); 910 if (!mProcessesReady) { 911 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 912 | Intent.FLAG_RECEIVER_FOREGROUND); 913 } 914 broadcastIntentLocked(null, null, intent, 915 null, null, 0, null, null, null, 916 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 917 918 if (mShowDialogs) { 919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 920 mContext, proc, (ActivityRecord)data.get("activity")); 921 d.show(); 922 proc.anrDialog = d; 923 } else { 924 // Just kill the app if there is no dialog to be shown. 925 killAppAtUsersRequest(proc, null); 926 } 927 } 928 929 ensureBootCompleted(); 930 } break; 931 case SHOW_STRICT_MODE_VIOLATION_MSG: { 932 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 933 synchronized (ActivityManagerService.this) { 934 ProcessRecord proc = (ProcessRecord) data.get("app"); 935 if (proc == null) { 936 Slog.e(TAG, "App not found when showing strict mode dialog."); 937 break; 938 } 939 if (proc.crashDialog != null) { 940 Slog.e(TAG, "App already has strict mode dialog: " + proc); 941 return; 942 } 943 AppErrorResult res = (AppErrorResult) data.get("result"); 944 if (mShowDialogs && !mSleeping && !mShuttingDown) { 945 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 946 d.show(); 947 proc.crashDialog = d; 948 } else { 949 // The device is asleep, so just pretend that the user 950 // saw a crash dialog and hit "force quit". 951 res.set(0); 952 } 953 } 954 ensureBootCompleted(); 955 } break; 956 case SHOW_FACTORY_ERROR_MSG: { 957 Dialog d = new FactoryErrorDialog( 958 mContext, msg.getData().getCharSequence("msg")); 959 d.show(); 960 ensureBootCompleted(); 961 } break; 962 case UPDATE_CONFIGURATION_MSG: { 963 final ContentResolver resolver = mContext.getContentResolver(); 964 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 965 } break; 966 case GC_BACKGROUND_PROCESSES_MSG: { 967 synchronized (ActivityManagerService.this) { 968 performAppGcsIfAppropriateLocked(); 969 } 970 } break; 971 case WAIT_FOR_DEBUGGER_MSG: { 972 synchronized (ActivityManagerService.this) { 973 ProcessRecord app = (ProcessRecord)msg.obj; 974 if (msg.arg1 != 0) { 975 if (!app.waitedForDebugger) { 976 Dialog d = new AppWaitingForDebuggerDialog( 977 ActivityManagerService.this, 978 mContext, app); 979 app.waitDialog = d; 980 app.waitedForDebugger = true; 981 d.show(); 982 } 983 } else { 984 if (app.waitDialog != null) { 985 app.waitDialog.dismiss(); 986 app.waitDialog = null; 987 } 988 } 989 } 990 } break; 991 case SERVICE_TIMEOUT_MSG: { 992 if (mDidDexOpt) { 993 mDidDexOpt = false; 994 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 995 nmsg.obj = msg.obj; 996 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 997 return; 998 } 999 mServices.serviceTimeout((ProcessRecord)msg.obj); 1000 } break; 1001 case UPDATE_TIME_ZONE: { 1002 synchronized (ActivityManagerService.this) { 1003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1004 ProcessRecord r = mLruProcesses.get(i); 1005 if (r.thread != null) { 1006 try { 1007 r.thread.updateTimeZone(); 1008 } catch (RemoteException ex) { 1009 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1010 } 1011 } 1012 } 1013 } 1014 } break; 1015 case CLEAR_DNS_CACHE: { 1016 synchronized (ActivityManagerService.this) { 1017 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1018 ProcessRecord r = mLruProcesses.get(i); 1019 if (r.thread != null) { 1020 try { 1021 r.thread.clearDnsCache(); 1022 } catch (RemoteException ex) { 1023 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1024 } 1025 } 1026 } 1027 } 1028 } break; 1029 case UPDATE_HTTP_PROXY: { 1030 ProxyProperties proxy = (ProxyProperties)msg.obj; 1031 String host = ""; 1032 String port = ""; 1033 String exclList = ""; 1034 if (proxy != null) { 1035 host = proxy.getHost(); 1036 port = Integer.toString(proxy.getPort()); 1037 exclList = proxy.getExclusionList(); 1038 } 1039 synchronized (ActivityManagerService.this) { 1040 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1041 ProcessRecord r = mLruProcesses.get(i); 1042 if (r.thread != null) { 1043 try { 1044 r.thread.setHttpProxy(host, port, exclList); 1045 } catch (RemoteException ex) { 1046 Slog.w(TAG, "Failed to update http proxy for: " + 1047 r.info.processName); 1048 } 1049 } 1050 } 1051 } 1052 } break; 1053 case SHOW_UID_ERROR_MSG: { 1054 String title = "System UIDs Inconsistent"; 1055 String text = "UIDs on the system are inconsistent, you need to wipe your" 1056 + " data partition or your device will be unstable."; 1057 Log.e(TAG, title + ": " + text); 1058 if (mShowDialogs) { 1059 // XXX This is a temporary dialog, no need to localize. 1060 AlertDialog d = new BaseErrorDialog(mContext); 1061 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1062 d.setCancelable(false); 1063 d.setTitle(title); 1064 d.setMessage(text); 1065 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1066 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1067 mUidAlert = d; 1068 d.show(); 1069 } 1070 } break; 1071 case IM_FEELING_LUCKY_MSG: { 1072 if (mUidAlert != null) { 1073 mUidAlert.dismiss(); 1074 mUidAlert = null; 1075 } 1076 } break; 1077 case PROC_START_TIMEOUT_MSG: { 1078 if (mDidDexOpt) { 1079 mDidDexOpt = false; 1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1081 nmsg.obj = msg.obj; 1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1083 return; 1084 } 1085 ProcessRecord app = (ProcessRecord)msg.obj; 1086 synchronized (ActivityManagerService.this) { 1087 processStartTimedOutLocked(app); 1088 } 1089 } break; 1090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1091 synchronized (ActivityManagerService.this) { 1092 doPendingActivityLaunchesLocked(true); 1093 } 1094 } break; 1095 case KILL_APPLICATION_MSG: { 1096 synchronized (ActivityManagerService.this) { 1097 int uid = msg.arg1; 1098 boolean restart = (msg.arg2 == 1); 1099 String pkg = (String) msg.obj; 1100 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1101 UserHandle.getUserId(uid)); 1102 } 1103 } break; 1104 case FINALIZE_PENDING_INTENT_MSG: { 1105 ((PendingIntentRecord)msg.obj).completeFinalize(); 1106 } break; 1107 case POST_HEAVY_NOTIFICATION_MSG: { 1108 INotificationManager inm = NotificationManager.getService(); 1109 if (inm == null) { 1110 return; 1111 } 1112 1113 ActivityRecord root = (ActivityRecord)msg.obj; 1114 ProcessRecord process = root.app; 1115 if (process == null) { 1116 return; 1117 } 1118 1119 try { 1120 Context context = mContext.createPackageContext(process.info.packageName, 0); 1121 String text = mContext.getString(R.string.heavy_weight_notification, 1122 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1123 Notification notification = new Notification(); 1124 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1125 notification.when = 0; 1126 notification.flags = Notification.FLAG_ONGOING_EVENT; 1127 notification.tickerText = text; 1128 notification.defaults = 0; // please be quiet 1129 notification.sound = null; 1130 notification.vibrate = null; 1131 notification.setLatestEventInfo(context, text, 1132 mContext.getText(R.string.heavy_weight_notification_detail), 1133 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1134 PendingIntent.FLAG_CANCEL_CURRENT, null, 1135 new UserHandle(root.userId))); 1136 1137 try { 1138 int[] outId = new int[1]; 1139 inm.enqueueNotificationWithTag("android", null, 1140 R.string.heavy_weight_notification, 1141 notification, outId, root.userId); 1142 } catch (RuntimeException e) { 1143 Slog.w(ActivityManagerService.TAG, 1144 "Error showing notification for heavy-weight app", e); 1145 } catch (RemoteException e) { 1146 } 1147 } catch (NameNotFoundException e) { 1148 Slog.w(TAG, "Unable to create context for heavy notification", e); 1149 } 1150 } break; 1151 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1152 INotificationManager inm = NotificationManager.getService(); 1153 if (inm == null) { 1154 return; 1155 } 1156 try { 1157 inm.cancelNotificationWithTag("android", null, 1158 R.string.heavy_weight_notification, msg.arg1); 1159 } catch (RuntimeException e) { 1160 Slog.w(ActivityManagerService.TAG, 1161 "Error canceling notification for service", e); 1162 } catch (RemoteException e) { 1163 } 1164 } break; 1165 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1166 synchronized (ActivityManagerService.this) { 1167 checkExcessivePowerUsageLocked(true); 1168 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1169 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1170 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1171 } 1172 } break; 1173 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1174 synchronized (ActivityManagerService.this) { 1175 ActivityRecord ar = (ActivityRecord)msg.obj; 1176 if (mCompatModeDialog != null) { 1177 if (mCompatModeDialog.mAppInfo.packageName.equals( 1178 ar.info.applicationInfo.packageName)) { 1179 return; 1180 } 1181 mCompatModeDialog.dismiss(); 1182 mCompatModeDialog = null; 1183 } 1184 if (ar != null && false) { 1185 if (mCompatModePackages.getPackageAskCompatModeLocked( 1186 ar.packageName)) { 1187 int mode = mCompatModePackages.computeCompatModeLocked( 1188 ar.info.applicationInfo); 1189 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1190 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1191 mCompatModeDialog = new CompatModeDialog( 1192 ActivityManagerService.this, mContext, 1193 ar.info.applicationInfo); 1194 mCompatModeDialog.show(); 1195 } 1196 } 1197 } 1198 } 1199 break; 1200 } 1201 case DISPATCH_PROCESSES_CHANGED: { 1202 dispatchProcessesChanged(); 1203 break; 1204 } 1205 case DISPATCH_PROCESS_DIED: { 1206 final int pid = msg.arg1; 1207 final int uid = msg.arg2; 1208 dispatchProcessDied(pid, uid); 1209 break; 1210 } 1211 case REPORT_MEM_USAGE: { 1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1213 if (!isDebuggable) { 1214 return; 1215 } 1216 synchronized (ActivityManagerService.this) { 1217 long now = SystemClock.uptimeMillis(); 1218 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1219 // Don't report more than every 5 minutes to somewhat 1220 // avoid spamming. 1221 return; 1222 } 1223 mLastMemUsageReportTime = now; 1224 } 1225 Thread thread = new Thread() { 1226 @Override public void run() { 1227 StringBuilder dropBuilder = new StringBuilder(1024); 1228 StringBuilder logBuilder = new StringBuilder(1024); 1229 StringWriter oomSw = new StringWriter(); 1230 PrintWriter oomPw = new PrintWriter(oomSw); 1231 StringWriter catSw = new StringWriter(); 1232 PrintWriter catPw = new PrintWriter(catSw); 1233 String[] emptyArgs = new String[] { }; 1234 StringBuilder tag = new StringBuilder(128); 1235 StringBuilder stack = new StringBuilder(128); 1236 tag.append("Low on memory -- "); 1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1238 tag, stack); 1239 dropBuilder.append(stack); 1240 dropBuilder.append('\n'); 1241 dropBuilder.append('\n'); 1242 String oomString = oomSw.toString(); 1243 dropBuilder.append(oomString); 1244 dropBuilder.append('\n'); 1245 logBuilder.append(oomString); 1246 try { 1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1248 "procrank", }); 1249 final InputStreamReader converter = new InputStreamReader( 1250 proc.getInputStream()); 1251 BufferedReader in = new BufferedReader(converter); 1252 String line; 1253 while (true) { 1254 line = in.readLine(); 1255 if (line == null) { 1256 break; 1257 } 1258 if (line.length() > 0) { 1259 logBuilder.append(line); 1260 logBuilder.append('\n'); 1261 } 1262 dropBuilder.append(line); 1263 dropBuilder.append('\n'); 1264 } 1265 converter.close(); 1266 } catch (IOException e) { 1267 } 1268 synchronized (ActivityManagerService.this) { 1269 catPw.println(); 1270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1271 catPw.println(); 1272 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1273 false, false, null); 1274 catPw.println(); 1275 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1276 } 1277 dropBuilder.append(catSw.toString()); 1278 addErrorToDropBox("lowmem", null, "system_server", null, 1279 null, tag.toString(), dropBuilder.toString(), null, null); 1280 Slog.i(TAG, logBuilder.toString()); 1281 synchronized (ActivityManagerService.this) { 1282 long now = SystemClock.uptimeMillis(); 1283 if (mLastMemUsageReportTime < now) { 1284 mLastMemUsageReportTime = now; 1285 } 1286 } 1287 } 1288 }; 1289 thread.start(); 1290 break; 1291 } 1292 } 1293 } 1294 }; 1295 1296 public static void setSystemProcess() { 1297 try { 1298 ActivityManagerService m = mSelf; 1299 1300 ServiceManager.addService("activity", m, true); 1301 ServiceManager.addService("meminfo", new MemBinder(m)); 1302 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1303 ServiceManager.addService("dbinfo", new DbBinder(m)); 1304 if (MONITOR_CPU_USAGE) { 1305 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1306 } 1307 ServiceManager.addService("permission", new PermissionController(m)); 1308 1309 ApplicationInfo info = 1310 mSelf.mContext.getPackageManager().getApplicationInfo( 1311 "android", STOCK_PM_FLAGS); 1312 mSystemThread.installSystemApplicationInfo(info); 1313 1314 synchronized (mSelf) { 1315 ProcessRecord app = mSelf.newProcessRecordLocked( 1316 mSystemThread.getApplicationThread(), info, 1317 info.processName, false); 1318 app.persistent = true; 1319 app.pid = MY_PID; 1320 app.maxAdj = ProcessList.SYSTEM_ADJ; 1321 mSelf.mProcessNames.put(app.processName, app.uid, app); 1322 synchronized (mSelf.mPidsSelfLocked) { 1323 mSelf.mPidsSelfLocked.put(app.pid, app); 1324 } 1325 mSelf.updateLruProcessLocked(app, true, true); 1326 } 1327 } catch (PackageManager.NameNotFoundException e) { 1328 throw new RuntimeException( 1329 "Unable to find android system package", e); 1330 } 1331 } 1332 1333 public void setWindowManager(WindowManagerService wm) { 1334 mWindowManager = wm; 1335 } 1336 1337 public static final Context main(int factoryTest) { 1338 AThread thr = new AThread(); 1339 thr.start(); 1340 1341 synchronized (thr) { 1342 while (thr.mService == null) { 1343 try { 1344 thr.wait(); 1345 } catch (InterruptedException e) { 1346 } 1347 } 1348 } 1349 1350 ActivityManagerService m = thr.mService; 1351 mSelf = m; 1352 ActivityThread at = ActivityThread.systemMain(); 1353 mSystemThread = at; 1354 Context context = at.getSystemContext(); 1355 context.setTheme(android.R.style.Theme_Holo); 1356 m.mContext = context; 1357 m.mFactoryTest = factoryTest; 1358 m.mMainStack = new ActivityStack(m, context, true); 1359 1360 m.mBatteryStatsService.publish(context); 1361 m.mUsageStatsService.publish(context); 1362 1363 synchronized (thr) { 1364 thr.mReady = true; 1365 thr.notifyAll(); 1366 } 1367 1368 m.startRunning(null, null, null, null); 1369 1370 return context; 1371 } 1372 1373 public static ActivityManagerService self() { 1374 return mSelf; 1375 } 1376 1377 static class AThread extends Thread { 1378 ActivityManagerService mService; 1379 boolean mReady = false; 1380 1381 public AThread() { 1382 super("ActivityManager"); 1383 } 1384 1385 public void run() { 1386 Looper.prepare(); 1387 1388 android.os.Process.setThreadPriority( 1389 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1390 android.os.Process.setCanSelfBackground(false); 1391 1392 ActivityManagerService m = new ActivityManagerService(); 1393 1394 synchronized (this) { 1395 mService = m; 1396 notifyAll(); 1397 } 1398 1399 synchronized (this) { 1400 while (!mReady) { 1401 try { 1402 wait(); 1403 } catch (InterruptedException e) { 1404 } 1405 } 1406 } 1407 1408 // For debug builds, log event loop stalls to dropbox for analysis. 1409 if (StrictMode.conditionallyEnableDebugLogging()) { 1410 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1411 } 1412 1413 Looper.loop(); 1414 } 1415 } 1416 1417 static class MemBinder extends Binder { 1418 ActivityManagerService mActivityManagerService; 1419 MemBinder(ActivityManagerService activityManagerService) { 1420 mActivityManagerService = activityManagerService; 1421 } 1422 1423 @Override 1424 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1425 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1426 != PackageManager.PERMISSION_GRANTED) { 1427 pw.println("Permission Denial: can't dump meminfo from from pid=" 1428 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1429 + " without permission " + android.Manifest.permission.DUMP); 1430 return; 1431 } 1432 1433 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1434 false, null, null, null); 1435 } 1436 } 1437 1438 static class GraphicsBinder extends Binder { 1439 ActivityManagerService mActivityManagerService; 1440 GraphicsBinder(ActivityManagerService activityManagerService) { 1441 mActivityManagerService = activityManagerService; 1442 } 1443 1444 @Override 1445 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1446 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1447 != PackageManager.PERMISSION_GRANTED) { 1448 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1449 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1450 + " without permission " + android.Manifest.permission.DUMP); 1451 return; 1452 } 1453 1454 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1455 } 1456 } 1457 1458 static class DbBinder extends Binder { 1459 ActivityManagerService mActivityManagerService; 1460 DbBinder(ActivityManagerService activityManagerService) { 1461 mActivityManagerService = activityManagerService; 1462 } 1463 1464 @Override 1465 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1466 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1467 != PackageManager.PERMISSION_GRANTED) { 1468 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1469 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1470 + " without permission " + android.Manifest.permission.DUMP); 1471 return; 1472 } 1473 1474 mActivityManagerService.dumpDbInfo(fd, pw, args); 1475 } 1476 } 1477 1478 static class CpuBinder extends Binder { 1479 ActivityManagerService mActivityManagerService; 1480 CpuBinder(ActivityManagerService activityManagerService) { 1481 mActivityManagerService = activityManagerService; 1482 } 1483 1484 @Override 1485 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1486 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1487 != PackageManager.PERMISSION_GRANTED) { 1488 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1489 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1490 + " without permission " + android.Manifest.permission.DUMP); 1491 return; 1492 } 1493 1494 synchronized (mActivityManagerService.mProcessStatsThread) { 1495 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1496 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1497 SystemClock.uptimeMillis())); 1498 } 1499 } 1500 } 1501 1502 private ActivityManagerService() { 1503 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1504 1505 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1506 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1507 mBroadcastQueues[0] = mFgBroadcastQueue; 1508 mBroadcastQueues[1] = mBgBroadcastQueue; 1509 1510 mServices = new ActiveServices(this); 1511 1512 File dataDir = Environment.getDataDirectory(); 1513 File systemDir = new File(dataDir, "system"); 1514 systemDir.mkdirs(); 1515 mBatteryStatsService = new BatteryStatsService(new File( 1516 systemDir, "batterystats.bin").toString()); 1517 mBatteryStatsService.getActiveStatistics().readLocked(); 1518 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1519 mOnBattery = DEBUG_POWER ? true 1520 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1521 mBatteryStatsService.getActiveStatistics().setCallback(this); 1522 1523 mUsageStatsService = new UsageStatsService(new File( 1524 systemDir, "usagestats").toString()); 1525 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1526 1527 // User 0 is the first and only user that runs at boot. 1528 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1529 1530 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1531 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1532 1533 mConfiguration.setToDefaults(); 1534 mConfiguration.setLocale(Locale.getDefault()); 1535 1536 mConfigurationSeq = mConfiguration.seq = 1; 1537 mProcessStats.init(); 1538 1539 mCompatModePackages = new CompatModePackages(this, systemDir); 1540 1541 // Add ourself to the Watchdog monitors. 1542 Watchdog.getInstance().addMonitor(this); 1543 1544 mProcessStatsThread = new Thread("ProcessStats") { 1545 public void run() { 1546 while (true) { 1547 try { 1548 try { 1549 synchronized(this) { 1550 final long now = SystemClock.uptimeMillis(); 1551 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1552 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1553 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1554 // + ", write delay=" + nextWriteDelay); 1555 if (nextWriteDelay < nextCpuDelay) { 1556 nextCpuDelay = nextWriteDelay; 1557 } 1558 if (nextCpuDelay > 0) { 1559 mProcessStatsMutexFree.set(true); 1560 this.wait(nextCpuDelay); 1561 } 1562 } 1563 } catch (InterruptedException e) { 1564 } 1565 updateCpuStatsNow(); 1566 } catch (Exception e) { 1567 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1568 } 1569 } 1570 } 1571 }; 1572 mProcessStatsThread.start(); 1573 } 1574 1575 @Override 1576 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1577 throws RemoteException { 1578 if (code == SYSPROPS_TRANSACTION) { 1579 // We need to tell all apps about the system property change. 1580 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1581 synchronized(this) { 1582 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1583 final int NA = apps.size(); 1584 for (int ia=0; ia<NA; ia++) { 1585 ProcessRecord app = apps.valueAt(ia); 1586 if (app.thread != null) { 1587 procs.add(app.thread.asBinder()); 1588 } 1589 } 1590 } 1591 } 1592 1593 int N = procs.size(); 1594 for (int i=0; i<N; i++) { 1595 Parcel data2 = Parcel.obtain(); 1596 try { 1597 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1598 } catch (RemoteException e) { 1599 } 1600 data2.recycle(); 1601 } 1602 } 1603 try { 1604 return super.onTransact(code, data, reply, flags); 1605 } catch (RuntimeException e) { 1606 // The activity manager only throws security exceptions, so let's 1607 // log all others. 1608 if (!(e instanceof SecurityException)) { 1609 Slog.e(TAG, "Activity Manager Crash", e); 1610 } 1611 throw e; 1612 } 1613 } 1614 1615 void updateCpuStats() { 1616 final long now = SystemClock.uptimeMillis(); 1617 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1618 return; 1619 } 1620 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1621 synchronized (mProcessStatsThread) { 1622 mProcessStatsThread.notify(); 1623 } 1624 } 1625 } 1626 1627 void updateCpuStatsNow() { 1628 synchronized (mProcessStatsThread) { 1629 mProcessStatsMutexFree.set(false); 1630 final long now = SystemClock.uptimeMillis(); 1631 boolean haveNewCpuStats = false; 1632 1633 if (MONITOR_CPU_USAGE && 1634 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1635 mLastCpuTime.set(now); 1636 haveNewCpuStats = true; 1637 mProcessStats.update(); 1638 //Slog.i(TAG, mProcessStats.printCurrentState()); 1639 //Slog.i(TAG, "Total CPU usage: " 1640 // + mProcessStats.getTotalCpuPercent() + "%"); 1641 1642 // Slog the cpu usage if the property is set. 1643 if ("true".equals(SystemProperties.get("events.cpu"))) { 1644 int user = mProcessStats.getLastUserTime(); 1645 int system = mProcessStats.getLastSystemTime(); 1646 int iowait = mProcessStats.getLastIoWaitTime(); 1647 int irq = mProcessStats.getLastIrqTime(); 1648 int softIrq = mProcessStats.getLastSoftIrqTime(); 1649 int idle = mProcessStats.getLastIdleTime(); 1650 1651 int total = user + system + iowait + irq + softIrq + idle; 1652 if (total == 0) total = 1; 1653 1654 EventLog.writeEvent(EventLogTags.CPU, 1655 ((user+system+iowait+irq+softIrq) * 100) / total, 1656 (user * 100) / total, 1657 (system * 100) / total, 1658 (iowait * 100) / total, 1659 (irq * 100) / total, 1660 (softIrq * 100) / total); 1661 } 1662 } 1663 1664 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1665 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1666 synchronized(bstats) { 1667 synchronized(mPidsSelfLocked) { 1668 if (haveNewCpuStats) { 1669 if (mOnBattery) { 1670 int perc = bstats.startAddingCpuLocked(); 1671 int totalUTime = 0; 1672 int totalSTime = 0; 1673 final int N = mProcessStats.countStats(); 1674 for (int i=0; i<N; i++) { 1675 ProcessStats.Stats st = mProcessStats.getStats(i); 1676 if (!st.working) { 1677 continue; 1678 } 1679 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1680 int otherUTime = (st.rel_utime*perc)/100; 1681 int otherSTime = (st.rel_stime*perc)/100; 1682 totalUTime += otherUTime; 1683 totalSTime += otherSTime; 1684 if (pr != null) { 1685 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1686 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1687 st.rel_stime-otherSTime); 1688 ps.addSpeedStepTimes(cpuSpeedTimes); 1689 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1690 } else { 1691 BatteryStatsImpl.Uid.Proc ps = 1692 bstats.getProcessStatsLocked(st.name, st.pid); 1693 if (ps != null) { 1694 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1695 st.rel_stime-otherSTime); 1696 ps.addSpeedStepTimes(cpuSpeedTimes); 1697 } 1698 } 1699 } 1700 bstats.finishAddingCpuLocked(perc, totalUTime, 1701 totalSTime, cpuSpeedTimes); 1702 } 1703 } 1704 } 1705 1706 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1707 mLastWriteTime = now; 1708 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1709 } 1710 } 1711 } 1712 } 1713 1714 @Override 1715 public void batteryNeedsCpuUpdate() { 1716 updateCpuStatsNow(); 1717 } 1718 1719 @Override 1720 public void batteryPowerChanged(boolean onBattery) { 1721 // When plugging in, update the CPU stats first before changing 1722 // the plug state. 1723 updateCpuStatsNow(); 1724 synchronized (this) { 1725 synchronized(mPidsSelfLocked) { 1726 mOnBattery = DEBUG_POWER ? true : onBattery; 1727 } 1728 } 1729 } 1730 1731 /** 1732 * Initialize the application bind args. These are passed to each 1733 * process when the bindApplication() IPC is sent to the process. They're 1734 * lazily setup to make sure the services are running when they're asked for. 1735 */ 1736 private HashMap<String, IBinder> getCommonServicesLocked() { 1737 if (mAppBindArgs == null) { 1738 mAppBindArgs = new HashMap<String, IBinder>(); 1739 1740 // Setup the application init args 1741 mAppBindArgs.put("package", ServiceManager.getService("package")); 1742 mAppBindArgs.put("window", ServiceManager.getService("window")); 1743 mAppBindArgs.put(Context.ALARM_SERVICE, 1744 ServiceManager.getService(Context.ALARM_SERVICE)); 1745 } 1746 return mAppBindArgs; 1747 } 1748 1749 final void setFocusedActivityLocked(ActivityRecord r) { 1750 if (mFocusedActivity != r) { 1751 mFocusedActivity = r; 1752 if (r != null) { 1753 mWindowManager.setFocusedApp(r.appToken, true); 1754 } 1755 } 1756 } 1757 1758 private final void updateLruProcessInternalLocked(ProcessRecord app, 1759 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1760 // put it on the LRU to keep track of when it should be exited. 1761 int lrui = mLruProcesses.indexOf(app); 1762 if (lrui >= 0) mLruProcesses.remove(lrui); 1763 1764 int i = mLruProcesses.size()-1; 1765 int skipTop = 0; 1766 1767 app.lruSeq = mLruSeq; 1768 1769 // compute the new weight for this process. 1770 if (updateActivityTime) { 1771 app.lastActivityTime = SystemClock.uptimeMillis(); 1772 } 1773 if (app.activities.size() > 0) { 1774 // If this process has activities, we more strongly want to keep 1775 // it around. 1776 app.lruWeight = app.lastActivityTime; 1777 } else if (app.pubProviders.size() > 0) { 1778 // If this process contains content providers, we want to keep 1779 // it a little more strongly. 1780 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1781 // Also don't let it kick out the first few "real" hidden processes. 1782 skipTop = ProcessList.MIN_HIDDEN_APPS; 1783 } else { 1784 // If this process doesn't have activities, we less strongly 1785 // want to keep it around, and generally want to avoid getting 1786 // in front of any very recently used activities. 1787 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1788 // Also don't let it kick out the first few "real" hidden processes. 1789 skipTop = ProcessList.MIN_HIDDEN_APPS; 1790 } 1791 1792 while (i >= 0) { 1793 ProcessRecord p = mLruProcesses.get(i); 1794 // If this app shouldn't be in front of the first N background 1795 // apps, then skip over that many that are currently hidden. 1796 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1797 skipTop--; 1798 } 1799 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1800 mLruProcesses.add(i+1, app); 1801 break; 1802 } 1803 i--; 1804 } 1805 if (i < 0) { 1806 mLruProcesses.add(0, app); 1807 } 1808 1809 // If the app is currently using a content provider or service, 1810 // bump those processes as well. 1811 if (app.connections.size() > 0) { 1812 for (ConnectionRecord cr : app.connections) { 1813 if (cr.binding != null && cr.binding.service != null 1814 && cr.binding.service.app != null 1815 && cr.binding.service.app.lruSeq != mLruSeq) { 1816 updateLruProcessInternalLocked(cr.binding.service.app, false, 1817 updateActivityTime, i+1); 1818 } 1819 } 1820 } 1821 for (int j=app.conProviders.size()-1; j>=0; j--) { 1822 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1823 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1824 updateLruProcessInternalLocked(cpr.proc, false, 1825 updateActivityTime, i+1); 1826 } 1827 } 1828 1829 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1830 if (oomAdj) { 1831 updateOomAdjLocked(); 1832 } 1833 } 1834 1835 final void updateLruProcessLocked(ProcessRecord app, 1836 boolean oomAdj, boolean updateActivityTime) { 1837 mLruSeq++; 1838 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1839 } 1840 1841 final ProcessRecord getProcessRecordLocked( 1842 String processName, int uid) { 1843 if (uid == Process.SYSTEM_UID) { 1844 // The system gets to run in any process. If there are multiple 1845 // processes with the same uid, just pick the first (this 1846 // should never happen). 1847 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1848 processName); 1849 if (procs == null) return null; 1850 final int N = procs.size(); 1851 for (int i = 0; i < N; i++) { 1852 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1853 } 1854 } 1855 ProcessRecord proc = mProcessNames.get(processName, uid); 1856 return proc; 1857 } 1858 1859 void ensurePackageDexOpt(String packageName) { 1860 IPackageManager pm = AppGlobals.getPackageManager(); 1861 try { 1862 if (pm.performDexOpt(packageName)) { 1863 mDidDexOpt = true; 1864 } 1865 } catch (RemoteException e) { 1866 } 1867 } 1868 1869 boolean isNextTransitionForward() { 1870 int transit = mWindowManager.getPendingAppTransition(); 1871 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1872 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1873 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1874 } 1875 1876 final ProcessRecord startProcessLocked(String processName, 1877 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1878 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1879 boolean isolated) { 1880 ProcessRecord app; 1881 if (!isolated) { 1882 app = getProcessRecordLocked(processName, info.uid); 1883 } else { 1884 // If this is an isolated process, it can't re-use an existing process. 1885 app = null; 1886 } 1887 // We don't have to do anything more if: 1888 // (1) There is an existing application record; and 1889 // (2) The caller doesn't think it is dead, OR there is no thread 1890 // object attached to it so we know it couldn't have crashed; and 1891 // (3) There is a pid assigned to it, so it is either starting or 1892 // already running. 1893 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1894 + " app=" + app + " knownToBeDead=" + knownToBeDead 1895 + " thread=" + (app != null ? app.thread : null) 1896 + " pid=" + (app != null ? app.pid : -1)); 1897 if (app != null && app.pid > 0) { 1898 if (!knownToBeDead || app.thread == null) { 1899 // We already have the app running, or are waiting for it to 1900 // come up (we have a pid but not yet its thread), so keep it. 1901 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1902 // If this is a new package in the process, add the package to the list 1903 app.addPackage(info.packageName); 1904 return app; 1905 } else { 1906 // An application record is attached to a previous process, 1907 // clean it up now. 1908 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1909 handleAppDiedLocked(app, true, true); 1910 } 1911 } 1912 1913 String hostingNameStr = hostingName != null 1914 ? hostingName.flattenToShortString() : null; 1915 1916 if (!isolated) { 1917 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1918 // If we are in the background, then check to see if this process 1919 // is bad. If so, we will just silently fail. 1920 if (mBadProcesses.get(info.processName, info.uid) != null) { 1921 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1922 + "/" + info.processName); 1923 return null; 1924 } 1925 } else { 1926 // When the user is explicitly starting a process, then clear its 1927 // crash count so that we won't make it bad until they see at 1928 // least one crash dialog again, and make the process good again 1929 // if it had been bad. 1930 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1931 + "/" + info.processName); 1932 mProcessCrashTimes.remove(info.processName, info.uid); 1933 if (mBadProcesses.get(info.processName, info.uid) != null) { 1934 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1935 info.processName); 1936 mBadProcesses.remove(info.processName, info.uid); 1937 if (app != null) { 1938 app.bad = false; 1939 } 1940 } 1941 } 1942 } 1943 1944 if (app == null) { 1945 app = newProcessRecordLocked(null, info, processName, isolated); 1946 if (app == null) { 1947 Slog.w(TAG, "Failed making new process record for " 1948 + processName + "/" + info.uid + " isolated=" + isolated); 1949 return null; 1950 } 1951 mProcessNames.put(processName, app.uid, app); 1952 if (isolated) { 1953 mIsolatedProcesses.put(app.uid, app); 1954 } 1955 } else { 1956 // If this is a new package in the process, add the package to the list 1957 app.addPackage(info.packageName); 1958 } 1959 1960 // If the system is not ready yet, then hold off on starting this 1961 // process until it is. 1962 if (!mProcessesReady 1963 && !isAllowedWhileBooting(info) 1964 && !allowWhileBooting) { 1965 if (!mProcessesOnHold.contains(app)) { 1966 mProcessesOnHold.add(app); 1967 } 1968 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1969 return app; 1970 } 1971 1972 startProcessLocked(app, hostingType, hostingNameStr); 1973 return (app.pid != 0) ? app : null; 1974 } 1975 1976 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1977 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1978 } 1979 1980 private final void startProcessLocked(ProcessRecord app, 1981 String hostingType, String hostingNameStr) { 1982 if (app.pid > 0 && app.pid != MY_PID) { 1983 synchronized (mPidsSelfLocked) { 1984 mPidsSelfLocked.remove(app.pid); 1985 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1986 } 1987 app.setPid(0); 1988 } 1989 1990 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1991 "startProcessLocked removing on hold: " + app); 1992 mProcessesOnHold.remove(app); 1993 1994 updateCpuStats(); 1995 1996 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1997 mProcDeaths[0] = 0; 1998 1999 try { 2000 int uid = app.uid; 2001 2002 int[] gids = null; 2003 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2004 if (!app.isolated) { 2005 try { 2006 final PackageManager pm = mContext.getPackageManager(); 2007 gids = pm.getPackageGids(app.info.packageName); 2008 2009 if (Environment.isExternalStorageEmulated()) { 2010 if (pm.checkPermission( 2011 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2012 app.info.packageName) == PERMISSION_GRANTED) { 2013 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2014 } else { 2015 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2016 } 2017 } 2018 } catch (PackageManager.NameNotFoundException e) { 2019 Slog.w(TAG, "Unable to retrieve gids", e); 2020 } 2021 } 2022 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2023 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2024 && mTopComponent != null 2025 && app.processName.equals(mTopComponent.getPackageName())) { 2026 uid = 0; 2027 } 2028 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2029 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2030 uid = 0; 2031 } 2032 } 2033 int debugFlags = 0; 2034 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2035 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2036 // Also turn on CheckJNI for debuggable apps. It's quite 2037 // awkward to turn on otherwise. 2038 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2039 } 2040 // Run the app in safe mode if its manifest requests so or the 2041 // system is booted in safe mode. 2042 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2043 Zygote.systemInSafeMode == true) { 2044 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2045 } 2046 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2047 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2048 } 2049 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2050 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2051 } 2052 if ("1".equals(SystemProperties.get("debug.assert"))) { 2053 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2054 } 2055 2056 // Start the process. It will either succeed and return a result containing 2057 // the PID of the new process, or else throw a RuntimeException. 2058 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2059 app.processName, uid, uid, gids, debugFlags, mountExternal, 2060 app.info.targetSdkVersion, null, null); 2061 2062 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2063 synchronized (bs) { 2064 if (bs.isOnBattery()) { 2065 app.batteryStats.incStartsLocked(); 2066 } 2067 } 2068 2069 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2070 app.processName, hostingType, 2071 hostingNameStr != null ? hostingNameStr : ""); 2072 2073 if (app.persistent) { 2074 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2075 } 2076 2077 StringBuilder buf = mStringBuilder; 2078 buf.setLength(0); 2079 buf.append("Start proc "); 2080 buf.append(app.processName); 2081 buf.append(" for "); 2082 buf.append(hostingType); 2083 if (hostingNameStr != null) { 2084 buf.append(" "); 2085 buf.append(hostingNameStr); 2086 } 2087 buf.append(": pid="); 2088 buf.append(startResult.pid); 2089 buf.append(" uid="); 2090 buf.append(uid); 2091 buf.append(" gids={"); 2092 if (gids != null) { 2093 for (int gi=0; gi<gids.length; gi++) { 2094 if (gi != 0) buf.append(", "); 2095 buf.append(gids[gi]); 2096 2097 } 2098 } 2099 buf.append("}"); 2100 Slog.i(TAG, buf.toString()); 2101 app.setPid(startResult.pid); 2102 app.usingWrapper = startResult.usingWrapper; 2103 app.removed = false; 2104 synchronized (mPidsSelfLocked) { 2105 this.mPidsSelfLocked.put(startResult.pid, app); 2106 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2107 msg.obj = app; 2108 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2109 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2110 } 2111 } catch (RuntimeException e) { 2112 // XXX do better error recovery. 2113 app.setPid(0); 2114 Slog.e(TAG, "Failure starting process " + app.processName, e); 2115 } 2116 } 2117 2118 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2119 if (resumed) { 2120 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2121 } else { 2122 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2123 } 2124 } 2125 2126 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) { 2127 if (mHeadless) { 2128 // Added because none of the other calls to ensureBootCompleted seem to fire 2129 // when running headless. 2130 ensureBootCompleted(); 2131 return false; 2132 } 2133 2134 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2135 && mTopAction == null) { 2136 // We are running in factory test mode, but unable to find 2137 // the factory test app, so just sit around displaying the 2138 // error message and don't try to start anything. 2139 return false; 2140 } 2141 Intent intent = new Intent( 2142 mTopAction, 2143 mTopData != null ? Uri.parse(mTopData) : null); 2144 intent.setComponent(mTopComponent); 2145 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2146 intent.addCategory(Intent.CATEGORY_HOME); 2147 } 2148 ActivityInfo aInfo = 2149 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2150 if (aInfo != null) { 2151 intent.setComponent(new ComponentName( 2152 aInfo.applicationInfo.packageName, aInfo.name)); 2153 // Don't do this if the home app is currently being 2154 // instrumented. 2155 aInfo = new ActivityInfo(aInfo); 2156 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2157 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2158 aInfo.applicationInfo.uid); 2159 if (app == null || app.instrumentationClass == null) { 2160 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2161 mMainStack.startActivityLocked(null, intent, null, aInfo, 2162 null, null, 0, 0, 0, 0, null, false, null); 2163 } 2164 } 2165 if (startingUser != null) { 2166 mMainStack.addStartingUserLocked(startingUser); 2167 } 2168 2169 return true; 2170 } 2171 2172 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2173 ActivityInfo ai = null; 2174 ComponentName comp = intent.getComponent(); 2175 try { 2176 if (comp != null) { 2177 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2178 } else { 2179 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2180 intent, 2181 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2182 flags, userId); 2183 2184 if (info != null) { 2185 ai = info.activityInfo; 2186 } 2187 } 2188 } catch (RemoteException e) { 2189 // ignore 2190 } 2191 2192 return ai; 2193 } 2194 2195 /** 2196 * Starts the "new version setup screen" if appropriate. 2197 */ 2198 void startSetupActivityLocked() { 2199 // Only do this once per boot. 2200 if (mCheckedForSetup) { 2201 return; 2202 } 2203 2204 // We will show this screen if the current one is a different 2205 // version than the last one shown, and we are not running in 2206 // low-level factory test mode. 2207 final ContentResolver resolver = mContext.getContentResolver(); 2208 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2209 Settings.Secure.getInt(resolver, 2210 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2211 mCheckedForSetup = true; 2212 2213 // See if we should be showing the platform update setup UI. 2214 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2215 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2216 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2217 2218 // We don't allow third party apps to replace this. 2219 ResolveInfo ri = null; 2220 for (int i=0; ris != null && i<ris.size(); i++) { 2221 if ((ris.get(i).activityInfo.applicationInfo.flags 2222 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2223 ri = ris.get(i); 2224 break; 2225 } 2226 } 2227 2228 if (ri != null) { 2229 String vers = ri.activityInfo.metaData != null 2230 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2231 : null; 2232 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2233 vers = ri.activityInfo.applicationInfo.metaData.getString( 2234 Intent.METADATA_SETUP_VERSION); 2235 } 2236 String lastVers = Settings.Secure.getString( 2237 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2238 if (vers != null && !vers.equals(lastVers)) { 2239 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2240 intent.setComponent(new ComponentName( 2241 ri.activityInfo.packageName, ri.activityInfo.name)); 2242 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2243 null, null, 0, 0, 0, 0, null, false, null); 2244 } 2245 } 2246 } 2247 } 2248 2249 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2250 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2251 } 2252 2253 void enforceNotIsolatedCaller(String caller) { 2254 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2255 throw new SecurityException("Isolated process not allowed to call " + caller); 2256 } 2257 } 2258 2259 public int getFrontActivityScreenCompatMode() { 2260 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2261 synchronized (this) { 2262 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2263 } 2264 } 2265 2266 public void setFrontActivityScreenCompatMode(int mode) { 2267 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2268 "setFrontActivityScreenCompatMode"); 2269 synchronized (this) { 2270 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2271 } 2272 } 2273 2274 public int getPackageScreenCompatMode(String packageName) { 2275 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2276 synchronized (this) { 2277 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2278 } 2279 } 2280 2281 public void setPackageScreenCompatMode(String packageName, int mode) { 2282 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2283 "setPackageScreenCompatMode"); 2284 synchronized (this) { 2285 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2286 } 2287 } 2288 2289 public boolean getPackageAskScreenCompat(String packageName) { 2290 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2291 synchronized (this) { 2292 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2293 } 2294 } 2295 2296 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2297 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2298 "setPackageAskScreenCompat"); 2299 synchronized (this) { 2300 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2301 } 2302 } 2303 2304 void reportResumedActivityLocked(ActivityRecord r) { 2305 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2306 updateUsageStats(r, true); 2307 } 2308 2309 private void dispatchProcessesChanged() { 2310 int N; 2311 synchronized (this) { 2312 N = mPendingProcessChanges.size(); 2313 if (mActiveProcessChanges.length < N) { 2314 mActiveProcessChanges = new ProcessChangeItem[N]; 2315 } 2316 mPendingProcessChanges.toArray(mActiveProcessChanges); 2317 mAvailProcessChanges.addAll(mPendingProcessChanges); 2318 mPendingProcessChanges.clear(); 2319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2320 } 2321 int i = mProcessObservers.beginBroadcast(); 2322 while (i > 0) { 2323 i--; 2324 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2325 if (observer != null) { 2326 try { 2327 for (int j=0; j<N; j++) { 2328 ProcessChangeItem item = mActiveProcessChanges[j]; 2329 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2330 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2331 + item.pid + " uid=" + item.uid + ": " 2332 + item.foregroundActivities); 2333 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2334 item.foregroundActivities); 2335 } 2336 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2337 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2338 + item.pid + " uid=" + item.uid + ": " + item.importance); 2339 observer.onImportanceChanged(item.pid, item.uid, 2340 item.importance); 2341 } 2342 } 2343 } catch (RemoteException e) { 2344 } 2345 } 2346 } 2347 mProcessObservers.finishBroadcast(); 2348 } 2349 2350 private void dispatchProcessDied(int pid, int uid) { 2351 int i = mProcessObservers.beginBroadcast(); 2352 while (i > 0) { 2353 i--; 2354 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2355 if (observer != null) { 2356 try { 2357 observer.onProcessDied(pid, uid); 2358 } catch (RemoteException e) { 2359 } 2360 } 2361 } 2362 mProcessObservers.finishBroadcast(); 2363 } 2364 2365 final void doPendingActivityLaunchesLocked(boolean doResume) { 2366 final int N = mPendingActivityLaunches.size(); 2367 if (N <= 0) { 2368 return; 2369 } 2370 for (int i=0; i<N; i++) { 2371 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2372 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2373 pal.startFlags, doResume && i == (N-1), null); 2374 } 2375 mPendingActivityLaunches.clear(); 2376 } 2377 2378 public final int startActivity(IApplicationThread caller, 2379 Intent intent, String resolvedType, IBinder resultTo, 2380 String resultWho, int requestCode, int startFlags, 2381 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2382 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2383 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2384 } 2385 2386 public final int startActivityAsUser(IApplicationThread caller, 2387 Intent intent, String resolvedType, IBinder resultTo, 2388 String resultWho, int requestCode, int startFlags, 2389 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2390 enforceNotIsolatedCaller("startActivity"); 2391 if (userId != UserHandle.getCallingUserId()) { 2392 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2393 false, true, "startActivity", null); 2394 } else { 2395 if (intent.getCategories() != null 2396 && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2397 // Requesting home, set the identity to the current user 2398 // HACK! 2399 userId = mCurrentUserId; 2400 } 2401 } 2402 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2403 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2404 null, null, options, userId); 2405 } 2406 2407 public final WaitResult startActivityAndWait(IApplicationThread caller, 2408 Intent intent, String resolvedType, IBinder resultTo, 2409 String resultWho, int requestCode, int startFlags, String profileFile, 2410 ParcelFileDescriptor profileFd, Bundle options) { 2411 enforceNotIsolatedCaller("startActivityAndWait"); 2412 WaitResult res = new WaitResult(); 2413 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2414 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2415 res, null, options, UserHandle.getCallingUserId()); 2416 return res; 2417 } 2418 2419 public final int startActivityWithConfig(IApplicationThread caller, 2420 Intent intent, String resolvedType, IBinder resultTo, 2421 String resultWho, int requestCode, int startFlags, Configuration config, 2422 Bundle options, int userId) { 2423 enforceNotIsolatedCaller("startActivityWithConfig"); 2424 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2425 false, true, "startActivityWithConfig", null); 2426 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2427 resultTo, resultWho, requestCode, startFlags, 2428 null, null, null, config, options, userId); 2429 return ret; 2430 } 2431 2432 public int startActivityIntentSender(IApplicationThread caller, 2433 IntentSender intent, Intent fillInIntent, String resolvedType, 2434 IBinder resultTo, String resultWho, int requestCode, 2435 int flagsMask, int flagsValues, Bundle options) { 2436 enforceNotIsolatedCaller("startActivityIntentSender"); 2437 // Refuse possible leaked file descriptors 2438 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2439 throw new IllegalArgumentException("File descriptors passed in Intent"); 2440 } 2441 2442 IIntentSender sender = intent.getTarget(); 2443 if (!(sender instanceof PendingIntentRecord)) { 2444 throw new IllegalArgumentException("Bad PendingIntent object"); 2445 } 2446 2447 PendingIntentRecord pir = (PendingIntentRecord)sender; 2448 2449 synchronized (this) { 2450 // If this is coming from the currently resumed activity, it is 2451 // effectively saying that app switches are allowed at this point. 2452 if (mMainStack.mResumedActivity != null 2453 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2454 Binder.getCallingUid()) { 2455 mAppSwitchesAllowedTime = 0; 2456 } 2457 } 2458 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2459 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2460 return ret; 2461 } 2462 2463 public boolean startNextMatchingActivity(IBinder callingActivity, 2464 Intent intent, Bundle options) { 2465 // Refuse possible leaked file descriptors 2466 if (intent != null && intent.hasFileDescriptors() == true) { 2467 throw new IllegalArgumentException("File descriptors passed in Intent"); 2468 } 2469 2470 synchronized (this) { 2471 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2472 if (r == null) { 2473 ActivityOptions.abort(options); 2474 return false; 2475 } 2476 if (r.app == null || r.app.thread == null) { 2477 // The caller is not running... d'oh! 2478 ActivityOptions.abort(options); 2479 return false; 2480 } 2481 intent = new Intent(intent); 2482 // The caller is not allowed to change the data. 2483 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2484 // And we are resetting to find the next component... 2485 intent.setComponent(null); 2486 2487 ActivityInfo aInfo = null; 2488 try { 2489 List<ResolveInfo> resolves = 2490 AppGlobals.getPackageManager().queryIntentActivities( 2491 intent, r.resolvedType, 2492 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2493 UserHandle.getCallingUserId()); 2494 2495 // Look for the original activity in the list... 2496 final int N = resolves != null ? resolves.size() : 0; 2497 for (int i=0; i<N; i++) { 2498 ResolveInfo rInfo = resolves.get(i); 2499 if (rInfo.activityInfo.packageName.equals(r.packageName) 2500 && rInfo.activityInfo.name.equals(r.info.name)) { 2501 // We found the current one... the next matching is 2502 // after it. 2503 i++; 2504 if (i<N) { 2505 aInfo = resolves.get(i).activityInfo; 2506 } 2507 break; 2508 } 2509 } 2510 } catch (RemoteException e) { 2511 } 2512 2513 if (aInfo == null) { 2514 // Nobody who is next! 2515 ActivityOptions.abort(options); 2516 return false; 2517 } 2518 2519 intent.setComponent(new ComponentName( 2520 aInfo.applicationInfo.packageName, aInfo.name)); 2521 intent.setFlags(intent.getFlags()&~( 2522 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2523 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2524 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2525 Intent.FLAG_ACTIVITY_NEW_TASK)); 2526 2527 // Okay now we need to start the new activity, replacing the 2528 // currently running activity. This is a little tricky because 2529 // we want to start the new one as if the current one is finished, 2530 // but not finish the current one first so that there is no flicker. 2531 // And thus... 2532 final boolean wasFinishing = r.finishing; 2533 r.finishing = true; 2534 2535 // Propagate reply information over to the new activity. 2536 final ActivityRecord resultTo = r.resultTo; 2537 final String resultWho = r.resultWho; 2538 final int requestCode = r.requestCode; 2539 r.resultTo = null; 2540 if (resultTo != null) { 2541 resultTo.removeResultsLocked(r, resultWho, requestCode); 2542 } 2543 2544 final long origId = Binder.clearCallingIdentity(); 2545 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2546 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2547 resultWho, requestCode, -1, r.launchedFromUid, 0, 2548 options, false, null); 2549 Binder.restoreCallingIdentity(origId); 2550 2551 r.finishing = wasFinishing; 2552 if (res != ActivityManager.START_SUCCESS) { 2553 return false; 2554 } 2555 return true; 2556 } 2557 } 2558 2559 final int startActivityInPackage(int uid, 2560 Intent intent, String resolvedType, IBinder resultTo, 2561 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2562 2563 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2564 false, true, "startActivityInPackage", null); 2565 2566 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2567 resultTo, resultWho, requestCode, startFlags, 2568 null, null, null, null, options, userId); 2569 return ret; 2570 } 2571 2572 public final int startActivities(IApplicationThread caller, 2573 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2574 enforceNotIsolatedCaller("startActivities"); 2575 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2576 options, UserHandle.getCallingUserId()); 2577 return ret; 2578 } 2579 2580 final int startActivitiesInPackage(int uid, 2581 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2582 Bundle options, int userId) { 2583 2584 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2585 false, true, "startActivityInPackage", null); 2586 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2587 options, userId); 2588 return ret; 2589 } 2590 2591 final void addRecentTaskLocked(TaskRecord task) { 2592 int N = mRecentTasks.size(); 2593 // Quick case: check if the top-most recent task is the same. 2594 if (N > 0 && mRecentTasks.get(0) == task) { 2595 return; 2596 } 2597 // Remove any existing entries that are the same kind of task. 2598 for (int i=0; i<N; i++) { 2599 TaskRecord tr = mRecentTasks.get(i); 2600 if (task.userId == tr.userId 2601 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2602 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2603 mRecentTasks.remove(i); 2604 i--; 2605 N--; 2606 if (task.intent == null) { 2607 // If the new recent task we are adding is not fully 2608 // specified, then replace it with the existing recent task. 2609 task = tr; 2610 } 2611 } 2612 } 2613 if (N >= MAX_RECENT_TASKS) { 2614 mRecentTasks.remove(N-1); 2615 } 2616 mRecentTasks.add(0, task); 2617 } 2618 2619 public void setRequestedOrientation(IBinder token, 2620 int requestedOrientation) { 2621 synchronized (this) { 2622 ActivityRecord r = mMainStack.isInStackLocked(token); 2623 if (r == null) { 2624 return; 2625 } 2626 final long origId = Binder.clearCallingIdentity(); 2627 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2628 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2629 mConfiguration, 2630 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2631 if (config != null) { 2632 r.frozenBeforeDestroy = true; 2633 if (!updateConfigurationLocked(config, r, false, false)) { 2634 mMainStack.resumeTopActivityLocked(null); 2635 } 2636 } 2637 Binder.restoreCallingIdentity(origId); 2638 } 2639 } 2640 2641 public int getRequestedOrientation(IBinder token) { 2642 synchronized (this) { 2643 ActivityRecord r = mMainStack.isInStackLocked(token); 2644 if (r == null) { 2645 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2646 } 2647 return mWindowManager.getAppOrientation(r.appToken); 2648 } 2649 } 2650 2651 /** 2652 * This is the internal entry point for handling Activity.finish(). 2653 * 2654 * @param token The Binder token referencing the Activity we want to finish. 2655 * @param resultCode Result code, if any, from this Activity. 2656 * @param resultData Result data (Intent), if any, from this Activity. 2657 * 2658 * @return Returns true if the activity successfully finished, or false if it is still running. 2659 */ 2660 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2661 // Refuse possible leaked file descriptors 2662 if (resultData != null && resultData.hasFileDescriptors() == true) { 2663 throw new IllegalArgumentException("File descriptors passed in Intent"); 2664 } 2665 2666 synchronized(this) { 2667 if (mController != null) { 2668 // Find the first activity that is not finishing. 2669 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2670 if (next != null) { 2671 // ask watcher if this is allowed 2672 boolean resumeOK = true; 2673 try { 2674 resumeOK = mController.activityResuming(next.packageName); 2675 } catch (RemoteException e) { 2676 mController = null; 2677 } 2678 2679 if (!resumeOK) { 2680 return false; 2681 } 2682 } 2683 } 2684 final long origId = Binder.clearCallingIdentity(); 2685 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2686 resultData, "app-request"); 2687 Binder.restoreCallingIdentity(origId); 2688 return res; 2689 } 2690 } 2691 2692 public final void finishHeavyWeightApp() { 2693 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2694 != PackageManager.PERMISSION_GRANTED) { 2695 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2696 + Binder.getCallingPid() 2697 + ", uid=" + Binder.getCallingUid() 2698 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2699 Slog.w(TAG, msg); 2700 throw new SecurityException(msg); 2701 } 2702 2703 synchronized(this) { 2704 if (mHeavyWeightProcess == null) { 2705 return; 2706 } 2707 2708 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2709 mHeavyWeightProcess.activities); 2710 for (int i=0; i<activities.size(); i++) { 2711 ActivityRecord r = activities.get(i); 2712 if (!r.finishing) { 2713 int index = mMainStack.indexOfTokenLocked(r.appToken); 2714 if (index >= 0) { 2715 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2716 null, "finish-heavy"); 2717 } 2718 } 2719 } 2720 2721 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2722 mHeavyWeightProcess.userId, 0)); 2723 mHeavyWeightProcess = null; 2724 } 2725 } 2726 2727 public void crashApplication(int uid, int initialPid, String packageName, 2728 String message) { 2729 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2730 != PackageManager.PERMISSION_GRANTED) { 2731 String msg = "Permission Denial: crashApplication() from pid=" 2732 + Binder.getCallingPid() 2733 + ", uid=" + Binder.getCallingUid() 2734 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2735 Slog.w(TAG, msg); 2736 throw new SecurityException(msg); 2737 } 2738 2739 synchronized(this) { 2740 ProcessRecord proc = null; 2741 2742 // Figure out which process to kill. We don't trust that initialPid 2743 // still has any relation to current pids, so must scan through the 2744 // list. 2745 synchronized (mPidsSelfLocked) { 2746 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2747 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2748 if (p.uid != uid) { 2749 continue; 2750 } 2751 if (p.pid == initialPid) { 2752 proc = p; 2753 break; 2754 } 2755 for (String str : p.pkgList) { 2756 if (str.equals(packageName)) { 2757 proc = p; 2758 } 2759 } 2760 } 2761 } 2762 2763 if (proc == null) { 2764 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2765 + " initialPid=" + initialPid 2766 + " packageName=" + packageName); 2767 return; 2768 } 2769 2770 if (proc.thread != null) { 2771 if (proc.pid == Process.myPid()) { 2772 Log.w(TAG, "crashApplication: trying to crash self!"); 2773 return; 2774 } 2775 long ident = Binder.clearCallingIdentity(); 2776 try { 2777 proc.thread.scheduleCrash(message); 2778 } catch (RemoteException e) { 2779 } 2780 Binder.restoreCallingIdentity(ident); 2781 } 2782 } 2783 } 2784 2785 public final void finishSubActivity(IBinder token, String resultWho, 2786 int requestCode) { 2787 synchronized(this) { 2788 final long origId = Binder.clearCallingIdentity(); 2789 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2790 Binder.restoreCallingIdentity(origId); 2791 } 2792 } 2793 2794 public boolean finishActivityAffinity(IBinder token) { 2795 synchronized(this) { 2796 final long origId = Binder.clearCallingIdentity(); 2797 boolean res = mMainStack.finishActivityAffinityLocked(token); 2798 Binder.restoreCallingIdentity(origId); 2799 return res; 2800 } 2801 } 2802 2803 public boolean willActivityBeVisible(IBinder token) { 2804 synchronized(this) { 2805 int i; 2806 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2807 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2808 if (r.appToken == token) { 2809 return true; 2810 } 2811 if (r.fullscreen && !r.finishing) { 2812 return false; 2813 } 2814 } 2815 return true; 2816 } 2817 } 2818 2819 public void overridePendingTransition(IBinder token, String packageName, 2820 int enterAnim, int exitAnim) { 2821 synchronized(this) { 2822 ActivityRecord self = mMainStack.isInStackLocked(token); 2823 if (self == null) { 2824 return; 2825 } 2826 2827 final long origId = Binder.clearCallingIdentity(); 2828 2829 if (self.state == ActivityState.RESUMED 2830 || self.state == ActivityState.PAUSING) { 2831 mWindowManager.overridePendingAppTransition(packageName, 2832 enterAnim, exitAnim, null); 2833 } 2834 2835 Binder.restoreCallingIdentity(origId); 2836 } 2837 } 2838 2839 /** 2840 * Main function for removing an existing process from the activity manager 2841 * as a result of that process going away. Clears out all connections 2842 * to the process. 2843 */ 2844 private final void handleAppDiedLocked(ProcessRecord app, 2845 boolean restarting, boolean allowRestart) { 2846 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2847 if (!restarting) { 2848 mLruProcesses.remove(app); 2849 } 2850 2851 if (mProfileProc == app) { 2852 clearProfilerLocked(); 2853 } 2854 2855 // Just in case... 2856 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2857 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2858 mMainStack.mPausingActivity = null; 2859 } 2860 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2861 mMainStack.mLastPausedActivity = null; 2862 } 2863 2864 // Remove this application's activities from active lists. 2865 mMainStack.removeHistoryRecordsForAppLocked(app); 2866 2867 boolean atTop = true; 2868 boolean hasVisibleActivities = false; 2869 2870 // Clean out the history list. 2871 int i = mMainStack.mHistory.size(); 2872 if (localLOGV) Slog.v( 2873 TAG, "Removing app " + app + " from history with " + i + " entries"); 2874 while (i > 0) { 2875 i--; 2876 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2877 if (localLOGV) Slog.v( 2878 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2879 if (r.app == app) { 2880 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2881 if (ActivityStack.DEBUG_ADD_REMOVE) { 2882 RuntimeException here = new RuntimeException("here"); 2883 here.fillInStackTrace(); 2884 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2885 + ": haveState=" + r.haveState 2886 + " stateNotNeeded=" + r.stateNotNeeded 2887 + " finishing=" + r.finishing 2888 + " state=" + r.state, here); 2889 } 2890 if (!r.finishing) { 2891 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2892 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2893 System.identityHashCode(r), 2894 r.task.taskId, r.shortComponentName, 2895 "proc died without state saved"); 2896 } 2897 mMainStack.removeActivityFromHistoryLocked(r); 2898 2899 } else { 2900 // We have the current state for this activity, so 2901 // it can be restarted later when needed. 2902 if (localLOGV) Slog.v( 2903 TAG, "Keeping entry, setting app to null"); 2904 if (r.visible) { 2905 hasVisibleActivities = true; 2906 } 2907 r.app = null; 2908 r.nowVisible = false; 2909 if (!r.haveState) { 2910 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2911 "App died, clearing saved state of " + r); 2912 r.icicle = null; 2913 } 2914 } 2915 2916 r.stack.cleanUpActivityLocked(r, true, true); 2917 } 2918 atTop = false; 2919 } 2920 2921 app.activities.clear(); 2922 2923 if (app.instrumentationClass != null) { 2924 Slog.w(TAG, "Crash of app " + app.processName 2925 + " running instrumentation " + app.instrumentationClass); 2926 Bundle info = new Bundle(); 2927 info.putString("shortMsg", "Process crashed."); 2928 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2929 } 2930 2931 if (!restarting) { 2932 if (!mMainStack.resumeTopActivityLocked(null)) { 2933 // If there was nothing to resume, and we are not already 2934 // restarting this process, but there is a visible activity that 2935 // is hosted by the process... then make sure all visible 2936 // activities are running, taking care of restarting this 2937 // process. 2938 if (hasVisibleActivities) { 2939 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2940 } 2941 } 2942 } 2943 } 2944 2945 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2946 IBinder threadBinder = thread.asBinder(); 2947 // Find the application record. 2948 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2949 ProcessRecord rec = mLruProcesses.get(i); 2950 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2951 return i; 2952 } 2953 } 2954 return -1; 2955 } 2956 2957 final ProcessRecord getRecordForAppLocked( 2958 IApplicationThread thread) { 2959 if (thread == null) { 2960 return null; 2961 } 2962 2963 int appIndex = getLRURecordIndexForAppLocked(thread); 2964 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2965 } 2966 2967 final void appDiedLocked(ProcessRecord app, int pid, 2968 IApplicationThread thread) { 2969 2970 mProcDeaths[0]++; 2971 2972 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2973 synchronized (stats) { 2974 stats.noteProcessDiedLocked(app.info.uid, pid); 2975 } 2976 2977 // Clean up already done if the process has been re-started. 2978 if (app.pid == pid && app.thread != null && 2979 app.thread.asBinder() == thread.asBinder()) { 2980 if (!app.killedBackground) { 2981 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2982 + ") has died."); 2983 } 2984 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2985 if (localLOGV) Slog.v( 2986 TAG, "Dying app: " + app + ", pid: " + pid 2987 + ", thread: " + thread.asBinder()); 2988 boolean doLowMem = app.instrumentationClass == null; 2989 handleAppDiedLocked(app, false, true); 2990 2991 if (doLowMem) { 2992 // If there are no longer any background processes running, 2993 // and the app that died was not running instrumentation, 2994 // then tell everyone we are now low on memory. 2995 boolean haveBg = false; 2996 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2997 ProcessRecord rec = mLruProcesses.get(i); 2998 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2999 haveBg = true; 3000 break; 3001 } 3002 } 3003 3004 if (!haveBg) { 3005 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3006 long now = SystemClock.uptimeMillis(); 3007 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3008 ProcessRecord rec = mLruProcesses.get(i); 3009 if (rec != app && rec.thread != null && 3010 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3011 // The low memory report is overriding any current 3012 // state for a GC request. Make sure to do 3013 // heavy/important/visible/foreground processes first. 3014 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3015 rec.lastRequestedGc = 0; 3016 } else { 3017 rec.lastRequestedGc = rec.lastLowMemory; 3018 } 3019 rec.reportLowMemory = true; 3020 rec.lastLowMemory = now; 3021 mProcessesToGc.remove(rec); 3022 addProcessToGcListLocked(rec); 3023 } 3024 } 3025 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3026 scheduleAppGcsLocked(); 3027 } 3028 } 3029 } else if (app.pid != pid) { 3030 // A new process has already been started. 3031 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3032 + ") has died and restarted (pid " + app.pid + ")."); 3033 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3034 } else if (DEBUG_PROCESSES) { 3035 Slog.d(TAG, "Received spurious death notification for thread " 3036 + thread.asBinder()); 3037 } 3038 } 3039 3040 /** 3041 * If a stack trace dump file is configured, dump process stack traces. 3042 * @param clearTraces causes the dump file to be erased prior to the new 3043 * traces being written, if true; when false, the new traces will be 3044 * appended to any existing file content. 3045 * @param firstPids of dalvik VM processes to dump stack traces for first 3046 * @param lastPids of dalvik VM processes to dump stack traces for last 3047 * @param nativeProcs optional list of native process names to dump stack crawls 3048 * @return file containing stack traces, or null if no dump file is configured 3049 */ 3050 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3051 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3052 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3053 if (tracesPath == null || tracesPath.length() == 0) { 3054 return null; 3055 } 3056 3057 File tracesFile = new File(tracesPath); 3058 try { 3059 File tracesDir = tracesFile.getParentFile(); 3060 if (!tracesDir.exists()) { 3061 tracesFile.mkdirs(); 3062 if (!SELinux.restorecon(tracesDir)) { 3063 return null; 3064 } 3065 } 3066 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3067 3068 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3069 tracesFile.createNewFile(); 3070 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3071 } catch (IOException e) { 3072 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3073 return null; 3074 } 3075 3076 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3077 return tracesFile; 3078 } 3079 3080 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3081 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3082 // Use a FileObserver to detect when traces finish writing. 3083 // The order of traces is considered important to maintain for legibility. 3084 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3085 public synchronized void onEvent(int event, String path) { notify(); } 3086 }; 3087 3088 try { 3089 observer.startWatching(); 3090 3091 // First collect all of the stacks of the most important pids. 3092 if (firstPids != null) { 3093 try { 3094 int num = firstPids.size(); 3095 for (int i = 0; i < num; i++) { 3096 synchronized (observer) { 3097 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3098 observer.wait(200); // Wait for write-close, give up after 200msec 3099 } 3100 } 3101 } catch (InterruptedException e) { 3102 Log.wtf(TAG, e); 3103 } 3104 } 3105 3106 // Next measure CPU usage. 3107 if (processStats != null) { 3108 processStats.init(); 3109 System.gc(); 3110 processStats.update(); 3111 try { 3112 synchronized (processStats) { 3113 processStats.wait(500); // measure over 1/2 second. 3114 } 3115 } catch (InterruptedException e) { 3116 } 3117 processStats.update(); 3118 3119 // We'll take the stack crawls of just the top apps using CPU. 3120 final int N = processStats.countWorkingStats(); 3121 int numProcs = 0; 3122 for (int i=0; i<N && numProcs<5; i++) { 3123 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3124 if (lastPids.indexOfKey(stats.pid) >= 0) { 3125 numProcs++; 3126 try { 3127 synchronized (observer) { 3128 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3129 observer.wait(200); // Wait for write-close, give up after 200msec 3130 } 3131 } catch (InterruptedException e) { 3132 Log.wtf(TAG, e); 3133 } 3134 3135 } 3136 } 3137 } 3138 3139 } finally { 3140 observer.stopWatching(); 3141 } 3142 3143 if (nativeProcs != null) { 3144 int[] pids = Process.getPidsForCommands(nativeProcs); 3145 if (pids != null) { 3146 for (int pid : pids) { 3147 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3148 } 3149 } 3150 } 3151 } 3152 3153 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3154 if (true || IS_USER_BUILD) { 3155 return; 3156 } 3157 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3158 if (tracesPath == null || tracesPath.length() == 0) { 3159 return; 3160 } 3161 3162 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3163 StrictMode.allowThreadDiskWrites(); 3164 try { 3165 final File tracesFile = new File(tracesPath); 3166 final File tracesDir = tracesFile.getParentFile(); 3167 final File tracesTmp = new File(tracesDir, "__tmp__"); 3168 try { 3169 if (!tracesDir.exists()) { 3170 tracesFile.mkdirs(); 3171 if (!SELinux.restorecon(tracesDir.getPath())) { 3172 return; 3173 } 3174 } 3175 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3176 3177 if (tracesFile.exists()) { 3178 tracesTmp.delete(); 3179 tracesFile.renameTo(tracesTmp); 3180 } 3181 StringBuilder sb = new StringBuilder(); 3182 Time tobj = new Time(); 3183 tobj.set(System.currentTimeMillis()); 3184 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3185 sb.append(": "); 3186 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3187 sb.append(" since "); 3188 sb.append(msg); 3189 FileOutputStream fos = new FileOutputStream(tracesFile); 3190 fos.write(sb.toString().getBytes()); 3191 if (app == null) { 3192 fos.write("\n*** No application process!".getBytes()); 3193 } 3194 fos.close(); 3195 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3196 } catch (IOException e) { 3197 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3198 return; 3199 } 3200 3201 if (app != null) { 3202 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3203 firstPids.add(app.pid); 3204 dumpStackTraces(tracesPath, firstPids, null, null, null); 3205 } 3206 3207 File lastTracesFile = null; 3208 File curTracesFile = null; 3209 for (int i=9; i>=0; i--) { 3210 String name = String.format("slow%02d.txt", i); 3211 curTracesFile = new File(tracesDir, name); 3212 if (curTracesFile.exists()) { 3213 if (lastTracesFile != null) { 3214 curTracesFile.renameTo(lastTracesFile); 3215 } else { 3216 curTracesFile.delete(); 3217 } 3218 } 3219 lastTracesFile = curTracesFile; 3220 } 3221 tracesFile.renameTo(curTracesFile); 3222 if (tracesTmp.exists()) { 3223 tracesTmp.renameTo(tracesFile); 3224 } 3225 } finally { 3226 StrictMode.setThreadPolicy(oldPolicy); 3227 } 3228 } 3229 3230 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3231 ActivityRecord parent, final String annotation) { 3232 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3233 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3234 3235 if (mController != null) { 3236 try { 3237 // 0 == continue, -1 = kill process immediately 3238 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3239 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3240 } catch (RemoteException e) { 3241 mController = null; 3242 } 3243 } 3244 3245 long anrTime = SystemClock.uptimeMillis(); 3246 if (MONITOR_CPU_USAGE) { 3247 updateCpuStatsNow(); 3248 } 3249 3250 synchronized (this) { 3251 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3252 if (mShuttingDown) { 3253 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3254 return; 3255 } else if (app.notResponding) { 3256 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3257 return; 3258 } else if (app.crashing) { 3259 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3260 return; 3261 } 3262 3263 // In case we come through here for the same app before completing 3264 // this one, mark as anring now so we will bail out. 3265 app.notResponding = true; 3266 3267 // Log the ANR to the event log. 3268 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3269 annotation); 3270 3271 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3272 firstPids.add(app.pid); 3273 3274 int parentPid = app.pid; 3275 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3276 if (parentPid != app.pid) firstPids.add(parentPid); 3277 3278 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3279 3280 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3281 ProcessRecord r = mLruProcesses.get(i); 3282 if (r != null && r.thread != null) { 3283 int pid = r.pid; 3284 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3285 if (r.persistent) { 3286 firstPids.add(pid); 3287 } else { 3288 lastPids.put(pid, Boolean.TRUE); 3289 } 3290 } 3291 } 3292 } 3293 } 3294 3295 // Log the ANR to the main log. 3296 StringBuilder info = new StringBuilder(); 3297 info.setLength(0); 3298 info.append("ANR in ").append(app.processName); 3299 if (activity != null && activity.shortComponentName != null) { 3300 info.append(" (").append(activity.shortComponentName).append(")"); 3301 } 3302 info.append("\n"); 3303 if (annotation != null) { 3304 info.append("Reason: ").append(annotation).append("\n"); 3305 } 3306 if (parent != null && parent != activity) { 3307 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3308 } 3309 3310 final ProcessStats processStats = new ProcessStats(true); 3311 3312 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3313 3314 String cpuInfo = null; 3315 if (MONITOR_CPU_USAGE) { 3316 updateCpuStatsNow(); 3317 synchronized (mProcessStatsThread) { 3318 cpuInfo = mProcessStats.printCurrentState(anrTime); 3319 } 3320 info.append(processStats.printCurrentLoad()); 3321 info.append(cpuInfo); 3322 } 3323 3324 info.append(processStats.printCurrentState(anrTime)); 3325 3326 Slog.e(TAG, info.toString()); 3327 if (tracesFile == null) { 3328 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3329 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3330 } 3331 3332 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3333 cpuInfo, tracesFile, null); 3334 3335 if (mController != null) { 3336 try { 3337 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3338 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3339 if (res != 0) { 3340 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3341 return; 3342 } 3343 } catch (RemoteException e) { 3344 mController = null; 3345 } 3346 } 3347 3348 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3349 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3350 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3351 3352 synchronized (this) { 3353 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3354 Slog.w(TAG, "Killing " + app + ": background ANR"); 3355 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3356 app.processName, app.setAdj, "background ANR"); 3357 Process.killProcessQuiet(app.pid); 3358 return; 3359 } 3360 3361 // Set the app's notResponding state, and look up the errorReportReceiver 3362 makeAppNotRespondingLocked(app, 3363 activity != null ? activity.shortComponentName : null, 3364 annotation != null ? "ANR " + annotation : "ANR", 3365 info.toString()); 3366 3367 // Bring up the infamous App Not Responding dialog 3368 Message msg = Message.obtain(); 3369 HashMap map = new HashMap(); 3370 msg.what = SHOW_NOT_RESPONDING_MSG; 3371 msg.obj = map; 3372 map.put("app", app); 3373 if (activity != null) { 3374 map.put("activity", activity); 3375 } 3376 3377 mHandler.sendMessage(msg); 3378 } 3379 } 3380 3381 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3382 if (!mLaunchWarningShown) { 3383 mLaunchWarningShown = true; 3384 mHandler.post(new Runnable() { 3385 @Override 3386 public void run() { 3387 synchronized (ActivityManagerService.this) { 3388 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3389 d.show(); 3390 mHandler.postDelayed(new Runnable() { 3391 @Override 3392 public void run() { 3393 synchronized (ActivityManagerService.this) { 3394 d.dismiss(); 3395 mLaunchWarningShown = false; 3396 } 3397 } 3398 }, 4000); 3399 } 3400 } 3401 }); 3402 } 3403 } 3404 3405 public boolean clearApplicationUserData(final String packageName, 3406 final IPackageDataObserver observer, final int userId) { 3407 enforceNotIsolatedCaller("clearApplicationUserData"); 3408 int uid = Binder.getCallingUid(); 3409 int pid = Binder.getCallingPid(); 3410 long callingId = Binder.clearCallingIdentity(); 3411 try { 3412 IPackageManager pm = AppGlobals.getPackageManager(); 3413 int pkgUid = -1; 3414 synchronized(this) { 3415 try { 3416 pkgUid = pm.getPackageUid(packageName, userId); 3417 } catch (RemoteException e) { 3418 } 3419 if (pkgUid == -1) { 3420 Slog.w(TAG, "Invalid packageName:" + packageName); 3421 return false; 3422 } 3423 if (uid == pkgUid || checkComponentPermission( 3424 android.Manifest.permission.CLEAR_APP_USER_DATA, 3425 pid, uid, -1, true) 3426 == PackageManager.PERMISSION_GRANTED) { 3427 forceStopPackageLocked(packageName, pkgUid); 3428 } else { 3429 throw new SecurityException(pid+" does not have permission:"+ 3430 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3431 "for process:"+packageName); 3432 } 3433 } 3434 3435 try { 3436 //clear application user data 3437 pm.clearApplicationUserData(packageName, observer, userId); 3438 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3439 Uri.fromParts("package", packageName, null)); 3440 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3441 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3442 null, null, 0, null, null, null, false, false, userId); 3443 } catch (RemoteException e) { 3444 } 3445 } finally { 3446 Binder.restoreCallingIdentity(callingId); 3447 } 3448 return true; 3449 } 3450 3451 public void killBackgroundProcesses(final String packageName) { 3452 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3453 != PackageManager.PERMISSION_GRANTED && 3454 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3455 != PackageManager.PERMISSION_GRANTED) { 3456 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3457 + Binder.getCallingPid() 3458 + ", uid=" + Binder.getCallingUid() 3459 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3460 Slog.w(TAG, msg); 3461 throw new SecurityException(msg); 3462 } 3463 3464 int userId = UserHandle.getCallingUserId(); 3465 long callingId = Binder.clearCallingIdentity(); 3466 try { 3467 IPackageManager pm = AppGlobals.getPackageManager(); 3468 int pkgUid = -1; 3469 synchronized(this) { 3470 try { 3471 pkgUid = pm.getPackageUid(packageName, userId); 3472 } catch (RemoteException e) { 3473 } 3474 if (pkgUid == -1) { 3475 Slog.w(TAG, "Invalid packageName: " + packageName); 3476 return; 3477 } 3478 killPackageProcessesLocked(packageName, pkgUid, -1, 3479 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3480 } 3481 } finally { 3482 Binder.restoreCallingIdentity(callingId); 3483 } 3484 } 3485 3486 public void killAllBackgroundProcesses() { 3487 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3488 != PackageManager.PERMISSION_GRANTED) { 3489 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3490 + Binder.getCallingPid() 3491 + ", uid=" + Binder.getCallingUid() 3492 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3493 Slog.w(TAG, msg); 3494 throw new SecurityException(msg); 3495 } 3496 3497 long callingId = Binder.clearCallingIdentity(); 3498 try { 3499 synchronized(this) { 3500 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3501 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3502 final int NA = apps.size(); 3503 for (int ia=0; ia<NA; ia++) { 3504 ProcessRecord app = apps.valueAt(ia); 3505 if (app.persistent) { 3506 // we don't kill persistent processes 3507 continue; 3508 } 3509 if (app.removed) { 3510 procs.add(app); 3511 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3512 app.removed = true; 3513 procs.add(app); 3514 } 3515 } 3516 } 3517 3518 int N = procs.size(); 3519 for (int i=0; i<N; i++) { 3520 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3521 } 3522 } 3523 } finally { 3524 Binder.restoreCallingIdentity(callingId); 3525 } 3526 } 3527 3528 public void forceStopPackage(final String packageName) { 3529 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3530 != PackageManager.PERMISSION_GRANTED) { 3531 String msg = "Permission Denial: forceStopPackage() from pid=" 3532 + Binder.getCallingPid() 3533 + ", uid=" + Binder.getCallingUid() 3534 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3535 Slog.w(TAG, msg); 3536 throw new SecurityException(msg); 3537 } 3538 final int userId = UserHandle.getCallingUserId(); 3539 long callingId = Binder.clearCallingIdentity(); 3540 try { 3541 IPackageManager pm = AppGlobals.getPackageManager(); 3542 int pkgUid = -1; 3543 synchronized(this) { 3544 try { 3545 pkgUid = pm.getPackageUid(packageName, userId); 3546 } catch (RemoteException e) { 3547 } 3548 if (pkgUid == -1) { 3549 Slog.w(TAG, "Invalid packageName: " + packageName); 3550 return; 3551 } 3552 forceStopPackageLocked(packageName, pkgUid); 3553 try { 3554 pm.setPackageStoppedState(packageName, true, userId); 3555 } catch (RemoteException e) { 3556 } catch (IllegalArgumentException e) { 3557 Slog.w(TAG, "Failed trying to unstop package " 3558 + packageName + ": " + e); 3559 } 3560 } 3561 } finally { 3562 Binder.restoreCallingIdentity(callingId); 3563 } 3564 } 3565 3566 /* 3567 * The pkg name and uid have to be specified. 3568 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3569 */ 3570 public void killApplicationWithUid(String pkg, int uid) { 3571 if (pkg == null) { 3572 return; 3573 } 3574 // Make sure the uid is valid. 3575 if (uid < 0) { 3576 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3577 return; 3578 } 3579 int callerUid = Binder.getCallingUid(); 3580 // Only the system server can kill an application 3581 if (callerUid == Process.SYSTEM_UID) { 3582 // Post an aysnc message to kill the application 3583 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3584 msg.arg1 = uid; 3585 msg.arg2 = 0; 3586 msg.obj = pkg; 3587 mHandler.sendMessage(msg); 3588 } else { 3589 throw new SecurityException(callerUid + " cannot kill pkg: " + 3590 pkg); 3591 } 3592 } 3593 3594 public void closeSystemDialogs(String reason) { 3595 enforceNotIsolatedCaller("closeSystemDialogs"); 3596 3597 final int pid = Binder.getCallingPid(); 3598 final int uid = Binder.getCallingUid(); 3599 final long origId = Binder.clearCallingIdentity(); 3600 try { 3601 synchronized (this) { 3602 // Only allow this from foreground processes, so that background 3603 // applications can't abuse it to prevent system UI from being shown. 3604 if (uid >= Process.FIRST_APPLICATION_UID) { 3605 ProcessRecord proc; 3606 synchronized (mPidsSelfLocked) { 3607 proc = mPidsSelfLocked.get(pid); 3608 } 3609 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3610 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3611 + " from background process " + proc); 3612 return; 3613 } 3614 } 3615 closeSystemDialogsLocked(reason); 3616 } 3617 } finally { 3618 Binder.restoreCallingIdentity(origId); 3619 } 3620 } 3621 3622 void closeSystemDialogsLocked(String reason) { 3623 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3624 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3625 if (reason != null) { 3626 intent.putExtra("reason", reason); 3627 } 3628 mWindowManager.closeSystemDialogs(reason); 3629 3630 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3631 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3632 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3633 r.stack.finishActivityLocked(r, i, 3634 Activity.RESULT_CANCELED, null, "close-sys"); 3635 } 3636 } 3637 3638 broadcastIntentLocked(null, null, intent, null, 3639 null, 0, null, null, null, false, false, -1, 3640 Process.SYSTEM_UID, UserHandle.USER_ALL); 3641 } 3642 3643 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3644 throws RemoteException { 3645 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3646 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3647 for (int i=pids.length-1; i>=0; i--) { 3648 infos[i] = new Debug.MemoryInfo(); 3649 Debug.getMemoryInfo(pids[i], infos[i]); 3650 } 3651 return infos; 3652 } 3653 3654 public long[] getProcessPss(int[] pids) throws RemoteException { 3655 enforceNotIsolatedCaller("getProcessPss"); 3656 long[] pss = new long[pids.length]; 3657 for (int i=pids.length-1; i>=0; i--) { 3658 pss[i] = Debug.getPss(pids[i]); 3659 } 3660 return pss; 3661 } 3662 3663 public void killApplicationProcess(String processName, int uid) { 3664 if (processName == null) { 3665 return; 3666 } 3667 3668 int callerUid = Binder.getCallingUid(); 3669 // Only the system server can kill an application 3670 if (callerUid == Process.SYSTEM_UID) { 3671 synchronized (this) { 3672 ProcessRecord app = getProcessRecordLocked(processName, uid); 3673 if (app != null && app.thread != null) { 3674 try { 3675 app.thread.scheduleSuicide(); 3676 } catch (RemoteException e) { 3677 // If the other end already died, then our work here is done. 3678 } 3679 } else { 3680 Slog.w(TAG, "Process/uid not found attempting kill of " 3681 + processName + " / " + uid); 3682 } 3683 } 3684 } else { 3685 throw new SecurityException(callerUid + " cannot kill app process: " + 3686 processName); 3687 } 3688 } 3689 3690 private void forceStopPackageLocked(final String packageName, int uid) { 3691 forceStopPackageLocked(packageName, uid, false, false, true, false, 3692 UserHandle.getUserId(uid)); 3693 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3694 Uri.fromParts("package", packageName, null)); 3695 if (!mProcessesReady) { 3696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3697 } 3698 intent.putExtra(Intent.EXTRA_UID, uid); 3699 broadcastIntentLocked(null, null, intent, 3700 null, null, 0, null, null, null, 3701 false, false, 3702 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3703 } 3704 3705 private void forceStopUserLocked(int userId) { 3706 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3707 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3708 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3709 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3710 broadcastIntentLocked(null, null, intent, 3711 null, null, 0, null, null, null, 3712 false, false, 3713 MY_PID, Process.SYSTEM_UID, userId); 3714 } 3715 3716 private final boolean killPackageProcessesLocked(String packageName, int uid, 3717 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3718 boolean doit, boolean evenPersistent, String reason) { 3719 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3720 3721 // Remove all processes this package may have touched: all with the 3722 // same UID (except for the system or root user), and all whose name 3723 // matches the package name. 3724 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3725 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3726 final int NA = apps.size(); 3727 for (int ia=0; ia<NA; ia++) { 3728 ProcessRecord app = apps.valueAt(ia); 3729 if (app.persistent && !evenPersistent) { 3730 // we don't kill persistent processes 3731 continue; 3732 } 3733 if (app.removed) { 3734 if (doit) { 3735 procs.add(app); 3736 } 3737 // If no package is specified, we call all processes under the 3738 // give user id. 3739 } else if (packageName == null) { 3740 if (app.userId == userId) { 3741 if (app.setAdj >= minOomAdj) { 3742 if (!doit) { 3743 return true; 3744 } 3745 app.removed = true; 3746 procs.add(app); 3747 } 3748 } 3749 // If uid is specified and the uid and process name match 3750 // Or, the uid is not specified and the process name matches 3751 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3752 || ((app.processName.equals(packageName) 3753 || app.processName.startsWith(procNamePrefix)) 3754 && uid < 0))) { 3755 if (app.setAdj >= minOomAdj) { 3756 if (!doit) { 3757 return true; 3758 } 3759 app.removed = true; 3760 procs.add(app); 3761 } 3762 } 3763 } 3764 } 3765 3766 int N = procs.size(); 3767 for (int i=0; i<N; i++) { 3768 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3769 } 3770 return N > 0; 3771 } 3772 3773 private final boolean forceStopPackageLocked(String name, int uid, 3774 boolean callerWillRestart, boolean purgeCache, boolean doit, 3775 boolean evenPersistent, int userId) { 3776 int i; 3777 int N; 3778 3779 if (uid < 0 && name != null) { 3780 try { 3781 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3782 } catch (RemoteException e) { 3783 } 3784 } 3785 3786 if (doit) { 3787 if (name != null) { 3788 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3789 } else { 3790 Slog.i(TAG, "Force stopping user " + userId); 3791 } 3792 3793 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3794 while (badApps.hasNext()) { 3795 SparseArray<Long> ba = badApps.next(); 3796 for (i=ba.size()-1; i>=0; i--) { 3797 boolean remove = false; 3798 final int entUid = ba.keyAt(i); 3799 if (name != null) { 3800 if (entUid == uid) { 3801 remove = true; 3802 } 3803 } else if (UserHandle.getUserId(entUid) == userId) { 3804 remove = true; 3805 } 3806 if (remove) { 3807 ba.removeAt(i); 3808 } 3809 } 3810 if (ba.size() == 0) { 3811 badApps.remove(); 3812 } 3813 } 3814 } 3815 3816 boolean didSomething = killPackageProcessesLocked(name, uid, 3817 name == null ? userId : -1 , -100, callerWillRestart, false, 3818 doit, evenPersistent, 3819 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3820 3821 TaskRecord lastTask = null; 3822 for (i=0; i<mMainStack.mHistory.size(); i++) { 3823 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3824 final boolean samePackage = r.packageName.equals(name) 3825 || (name == null && r.userId == userId); 3826 if (r.userId == userId 3827 && (samePackage || r.task == lastTask) 3828 && (r.app == null || evenPersistent || !r.app.persistent)) { 3829 if (!doit) { 3830 if (r.finishing) { 3831 // If this activity is just finishing, then it is not 3832 // interesting as far as something to stop. 3833 continue; 3834 } 3835 return true; 3836 } 3837 didSomething = true; 3838 Slog.i(TAG, " Force finishing activity " + r); 3839 if (samePackage) { 3840 if (r.app != null) { 3841 r.app.removed = true; 3842 } 3843 r.app = null; 3844 } 3845 lastTask = r.task; 3846 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3847 null, "force-stop", true)) { 3848 i--; 3849 } 3850 } 3851 } 3852 3853 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3854 if (!doit) { 3855 return true; 3856 } 3857 didSomething = true; 3858 } 3859 3860 if (name == null) { 3861 // Remove all sticky broadcasts from this user. 3862 mStickyBroadcasts.remove(userId); 3863 } 3864 3865 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3866 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3867 if ((name == null || provider.info.packageName.equals(name)) 3868 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3869 if (!doit) { 3870 return true; 3871 } 3872 didSomething = true; 3873 providers.add(provider); 3874 } 3875 } 3876 3877 N = providers.size(); 3878 for (i=0; i<N; i++) { 3879 removeDyingProviderLocked(null, providers.get(i), true); 3880 } 3881 3882 if (doit) { 3883 if (purgeCache && name != null) { 3884 AttributeCache ac = AttributeCache.instance(); 3885 if (ac != null) { 3886 ac.removePackage(name); 3887 } 3888 } 3889 if (mBooted) { 3890 mMainStack.resumeTopActivityLocked(null); 3891 mMainStack.scheduleIdleLocked(); 3892 } 3893 } 3894 3895 return didSomething; 3896 } 3897 3898 private final boolean removeProcessLocked(ProcessRecord app, 3899 boolean callerWillRestart, boolean allowRestart, String reason) { 3900 final String name = app.processName; 3901 final int uid = app.uid; 3902 if (DEBUG_PROCESSES) Slog.d( 3903 TAG, "Force removing proc " + app.toShortString() + " (" + name 3904 + "/" + uid + ")"); 3905 3906 mProcessNames.remove(name, uid); 3907 mIsolatedProcesses.remove(app.uid); 3908 if (mHeavyWeightProcess == app) { 3909 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3910 mHeavyWeightProcess.userId, 0)); 3911 mHeavyWeightProcess = null; 3912 } 3913 boolean needRestart = false; 3914 if (app.pid > 0 && app.pid != MY_PID) { 3915 int pid = app.pid; 3916 synchronized (mPidsSelfLocked) { 3917 mPidsSelfLocked.remove(pid); 3918 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3919 } 3920 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3921 handleAppDiedLocked(app, true, allowRestart); 3922 mLruProcesses.remove(app); 3923 Process.killProcessQuiet(pid); 3924 3925 if (app.persistent && !app.isolated) { 3926 if (!callerWillRestart) { 3927 addAppLocked(app.info, false); 3928 } else { 3929 needRestart = true; 3930 } 3931 } 3932 } else { 3933 mRemovedProcesses.add(app); 3934 } 3935 3936 return needRestart; 3937 } 3938 3939 private final void processStartTimedOutLocked(ProcessRecord app) { 3940 final int pid = app.pid; 3941 boolean gone = false; 3942 synchronized (mPidsSelfLocked) { 3943 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3944 if (knownApp != null && knownApp.thread == null) { 3945 mPidsSelfLocked.remove(pid); 3946 gone = true; 3947 } 3948 } 3949 3950 if (gone) { 3951 Slog.w(TAG, "Process " + app + " failed to attach"); 3952 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3953 app.processName); 3954 mProcessNames.remove(app.processName, app.uid); 3955 mIsolatedProcesses.remove(app.uid); 3956 if (mHeavyWeightProcess == app) { 3957 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3958 mHeavyWeightProcess.userId, 0)); 3959 mHeavyWeightProcess = null; 3960 } 3961 // Take care of any launching providers waiting for this process. 3962 checkAppInLaunchingProvidersLocked(app, true); 3963 // Take care of any services that are waiting for the process. 3964 mServices.processStartTimedOutLocked(app); 3965 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3966 app.processName, app.setAdj, "start timeout"); 3967 Process.killProcessQuiet(pid); 3968 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3969 Slog.w(TAG, "Unattached app died before backup, skipping"); 3970 try { 3971 IBackupManager bm = IBackupManager.Stub.asInterface( 3972 ServiceManager.getService(Context.BACKUP_SERVICE)); 3973 bm.agentDisconnected(app.info.packageName); 3974 } catch (RemoteException e) { 3975 // Can't happen; the backup manager is local 3976 } 3977 } 3978 if (isPendingBroadcastProcessLocked(pid)) { 3979 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3980 skipPendingBroadcastLocked(pid); 3981 } 3982 } else { 3983 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3984 } 3985 } 3986 3987 private final boolean attachApplicationLocked(IApplicationThread thread, 3988 int pid) { 3989 3990 // Find the application record that is being attached... either via 3991 // the pid if we are running in multiple processes, or just pull the 3992 // next app record if we are emulating process with anonymous threads. 3993 ProcessRecord app; 3994 if (pid != MY_PID && pid >= 0) { 3995 synchronized (mPidsSelfLocked) { 3996 app = mPidsSelfLocked.get(pid); 3997 } 3998 } else { 3999 app = null; 4000 } 4001 4002 if (app == null) { 4003 Slog.w(TAG, "No pending application record for pid " + pid 4004 + " (IApplicationThread " + thread + "); dropping process"); 4005 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4006 if (pid > 0 && pid != MY_PID) { 4007 Process.killProcessQuiet(pid); 4008 } else { 4009 try { 4010 thread.scheduleExit(); 4011 } catch (Exception e) { 4012 // Ignore exceptions. 4013 } 4014 } 4015 return false; 4016 } 4017 4018 // If this application record is still attached to a previous 4019 // process, clean it up now. 4020 if (app.thread != null) { 4021 handleAppDiedLocked(app, true, true); 4022 } 4023 4024 // Tell the process all about itself. 4025 4026 if (localLOGV) Slog.v( 4027 TAG, "Binding process pid " + pid + " to record " + app); 4028 4029 String processName = app.processName; 4030 try { 4031 AppDeathRecipient adr = new AppDeathRecipient( 4032 app, pid, thread); 4033 thread.asBinder().linkToDeath(adr, 0); 4034 app.deathRecipient = adr; 4035 } catch (RemoteException e) { 4036 app.resetPackageList(); 4037 startProcessLocked(app, "link fail", processName); 4038 return false; 4039 } 4040 4041 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4042 4043 app.thread = thread; 4044 app.curAdj = app.setAdj = -100; 4045 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4046 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4047 app.forcingToForeground = null; 4048 app.foregroundServices = false; 4049 app.hasShownUi = false; 4050 app.debugging = false; 4051 4052 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4053 4054 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4055 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4056 4057 if (!normalMode) { 4058 Slog.i(TAG, "Launching preboot mode app: " + app); 4059 } 4060 4061 if (localLOGV) Slog.v( 4062 TAG, "New app record " + app 4063 + " thread=" + thread.asBinder() + " pid=" + pid); 4064 try { 4065 int testMode = IApplicationThread.DEBUG_OFF; 4066 if (mDebugApp != null && mDebugApp.equals(processName)) { 4067 testMode = mWaitForDebugger 4068 ? IApplicationThread.DEBUG_WAIT 4069 : IApplicationThread.DEBUG_ON; 4070 app.debugging = true; 4071 if (mDebugTransient) { 4072 mDebugApp = mOrigDebugApp; 4073 mWaitForDebugger = mOrigWaitForDebugger; 4074 } 4075 } 4076 String profileFile = app.instrumentationProfileFile; 4077 ParcelFileDescriptor profileFd = null; 4078 boolean profileAutoStop = false; 4079 if (mProfileApp != null && mProfileApp.equals(processName)) { 4080 mProfileProc = app; 4081 profileFile = mProfileFile; 4082 profileFd = mProfileFd; 4083 profileAutoStop = mAutoStopProfiler; 4084 } 4085 boolean enableOpenGlTrace = false; 4086 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4087 enableOpenGlTrace = true; 4088 mOpenGlTraceApp = null; 4089 } 4090 4091 // If the app is being launched for restore or full backup, set it up specially 4092 boolean isRestrictedBackupMode = false; 4093 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4094 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4095 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4096 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4097 } 4098 4099 ensurePackageDexOpt(app.instrumentationInfo != null 4100 ? app.instrumentationInfo.packageName 4101 : app.info.packageName); 4102 if (app.instrumentationClass != null) { 4103 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4104 } 4105 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4106 + processName + " with config " + mConfiguration); 4107 ApplicationInfo appInfo = app.instrumentationInfo != null 4108 ? app.instrumentationInfo : app.info; 4109 app.compat = compatibilityInfoForPackageLocked(appInfo); 4110 if (profileFd != null) { 4111 profileFd = profileFd.dup(); 4112 } 4113 thread.bindApplication(processName, appInfo, providers, 4114 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4115 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4116 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4117 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4118 mCoreSettingsObserver.getCoreSettingsLocked()); 4119 updateLruProcessLocked(app, false, true); 4120 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4121 } catch (Exception e) { 4122 // todo: Yikes! What should we do? For now we will try to 4123 // start another process, but that could easily get us in 4124 // an infinite loop of restarting processes... 4125 Slog.w(TAG, "Exception thrown during bind!", e); 4126 4127 app.resetPackageList(); 4128 app.unlinkDeathRecipient(); 4129 startProcessLocked(app, "bind fail", processName); 4130 return false; 4131 } 4132 4133 // Remove this record from the list of starting applications. 4134 mPersistentStartingProcesses.remove(app); 4135 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4136 "Attach application locked removing on hold: " + app); 4137 mProcessesOnHold.remove(app); 4138 4139 boolean badApp = false; 4140 boolean didSomething = false; 4141 4142 // See if the top visible activity is waiting to run in this process... 4143 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4144 if (hr != null && normalMode) { 4145 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4146 && processName.equals(hr.processName)) { 4147 try { 4148 if (mHeadless) { 4149 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4150 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4151 didSomething = true; 4152 } 4153 } catch (Exception e) { 4154 Slog.w(TAG, "Exception in new application when starting activity " 4155 + hr.intent.getComponent().flattenToShortString(), e); 4156 badApp = true; 4157 } 4158 } else { 4159 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4160 } 4161 } 4162 4163 // Find any services that should be running in this process... 4164 if (!badApp) { 4165 try { 4166 didSomething |= mServices.attachApplicationLocked(app, processName); 4167 } catch (Exception e) { 4168 badApp = true; 4169 } 4170 } 4171 4172 // Check if a next-broadcast receiver is in this process... 4173 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4174 try { 4175 didSomething = sendPendingBroadcastsLocked(app); 4176 } catch (Exception e) { 4177 // If the app died trying to launch the receiver we declare it 'bad' 4178 badApp = true; 4179 } 4180 } 4181 4182 // Check whether the next backup agent is in this process... 4183 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4184 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4185 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4186 try { 4187 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4188 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4189 mBackupTarget.backupMode); 4190 } catch (Exception e) { 4191 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4192 e.printStackTrace(); 4193 } 4194 } 4195 4196 if (badApp) { 4197 // todo: Also need to kill application to deal with all 4198 // kinds of exceptions. 4199 handleAppDiedLocked(app, false, true); 4200 return false; 4201 } 4202 4203 if (!didSomething) { 4204 updateOomAdjLocked(); 4205 } 4206 4207 return true; 4208 } 4209 4210 public final void attachApplication(IApplicationThread thread) { 4211 synchronized (this) { 4212 int callingPid = Binder.getCallingPid(); 4213 final long origId = Binder.clearCallingIdentity(); 4214 attachApplicationLocked(thread, callingPid); 4215 Binder.restoreCallingIdentity(origId); 4216 } 4217 } 4218 4219 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4220 final long origId = Binder.clearCallingIdentity(); 4221 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4222 if (stopProfiling) { 4223 synchronized (this) { 4224 if (mProfileProc == r.app) { 4225 if (mProfileFd != null) { 4226 try { 4227 mProfileFd.close(); 4228 } catch (IOException e) { 4229 } 4230 clearProfilerLocked(); 4231 } 4232 } 4233 } 4234 } 4235 Binder.restoreCallingIdentity(origId); 4236 } 4237 4238 void enableScreenAfterBoot() { 4239 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4240 SystemClock.uptimeMillis()); 4241 mWindowManager.enableScreenAfterBoot(); 4242 4243 synchronized (this) { 4244 updateEventDispatchingLocked(); 4245 } 4246 } 4247 4248 public void showBootMessage(final CharSequence msg, final boolean always) { 4249 enforceNotIsolatedCaller("showBootMessage"); 4250 mWindowManager.showBootMessage(msg, always); 4251 } 4252 4253 public void dismissKeyguardOnNextActivity() { 4254 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4255 final long token = Binder.clearCallingIdentity(); 4256 try { 4257 synchronized (this) { 4258 if (mLockScreenShown) { 4259 mLockScreenShown = false; 4260 comeOutOfSleepIfNeededLocked(); 4261 } 4262 mMainStack.dismissKeyguardOnNextActivityLocked(); 4263 } 4264 } finally { 4265 Binder.restoreCallingIdentity(token); 4266 } 4267 } 4268 4269 final void finishBooting() { 4270 IntentFilter pkgFilter = new IntentFilter(); 4271 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4272 pkgFilter.addDataScheme("package"); 4273 mContext.registerReceiver(new BroadcastReceiver() { 4274 @Override 4275 public void onReceive(Context context, Intent intent) { 4276 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4277 if (pkgs != null) { 4278 for (String pkg : pkgs) { 4279 synchronized (ActivityManagerService.this) { 4280 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4281 setResultCode(Activity.RESULT_OK); 4282 return; 4283 } 4284 } 4285 } 4286 } 4287 } 4288 }, pkgFilter); 4289 4290 synchronized (this) { 4291 // Ensure that any processes we had put on hold are now started 4292 // up. 4293 final int NP = mProcessesOnHold.size(); 4294 if (NP > 0) { 4295 ArrayList<ProcessRecord> procs = 4296 new ArrayList<ProcessRecord>(mProcessesOnHold); 4297 for (int ip=0; ip<NP; ip++) { 4298 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4299 + procs.get(ip)); 4300 startProcessLocked(procs.get(ip), "on-hold", null); 4301 } 4302 } 4303 4304 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4305 // Start looking for apps that are abusing wake locks. 4306 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4307 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4308 // Tell anyone interested that we are done booting! 4309 SystemProperties.set("sys.boot_completed", "1"); 4310 SystemProperties.set("dev.bootcomplete", "1"); 4311 for (int i=0; i<mStartedUsers.size(); i++) { 4312 UserStartedState uss = mStartedUsers.valueAt(i); 4313 if (uss.mState == UserStartedState.STATE_BOOTING) { 4314 uss.mState = UserStartedState.STATE_RUNNING; 4315 final int userId = mStartedUsers.keyAt(i); 4316 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4317 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4318 broadcastIntentLocked(null, null, intent, 4319 null, null, 0, null, null, 4320 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4321 false, false, MY_PID, Process.SYSTEM_UID, userId); 4322 } 4323 } 4324 } 4325 } 4326 } 4327 4328 final void ensureBootCompleted() { 4329 boolean booting; 4330 boolean enableScreen; 4331 synchronized (this) { 4332 booting = mBooting; 4333 mBooting = false; 4334 enableScreen = !mBooted; 4335 mBooted = true; 4336 } 4337 4338 if (booting) { 4339 finishBooting(); 4340 } 4341 4342 if (enableScreen) { 4343 enableScreenAfterBoot(); 4344 } 4345 } 4346 4347 public final void activityPaused(IBinder token) { 4348 final long origId = Binder.clearCallingIdentity(); 4349 mMainStack.activityPaused(token, false); 4350 Binder.restoreCallingIdentity(origId); 4351 } 4352 4353 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4354 CharSequence description) { 4355 if (localLOGV) Slog.v( 4356 TAG, "Activity stopped: token=" + token); 4357 4358 // Refuse possible leaked file descriptors 4359 if (icicle != null && icicle.hasFileDescriptors()) { 4360 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4361 } 4362 4363 ActivityRecord r = null; 4364 4365 final long origId = Binder.clearCallingIdentity(); 4366 4367 synchronized (this) { 4368 r = mMainStack.isInStackLocked(token); 4369 if (r != null) { 4370 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4371 } 4372 } 4373 4374 if (r != null) { 4375 sendPendingThumbnail(r, null, null, null, false); 4376 } 4377 4378 trimApplications(); 4379 4380 Binder.restoreCallingIdentity(origId); 4381 } 4382 4383 public final void activityDestroyed(IBinder token) { 4384 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4385 mMainStack.activityDestroyed(token); 4386 } 4387 4388 public String getCallingPackage(IBinder token) { 4389 synchronized (this) { 4390 ActivityRecord r = getCallingRecordLocked(token); 4391 return r != null && r.app != null ? r.info.packageName : null; 4392 } 4393 } 4394 4395 public ComponentName getCallingActivity(IBinder token) { 4396 synchronized (this) { 4397 ActivityRecord r = getCallingRecordLocked(token); 4398 return r != null ? r.intent.getComponent() : null; 4399 } 4400 } 4401 4402 private ActivityRecord getCallingRecordLocked(IBinder token) { 4403 ActivityRecord r = mMainStack.isInStackLocked(token); 4404 if (r == null) { 4405 return null; 4406 } 4407 return r.resultTo; 4408 } 4409 4410 public ComponentName getActivityClassForToken(IBinder token) { 4411 synchronized(this) { 4412 ActivityRecord r = mMainStack.isInStackLocked(token); 4413 if (r == null) { 4414 return null; 4415 } 4416 return r.intent.getComponent(); 4417 } 4418 } 4419 4420 public String getPackageForToken(IBinder token) { 4421 synchronized(this) { 4422 ActivityRecord r = mMainStack.isInStackLocked(token); 4423 if (r == null) { 4424 return null; 4425 } 4426 return r.packageName; 4427 } 4428 } 4429 4430 public IIntentSender getIntentSender(int type, 4431 String packageName, IBinder token, String resultWho, 4432 int requestCode, Intent[] intents, String[] resolvedTypes, 4433 int flags, Bundle options, int userId) { 4434 enforceNotIsolatedCaller("getIntentSender"); 4435 // Refuse possible leaked file descriptors 4436 if (intents != null) { 4437 if (intents.length < 1) { 4438 throw new IllegalArgumentException("Intents array length must be >= 1"); 4439 } 4440 for (int i=0; i<intents.length; i++) { 4441 Intent intent = intents[i]; 4442 if (intent != null) { 4443 if (intent.hasFileDescriptors()) { 4444 throw new IllegalArgumentException("File descriptors passed in Intent"); 4445 } 4446 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4447 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4448 throw new IllegalArgumentException( 4449 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4450 } 4451 intents[i] = new Intent(intent); 4452 } 4453 } 4454 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4455 throw new IllegalArgumentException( 4456 "Intent array length does not match resolvedTypes length"); 4457 } 4458 } 4459 if (options != null) { 4460 if (options.hasFileDescriptors()) { 4461 throw new IllegalArgumentException("File descriptors passed in options"); 4462 } 4463 } 4464 4465 synchronized(this) { 4466 int callingUid = Binder.getCallingUid(); 4467 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4468 false, true, "getIntentSender", null); 4469 try { 4470 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4471 int uid = AppGlobals.getPackageManager() 4472 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4473 if (!UserHandle.isSameApp(callingUid, uid)) { 4474 String msg = "Permission Denial: getIntentSender() from pid=" 4475 + Binder.getCallingPid() 4476 + ", uid=" + Binder.getCallingUid() 4477 + ", (need uid=" + uid + ")" 4478 + " is not allowed to send as package " + packageName; 4479 Slog.w(TAG, msg); 4480 throw new SecurityException(msg); 4481 } 4482 } 4483 4484 return getIntentSenderLocked(type, packageName, callingUid, userId, 4485 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4486 4487 } catch (RemoteException e) { 4488 throw new SecurityException(e); 4489 } 4490 } 4491 } 4492 4493 IIntentSender getIntentSenderLocked(int type, String packageName, 4494 int callingUid, int userId, IBinder token, String resultWho, 4495 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4496 Bundle options) { 4497 if (DEBUG_MU) 4498 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4499 ActivityRecord activity = null; 4500 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4501 activity = mMainStack.isInStackLocked(token); 4502 if (activity == null) { 4503 return null; 4504 } 4505 if (activity.finishing) { 4506 return null; 4507 } 4508 } 4509 4510 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4511 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4512 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4513 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4514 |PendingIntent.FLAG_UPDATE_CURRENT); 4515 4516 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4517 type, packageName, activity, resultWho, 4518 requestCode, intents, resolvedTypes, flags, options, userId); 4519 WeakReference<PendingIntentRecord> ref; 4520 ref = mIntentSenderRecords.get(key); 4521 PendingIntentRecord rec = ref != null ? ref.get() : null; 4522 if (rec != null) { 4523 if (!cancelCurrent) { 4524 if (updateCurrent) { 4525 if (rec.key.requestIntent != null) { 4526 rec.key.requestIntent.replaceExtras(intents != null ? 4527 intents[intents.length - 1] : null); 4528 } 4529 if (intents != null) { 4530 intents[intents.length-1] = rec.key.requestIntent; 4531 rec.key.allIntents = intents; 4532 rec.key.allResolvedTypes = resolvedTypes; 4533 } else { 4534 rec.key.allIntents = null; 4535 rec.key.allResolvedTypes = null; 4536 } 4537 } 4538 return rec; 4539 } 4540 rec.canceled = true; 4541 mIntentSenderRecords.remove(key); 4542 } 4543 if (noCreate) { 4544 return rec; 4545 } 4546 rec = new PendingIntentRecord(this, key, callingUid); 4547 mIntentSenderRecords.put(key, rec.ref); 4548 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4549 if (activity.pendingResults == null) { 4550 activity.pendingResults 4551 = new HashSet<WeakReference<PendingIntentRecord>>(); 4552 } 4553 activity.pendingResults.add(rec.ref); 4554 } 4555 return rec; 4556 } 4557 4558 public void cancelIntentSender(IIntentSender sender) { 4559 if (!(sender instanceof PendingIntentRecord)) { 4560 return; 4561 } 4562 synchronized(this) { 4563 PendingIntentRecord rec = (PendingIntentRecord)sender; 4564 try { 4565 int uid = AppGlobals.getPackageManager() 4566 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4567 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4568 String msg = "Permission Denial: cancelIntentSender() from pid=" 4569 + Binder.getCallingPid() 4570 + ", uid=" + Binder.getCallingUid() 4571 + " is not allowed to cancel packges " 4572 + rec.key.packageName; 4573 Slog.w(TAG, msg); 4574 throw new SecurityException(msg); 4575 } 4576 } catch (RemoteException e) { 4577 throw new SecurityException(e); 4578 } 4579 cancelIntentSenderLocked(rec, true); 4580 } 4581 } 4582 4583 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4584 rec.canceled = true; 4585 mIntentSenderRecords.remove(rec.key); 4586 if (cleanActivity && rec.key.activity != null) { 4587 rec.key.activity.pendingResults.remove(rec.ref); 4588 } 4589 } 4590 4591 public String getPackageForIntentSender(IIntentSender pendingResult) { 4592 if (!(pendingResult instanceof PendingIntentRecord)) { 4593 return null; 4594 } 4595 try { 4596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4597 return res.key.packageName; 4598 } catch (ClassCastException e) { 4599 } 4600 return null; 4601 } 4602 4603 public int getUidForIntentSender(IIntentSender sender) { 4604 if (sender instanceof PendingIntentRecord) { 4605 try { 4606 PendingIntentRecord res = (PendingIntentRecord)sender; 4607 return res.uid; 4608 } catch (ClassCastException e) { 4609 } 4610 } 4611 return -1; 4612 } 4613 4614 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4615 if (!(pendingResult instanceof PendingIntentRecord)) { 4616 return false; 4617 } 4618 try { 4619 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4620 if (res.key.allIntents == null) { 4621 return false; 4622 } 4623 for (int i=0; i<res.key.allIntents.length; i++) { 4624 Intent intent = res.key.allIntents[i]; 4625 if (intent.getPackage() != null && intent.getComponent() != null) { 4626 return false; 4627 } 4628 } 4629 return true; 4630 } catch (ClassCastException e) { 4631 } 4632 return false; 4633 } 4634 4635 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4636 if (!(pendingResult instanceof PendingIntentRecord)) { 4637 return false; 4638 } 4639 try { 4640 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4641 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4642 return true; 4643 } 4644 return false; 4645 } catch (ClassCastException e) { 4646 } 4647 return false; 4648 } 4649 4650 public void setProcessLimit(int max) { 4651 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4652 "setProcessLimit()"); 4653 synchronized (this) { 4654 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4655 mProcessLimitOverride = max; 4656 } 4657 trimApplications(); 4658 } 4659 4660 public int getProcessLimit() { 4661 synchronized (this) { 4662 return mProcessLimitOverride; 4663 } 4664 } 4665 4666 void foregroundTokenDied(ForegroundToken token) { 4667 synchronized (ActivityManagerService.this) { 4668 synchronized (mPidsSelfLocked) { 4669 ForegroundToken cur 4670 = mForegroundProcesses.get(token.pid); 4671 if (cur != token) { 4672 return; 4673 } 4674 mForegroundProcesses.remove(token.pid); 4675 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4676 if (pr == null) { 4677 return; 4678 } 4679 pr.forcingToForeground = null; 4680 pr.foregroundServices = false; 4681 } 4682 updateOomAdjLocked(); 4683 } 4684 } 4685 4686 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4687 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4688 "setProcessForeground()"); 4689 synchronized(this) { 4690 boolean changed = false; 4691 4692 synchronized (mPidsSelfLocked) { 4693 ProcessRecord pr = mPidsSelfLocked.get(pid); 4694 if (pr == null && isForeground) { 4695 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4696 return; 4697 } 4698 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4699 if (oldToken != null) { 4700 oldToken.token.unlinkToDeath(oldToken, 0); 4701 mForegroundProcesses.remove(pid); 4702 if (pr != null) { 4703 pr.forcingToForeground = null; 4704 } 4705 changed = true; 4706 } 4707 if (isForeground && token != null) { 4708 ForegroundToken newToken = new ForegroundToken() { 4709 public void binderDied() { 4710 foregroundTokenDied(this); 4711 } 4712 }; 4713 newToken.pid = pid; 4714 newToken.token = token; 4715 try { 4716 token.linkToDeath(newToken, 0); 4717 mForegroundProcesses.put(pid, newToken); 4718 pr.forcingToForeground = token; 4719 changed = true; 4720 } catch (RemoteException e) { 4721 // If the process died while doing this, we will later 4722 // do the cleanup with the process death link. 4723 } 4724 } 4725 } 4726 4727 if (changed) { 4728 updateOomAdjLocked(); 4729 } 4730 } 4731 } 4732 4733 // ========================================================= 4734 // PERMISSIONS 4735 // ========================================================= 4736 4737 static class PermissionController extends IPermissionController.Stub { 4738 ActivityManagerService mActivityManagerService; 4739 PermissionController(ActivityManagerService activityManagerService) { 4740 mActivityManagerService = activityManagerService; 4741 } 4742 4743 public boolean checkPermission(String permission, int pid, int uid) { 4744 return mActivityManagerService.checkPermission(permission, pid, 4745 uid) == PackageManager.PERMISSION_GRANTED; 4746 } 4747 } 4748 4749 /** 4750 * This can be called with or without the global lock held. 4751 */ 4752 int checkComponentPermission(String permission, int pid, int uid, 4753 int owningUid, boolean exported) { 4754 // We might be performing an operation on behalf of an indirect binder 4755 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4756 // client identity accordingly before proceeding. 4757 Identity tlsIdentity = sCallerIdentity.get(); 4758 if (tlsIdentity != null) { 4759 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4760 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4761 uid = tlsIdentity.uid; 4762 pid = tlsIdentity.pid; 4763 } 4764 4765 if (pid == MY_PID) { 4766 return PackageManager.PERMISSION_GRANTED; 4767 } 4768 4769 return ActivityManager.checkComponentPermission(permission, uid, 4770 owningUid, exported); 4771 } 4772 4773 /** 4774 * As the only public entry point for permissions checking, this method 4775 * can enforce the semantic that requesting a check on a null global 4776 * permission is automatically denied. (Internally a null permission 4777 * string is used when calling {@link #checkComponentPermission} in cases 4778 * when only uid-based security is needed.) 4779 * 4780 * This can be called with or without the global lock held. 4781 */ 4782 public int checkPermission(String permission, int pid, int uid) { 4783 if (permission == null) { 4784 return PackageManager.PERMISSION_DENIED; 4785 } 4786 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4787 } 4788 4789 /** 4790 * Binder IPC calls go through the public entry point. 4791 * This can be called with or without the global lock held. 4792 */ 4793 int checkCallingPermission(String permission) { 4794 return checkPermission(permission, 4795 Binder.getCallingPid(), 4796 UserHandle.getAppId(Binder.getCallingUid())); 4797 } 4798 4799 /** 4800 * This can be called with or without the global lock held. 4801 */ 4802 void enforceCallingPermission(String permission, String func) { 4803 if (checkCallingPermission(permission) 4804 == PackageManager.PERMISSION_GRANTED) { 4805 return; 4806 } 4807 4808 String msg = "Permission Denial: " + func + " from pid=" 4809 + Binder.getCallingPid() 4810 + ", uid=" + Binder.getCallingUid() 4811 + " requires " + permission; 4812 Slog.w(TAG, msg); 4813 throw new SecurityException(msg); 4814 } 4815 4816 /** 4817 * Determine if UID is holding permissions required to access {@link Uri} in 4818 * the given {@link ProviderInfo}. Final permission checking is always done 4819 * in {@link ContentProvider}. 4820 */ 4821 private final boolean checkHoldingPermissionsLocked( 4822 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4823 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4824 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4825 4826 if (pi.applicationInfo.uid == uid) { 4827 return true; 4828 } else if (!pi.exported) { 4829 return false; 4830 } 4831 4832 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4833 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4834 try { 4835 // check if target holds top-level <provider> permissions 4836 if (!readMet && pi.readPermission != null 4837 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4838 readMet = true; 4839 } 4840 if (!writeMet && pi.writePermission != null 4841 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4842 writeMet = true; 4843 } 4844 4845 // track if unprotected read/write is allowed; any denied 4846 // <path-permission> below removes this ability 4847 boolean allowDefaultRead = pi.readPermission == null; 4848 boolean allowDefaultWrite = pi.writePermission == null; 4849 4850 // check if target holds any <path-permission> that match uri 4851 final PathPermission[] pps = pi.pathPermissions; 4852 if (pps != null) { 4853 final String path = uri.getPath(); 4854 int i = pps.length; 4855 while (i > 0 && (!readMet || !writeMet)) { 4856 i--; 4857 PathPermission pp = pps[i]; 4858 if (pp.match(path)) { 4859 if (!readMet) { 4860 final String pprperm = pp.getReadPermission(); 4861 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4862 + pprperm + " for " + pp.getPath() 4863 + ": match=" + pp.match(path) 4864 + " check=" + pm.checkUidPermission(pprperm, uid)); 4865 if (pprperm != null) { 4866 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4867 readMet = true; 4868 } else { 4869 allowDefaultRead = false; 4870 } 4871 } 4872 } 4873 if (!writeMet) { 4874 final String ppwperm = pp.getWritePermission(); 4875 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4876 + ppwperm + " for " + pp.getPath() 4877 + ": match=" + pp.match(path) 4878 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4879 if (ppwperm != null) { 4880 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4881 writeMet = true; 4882 } else { 4883 allowDefaultWrite = false; 4884 } 4885 } 4886 } 4887 } 4888 } 4889 } 4890 4891 // grant unprotected <provider> read/write, if not blocked by 4892 // <path-permission> above 4893 if (allowDefaultRead) readMet = true; 4894 if (allowDefaultWrite) writeMet = true; 4895 4896 } catch (RemoteException e) { 4897 return false; 4898 } 4899 4900 return readMet && writeMet; 4901 } 4902 4903 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4904 int modeFlags) { 4905 // Root gets to do everything. 4906 if (uid == 0) { 4907 return true; 4908 } 4909 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4910 if (perms == null) return false; 4911 UriPermission perm = perms.get(uri); 4912 if (perm == null) return false; 4913 return (modeFlags&perm.modeFlags) == modeFlags; 4914 } 4915 4916 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4917 enforceNotIsolatedCaller("checkUriPermission"); 4918 4919 // Another redirected-binder-call permissions check as in 4920 // {@link checkComponentPermission}. 4921 Identity tlsIdentity = sCallerIdentity.get(); 4922 if (tlsIdentity != null) { 4923 uid = tlsIdentity.uid; 4924 pid = tlsIdentity.pid; 4925 } 4926 4927 uid = UserHandle.getAppId(uid); 4928 // Our own process gets to do everything. 4929 if (pid == MY_PID) { 4930 return PackageManager.PERMISSION_GRANTED; 4931 } 4932 synchronized(this) { 4933 return checkUriPermissionLocked(uri, uid, modeFlags) 4934 ? PackageManager.PERMISSION_GRANTED 4935 : PackageManager.PERMISSION_DENIED; 4936 } 4937 } 4938 4939 /** 4940 * Check if the targetPkg can be granted permission to access uri by 4941 * the callingUid using the given modeFlags. Throws a security exception 4942 * if callingUid is not allowed to do this. Returns the uid of the target 4943 * if the URI permission grant should be performed; returns -1 if it is not 4944 * needed (for example targetPkg already has permission to access the URI). 4945 * If you already know the uid of the target, you can supply it in 4946 * lastTargetUid else set that to -1. 4947 */ 4948 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4949 Uri uri, int modeFlags, int lastTargetUid) { 4950 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4951 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4952 if (modeFlags == 0) { 4953 return -1; 4954 } 4955 4956 if (targetPkg != null) { 4957 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4958 "Checking grant " + targetPkg + " permission to " + uri); 4959 } 4960 4961 final IPackageManager pm = AppGlobals.getPackageManager(); 4962 4963 // If this is not a content: uri, we can't do anything with it. 4964 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4965 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4966 "Can't grant URI permission for non-content URI: " + uri); 4967 return -1; 4968 } 4969 4970 String name = uri.getAuthority(); 4971 ProviderInfo pi = null; 4972 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4973 UserHandle.getUserId(callingUid)); 4974 if (cpr != null) { 4975 pi = cpr.info; 4976 } else { 4977 try { 4978 pi = pm.resolveContentProvider(name, 4979 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid)); 4980 } catch (RemoteException ex) { 4981 } 4982 } 4983 if (pi == null) { 4984 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4985 return -1; 4986 } 4987 4988 int targetUid = lastTargetUid; 4989 if (targetUid < 0 && targetPkg != null) { 4990 try { 4991 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 4992 if (targetUid < 0) { 4993 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4994 "Can't grant URI permission no uid for: " + targetPkg); 4995 return -1; 4996 } 4997 } catch (RemoteException ex) { 4998 return -1; 4999 } 5000 } 5001 5002 if (targetUid >= 0) { 5003 // First... does the target actually need this permission? 5004 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5005 // No need to grant the target this permission. 5006 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5007 "Target " + targetPkg + " already has full permission to " + uri); 5008 return -1; 5009 } 5010 } else { 5011 // First... there is no target package, so can anyone access it? 5012 boolean allowed = pi.exported; 5013 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5014 if (pi.readPermission != null) { 5015 allowed = false; 5016 } 5017 } 5018 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5019 if (pi.writePermission != null) { 5020 allowed = false; 5021 } 5022 } 5023 if (allowed) { 5024 return -1; 5025 } 5026 } 5027 5028 // Second... is the provider allowing granting of URI permissions? 5029 if (!pi.grantUriPermissions) { 5030 throw new SecurityException("Provider " + pi.packageName 5031 + "/" + pi.name 5032 + " does not allow granting of Uri permissions (uri " 5033 + uri + ")"); 5034 } 5035 if (pi.uriPermissionPatterns != null) { 5036 final int N = pi.uriPermissionPatterns.length; 5037 boolean allowed = false; 5038 for (int i=0; i<N; i++) { 5039 if (pi.uriPermissionPatterns[i] != null 5040 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5041 allowed = true; 5042 break; 5043 } 5044 } 5045 if (!allowed) { 5046 throw new SecurityException("Provider " + pi.packageName 5047 + "/" + pi.name 5048 + " does not allow granting of permission to path of Uri " 5049 + uri); 5050 } 5051 } 5052 5053 // Third... does the caller itself have permission to access 5054 // this uri? 5055 if (callingUid != Process.myUid()) { 5056 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5057 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5058 throw new SecurityException("Uid " + callingUid 5059 + " does not have permission to uri " + uri); 5060 } 5061 } 5062 } 5063 5064 return targetUid; 5065 } 5066 5067 public int checkGrantUriPermission(int callingUid, String targetPkg, 5068 Uri uri, int modeFlags) { 5069 enforceNotIsolatedCaller("checkGrantUriPermission"); 5070 synchronized(this) { 5071 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5072 } 5073 } 5074 5075 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5076 Uri uri, int modeFlags, UriPermissionOwner owner) { 5077 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5078 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5079 if (modeFlags == 0) { 5080 return; 5081 } 5082 5083 // So here we are: the caller has the assumed permission 5084 // to the uri, and the target doesn't. Let's now give this to 5085 // the target. 5086 5087 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5088 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5089 5090 HashMap<Uri, UriPermission> targetUris 5091 = mGrantedUriPermissions.get(targetUid); 5092 if (targetUris == null) { 5093 targetUris = new HashMap<Uri, UriPermission>(); 5094 mGrantedUriPermissions.put(targetUid, targetUris); 5095 } 5096 5097 UriPermission perm = targetUris.get(uri); 5098 if (perm == null) { 5099 perm = new UriPermission(targetUid, uri); 5100 targetUris.put(uri, perm); 5101 } 5102 5103 perm.modeFlags |= modeFlags; 5104 if (owner == null) { 5105 perm.globalModeFlags |= modeFlags; 5106 } else { 5107 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5108 perm.readOwners.add(owner); 5109 owner.addReadPermission(perm); 5110 } 5111 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5112 perm.writeOwners.add(owner); 5113 owner.addWritePermission(perm); 5114 } 5115 } 5116 } 5117 5118 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5119 int modeFlags, UriPermissionOwner owner) { 5120 if (targetPkg == null) { 5121 throw new NullPointerException("targetPkg"); 5122 } 5123 5124 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5125 if (targetUid < 0) { 5126 return; 5127 } 5128 5129 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5130 } 5131 5132 static class NeededUriGrants extends ArrayList<Uri> { 5133 final String targetPkg; 5134 final int targetUid; 5135 final int flags; 5136 5137 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5138 targetPkg = _targetPkg; 5139 targetUid = _targetUid; 5140 flags = _flags; 5141 } 5142 } 5143 5144 /** 5145 * Like checkGrantUriPermissionLocked, but takes an Intent. 5146 */ 5147 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5148 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5149 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5150 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5151 + " clip=" + (intent != null ? intent.getClipData() : null) 5152 + " from " + intent + "; flags=0x" 5153 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5154 5155 if (targetPkg == null) { 5156 throw new NullPointerException("targetPkg"); 5157 } 5158 5159 if (intent == null) { 5160 return null; 5161 } 5162 Uri data = intent.getData(); 5163 ClipData clip = intent.getClipData(); 5164 if (data == null && clip == null) { 5165 return null; 5166 } 5167 if (data != null) { 5168 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5169 mode, needed != null ? needed.targetUid : -1); 5170 if (target > 0) { 5171 if (needed == null) { 5172 needed = new NeededUriGrants(targetPkg, target, mode); 5173 } 5174 needed.add(data); 5175 } 5176 } 5177 if (clip != null) { 5178 for (int i=0; i<clip.getItemCount(); i++) { 5179 Uri uri = clip.getItemAt(i).getUri(); 5180 if (uri != null) { 5181 int target = -1; 5182 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5183 mode, needed != null ? needed.targetUid : -1); 5184 if (target > 0) { 5185 if (needed == null) { 5186 needed = new NeededUriGrants(targetPkg, target, mode); 5187 } 5188 needed.add(uri); 5189 } 5190 } else { 5191 Intent clipIntent = clip.getItemAt(i).getIntent(); 5192 if (clipIntent != null) { 5193 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5194 callingUid, targetPkg, clipIntent, mode, needed); 5195 if (newNeeded != null) { 5196 needed = newNeeded; 5197 } 5198 } 5199 } 5200 } 5201 } 5202 5203 return needed; 5204 } 5205 5206 /** 5207 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5208 */ 5209 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5210 UriPermissionOwner owner) { 5211 if (needed != null) { 5212 for (int i=0; i<needed.size(); i++) { 5213 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5214 needed.get(i), needed.flags, owner); 5215 } 5216 } 5217 } 5218 5219 void grantUriPermissionFromIntentLocked(int callingUid, 5220 String targetPkg, Intent intent, UriPermissionOwner owner) { 5221 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5222 intent, intent != null ? intent.getFlags() : 0, null); 5223 if (needed == null) { 5224 return; 5225 } 5226 5227 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5228 } 5229 5230 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5231 Uri uri, int modeFlags) { 5232 enforceNotIsolatedCaller("grantUriPermission"); 5233 synchronized(this) { 5234 final ProcessRecord r = getRecordForAppLocked(caller); 5235 if (r == null) { 5236 throw new SecurityException("Unable to find app for caller " 5237 + caller 5238 + " when granting permission to uri " + uri); 5239 } 5240 if (targetPkg == null) { 5241 throw new IllegalArgumentException("null target"); 5242 } 5243 if (uri == null) { 5244 throw new IllegalArgumentException("null uri"); 5245 } 5246 5247 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5248 null); 5249 } 5250 } 5251 5252 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5253 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5254 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5255 HashMap<Uri, UriPermission> perms 5256 = mGrantedUriPermissions.get(perm.uid); 5257 if (perms != null) { 5258 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5259 "Removing " + perm.uid + " permission to " + perm.uri); 5260 perms.remove(perm.uri); 5261 if (perms.size() == 0) { 5262 mGrantedUriPermissions.remove(perm.uid); 5263 } 5264 } 5265 } 5266 } 5267 5268 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5269 int modeFlags) { 5270 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5271 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5272 if (modeFlags == 0) { 5273 return; 5274 } 5275 5276 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5277 "Revoking all granted permissions to " + uri); 5278 5279 final IPackageManager pm = AppGlobals.getPackageManager(); 5280 5281 final String authority = uri.getAuthority(); 5282 ProviderInfo pi = null; 5283 int userId = UserHandle.getUserId(callingUid); 5284 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5285 if (cpr != null) { 5286 pi = cpr.info; 5287 } else { 5288 try { 5289 pi = pm.resolveContentProvider(authority, 5290 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5291 } catch (RemoteException ex) { 5292 } 5293 } 5294 if (pi == null) { 5295 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5296 return; 5297 } 5298 5299 // Does the caller have this permission on the URI? 5300 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5301 // Right now, if you are not the original owner of the permission, 5302 // you are not allowed to revoke it. 5303 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5304 throw new SecurityException("Uid " + callingUid 5305 + " does not have permission to uri " + uri); 5306 //} 5307 } 5308 5309 // Go through all of the permissions and remove any that match. 5310 final List<String> SEGMENTS = uri.getPathSegments(); 5311 if (SEGMENTS != null) { 5312 final int NS = SEGMENTS.size(); 5313 int N = mGrantedUriPermissions.size(); 5314 for (int i=0; i<N; i++) { 5315 HashMap<Uri, UriPermission> perms 5316 = mGrantedUriPermissions.valueAt(i); 5317 Iterator<UriPermission> it = perms.values().iterator(); 5318 toploop: 5319 while (it.hasNext()) { 5320 UriPermission perm = it.next(); 5321 Uri targetUri = perm.uri; 5322 if (!authority.equals(targetUri.getAuthority())) { 5323 continue; 5324 } 5325 List<String> targetSegments = targetUri.getPathSegments(); 5326 if (targetSegments == null) { 5327 continue; 5328 } 5329 if (targetSegments.size() < NS) { 5330 continue; 5331 } 5332 for (int j=0; j<NS; j++) { 5333 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5334 continue toploop; 5335 } 5336 } 5337 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5338 "Revoking " + perm.uid + " permission to " + perm.uri); 5339 perm.clearModes(modeFlags); 5340 if (perm.modeFlags == 0) { 5341 it.remove(); 5342 } 5343 } 5344 if (perms.size() == 0) { 5345 mGrantedUriPermissions.remove( 5346 mGrantedUriPermissions.keyAt(i)); 5347 N--; 5348 i--; 5349 } 5350 } 5351 } 5352 } 5353 5354 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5355 int modeFlags) { 5356 enforceNotIsolatedCaller("revokeUriPermission"); 5357 synchronized(this) { 5358 final ProcessRecord r = getRecordForAppLocked(caller); 5359 if (r == null) { 5360 throw new SecurityException("Unable to find app for caller " 5361 + caller 5362 + " when revoking permission to uri " + uri); 5363 } 5364 if (uri == null) { 5365 Slog.w(TAG, "revokeUriPermission: null uri"); 5366 return; 5367 } 5368 5369 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5370 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5371 if (modeFlags == 0) { 5372 return; 5373 } 5374 5375 final IPackageManager pm = AppGlobals.getPackageManager(); 5376 5377 final String authority = uri.getAuthority(); 5378 ProviderInfo pi = null; 5379 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5380 if (cpr != null) { 5381 pi = cpr.info; 5382 } else { 5383 try { 5384 pi = pm.resolveContentProvider(authority, 5385 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5386 } catch (RemoteException ex) { 5387 } 5388 } 5389 if (pi == null) { 5390 Slog.w(TAG, "No content provider found for permission revoke: " 5391 + uri.toSafeString()); 5392 return; 5393 } 5394 5395 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5396 } 5397 } 5398 5399 @Override 5400 public IBinder newUriPermissionOwner(String name) { 5401 enforceNotIsolatedCaller("newUriPermissionOwner"); 5402 synchronized(this) { 5403 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5404 return owner.getExternalTokenLocked(); 5405 } 5406 } 5407 5408 @Override 5409 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5410 Uri uri, int modeFlags) { 5411 synchronized(this) { 5412 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5413 if (owner == null) { 5414 throw new IllegalArgumentException("Unknown owner: " + token); 5415 } 5416 if (fromUid != Binder.getCallingUid()) { 5417 if (Binder.getCallingUid() != Process.myUid()) { 5418 // Only system code can grant URI permissions on behalf 5419 // of other users. 5420 throw new SecurityException("nice try"); 5421 } 5422 } 5423 if (targetPkg == null) { 5424 throw new IllegalArgumentException("null target"); 5425 } 5426 if (uri == null) { 5427 throw new IllegalArgumentException("null uri"); 5428 } 5429 5430 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5431 } 5432 } 5433 5434 @Override 5435 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5436 synchronized(this) { 5437 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5438 if (owner == null) { 5439 throw new IllegalArgumentException("Unknown owner: " + token); 5440 } 5441 5442 if (uri == null) { 5443 owner.removeUriPermissionsLocked(mode); 5444 } else { 5445 owner.removeUriPermissionLocked(uri, mode); 5446 } 5447 } 5448 } 5449 5450 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5451 synchronized (this) { 5452 ProcessRecord app = 5453 who != null ? getRecordForAppLocked(who) : null; 5454 if (app == null) return; 5455 5456 Message msg = Message.obtain(); 5457 msg.what = WAIT_FOR_DEBUGGER_MSG; 5458 msg.obj = app; 5459 msg.arg1 = waiting ? 1 : 0; 5460 mHandler.sendMessage(msg); 5461 } 5462 } 5463 5464 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5465 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5466 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5467 outInfo.availMem = Process.getFreeMemory(); 5468 outInfo.totalMem = Process.getTotalMemory(); 5469 outInfo.threshold = homeAppMem; 5470 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5471 outInfo.hiddenAppThreshold = hiddenAppMem; 5472 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5473 ProcessList.SERVICE_ADJ); 5474 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5475 ProcessList.VISIBLE_APP_ADJ); 5476 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5477 ProcessList.FOREGROUND_APP_ADJ); 5478 } 5479 5480 // ========================================================= 5481 // TASK MANAGEMENT 5482 // ========================================================= 5483 5484 public List getTasks(int maxNum, int flags, 5485 IThumbnailReceiver receiver) { 5486 ArrayList list = new ArrayList(); 5487 5488 PendingThumbnailsRecord pending = null; 5489 IApplicationThread topThumbnail = null; 5490 ActivityRecord topRecord = null; 5491 5492 synchronized(this) { 5493 if (localLOGV) Slog.v( 5494 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5495 + ", receiver=" + receiver); 5496 5497 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5498 != PackageManager.PERMISSION_GRANTED) { 5499 if (receiver != null) { 5500 // If the caller wants to wait for pending thumbnails, 5501 // it ain't gonna get them. 5502 try { 5503 receiver.finished(); 5504 } catch (RemoteException ex) { 5505 } 5506 } 5507 String msg = "Permission Denial: getTasks() from pid=" 5508 + Binder.getCallingPid() 5509 + ", uid=" + Binder.getCallingUid() 5510 + " requires " + android.Manifest.permission.GET_TASKS; 5511 Slog.w(TAG, msg); 5512 throw new SecurityException(msg); 5513 } 5514 5515 int pos = mMainStack.mHistory.size()-1; 5516 ActivityRecord next = 5517 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5518 ActivityRecord top = null; 5519 TaskRecord curTask = null; 5520 int numActivities = 0; 5521 int numRunning = 0; 5522 while (pos >= 0 && maxNum > 0) { 5523 final ActivityRecord r = next; 5524 pos--; 5525 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5526 5527 // Initialize state for next task if needed. 5528 if (top == null || 5529 (top.state == ActivityState.INITIALIZING 5530 && top.task == r.task)) { 5531 top = r; 5532 curTask = r.task; 5533 numActivities = numRunning = 0; 5534 } 5535 5536 // Add 'r' into the current task. 5537 numActivities++; 5538 if (r.app != null && r.app.thread != null) { 5539 numRunning++; 5540 } 5541 5542 if (localLOGV) Slog.v( 5543 TAG, r.intent.getComponent().flattenToShortString() 5544 + ": task=" + r.task); 5545 5546 // If the next one is a different task, generate a new 5547 // TaskInfo entry for what we have. 5548 if (next == null || next.task != curTask) { 5549 ActivityManager.RunningTaskInfo ci 5550 = new ActivityManager.RunningTaskInfo(); 5551 ci.id = curTask.taskId; 5552 ci.baseActivity = r.intent.getComponent(); 5553 ci.topActivity = top.intent.getComponent(); 5554 if (top.thumbHolder != null) { 5555 ci.description = top.thumbHolder.lastDescription; 5556 } 5557 ci.numActivities = numActivities; 5558 ci.numRunning = numRunning; 5559 //System.out.println( 5560 // "#" + maxNum + ": " + " descr=" + ci.description); 5561 if (ci.thumbnail == null && receiver != null) { 5562 if (localLOGV) Slog.v( 5563 TAG, "State=" + top.state + "Idle=" + top.idle 5564 + " app=" + top.app 5565 + " thr=" + (top.app != null ? top.app.thread : null)); 5566 if (top.state == ActivityState.RESUMED 5567 || top.state == ActivityState.PAUSING) { 5568 if (top.idle && top.app != null 5569 && top.app.thread != null) { 5570 topRecord = top; 5571 topThumbnail = top.app.thread; 5572 } else { 5573 top.thumbnailNeeded = true; 5574 } 5575 } 5576 if (pending == null) { 5577 pending = new PendingThumbnailsRecord(receiver); 5578 } 5579 pending.pendingRecords.add(top); 5580 } 5581 list.add(ci); 5582 maxNum--; 5583 top = null; 5584 } 5585 } 5586 5587 if (pending != null) { 5588 mPendingThumbnails.add(pending); 5589 } 5590 } 5591 5592 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5593 5594 if (topThumbnail != null) { 5595 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5596 try { 5597 topThumbnail.requestThumbnail(topRecord.appToken); 5598 } catch (Exception e) { 5599 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5600 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5601 } 5602 } 5603 5604 if (pending == null && receiver != null) { 5605 // In this case all thumbnails were available and the client 5606 // is being asked to be told when the remaining ones come in... 5607 // which is unusually, since the top-most currently running 5608 // activity should never have a canned thumbnail! Oh well. 5609 try { 5610 receiver.finished(); 5611 } catch (RemoteException ex) { 5612 } 5613 } 5614 5615 return list; 5616 } 5617 5618 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5619 int flags, int userId) { 5620 final int callingUid = Binder.getCallingUid(); 5621 if (userId != UserHandle.getCallingUserId()) { 5622 // Check if the caller is holding permissions for cross-user requests. 5623 if (checkComponentPermission( 5624 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5625 Binder.getCallingPid(), callingUid, -1, true) 5626 != PackageManager.PERMISSION_GRANTED) { 5627 String msg = "Permission Denial: " 5628 + "Request to get recent tasks for user " + userId 5629 + " but is calling from user " + UserHandle.getUserId(callingUid) 5630 + "; this requires " 5631 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5632 Slog.w(TAG, msg); 5633 throw new SecurityException(msg); 5634 } else { 5635 if (userId == UserHandle.USER_CURRENT) { 5636 userId = mCurrentUserId; 5637 } 5638 } 5639 } 5640 5641 synchronized (this) { 5642 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5643 "getRecentTasks()"); 5644 final boolean detailed = checkCallingPermission( 5645 android.Manifest.permission.GET_DETAILED_TASKS) 5646 == PackageManager.PERMISSION_GRANTED; 5647 5648 IPackageManager pm = AppGlobals.getPackageManager(); 5649 5650 final int N = mRecentTasks.size(); 5651 ArrayList<ActivityManager.RecentTaskInfo> res 5652 = new ArrayList<ActivityManager.RecentTaskInfo>( 5653 maxNum < N ? maxNum : N); 5654 for (int i=0; i<N && maxNum > 0; i++) { 5655 TaskRecord tr = mRecentTasks.get(i); 5656 // Only add calling user's recent tasks 5657 if (tr.userId != userId) continue; 5658 // Return the entry if desired by the caller. We always return 5659 // the first entry, because callers always expect this to be the 5660 // foreground app. We may filter others if the caller has 5661 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5662 // we should exclude the entry. 5663 5664 if (i == 0 5665 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5666 || (tr.intent == null) 5667 || ((tr.intent.getFlags() 5668 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5669 ActivityManager.RecentTaskInfo rti 5670 = new ActivityManager.RecentTaskInfo(); 5671 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5672 rti.persistentId = tr.taskId; 5673 rti.baseIntent = new Intent( 5674 tr.intent != null ? tr.intent : tr.affinityIntent); 5675 if (!detailed) { 5676 rti.baseIntent.replaceExtras((Bundle)null); 5677 } 5678 rti.origActivity = tr.origActivity; 5679 rti.description = tr.lastDescription; 5680 5681 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5682 // Check whether this activity is currently available. 5683 try { 5684 if (rti.origActivity != null) { 5685 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5686 == null) { 5687 continue; 5688 } 5689 } else if (rti.baseIntent != null) { 5690 if (pm.queryIntentActivities(rti.baseIntent, 5691 null, 0, userId) == null) { 5692 continue; 5693 } 5694 } 5695 } catch (RemoteException e) { 5696 // Will never happen. 5697 } 5698 } 5699 5700 res.add(rti); 5701 maxNum--; 5702 } 5703 } 5704 return res; 5705 } 5706 } 5707 5708 private TaskRecord taskForIdLocked(int id) { 5709 final int N = mRecentTasks.size(); 5710 for (int i=0; i<N; i++) { 5711 TaskRecord tr = mRecentTasks.get(i); 5712 if (tr.taskId == id) { 5713 return tr; 5714 } 5715 } 5716 return null; 5717 } 5718 5719 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5720 synchronized (this) { 5721 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5722 "getTaskThumbnails()"); 5723 TaskRecord tr = taskForIdLocked(id); 5724 if (tr != null) { 5725 return mMainStack.getTaskThumbnailsLocked(tr); 5726 } 5727 } 5728 return null; 5729 } 5730 5731 public boolean removeSubTask(int taskId, int subTaskIndex) { 5732 synchronized (this) { 5733 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5734 "removeSubTask()"); 5735 long ident = Binder.clearCallingIdentity(); 5736 try { 5737 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5738 true) != null; 5739 } finally { 5740 Binder.restoreCallingIdentity(ident); 5741 } 5742 } 5743 } 5744 5745 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5746 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5747 Intent baseIntent = new Intent( 5748 tr.intent != null ? tr.intent : tr.affinityIntent); 5749 ComponentName component = baseIntent.getComponent(); 5750 if (component == null) { 5751 Slog.w(TAG, "Now component for base intent of task: " + tr); 5752 return; 5753 } 5754 5755 // Find any running services associated with this app. 5756 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5757 5758 if (killProcesses) { 5759 // Find any running processes associated with this app. 5760 final String pkg = component.getPackageName(); 5761 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5762 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5763 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5764 for (int i=0; i<uids.size(); i++) { 5765 ProcessRecord proc = uids.valueAt(i); 5766 if (proc.userId != tr.userId) { 5767 continue; 5768 } 5769 if (!proc.pkgList.contains(pkg)) { 5770 continue; 5771 } 5772 procs.add(proc); 5773 } 5774 } 5775 5776 // Kill the running processes. 5777 for (int i=0; i<procs.size(); i++) { 5778 ProcessRecord pr = procs.get(i); 5779 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5780 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5781 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5782 pr.processName, pr.setAdj, "remove task"); 5783 pr.killedBackground = true; 5784 Process.killProcessQuiet(pr.pid); 5785 } else { 5786 pr.waitingToKill = "remove task"; 5787 } 5788 } 5789 } 5790 } 5791 5792 public boolean removeTask(int taskId, int flags) { 5793 synchronized (this) { 5794 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5795 "removeTask()"); 5796 long ident = Binder.clearCallingIdentity(); 5797 try { 5798 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5799 false); 5800 if (r != null) { 5801 mRecentTasks.remove(r.task); 5802 cleanUpRemovedTaskLocked(r.task, flags); 5803 return true; 5804 } else { 5805 TaskRecord tr = null; 5806 int i=0; 5807 while (i < mRecentTasks.size()) { 5808 TaskRecord t = mRecentTasks.get(i); 5809 if (t.taskId == taskId) { 5810 tr = t; 5811 break; 5812 } 5813 i++; 5814 } 5815 if (tr != null) { 5816 if (tr.numActivities <= 0) { 5817 // Caller is just removing a recent task that is 5818 // not actively running. That is easy! 5819 mRecentTasks.remove(i); 5820 cleanUpRemovedTaskLocked(tr, flags); 5821 return true; 5822 } else { 5823 Slog.w(TAG, "removeTask: task " + taskId 5824 + " does not have activities to remove, " 5825 + " but numActivities=" + tr.numActivities 5826 + ": " + tr); 5827 } 5828 } 5829 } 5830 } finally { 5831 Binder.restoreCallingIdentity(ident); 5832 } 5833 } 5834 return false; 5835 } 5836 5837 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5838 int j; 5839 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5840 TaskRecord jt = startTask; 5841 5842 // First look backwards 5843 for (j=startIndex-1; j>=0; j--) { 5844 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5845 if (r.task != jt) { 5846 jt = r.task; 5847 if (affinity.equals(jt.affinity)) { 5848 return j; 5849 } 5850 } 5851 } 5852 5853 // Now look forwards 5854 final int N = mMainStack.mHistory.size(); 5855 jt = startTask; 5856 for (j=startIndex+1; j<N; j++) { 5857 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5858 if (r.task != jt) { 5859 if (affinity.equals(jt.affinity)) { 5860 return j; 5861 } 5862 jt = r.task; 5863 } 5864 } 5865 5866 // Might it be at the top? 5867 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5868 return N-1; 5869 } 5870 5871 return -1; 5872 } 5873 5874 /** 5875 * TODO: Add mController hook 5876 */ 5877 public void moveTaskToFront(int task, int flags, Bundle options) { 5878 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5879 "moveTaskToFront()"); 5880 5881 synchronized(this) { 5882 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5883 Binder.getCallingUid(), "Task to front")) { 5884 ActivityOptions.abort(options); 5885 return; 5886 } 5887 final long origId = Binder.clearCallingIdentity(); 5888 try { 5889 TaskRecord tr = taskForIdLocked(task); 5890 if (tr != null) { 5891 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5892 mMainStack.mUserLeaving = true; 5893 } 5894 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5895 // Caller wants the home activity moved with it. To accomplish this, 5896 // we'll just move the home task to the top first. 5897 mMainStack.moveHomeToFrontLocked(); 5898 } 5899 mMainStack.moveTaskToFrontLocked(tr, null, options); 5900 return; 5901 } 5902 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5903 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5904 if (hr.task.taskId == task) { 5905 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5906 mMainStack.mUserLeaving = true; 5907 } 5908 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5909 // Caller wants the home activity moved with it. To accomplish this, 5910 // we'll just move the home task to the top first. 5911 mMainStack.moveHomeToFrontLocked(); 5912 } 5913 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5914 return; 5915 } 5916 } 5917 } finally { 5918 Binder.restoreCallingIdentity(origId); 5919 } 5920 ActivityOptions.abort(options); 5921 } 5922 } 5923 5924 public void moveTaskToBack(int task) { 5925 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5926 "moveTaskToBack()"); 5927 5928 synchronized(this) { 5929 if (mMainStack.mResumedActivity != null 5930 && mMainStack.mResumedActivity.task.taskId == task) { 5931 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5932 Binder.getCallingUid(), "Task to back")) { 5933 return; 5934 } 5935 } 5936 final long origId = Binder.clearCallingIdentity(); 5937 mMainStack.moveTaskToBackLocked(task, null); 5938 Binder.restoreCallingIdentity(origId); 5939 } 5940 } 5941 5942 /** 5943 * Moves an activity, and all of the other activities within the same task, to the bottom 5944 * of the history stack. The activity's order within the task is unchanged. 5945 * 5946 * @param token A reference to the activity we wish to move 5947 * @param nonRoot If false then this only works if the activity is the root 5948 * of a task; if true it will work for any activity in a task. 5949 * @return Returns true if the move completed, false if not. 5950 */ 5951 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5952 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5953 synchronized(this) { 5954 final long origId = Binder.clearCallingIdentity(); 5955 int taskId = getTaskForActivityLocked(token, !nonRoot); 5956 if (taskId >= 0) { 5957 return mMainStack.moveTaskToBackLocked(taskId, null); 5958 } 5959 Binder.restoreCallingIdentity(origId); 5960 } 5961 return false; 5962 } 5963 5964 public void moveTaskBackwards(int task) { 5965 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5966 "moveTaskBackwards()"); 5967 5968 synchronized(this) { 5969 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5970 Binder.getCallingUid(), "Task backwards")) { 5971 return; 5972 } 5973 final long origId = Binder.clearCallingIdentity(); 5974 moveTaskBackwardsLocked(task); 5975 Binder.restoreCallingIdentity(origId); 5976 } 5977 } 5978 5979 private final void moveTaskBackwardsLocked(int task) { 5980 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5981 } 5982 5983 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5984 synchronized(this) { 5985 return getTaskForActivityLocked(token, onlyRoot); 5986 } 5987 } 5988 5989 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5990 final int N = mMainStack.mHistory.size(); 5991 TaskRecord lastTask = null; 5992 for (int i=0; i<N; i++) { 5993 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5994 if (r.appToken == token) { 5995 if (!onlyRoot || lastTask != r.task) { 5996 return r.task.taskId; 5997 } 5998 return -1; 5999 } 6000 lastTask = r.task; 6001 } 6002 6003 return -1; 6004 } 6005 6006 // ========================================================= 6007 // THUMBNAILS 6008 // ========================================================= 6009 6010 public void reportThumbnail(IBinder token, 6011 Bitmap thumbnail, CharSequence description) { 6012 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6013 final long origId = Binder.clearCallingIdentity(); 6014 sendPendingThumbnail(null, token, thumbnail, description, true); 6015 Binder.restoreCallingIdentity(origId); 6016 } 6017 6018 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6019 Bitmap thumbnail, CharSequence description, boolean always) { 6020 TaskRecord task = null; 6021 ArrayList receivers = null; 6022 6023 //System.out.println("Send pending thumbnail: " + r); 6024 6025 synchronized(this) { 6026 if (r == null) { 6027 r = mMainStack.isInStackLocked(token); 6028 if (r == null) { 6029 return; 6030 } 6031 } 6032 if (thumbnail == null && r.thumbHolder != null) { 6033 thumbnail = r.thumbHolder.lastThumbnail; 6034 description = r.thumbHolder.lastDescription; 6035 } 6036 if (thumbnail == null && !always) { 6037 // If there is no thumbnail, and this entry is not actually 6038 // going away, then abort for now and pick up the next 6039 // thumbnail we get. 6040 return; 6041 } 6042 task = r.task; 6043 6044 int N = mPendingThumbnails.size(); 6045 int i=0; 6046 while (i<N) { 6047 PendingThumbnailsRecord pr = 6048 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6049 //System.out.println("Looking in " + pr.pendingRecords); 6050 if (pr.pendingRecords.remove(r)) { 6051 if (receivers == null) { 6052 receivers = new ArrayList(); 6053 } 6054 receivers.add(pr); 6055 if (pr.pendingRecords.size() == 0) { 6056 pr.finished = true; 6057 mPendingThumbnails.remove(i); 6058 N--; 6059 continue; 6060 } 6061 } 6062 i++; 6063 } 6064 } 6065 6066 if (receivers != null) { 6067 final int N = receivers.size(); 6068 for (int i=0; i<N; i++) { 6069 try { 6070 PendingThumbnailsRecord pr = 6071 (PendingThumbnailsRecord)receivers.get(i); 6072 pr.receiver.newThumbnail( 6073 task != null ? task.taskId : -1, thumbnail, description); 6074 if (pr.finished) { 6075 pr.receiver.finished(); 6076 } 6077 } catch (Exception e) { 6078 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6079 } 6080 } 6081 } 6082 } 6083 6084 // ========================================================= 6085 // CONTENT PROVIDERS 6086 // ========================================================= 6087 6088 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6089 List<ProviderInfo> providers = null; 6090 try { 6091 providers = AppGlobals.getPackageManager(). 6092 queryContentProviders(app.processName, app.uid, 6093 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6094 } catch (RemoteException ex) { 6095 } 6096 if (DEBUG_MU) 6097 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6098 int userId = app.userId; 6099 if (providers != null) { 6100 int N = providers.size(); 6101 for (int i=0; i<N; i++) { 6102 ProviderInfo cpi = 6103 (ProviderInfo)providers.get(i); 6104 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6105 cpi.name, cpi.flags); 6106 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6107 // This is a singleton provider, but a user besides the 6108 // default user is asking to initialize a process it runs 6109 // in... well, no, it doesn't actually run in this process, 6110 // it runs in the process of the default user. Get rid of it. 6111 providers.remove(i); 6112 N--; 6113 continue; 6114 } 6115 6116 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6117 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6118 if (cpr == null) { 6119 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6120 mProviderMap.putProviderByClass(comp, cpr); 6121 } 6122 if (DEBUG_MU) 6123 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6124 app.pubProviders.put(cpi.name, cpr); 6125 app.addPackage(cpi.applicationInfo.packageName); 6126 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6127 } 6128 } 6129 return providers; 6130 } 6131 6132 /** 6133 * Check if {@link ProcessRecord} has a possible chance at accessing the 6134 * given {@link ProviderInfo}. Final permission checking is always done 6135 * in {@link ContentProvider}. 6136 */ 6137 private final String checkContentProviderPermissionLocked( 6138 ProviderInfo cpi, ProcessRecord r) { 6139 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6140 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6141 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6142 cpi.applicationInfo.uid, cpi.exported) 6143 == PackageManager.PERMISSION_GRANTED) { 6144 return null; 6145 } 6146 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6147 cpi.applicationInfo.uid, cpi.exported) 6148 == PackageManager.PERMISSION_GRANTED) { 6149 return null; 6150 } 6151 6152 PathPermission[] pps = cpi.pathPermissions; 6153 if (pps != null) { 6154 int i = pps.length; 6155 while (i > 0) { 6156 i--; 6157 PathPermission pp = pps[i]; 6158 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6159 cpi.applicationInfo.uid, cpi.exported) 6160 == PackageManager.PERMISSION_GRANTED) { 6161 return null; 6162 } 6163 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6164 cpi.applicationInfo.uid, cpi.exported) 6165 == PackageManager.PERMISSION_GRANTED) { 6166 return null; 6167 } 6168 } 6169 } 6170 6171 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6172 if (perms != null) { 6173 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6174 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6175 return null; 6176 } 6177 } 6178 } 6179 6180 String msg; 6181 if (!cpi.exported) { 6182 msg = "Permission Denial: opening provider " + cpi.name 6183 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6184 + ", uid=" + callingUid + ") that is not exported from uid " 6185 + cpi.applicationInfo.uid; 6186 } else { 6187 msg = "Permission Denial: opening provider " + cpi.name 6188 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6189 + ", uid=" + callingUid + ") requires " 6190 + cpi.readPermission + " or " + cpi.writePermission; 6191 } 6192 Slog.w(TAG, msg); 6193 return msg; 6194 } 6195 6196 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6197 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6198 if (r != null) { 6199 for (int i=0; i<r.conProviders.size(); i++) { 6200 ContentProviderConnection conn = r.conProviders.get(i); 6201 if (conn.provider == cpr) { 6202 if (DEBUG_PROVIDER) Slog.v(TAG, 6203 "Adding provider requested by " 6204 + r.processName + " from process " 6205 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6206 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6207 if (stable) { 6208 conn.stableCount++; 6209 conn.numStableIncs++; 6210 } else { 6211 conn.unstableCount++; 6212 conn.numUnstableIncs++; 6213 } 6214 return conn; 6215 } 6216 } 6217 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6218 if (stable) { 6219 conn.stableCount = 1; 6220 conn.numStableIncs = 1; 6221 } else { 6222 conn.unstableCount = 1; 6223 conn.numUnstableIncs = 1; 6224 } 6225 cpr.connections.add(conn); 6226 r.conProviders.add(conn); 6227 return conn; 6228 } 6229 cpr.addExternalProcessHandleLocked(externalProcessToken); 6230 return null; 6231 } 6232 6233 boolean decProviderCountLocked(ContentProviderConnection conn, 6234 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6235 if (conn != null) { 6236 cpr = conn.provider; 6237 if (DEBUG_PROVIDER) Slog.v(TAG, 6238 "Removing provider requested by " 6239 + conn.client.processName + " from process " 6240 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6241 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6242 if (stable) { 6243 conn.stableCount--; 6244 } else { 6245 conn.unstableCount--; 6246 } 6247 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6248 cpr.connections.remove(conn); 6249 conn.client.conProviders.remove(conn); 6250 return true; 6251 } 6252 return false; 6253 } 6254 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6255 return false; 6256 } 6257 6258 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6259 String name, IBinder token, boolean stable, int userId) { 6260 ContentProviderRecord cpr; 6261 ContentProviderConnection conn = null; 6262 ProviderInfo cpi = null; 6263 6264 synchronized(this) { 6265 ProcessRecord r = null; 6266 if (caller != null) { 6267 r = getRecordForAppLocked(caller); 6268 if (r == null) { 6269 throw new SecurityException( 6270 "Unable to find app for caller " + caller 6271 + " (pid=" + Binder.getCallingPid() 6272 + ") when getting content provider " + name); 6273 } 6274 if (r.userId != userId) { 6275 throw new SecurityException("Calling requested user " + userId 6276 + " but app is user " + r.userId); 6277 } 6278 } 6279 6280 // First check if this content provider has been published... 6281 cpr = mProviderMap.getProviderByName(name, userId); 6282 boolean providerRunning = cpr != null; 6283 if (providerRunning) { 6284 cpi = cpr.info; 6285 String msg; 6286 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6287 throw new SecurityException(msg); 6288 } 6289 6290 if (r != null && cpr.canRunHere(r)) { 6291 // This provider has been published or is in the process 6292 // of being published... but it is also allowed to run 6293 // in the caller's process, so don't make a connection 6294 // and just let the caller instantiate its own instance. 6295 ContentProviderHolder holder = cpr.newHolder(null); 6296 // don't give caller the provider object, it needs 6297 // to make its own. 6298 holder.provider = null; 6299 return holder; 6300 } 6301 6302 final long origId = Binder.clearCallingIdentity(); 6303 6304 // In this case the provider instance already exists, so we can 6305 // return it right away. 6306 conn = incProviderCountLocked(r, cpr, token, stable); 6307 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6308 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6309 // If this is a perceptible app accessing the provider, 6310 // make sure to count it as being accessed and thus 6311 // back up on the LRU list. This is good because 6312 // content providers are often expensive to start. 6313 updateLruProcessLocked(cpr.proc, false, true); 6314 } 6315 } 6316 6317 if (cpr.proc != null) { 6318 if (false) { 6319 if (cpr.name.flattenToShortString().equals( 6320 "com.android.providers.calendar/.CalendarProvider2")) { 6321 Slog.v(TAG, "****************** KILLING " 6322 + cpr.name.flattenToShortString()); 6323 Process.killProcess(cpr.proc.pid); 6324 } 6325 } 6326 boolean success = updateOomAdjLocked(cpr.proc); 6327 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6328 // NOTE: there is still a race here where a signal could be 6329 // pending on the process even though we managed to update its 6330 // adj level. Not sure what to do about this, but at least 6331 // the race is now smaller. 6332 if (!success) { 6333 // Uh oh... it looks like the provider's process 6334 // has been killed on us. We need to wait for a new 6335 // process to be started, and make sure its death 6336 // doesn't kill our process. 6337 Slog.i(TAG, 6338 "Existing provider " + cpr.name.flattenToShortString() 6339 + " is crashing; detaching " + r); 6340 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6341 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6342 if (!lastRef) { 6343 // This wasn't the last ref our process had on 6344 // the provider... we have now been killed, bail. 6345 return null; 6346 } 6347 providerRunning = false; 6348 conn = null; 6349 } 6350 } 6351 6352 Binder.restoreCallingIdentity(origId); 6353 } 6354 6355 boolean singleton; 6356 if (!providerRunning) { 6357 try { 6358 cpi = AppGlobals.getPackageManager(). 6359 resolveContentProvider(name, 6360 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6361 } catch (RemoteException ex) { 6362 } 6363 if (cpi == null) { 6364 return null; 6365 } 6366 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6367 cpi.name, cpi.flags); 6368 if (singleton) { 6369 userId = 0; 6370 } 6371 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6372 6373 String msg; 6374 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6375 throw new SecurityException(msg); 6376 } 6377 6378 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6379 && !cpi.processName.equals("system")) { 6380 // If this content provider does not run in the system 6381 // process, and the system is not yet ready to run other 6382 // processes, then fail fast instead of hanging. 6383 throw new IllegalArgumentException( 6384 "Attempt to launch content provider before system ready"); 6385 } 6386 6387 // Make sure that the user who owns this provider is started. If not, 6388 // we don't want to allow it to run. 6389 if (mStartedUsers.get(userId) == null) { 6390 Slog.w(TAG, "Unable to launch app " 6391 + cpi.applicationInfo.packageName + "/" 6392 + cpi.applicationInfo.uid + " for provider " 6393 + name + ": user " + userId + " is stopped"); 6394 return null; 6395 } 6396 6397 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6398 cpr = mProviderMap.getProviderByClass(comp, userId); 6399 final boolean firstClass = cpr == null; 6400 if (firstClass) { 6401 try { 6402 ApplicationInfo ai = 6403 AppGlobals.getPackageManager(). 6404 getApplicationInfo( 6405 cpi.applicationInfo.packageName, 6406 STOCK_PM_FLAGS, userId); 6407 if (ai == null) { 6408 Slog.w(TAG, "No package info for content provider " 6409 + cpi.name); 6410 return null; 6411 } 6412 ai = getAppInfoForUser(ai, userId); 6413 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6414 } catch (RemoteException ex) { 6415 // pm is in same process, this will never happen. 6416 } 6417 } 6418 6419 if (r != null && cpr.canRunHere(r)) { 6420 // If this is a multiprocess provider, then just return its 6421 // info and allow the caller to instantiate it. Only do 6422 // this if the provider is the same user as the caller's 6423 // process, or can run as root (so can be in any process). 6424 return cpr.newHolder(null); 6425 } 6426 6427 if (DEBUG_PROVIDER) { 6428 RuntimeException e = new RuntimeException("here"); 6429 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6430 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6431 } 6432 6433 // This is single process, and our app is now connecting to it. 6434 // See if we are already in the process of launching this 6435 // provider. 6436 final int N = mLaunchingProviders.size(); 6437 int i; 6438 for (i=0; i<N; i++) { 6439 if (mLaunchingProviders.get(i) == cpr) { 6440 break; 6441 } 6442 } 6443 6444 // If the provider is not already being launched, then get it 6445 // started. 6446 if (i >= N) { 6447 final long origId = Binder.clearCallingIdentity(); 6448 6449 try { 6450 // Content provider is now in use, its package can't be stopped. 6451 try { 6452 AppGlobals.getPackageManager().setPackageStoppedState( 6453 cpr.appInfo.packageName, false, userId); 6454 } catch (RemoteException e) { 6455 } catch (IllegalArgumentException e) { 6456 Slog.w(TAG, "Failed trying to unstop package " 6457 + cpr.appInfo.packageName + ": " + e); 6458 } 6459 6460 ProcessRecord proc = startProcessLocked(cpi.processName, 6461 cpr.appInfo, false, 0, "content provider", 6462 new ComponentName(cpi.applicationInfo.packageName, 6463 cpi.name), false, false); 6464 if (proc == null) { 6465 Slog.w(TAG, "Unable to launch app " 6466 + cpi.applicationInfo.packageName + "/" 6467 + cpi.applicationInfo.uid + " for provider " 6468 + name + ": process is bad"); 6469 return null; 6470 } 6471 cpr.launchingApp = proc; 6472 mLaunchingProviders.add(cpr); 6473 } finally { 6474 Binder.restoreCallingIdentity(origId); 6475 } 6476 } 6477 6478 // Make sure the provider is published (the same provider class 6479 // may be published under multiple names). 6480 if (firstClass) { 6481 mProviderMap.putProviderByClass(comp, cpr); 6482 } 6483 6484 mProviderMap.putProviderByName(name, cpr); 6485 conn = incProviderCountLocked(r, cpr, token, stable); 6486 if (conn != null) { 6487 conn.waiting = true; 6488 } 6489 } 6490 } 6491 6492 // Wait for the provider to be published... 6493 synchronized (cpr) { 6494 while (cpr.provider == null) { 6495 if (cpr.launchingApp == null) { 6496 Slog.w(TAG, "Unable to launch app " 6497 + cpi.applicationInfo.packageName + "/" 6498 + cpi.applicationInfo.uid + " for provider " 6499 + name + ": launching app became null"); 6500 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6501 cpi.applicationInfo.packageName, 6502 cpi.applicationInfo.uid, name); 6503 return null; 6504 } 6505 try { 6506 if (DEBUG_MU) { 6507 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6508 + cpr.launchingApp); 6509 } 6510 if (conn != null) { 6511 conn.waiting = true; 6512 } 6513 cpr.wait(); 6514 } catch (InterruptedException ex) { 6515 } finally { 6516 if (conn != null) { 6517 conn.waiting = false; 6518 } 6519 } 6520 } 6521 } 6522 return cpr != null ? cpr.newHolder(conn) : null; 6523 } 6524 6525 public final ContentProviderHolder getContentProvider( 6526 IApplicationThread caller, String name, boolean stable) { 6527 enforceNotIsolatedCaller("getContentProvider"); 6528 if (caller == null) { 6529 String msg = "null IApplicationThread when getting content provider " 6530 + name; 6531 Slog.w(TAG, msg); 6532 throw new SecurityException(msg); 6533 } 6534 6535 return getContentProviderImpl(caller, name, null, stable, 6536 UserHandle.getCallingUserId()); 6537 } 6538 6539 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6540 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6541 "Do not have permission in call getContentProviderExternal()"); 6542 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6543 } 6544 6545 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6546 IBinder token, int userId) { 6547 return getContentProviderImpl(null, name, token, true, userId); 6548 } 6549 6550 /** 6551 * Drop a content provider from a ProcessRecord's bookkeeping 6552 * @param cpr 6553 */ 6554 public void removeContentProvider(IBinder connection, boolean stable) { 6555 enforceNotIsolatedCaller("removeContentProvider"); 6556 synchronized (this) { 6557 ContentProviderConnection conn; 6558 try { 6559 conn = (ContentProviderConnection)connection; 6560 } catch (ClassCastException e) { 6561 String msg ="removeContentProvider: " + connection 6562 + " not a ContentProviderConnection"; 6563 Slog.w(TAG, msg); 6564 throw new IllegalArgumentException(msg); 6565 } 6566 if (conn == null) { 6567 throw new NullPointerException("connection is null"); 6568 } 6569 if (decProviderCountLocked(conn, null, null, stable)) { 6570 updateOomAdjLocked(); 6571 } 6572 } 6573 } 6574 6575 public void removeContentProviderExternal(String name, IBinder token) { 6576 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6577 "Do not have permission in call removeContentProviderExternal()"); 6578 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6579 } 6580 6581 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6582 synchronized (this) { 6583 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6584 if(cpr == null) { 6585 //remove from mProvidersByClass 6586 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6587 return; 6588 } 6589 6590 //update content provider record entry info 6591 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6592 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6593 if (localCpr.hasExternalProcessHandles()) { 6594 if (localCpr.removeExternalProcessHandleLocked(token)) { 6595 updateOomAdjLocked(); 6596 } else { 6597 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6598 + " with no external reference for token: " 6599 + token + "."); 6600 } 6601 } else { 6602 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6603 + " with no external references."); 6604 } 6605 } 6606 } 6607 6608 public final void publishContentProviders(IApplicationThread caller, 6609 List<ContentProviderHolder> providers) { 6610 if (providers == null) { 6611 return; 6612 } 6613 6614 enforceNotIsolatedCaller("publishContentProviders"); 6615 synchronized (this) { 6616 final ProcessRecord r = getRecordForAppLocked(caller); 6617 if (DEBUG_MU) 6618 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6619 if (r == null) { 6620 throw new SecurityException( 6621 "Unable to find app for caller " + caller 6622 + " (pid=" + Binder.getCallingPid() 6623 + ") when publishing content providers"); 6624 } 6625 6626 final long origId = Binder.clearCallingIdentity(); 6627 6628 final int N = providers.size(); 6629 for (int i=0; i<N; i++) { 6630 ContentProviderHolder src = providers.get(i); 6631 if (src == null || src.info == null || src.provider == null) { 6632 continue; 6633 } 6634 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6635 if (DEBUG_MU) 6636 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6637 if (dst != null) { 6638 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6639 mProviderMap.putProviderByClass(comp, dst); 6640 String names[] = dst.info.authority.split(";"); 6641 for (int j = 0; j < names.length; j++) { 6642 mProviderMap.putProviderByName(names[j], dst); 6643 } 6644 6645 int NL = mLaunchingProviders.size(); 6646 int j; 6647 for (j=0; j<NL; j++) { 6648 if (mLaunchingProviders.get(j) == dst) { 6649 mLaunchingProviders.remove(j); 6650 j--; 6651 NL--; 6652 } 6653 } 6654 synchronized (dst) { 6655 dst.provider = src.provider; 6656 dst.proc = r; 6657 dst.notifyAll(); 6658 } 6659 updateOomAdjLocked(r); 6660 } 6661 } 6662 6663 Binder.restoreCallingIdentity(origId); 6664 } 6665 } 6666 6667 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6668 ContentProviderConnection conn; 6669 try { 6670 conn = (ContentProviderConnection)connection; 6671 } catch (ClassCastException e) { 6672 String msg ="refContentProvider: " + connection 6673 + " not a ContentProviderConnection"; 6674 Slog.w(TAG, msg); 6675 throw new IllegalArgumentException(msg); 6676 } 6677 if (conn == null) { 6678 throw new NullPointerException("connection is null"); 6679 } 6680 6681 synchronized (this) { 6682 if (stable > 0) { 6683 conn.numStableIncs += stable; 6684 } 6685 stable = conn.stableCount + stable; 6686 if (stable < 0) { 6687 throw new IllegalStateException("stableCount < 0: " + stable); 6688 } 6689 6690 if (unstable > 0) { 6691 conn.numUnstableIncs += unstable; 6692 } 6693 unstable = conn.unstableCount + unstable; 6694 if (unstable < 0) { 6695 throw new IllegalStateException("unstableCount < 0: " + unstable); 6696 } 6697 6698 if ((stable+unstable) <= 0) { 6699 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6700 + stable + " unstable=" + unstable); 6701 } 6702 conn.stableCount = stable; 6703 conn.unstableCount = unstable; 6704 return !conn.dead; 6705 } 6706 } 6707 6708 public void unstableProviderDied(IBinder connection) { 6709 ContentProviderConnection conn; 6710 try { 6711 conn = (ContentProviderConnection)connection; 6712 } catch (ClassCastException e) { 6713 String msg ="refContentProvider: " + connection 6714 + " not a ContentProviderConnection"; 6715 Slog.w(TAG, msg); 6716 throw new IllegalArgumentException(msg); 6717 } 6718 if (conn == null) { 6719 throw new NullPointerException("connection is null"); 6720 } 6721 6722 // Safely retrieve the content provider associated with the connection. 6723 IContentProvider provider; 6724 synchronized (this) { 6725 provider = conn.provider.provider; 6726 } 6727 6728 if (provider == null) { 6729 // Um, yeah, we're way ahead of you. 6730 return; 6731 } 6732 6733 // Make sure the caller is being honest with us. 6734 if (provider.asBinder().pingBinder()) { 6735 // Er, no, still looks good to us. 6736 synchronized (this) { 6737 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6738 + " says " + conn + " died, but we don't agree"); 6739 return; 6740 } 6741 } 6742 6743 // Well look at that! It's dead! 6744 synchronized (this) { 6745 if (conn.provider.provider != provider) { 6746 // But something changed... good enough. 6747 return; 6748 } 6749 6750 ProcessRecord proc = conn.provider.proc; 6751 if (proc == null || proc.thread == null) { 6752 // Seems like the process is already cleaned up. 6753 return; 6754 } 6755 6756 // As far as we're concerned, this is just like receiving a 6757 // death notification... just a bit prematurely. 6758 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6759 + ") early provider death"); 6760 final long ident = Binder.clearCallingIdentity(); 6761 try { 6762 appDiedLocked(proc, proc.pid, proc.thread); 6763 } finally { 6764 Binder.restoreCallingIdentity(ident); 6765 } 6766 } 6767 } 6768 6769 public static final void installSystemProviders() { 6770 List<ProviderInfo> providers; 6771 synchronized (mSelf) { 6772 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6773 providers = mSelf.generateApplicationProvidersLocked(app); 6774 if (providers != null) { 6775 for (int i=providers.size()-1; i>=0; i--) { 6776 ProviderInfo pi = (ProviderInfo)providers.get(i); 6777 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6778 Slog.w(TAG, "Not installing system proc provider " + pi.name 6779 + ": not system .apk"); 6780 providers.remove(i); 6781 } 6782 } 6783 } 6784 } 6785 if (providers != null) { 6786 mSystemThread.installSystemProviders(providers); 6787 } 6788 6789 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6790 6791 mSelf.mUsageStatsService.monitorPackages(); 6792 } 6793 6794 /** 6795 * Allows app to retrieve the MIME type of a URI without having permission 6796 * to access its content provider. 6797 * 6798 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6799 * 6800 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6801 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6802 */ 6803 public String getProviderMimeType(Uri uri) { 6804 enforceNotIsolatedCaller("getProviderMimeType"); 6805 final String name = uri.getAuthority(); 6806 final int userId = UserHandle.getCallingUserId(); 6807 final long ident = Binder.clearCallingIdentity(); 6808 ContentProviderHolder holder = null; 6809 6810 try { 6811 holder = getContentProviderExternalUnchecked(name, null, userId); 6812 if (holder != null) { 6813 return holder.provider.getType(uri); 6814 } 6815 } catch (RemoteException e) { 6816 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6817 return null; 6818 } finally { 6819 if (holder != null) { 6820 removeContentProviderExternalUnchecked(name, null, userId); 6821 } 6822 Binder.restoreCallingIdentity(ident); 6823 } 6824 6825 return null; 6826 } 6827 6828 // ========================================================= 6829 // GLOBAL MANAGEMENT 6830 // ========================================================= 6831 6832 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6833 ApplicationInfo info, String customProcess, boolean isolated) { 6834 String proc = customProcess != null ? customProcess : info.processName; 6835 BatteryStatsImpl.Uid.Proc ps = null; 6836 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6837 int uid = info.uid; 6838 if (isolated) { 6839 int userId = UserHandle.getUserId(uid); 6840 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6841 uid = 0; 6842 while (true) { 6843 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6844 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6845 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6846 } 6847 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6848 mNextIsolatedProcessUid++; 6849 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6850 // No process for this uid, use it. 6851 break; 6852 } 6853 stepsLeft--; 6854 if (stepsLeft <= 0) { 6855 return null; 6856 } 6857 } 6858 } 6859 synchronized (stats) { 6860 ps = stats.getProcessStatsLocked(info.uid, proc); 6861 } 6862 return new ProcessRecord(ps, thread, info, proc, uid); 6863 } 6864 6865 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6866 ProcessRecord app; 6867 if (!isolated) { 6868 app = getProcessRecordLocked(info.processName, info.uid); 6869 } else { 6870 app = null; 6871 } 6872 6873 if (app == null) { 6874 app = newProcessRecordLocked(null, info, null, isolated); 6875 mProcessNames.put(info.processName, app.uid, app); 6876 if (isolated) { 6877 mIsolatedProcesses.put(app.uid, app); 6878 } 6879 updateLruProcessLocked(app, true, true); 6880 } 6881 6882 // This package really, really can not be stopped. 6883 try { 6884 AppGlobals.getPackageManager().setPackageStoppedState( 6885 info.packageName, false, UserHandle.getUserId(app.uid)); 6886 } catch (RemoteException e) { 6887 } catch (IllegalArgumentException e) { 6888 Slog.w(TAG, "Failed trying to unstop package " 6889 + info.packageName + ": " + e); 6890 } 6891 6892 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6893 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6894 app.persistent = true; 6895 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6896 } 6897 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6898 mPersistentStartingProcesses.add(app); 6899 startProcessLocked(app, "added application", app.processName); 6900 } 6901 6902 return app; 6903 } 6904 6905 public void unhandledBack() { 6906 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6907 "unhandledBack()"); 6908 6909 synchronized(this) { 6910 int count = mMainStack.mHistory.size(); 6911 if (DEBUG_SWITCH) Slog.d( 6912 TAG, "Performing unhandledBack(): stack size = " + count); 6913 if (count > 1) { 6914 final long origId = Binder.clearCallingIdentity(); 6915 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6916 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6917 Binder.restoreCallingIdentity(origId); 6918 } 6919 } 6920 } 6921 6922 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6923 enforceNotIsolatedCaller("openContentUri"); 6924 final int userId = UserHandle.getCallingUserId(); 6925 String name = uri.getAuthority(); 6926 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 6927 ParcelFileDescriptor pfd = null; 6928 if (cph != null) { 6929 // We record the binder invoker's uid in thread-local storage before 6930 // going to the content provider to open the file. Later, in the code 6931 // that handles all permissions checks, we look for this uid and use 6932 // that rather than the Activity Manager's own uid. The effect is that 6933 // we do the check against the caller's permissions even though it looks 6934 // to the content provider like the Activity Manager itself is making 6935 // the request. 6936 sCallerIdentity.set(new Identity( 6937 Binder.getCallingPid(), Binder.getCallingUid())); 6938 try { 6939 pfd = cph.provider.openFile(uri, "r"); 6940 } catch (FileNotFoundException e) { 6941 // do nothing; pfd will be returned null 6942 } finally { 6943 // Ensure that whatever happens, we clean up the identity state 6944 sCallerIdentity.remove(); 6945 } 6946 6947 // We've got the fd now, so we're done with the provider. 6948 removeContentProviderExternalUnchecked(name, null, userId); 6949 } else { 6950 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6951 } 6952 return pfd; 6953 } 6954 6955 // Actually is sleeping or shutting down or whatever else in the future 6956 // is an inactive state. 6957 public boolean isSleeping() { 6958 return mSleeping || mShuttingDown; 6959 } 6960 6961 public void goingToSleep() { 6962 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6963 != PackageManager.PERMISSION_GRANTED) { 6964 throw new SecurityException("Requires permission " 6965 + android.Manifest.permission.DEVICE_POWER); 6966 } 6967 6968 synchronized(this) { 6969 mWentToSleep = true; 6970 updateEventDispatchingLocked(); 6971 6972 if (!mSleeping) { 6973 mSleeping = true; 6974 mMainStack.stopIfSleepingLocked(); 6975 6976 // Initialize the wake times of all processes. 6977 checkExcessivePowerUsageLocked(false); 6978 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6979 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6980 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6981 } 6982 } 6983 } 6984 6985 public boolean shutdown(int timeout) { 6986 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6987 != PackageManager.PERMISSION_GRANTED) { 6988 throw new SecurityException("Requires permission " 6989 + android.Manifest.permission.SHUTDOWN); 6990 } 6991 6992 boolean timedout = false; 6993 6994 synchronized(this) { 6995 mShuttingDown = true; 6996 updateEventDispatchingLocked(); 6997 6998 if (mMainStack.mResumedActivity != null) { 6999 mMainStack.stopIfSleepingLocked(); 7000 final long endTime = System.currentTimeMillis() + timeout; 7001 while (mMainStack.mResumedActivity != null 7002 || mMainStack.mPausingActivity != null) { 7003 long delay = endTime - System.currentTimeMillis(); 7004 if (delay <= 0) { 7005 Slog.w(TAG, "Activity manager shutdown timed out"); 7006 timedout = true; 7007 break; 7008 } 7009 try { 7010 this.wait(); 7011 } catch (InterruptedException e) { 7012 } 7013 } 7014 } 7015 } 7016 7017 mUsageStatsService.shutdown(); 7018 mBatteryStatsService.shutdown(); 7019 7020 return timedout; 7021 } 7022 7023 public final void activitySlept(IBinder token) { 7024 if (localLOGV) Slog.v( 7025 TAG, "Activity slept: token=" + token); 7026 7027 ActivityRecord r = null; 7028 7029 final long origId = Binder.clearCallingIdentity(); 7030 7031 synchronized (this) { 7032 r = mMainStack.isInStackLocked(token); 7033 if (r != null) { 7034 mMainStack.activitySleptLocked(r); 7035 } 7036 } 7037 7038 Binder.restoreCallingIdentity(origId); 7039 } 7040 7041 private void comeOutOfSleepIfNeededLocked() { 7042 if (!mWentToSleep && !mLockScreenShown) { 7043 if (mSleeping) { 7044 mSleeping = false; 7045 mMainStack.awakeFromSleepingLocked(); 7046 mMainStack.resumeTopActivityLocked(null); 7047 } 7048 } 7049 } 7050 7051 public void wakingUp() { 7052 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7053 != PackageManager.PERMISSION_GRANTED) { 7054 throw new SecurityException("Requires permission " 7055 + android.Manifest.permission.DEVICE_POWER); 7056 } 7057 7058 synchronized(this) { 7059 mWentToSleep = false; 7060 updateEventDispatchingLocked(); 7061 comeOutOfSleepIfNeededLocked(); 7062 } 7063 } 7064 7065 private void updateEventDispatchingLocked() { 7066 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7067 } 7068 7069 public void setLockScreenShown(boolean shown) { 7070 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7071 != PackageManager.PERMISSION_GRANTED) { 7072 throw new SecurityException("Requires permission " 7073 + android.Manifest.permission.DEVICE_POWER); 7074 } 7075 7076 synchronized(this) { 7077 mLockScreenShown = shown; 7078 comeOutOfSleepIfNeededLocked(); 7079 } 7080 } 7081 7082 public void stopAppSwitches() { 7083 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7084 != PackageManager.PERMISSION_GRANTED) { 7085 throw new SecurityException("Requires permission " 7086 + android.Manifest.permission.STOP_APP_SWITCHES); 7087 } 7088 7089 synchronized(this) { 7090 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7091 + APP_SWITCH_DELAY_TIME; 7092 mDidAppSwitch = false; 7093 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7094 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7095 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7096 } 7097 } 7098 7099 public void resumeAppSwitches() { 7100 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7101 != PackageManager.PERMISSION_GRANTED) { 7102 throw new SecurityException("Requires permission " 7103 + android.Manifest.permission.STOP_APP_SWITCHES); 7104 } 7105 7106 synchronized(this) { 7107 // Note that we don't execute any pending app switches... we will 7108 // let those wait until either the timeout, or the next start 7109 // activity request. 7110 mAppSwitchesAllowedTime = 0; 7111 } 7112 } 7113 7114 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7115 String name) { 7116 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7117 return true; 7118 } 7119 7120 final int perm = checkComponentPermission( 7121 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7122 callingUid, -1, true); 7123 if (perm == PackageManager.PERMISSION_GRANTED) { 7124 return true; 7125 } 7126 7127 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7128 return false; 7129 } 7130 7131 public void setDebugApp(String packageName, boolean waitForDebugger, 7132 boolean persistent) { 7133 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7134 "setDebugApp()"); 7135 7136 // Note that this is not really thread safe if there are multiple 7137 // callers into it at the same time, but that's not a situation we 7138 // care about. 7139 if (persistent) { 7140 final ContentResolver resolver = mContext.getContentResolver(); 7141 Settings.System.putString( 7142 resolver, Settings.System.DEBUG_APP, 7143 packageName); 7144 Settings.System.putInt( 7145 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7146 waitForDebugger ? 1 : 0); 7147 } 7148 7149 synchronized (this) { 7150 if (!persistent) { 7151 mOrigDebugApp = mDebugApp; 7152 mOrigWaitForDebugger = mWaitForDebugger; 7153 } 7154 mDebugApp = packageName; 7155 mWaitForDebugger = waitForDebugger; 7156 mDebugTransient = !persistent; 7157 if (packageName != null) { 7158 final long origId = Binder.clearCallingIdentity(); 7159 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7160 Binder.restoreCallingIdentity(origId); 7161 } 7162 } 7163 } 7164 7165 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7166 synchronized (this) { 7167 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7168 if (!isDebuggable) { 7169 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7170 throw new SecurityException("Process not debuggable: " + app.packageName); 7171 } 7172 } 7173 7174 mOpenGlTraceApp = processName; 7175 } 7176 } 7177 7178 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7179 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7180 synchronized (this) { 7181 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7182 if (!isDebuggable) { 7183 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7184 throw new SecurityException("Process not debuggable: " + app.packageName); 7185 } 7186 } 7187 mProfileApp = processName; 7188 mProfileFile = profileFile; 7189 if (mProfileFd != null) { 7190 try { 7191 mProfileFd.close(); 7192 } catch (IOException e) { 7193 } 7194 mProfileFd = null; 7195 } 7196 mProfileFd = profileFd; 7197 mProfileType = 0; 7198 mAutoStopProfiler = autoStopProfiler; 7199 } 7200 } 7201 7202 public void setAlwaysFinish(boolean enabled) { 7203 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7204 "setAlwaysFinish()"); 7205 7206 Settings.System.putInt( 7207 mContext.getContentResolver(), 7208 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7209 7210 synchronized (this) { 7211 mAlwaysFinishActivities = enabled; 7212 } 7213 } 7214 7215 public void setActivityController(IActivityController controller) { 7216 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7217 "setActivityController()"); 7218 synchronized (this) { 7219 mController = controller; 7220 } 7221 } 7222 7223 public boolean isUserAMonkey() { 7224 // For now the fact that there is a controller implies 7225 // we have a monkey. 7226 synchronized (this) { 7227 return mController != null; 7228 } 7229 } 7230 7231 public void registerProcessObserver(IProcessObserver observer) { 7232 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7233 "registerProcessObserver()"); 7234 synchronized (this) { 7235 mProcessObservers.register(observer); 7236 } 7237 } 7238 7239 public void unregisterProcessObserver(IProcessObserver observer) { 7240 synchronized (this) { 7241 mProcessObservers.unregister(observer); 7242 } 7243 } 7244 7245 public void setImmersive(IBinder token, boolean immersive) { 7246 synchronized(this) { 7247 ActivityRecord r = mMainStack.isInStackLocked(token); 7248 if (r == null) { 7249 throw new IllegalArgumentException(); 7250 } 7251 r.immersive = immersive; 7252 } 7253 } 7254 7255 public boolean isImmersive(IBinder token) { 7256 synchronized (this) { 7257 ActivityRecord r = mMainStack.isInStackLocked(token); 7258 if (r == null) { 7259 throw new IllegalArgumentException(); 7260 } 7261 return r.immersive; 7262 } 7263 } 7264 7265 public boolean isTopActivityImmersive() { 7266 enforceNotIsolatedCaller("startActivity"); 7267 synchronized (this) { 7268 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7269 return (r != null) ? r.immersive : false; 7270 } 7271 } 7272 7273 public final void enterSafeMode() { 7274 synchronized(this) { 7275 // It only makes sense to do this before the system is ready 7276 // and started launching other packages. 7277 if (!mSystemReady) { 7278 try { 7279 AppGlobals.getPackageManager().enterSafeMode(); 7280 } catch (RemoteException e) { 7281 } 7282 } 7283 } 7284 } 7285 7286 public final void showSafeModeOverlay() { 7287 View v = LayoutInflater.from(mContext).inflate( 7288 com.android.internal.R.layout.safe_mode, null); 7289 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7290 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7291 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7292 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7293 lp.gravity = Gravity.BOTTOM | Gravity.START; 7294 lp.format = v.getBackground().getOpacity(); 7295 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7296 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7297 ((WindowManager)mContext.getSystemService( 7298 Context.WINDOW_SERVICE)).addView(v, lp); 7299 } 7300 7301 public void noteWakeupAlarm(IIntentSender sender) { 7302 if (!(sender instanceof PendingIntentRecord)) { 7303 return; 7304 } 7305 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7306 synchronized (stats) { 7307 if (mBatteryStatsService.isOnBattery()) { 7308 mBatteryStatsService.enforceCallingPermission(); 7309 PendingIntentRecord rec = (PendingIntentRecord)sender; 7310 int MY_UID = Binder.getCallingUid(); 7311 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7312 BatteryStatsImpl.Uid.Pkg pkg = 7313 stats.getPackageStatsLocked(uid, rec.key.packageName); 7314 pkg.incWakeupsLocked(); 7315 } 7316 } 7317 } 7318 7319 public boolean killPids(int[] pids, String pReason, boolean secure) { 7320 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7321 throw new SecurityException("killPids only available to the system"); 7322 } 7323 String reason = (pReason == null) ? "Unknown" : pReason; 7324 // XXX Note: don't acquire main activity lock here, because the window 7325 // manager calls in with its locks held. 7326 7327 boolean killed = false; 7328 synchronized (mPidsSelfLocked) { 7329 int[] types = new int[pids.length]; 7330 int worstType = 0; 7331 for (int i=0; i<pids.length; i++) { 7332 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7333 if (proc != null) { 7334 int type = proc.setAdj; 7335 types[i] = type; 7336 if (type > worstType) { 7337 worstType = type; 7338 } 7339 } 7340 } 7341 7342 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7343 // then constrain it so we will kill all hidden procs. 7344 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7345 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7346 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7347 } 7348 7349 // If this is not a secure call, don't let it kill processes that 7350 // are important. 7351 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7352 worstType = ProcessList.SERVICE_ADJ; 7353 } 7354 7355 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7356 for (int i=0; i<pids.length; i++) { 7357 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7358 if (proc == null) { 7359 continue; 7360 } 7361 int adj = proc.setAdj; 7362 if (adj >= worstType && !proc.killedBackground) { 7363 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7364 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7365 proc.processName, adj, reason); 7366 killed = true; 7367 proc.killedBackground = true; 7368 Process.killProcessQuiet(pids[i]); 7369 } 7370 } 7371 } 7372 return killed; 7373 } 7374 7375 @Override 7376 public boolean killProcessesBelowForeground(String reason) { 7377 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7378 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7379 } 7380 7381 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7382 } 7383 7384 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7385 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7386 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7387 } 7388 7389 boolean killed = false; 7390 synchronized (mPidsSelfLocked) { 7391 final int size = mPidsSelfLocked.size(); 7392 for (int i = 0; i < size; i++) { 7393 final int pid = mPidsSelfLocked.keyAt(i); 7394 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7395 if (proc == null) continue; 7396 7397 final int adj = proc.setAdj; 7398 if (adj > belowAdj && !proc.killedBackground) { 7399 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7400 EventLog.writeEvent( 7401 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7402 killed = true; 7403 proc.killedBackground = true; 7404 Process.killProcessQuiet(pid); 7405 } 7406 } 7407 } 7408 return killed; 7409 } 7410 7411 public final void startRunning(String pkg, String cls, String action, 7412 String data) { 7413 synchronized(this) { 7414 if (mStartRunning) { 7415 return; 7416 } 7417 mStartRunning = true; 7418 mTopComponent = pkg != null && cls != null 7419 ? new ComponentName(pkg, cls) : null; 7420 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7421 mTopData = data; 7422 if (!mSystemReady) { 7423 return; 7424 } 7425 } 7426 7427 systemReady(null); 7428 } 7429 7430 private void retrieveSettings() { 7431 final ContentResolver resolver = mContext.getContentResolver(); 7432 String debugApp = Settings.System.getString( 7433 resolver, Settings.System.DEBUG_APP); 7434 boolean waitForDebugger = Settings.System.getInt( 7435 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7436 boolean alwaysFinishActivities = Settings.System.getInt( 7437 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7438 7439 Configuration configuration = new Configuration(); 7440 Settings.System.getConfiguration(resolver, configuration); 7441 7442 synchronized (this) { 7443 mDebugApp = mOrigDebugApp = debugApp; 7444 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7445 mAlwaysFinishActivities = alwaysFinishActivities; 7446 // This happens before any activities are started, so we can 7447 // change mConfiguration in-place. 7448 updateConfigurationLocked(configuration, null, false, true); 7449 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7450 } 7451 } 7452 7453 public boolean testIsSystemReady() { 7454 // no need to synchronize(this) just to read & return the value 7455 return mSystemReady; 7456 } 7457 7458 private static File getCalledPreBootReceiversFile() { 7459 File dataDir = Environment.getDataDirectory(); 7460 File systemDir = new File(dataDir, "system"); 7461 File fname = new File(systemDir, "called_pre_boots.dat"); 7462 return fname; 7463 } 7464 7465 static final int LAST_DONE_VERSION = 10000; 7466 7467 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7468 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7469 File file = getCalledPreBootReceiversFile(); 7470 FileInputStream fis = null; 7471 try { 7472 fis = new FileInputStream(file); 7473 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7474 int fvers = dis.readInt(); 7475 if (fvers == LAST_DONE_VERSION) { 7476 String vers = dis.readUTF(); 7477 String codename = dis.readUTF(); 7478 String build = dis.readUTF(); 7479 if (android.os.Build.VERSION.RELEASE.equals(vers) 7480 && android.os.Build.VERSION.CODENAME.equals(codename) 7481 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7482 int num = dis.readInt(); 7483 while (num > 0) { 7484 num--; 7485 String pkg = dis.readUTF(); 7486 String cls = dis.readUTF(); 7487 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7488 } 7489 } 7490 } 7491 } catch (FileNotFoundException e) { 7492 } catch (IOException e) { 7493 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7494 } finally { 7495 if (fis != null) { 7496 try { 7497 fis.close(); 7498 } catch (IOException e) { 7499 } 7500 } 7501 } 7502 return lastDoneReceivers; 7503 } 7504 7505 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7506 File file = getCalledPreBootReceiversFile(); 7507 FileOutputStream fos = null; 7508 DataOutputStream dos = null; 7509 try { 7510 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7511 fos = new FileOutputStream(file); 7512 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7513 dos.writeInt(LAST_DONE_VERSION); 7514 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7515 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7516 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7517 dos.writeInt(list.size()); 7518 for (int i=0; i<list.size(); i++) { 7519 dos.writeUTF(list.get(i).getPackageName()); 7520 dos.writeUTF(list.get(i).getClassName()); 7521 } 7522 } catch (IOException e) { 7523 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7524 file.delete(); 7525 } finally { 7526 FileUtils.sync(fos); 7527 if (dos != null) { 7528 try { 7529 dos.close(); 7530 } catch (IOException e) { 7531 // TODO Auto-generated catch block 7532 e.printStackTrace(); 7533 } 7534 } 7535 } 7536 } 7537 7538 public void systemReady(final Runnable goingCallback) { 7539 synchronized(this) { 7540 if (mSystemReady) { 7541 if (goingCallback != null) goingCallback.run(); 7542 return; 7543 } 7544 7545 // Check to see if there are any update receivers to run. 7546 if (!mDidUpdate) { 7547 if (mWaitingUpdate) { 7548 return; 7549 } 7550 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7551 List<ResolveInfo> ris = null; 7552 try { 7553 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7554 intent, null, 0, 0); 7555 } catch (RemoteException e) { 7556 } 7557 if (ris != null) { 7558 for (int i=ris.size()-1; i>=0; i--) { 7559 if ((ris.get(i).activityInfo.applicationInfo.flags 7560 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7561 ris.remove(i); 7562 } 7563 } 7564 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7565 7566 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7567 7568 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7569 for (int i=0; i<ris.size(); i++) { 7570 ActivityInfo ai = ris.get(i).activityInfo; 7571 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7572 if (lastDoneReceivers.contains(comp)) { 7573 ris.remove(i); 7574 i--; 7575 } 7576 } 7577 7578 for (int i=0; i<ris.size(); i++) { 7579 ActivityInfo ai = ris.get(i).activityInfo; 7580 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7581 doneReceivers.add(comp); 7582 intent.setComponent(comp); 7583 IIntentReceiver finisher = null; 7584 if (i == ris.size()-1) { 7585 finisher = new IIntentReceiver.Stub() { 7586 public void performReceive(Intent intent, int resultCode, 7587 String data, Bundle extras, boolean ordered, 7588 boolean sticky, int sendingUser) { 7589 // The raw IIntentReceiver interface is called 7590 // with the AM lock held, so redispatch to 7591 // execute our code without the lock. 7592 mHandler.post(new Runnable() { 7593 public void run() { 7594 synchronized (ActivityManagerService.this) { 7595 mDidUpdate = true; 7596 } 7597 writeLastDonePreBootReceivers(doneReceivers); 7598 showBootMessage(mContext.getText( 7599 R.string.android_upgrading_complete), 7600 false); 7601 systemReady(goingCallback); 7602 } 7603 }); 7604 } 7605 }; 7606 } 7607 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7608 // XXX also need to send this to stopped users(!!!) 7609 broadcastIntentLocked(null, null, intent, null, finisher, 7610 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7611 UserHandle.USER_ALL); 7612 if (finisher != null) { 7613 mWaitingUpdate = true; 7614 } 7615 } 7616 } 7617 if (mWaitingUpdate) { 7618 return; 7619 } 7620 mDidUpdate = true; 7621 } 7622 7623 mSystemReady = true; 7624 if (!mStartRunning) { 7625 return; 7626 } 7627 } 7628 7629 ArrayList<ProcessRecord> procsToKill = null; 7630 synchronized(mPidsSelfLocked) { 7631 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7632 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7633 if (!isAllowedWhileBooting(proc.info)){ 7634 if (procsToKill == null) { 7635 procsToKill = new ArrayList<ProcessRecord>(); 7636 } 7637 procsToKill.add(proc); 7638 } 7639 } 7640 } 7641 7642 synchronized(this) { 7643 if (procsToKill != null) { 7644 for (int i=procsToKill.size()-1; i>=0; i--) { 7645 ProcessRecord proc = procsToKill.get(i); 7646 Slog.i(TAG, "Removing system update proc: " + proc); 7647 removeProcessLocked(proc, true, false, "system update done"); 7648 } 7649 } 7650 7651 // Now that we have cleaned up any update processes, we 7652 // are ready to start launching real processes and know that 7653 // we won't trample on them any more. 7654 mProcessesReady = true; 7655 } 7656 7657 Slog.i(TAG, "System now ready"); 7658 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7659 SystemClock.uptimeMillis()); 7660 7661 synchronized(this) { 7662 // Make sure we have no pre-ready processes sitting around. 7663 7664 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7665 ResolveInfo ri = mContext.getPackageManager() 7666 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7667 STOCK_PM_FLAGS); 7668 CharSequence errorMsg = null; 7669 if (ri != null) { 7670 ActivityInfo ai = ri.activityInfo; 7671 ApplicationInfo app = ai.applicationInfo; 7672 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7673 mTopAction = Intent.ACTION_FACTORY_TEST; 7674 mTopData = null; 7675 mTopComponent = new ComponentName(app.packageName, 7676 ai.name); 7677 } else { 7678 errorMsg = mContext.getResources().getText( 7679 com.android.internal.R.string.factorytest_not_system); 7680 } 7681 } else { 7682 errorMsg = mContext.getResources().getText( 7683 com.android.internal.R.string.factorytest_no_action); 7684 } 7685 if (errorMsg != null) { 7686 mTopAction = null; 7687 mTopData = null; 7688 mTopComponent = null; 7689 Message msg = Message.obtain(); 7690 msg.what = SHOW_FACTORY_ERROR_MSG; 7691 msg.getData().putCharSequence("msg", errorMsg); 7692 mHandler.sendMessage(msg); 7693 } 7694 } 7695 } 7696 7697 retrieveSettings(); 7698 7699 if (goingCallback != null) goingCallback.run(); 7700 7701 synchronized (this) { 7702 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7703 try { 7704 List apps = AppGlobals.getPackageManager(). 7705 getPersistentApplications(STOCK_PM_FLAGS); 7706 if (apps != null) { 7707 int N = apps.size(); 7708 int i; 7709 for (i=0; i<N; i++) { 7710 ApplicationInfo info 7711 = (ApplicationInfo)apps.get(i); 7712 if (info != null && 7713 !info.packageName.equals("android")) { 7714 addAppLocked(info, false); 7715 } 7716 } 7717 } 7718 } catch (RemoteException ex) { 7719 // pm is in same process, this will never happen. 7720 } 7721 } 7722 7723 // Start up initial activity. 7724 mBooting = true; 7725 7726 try { 7727 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7728 Message msg = Message.obtain(); 7729 msg.what = SHOW_UID_ERROR_MSG; 7730 mHandler.sendMessage(msg); 7731 } 7732 } catch (RemoteException e) { 7733 } 7734 7735 mMainStack.resumeTopActivityLocked(null); 7736 } 7737 } 7738 7739 private boolean makeAppCrashingLocked(ProcessRecord app, 7740 String shortMsg, String longMsg, String stackTrace) { 7741 app.crashing = true; 7742 app.crashingReport = generateProcessError(app, 7743 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7744 startAppProblemLocked(app); 7745 app.stopFreezingAllLocked(); 7746 return handleAppCrashLocked(app); 7747 } 7748 7749 private void makeAppNotRespondingLocked(ProcessRecord app, 7750 String activity, String shortMsg, String longMsg) { 7751 app.notResponding = true; 7752 app.notRespondingReport = generateProcessError(app, 7753 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7754 activity, shortMsg, longMsg, null); 7755 startAppProblemLocked(app); 7756 app.stopFreezingAllLocked(); 7757 } 7758 7759 /** 7760 * Generate a process error record, suitable for attachment to a ProcessRecord. 7761 * 7762 * @param app The ProcessRecord in which the error occurred. 7763 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7764 * ActivityManager.AppErrorStateInfo 7765 * @param activity The activity associated with the crash, if known. 7766 * @param shortMsg Short message describing the crash. 7767 * @param longMsg Long message describing the crash. 7768 * @param stackTrace Full crash stack trace, may be null. 7769 * 7770 * @return Returns a fully-formed AppErrorStateInfo record. 7771 */ 7772 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7773 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7774 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7775 7776 report.condition = condition; 7777 report.processName = app.processName; 7778 report.pid = app.pid; 7779 report.uid = app.info.uid; 7780 report.tag = activity; 7781 report.shortMsg = shortMsg; 7782 report.longMsg = longMsg; 7783 report.stackTrace = stackTrace; 7784 7785 return report; 7786 } 7787 7788 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7789 synchronized (this) { 7790 app.crashing = false; 7791 app.crashingReport = null; 7792 app.notResponding = false; 7793 app.notRespondingReport = null; 7794 if (app.anrDialog == fromDialog) { 7795 app.anrDialog = null; 7796 } 7797 if (app.waitDialog == fromDialog) { 7798 app.waitDialog = null; 7799 } 7800 if (app.pid > 0 && app.pid != MY_PID) { 7801 handleAppCrashLocked(app); 7802 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7803 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7804 app.processName, app.setAdj, "user's request after error"); 7805 Process.killProcessQuiet(app.pid); 7806 } 7807 } 7808 } 7809 7810 private boolean handleAppCrashLocked(ProcessRecord app) { 7811 if (mHeadless) { 7812 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7813 return false; 7814 } 7815 long now = SystemClock.uptimeMillis(); 7816 7817 Long crashTime; 7818 if (!app.isolated) { 7819 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7820 } else { 7821 crashTime = null; 7822 } 7823 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7824 // This process loses! 7825 Slog.w(TAG, "Process " + app.info.processName 7826 + " has crashed too many times: killing!"); 7827 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7828 app.info.processName, app.uid); 7829 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7830 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7831 if (r.app == app) { 7832 Slog.w(TAG, " Force finishing activity " 7833 + r.intent.getComponent().flattenToShortString()); 7834 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7835 } 7836 } 7837 if (!app.persistent) { 7838 // We don't want to start this process again until the user 7839 // explicitly does so... but for persistent process, we really 7840 // need to keep it running. If a persistent process is actually 7841 // repeatedly crashing, then badness for everyone. 7842 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7843 app.info.processName); 7844 if (!app.isolated) { 7845 // XXX We don't have a way to mark isolated processes 7846 // as bad, since they don't have a peristent identity. 7847 mBadProcesses.put(app.info.processName, app.uid, now); 7848 mProcessCrashTimes.remove(app.info.processName, app.uid); 7849 } 7850 app.bad = true; 7851 app.removed = true; 7852 // Don't let services in this process be restarted and potentially 7853 // annoy the user repeatedly. Unless it is persistent, since those 7854 // processes run critical code. 7855 removeProcessLocked(app, false, false, "crash"); 7856 mMainStack.resumeTopActivityLocked(null); 7857 return false; 7858 } 7859 mMainStack.resumeTopActivityLocked(null); 7860 } else { 7861 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7862 if (r != null && r.app == app) { 7863 // If the top running activity is from this crashing 7864 // process, then terminate it to avoid getting in a loop. 7865 Slog.w(TAG, " Force finishing activity " 7866 + r.intent.getComponent().flattenToShortString()); 7867 int index = mMainStack.indexOfActivityLocked(r); 7868 r.stack.finishActivityLocked(r, index, 7869 Activity.RESULT_CANCELED, null, "crashed"); 7870 // Also terminate any activities below it that aren't yet 7871 // stopped, to avoid a situation where one will get 7872 // re-start our crashing activity once it gets resumed again. 7873 index--; 7874 if (index >= 0) { 7875 r = (ActivityRecord)mMainStack.mHistory.get(index); 7876 if (r.state == ActivityState.RESUMED 7877 || r.state == ActivityState.PAUSING 7878 || r.state == ActivityState.PAUSED) { 7879 if (!r.isHomeActivity || mHomeProcess != r.app) { 7880 Slog.w(TAG, " Force finishing activity " 7881 + r.intent.getComponent().flattenToShortString()); 7882 r.stack.finishActivityLocked(r, index, 7883 Activity.RESULT_CANCELED, null, "crashed"); 7884 } 7885 } 7886 } 7887 } 7888 } 7889 7890 // Bump up the crash count of any services currently running in the proc. 7891 if (app.services.size() != 0) { 7892 // Any services running in the application need to be placed 7893 // back in the pending list. 7894 Iterator<ServiceRecord> it = app.services.iterator(); 7895 while (it.hasNext()) { 7896 ServiceRecord sr = it.next(); 7897 sr.crashCount++; 7898 } 7899 } 7900 7901 // If the crashing process is what we consider to be the "home process" and it has been 7902 // replaced by a third-party app, clear the package preferred activities from packages 7903 // with a home activity running in the process to prevent a repeatedly crashing app 7904 // from blocking the user to manually clear the list. 7905 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7906 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7907 Iterator it = mHomeProcess.activities.iterator(); 7908 while (it.hasNext()) { 7909 ActivityRecord r = (ActivityRecord)it.next(); 7910 if (r.isHomeActivity) { 7911 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7912 try { 7913 ActivityThread.getPackageManager() 7914 .clearPackagePreferredActivities(r.packageName); 7915 } catch (RemoteException c) { 7916 // pm is in same process, this will never happen. 7917 } 7918 } 7919 } 7920 } 7921 7922 if (!app.isolated) { 7923 // XXX Can't keep track of crash times for isolated processes, 7924 // because they don't have a perisistent identity. 7925 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7926 } 7927 7928 return true; 7929 } 7930 7931 void startAppProblemLocked(ProcessRecord app) { 7932 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7933 mContext, app.info.packageName, app.info.flags); 7934 skipCurrentReceiverLocked(app); 7935 } 7936 7937 void skipCurrentReceiverLocked(ProcessRecord app) { 7938 for (BroadcastQueue queue : mBroadcastQueues) { 7939 queue.skipCurrentReceiverLocked(app); 7940 } 7941 } 7942 7943 /** 7944 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7945 * The application process will exit immediately after this call returns. 7946 * @param app object of the crashing app, null for the system server 7947 * @param crashInfo describing the exception 7948 */ 7949 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7950 ProcessRecord r = findAppProcess(app, "Crash"); 7951 final String processName = app == null ? "system_server" 7952 : (r == null ? "unknown" : r.processName); 7953 7954 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7955 processName, 7956 r == null ? -1 : r.info.flags, 7957 crashInfo.exceptionClassName, 7958 crashInfo.exceptionMessage, 7959 crashInfo.throwFileName, 7960 crashInfo.throwLineNumber); 7961 7962 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7963 7964 crashApplication(r, crashInfo); 7965 } 7966 7967 public void handleApplicationStrictModeViolation( 7968 IBinder app, 7969 int violationMask, 7970 StrictMode.ViolationInfo info) { 7971 ProcessRecord r = findAppProcess(app, "StrictMode"); 7972 if (r == null) { 7973 return; 7974 } 7975 7976 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7977 Integer stackFingerprint = info.hashCode(); 7978 boolean logIt = true; 7979 synchronized (mAlreadyLoggedViolatedStacks) { 7980 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7981 logIt = false; 7982 // TODO: sub-sample into EventLog for these, with 7983 // the info.durationMillis? Then we'd get 7984 // the relative pain numbers, without logging all 7985 // the stack traces repeatedly. We'd want to do 7986 // likewise in the client code, which also does 7987 // dup suppression, before the Binder call. 7988 } else { 7989 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7990 mAlreadyLoggedViolatedStacks.clear(); 7991 } 7992 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7993 } 7994 } 7995 if (logIt) { 7996 logStrictModeViolationToDropBox(r, info); 7997 } 7998 } 7999 8000 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8001 AppErrorResult result = new AppErrorResult(); 8002 synchronized (this) { 8003 final long origId = Binder.clearCallingIdentity(); 8004 8005 Message msg = Message.obtain(); 8006 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8007 HashMap<String, Object> data = new HashMap<String, Object>(); 8008 data.put("result", result); 8009 data.put("app", r); 8010 data.put("violationMask", violationMask); 8011 data.put("info", info); 8012 msg.obj = data; 8013 mHandler.sendMessage(msg); 8014 8015 Binder.restoreCallingIdentity(origId); 8016 } 8017 int res = result.get(); 8018 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8019 } 8020 } 8021 8022 // Depending on the policy in effect, there could be a bunch of 8023 // these in quick succession so we try to batch these together to 8024 // minimize disk writes, number of dropbox entries, and maximize 8025 // compression, by having more fewer, larger records. 8026 private void logStrictModeViolationToDropBox( 8027 ProcessRecord process, 8028 StrictMode.ViolationInfo info) { 8029 if (info == null) { 8030 return; 8031 } 8032 final boolean isSystemApp = process == null || 8033 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8034 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8035 final String processName = process == null ? "unknown" : process.processName; 8036 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8037 final DropBoxManager dbox = (DropBoxManager) 8038 mContext.getSystemService(Context.DROPBOX_SERVICE); 8039 8040 // Exit early if the dropbox isn't configured to accept this report type. 8041 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8042 8043 boolean bufferWasEmpty; 8044 boolean needsFlush; 8045 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8046 synchronized (sb) { 8047 bufferWasEmpty = sb.length() == 0; 8048 appendDropBoxProcessHeaders(process, processName, sb); 8049 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8050 sb.append("System-App: ").append(isSystemApp).append("\n"); 8051 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8052 if (info.violationNumThisLoop != 0) { 8053 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8054 } 8055 if (info.numAnimationsRunning != 0) { 8056 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8057 } 8058 if (info.broadcastIntentAction != null) { 8059 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8060 } 8061 if (info.durationMillis != -1) { 8062 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8063 } 8064 if (info.numInstances != -1) { 8065 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8066 } 8067 if (info.tags != null) { 8068 for (String tag : info.tags) { 8069 sb.append("Span-Tag: ").append(tag).append("\n"); 8070 } 8071 } 8072 sb.append("\n"); 8073 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8074 sb.append(info.crashInfo.stackTrace); 8075 } 8076 sb.append("\n"); 8077 8078 // Only buffer up to ~64k. Various logging bits truncate 8079 // things at 128k. 8080 needsFlush = (sb.length() > 64 * 1024); 8081 } 8082 8083 // Flush immediately if the buffer's grown too large, or this 8084 // is a non-system app. Non-system apps are isolated with a 8085 // different tag & policy and not batched. 8086 // 8087 // Batching is useful during internal testing with 8088 // StrictMode settings turned up high. Without batching, 8089 // thousands of separate files could be created on boot. 8090 if (!isSystemApp || needsFlush) { 8091 new Thread("Error dump: " + dropboxTag) { 8092 @Override 8093 public void run() { 8094 String report; 8095 synchronized (sb) { 8096 report = sb.toString(); 8097 sb.delete(0, sb.length()); 8098 sb.trimToSize(); 8099 } 8100 if (report.length() != 0) { 8101 dbox.addText(dropboxTag, report); 8102 } 8103 } 8104 }.start(); 8105 return; 8106 } 8107 8108 // System app batching: 8109 if (!bufferWasEmpty) { 8110 // An existing dropbox-writing thread is outstanding, so 8111 // we don't need to start it up. The existing thread will 8112 // catch the buffer appends we just did. 8113 return; 8114 } 8115 8116 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8117 // (After this point, we shouldn't access AMS internal data structures.) 8118 new Thread("Error dump: " + dropboxTag) { 8119 @Override 8120 public void run() { 8121 // 5 second sleep to let stacks arrive and be batched together 8122 try { 8123 Thread.sleep(5000); // 5 seconds 8124 } catch (InterruptedException e) {} 8125 8126 String errorReport; 8127 synchronized (mStrictModeBuffer) { 8128 errorReport = mStrictModeBuffer.toString(); 8129 if (errorReport.length() == 0) { 8130 return; 8131 } 8132 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8133 mStrictModeBuffer.trimToSize(); 8134 } 8135 dbox.addText(dropboxTag, errorReport); 8136 } 8137 }.start(); 8138 } 8139 8140 /** 8141 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8142 * @param app object of the crashing app, null for the system server 8143 * @param tag reported by the caller 8144 * @param crashInfo describing the context of the error 8145 * @return true if the process should exit immediately (WTF is fatal) 8146 */ 8147 public boolean handleApplicationWtf(IBinder app, String tag, 8148 ApplicationErrorReport.CrashInfo crashInfo) { 8149 ProcessRecord r = findAppProcess(app, "WTF"); 8150 final String processName = app == null ? "system_server" 8151 : (r == null ? "unknown" : r.processName); 8152 8153 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8154 processName, 8155 r == null ? -1 : r.info.flags, 8156 tag, crashInfo.exceptionMessage); 8157 8158 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8159 8160 if (r != null && r.pid != Process.myPid() && 8161 Settings.Secure.getInt(mContext.getContentResolver(), 8162 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8163 crashApplication(r, crashInfo); 8164 return true; 8165 } else { 8166 return false; 8167 } 8168 } 8169 8170 /** 8171 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8172 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8173 */ 8174 private ProcessRecord findAppProcess(IBinder app, String reason) { 8175 if (app == null) { 8176 return null; 8177 } 8178 8179 synchronized (this) { 8180 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8181 final int NA = apps.size(); 8182 for (int ia=0; ia<NA; ia++) { 8183 ProcessRecord p = apps.valueAt(ia); 8184 if (p.thread != null && p.thread.asBinder() == app) { 8185 return p; 8186 } 8187 } 8188 } 8189 8190 Slog.w(TAG, "Can't find mystery application for " + reason 8191 + " from pid=" + Binder.getCallingPid() 8192 + " uid=" + Binder.getCallingUid() + ": " + app); 8193 return null; 8194 } 8195 } 8196 8197 /** 8198 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8199 * to append various headers to the dropbox log text. 8200 */ 8201 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8202 StringBuilder sb) { 8203 // Watchdog thread ends up invoking this function (with 8204 // a null ProcessRecord) to add the stack file to dropbox. 8205 // Do not acquire a lock on this (am) in such cases, as it 8206 // could cause a potential deadlock, if and when watchdog 8207 // is invoked due to unavailability of lock on am and it 8208 // would prevent watchdog from killing system_server. 8209 if (process == null) { 8210 sb.append("Process: ").append(processName).append("\n"); 8211 return; 8212 } 8213 // Note: ProcessRecord 'process' is guarded by the service 8214 // instance. (notably process.pkgList, which could otherwise change 8215 // concurrently during execution of this method) 8216 synchronized (this) { 8217 sb.append("Process: ").append(processName).append("\n"); 8218 int flags = process.info.flags; 8219 IPackageManager pm = AppGlobals.getPackageManager(); 8220 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8221 for (String pkg : process.pkgList) { 8222 sb.append("Package: ").append(pkg); 8223 try { 8224 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8225 if (pi != null) { 8226 sb.append(" v").append(pi.versionCode); 8227 if (pi.versionName != null) { 8228 sb.append(" (").append(pi.versionName).append(")"); 8229 } 8230 } 8231 } catch (RemoteException e) { 8232 Slog.e(TAG, "Error getting package info: " + pkg, e); 8233 } 8234 sb.append("\n"); 8235 } 8236 } 8237 } 8238 8239 private static String processClass(ProcessRecord process) { 8240 if (process == null || process.pid == MY_PID) { 8241 return "system_server"; 8242 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8243 return "system_app"; 8244 } else { 8245 return "data_app"; 8246 } 8247 } 8248 8249 /** 8250 * Write a description of an error (crash, WTF, ANR) to the drop box. 8251 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8252 * @param process which caused the error, null means the system server 8253 * @param activity which triggered the error, null if unknown 8254 * @param parent activity related to the error, null if unknown 8255 * @param subject line related to the error, null if absent 8256 * @param report in long form describing the error, null if absent 8257 * @param logFile to include in the report, null if none 8258 * @param crashInfo giving an application stack trace, null if absent 8259 */ 8260 public void addErrorToDropBox(String eventType, 8261 ProcessRecord process, String processName, ActivityRecord activity, 8262 ActivityRecord parent, String subject, 8263 final String report, final File logFile, 8264 final ApplicationErrorReport.CrashInfo crashInfo) { 8265 // NOTE -- this must never acquire the ActivityManagerService lock, 8266 // otherwise the watchdog may be prevented from resetting the system. 8267 8268 final String dropboxTag = processClass(process) + "_" + eventType; 8269 final DropBoxManager dbox = (DropBoxManager) 8270 mContext.getSystemService(Context.DROPBOX_SERVICE); 8271 8272 // Exit early if the dropbox isn't configured to accept this report type. 8273 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8274 8275 final StringBuilder sb = new StringBuilder(1024); 8276 appendDropBoxProcessHeaders(process, processName, sb); 8277 if (activity != null) { 8278 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8279 } 8280 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8281 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8282 } 8283 if (parent != null && parent != activity) { 8284 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8285 } 8286 if (subject != null) { 8287 sb.append("Subject: ").append(subject).append("\n"); 8288 } 8289 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8290 if (Debug.isDebuggerConnected()) { 8291 sb.append("Debugger: Connected\n"); 8292 } 8293 sb.append("\n"); 8294 8295 // Do the rest in a worker thread to avoid blocking the caller on I/O 8296 // (After this point, we shouldn't access AMS internal data structures.) 8297 Thread worker = new Thread("Error dump: " + dropboxTag) { 8298 @Override 8299 public void run() { 8300 if (report != null) { 8301 sb.append(report); 8302 } 8303 if (logFile != null) { 8304 try { 8305 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8306 } catch (IOException e) { 8307 Slog.e(TAG, "Error reading " + logFile, e); 8308 } 8309 } 8310 if (crashInfo != null && crashInfo.stackTrace != null) { 8311 sb.append(crashInfo.stackTrace); 8312 } 8313 8314 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8315 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8316 if (lines > 0) { 8317 sb.append("\n"); 8318 8319 // Merge several logcat streams, and take the last N lines 8320 InputStreamReader input = null; 8321 try { 8322 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8323 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8324 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8325 8326 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8327 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8328 input = new InputStreamReader(logcat.getInputStream()); 8329 8330 int num; 8331 char[] buf = new char[8192]; 8332 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8333 } catch (IOException e) { 8334 Slog.e(TAG, "Error running logcat", e); 8335 } finally { 8336 if (input != null) try { input.close(); } catch (IOException e) {} 8337 } 8338 } 8339 8340 dbox.addText(dropboxTag, sb.toString()); 8341 } 8342 }; 8343 8344 if (process == null) { 8345 // If process is null, we are being called from some internal code 8346 // and may be about to die -- run this synchronously. 8347 worker.run(); 8348 } else { 8349 worker.start(); 8350 } 8351 } 8352 8353 /** 8354 * Bring up the "unexpected error" dialog box for a crashing app. 8355 * Deal with edge cases (intercepts from instrumented applications, 8356 * ActivityController, error intent receivers, that sort of thing). 8357 * @param r the application crashing 8358 * @param crashInfo describing the failure 8359 */ 8360 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8361 long timeMillis = System.currentTimeMillis(); 8362 String shortMsg = crashInfo.exceptionClassName; 8363 String longMsg = crashInfo.exceptionMessage; 8364 String stackTrace = crashInfo.stackTrace; 8365 if (shortMsg != null && longMsg != null) { 8366 longMsg = shortMsg + ": " + longMsg; 8367 } else if (shortMsg != null) { 8368 longMsg = shortMsg; 8369 } 8370 8371 AppErrorResult result = new AppErrorResult(); 8372 synchronized (this) { 8373 if (mController != null) { 8374 try { 8375 String name = r != null ? r.processName : null; 8376 int pid = r != null ? r.pid : Binder.getCallingPid(); 8377 if (!mController.appCrashed(name, pid, 8378 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8379 Slog.w(TAG, "Force-killing crashed app " + name 8380 + " at watcher's request"); 8381 Process.killProcess(pid); 8382 return; 8383 } 8384 } catch (RemoteException e) { 8385 mController = null; 8386 } 8387 } 8388 8389 final long origId = Binder.clearCallingIdentity(); 8390 8391 // If this process is running instrumentation, finish it. 8392 if (r != null && r.instrumentationClass != null) { 8393 Slog.w(TAG, "Error in app " + r.processName 8394 + " running instrumentation " + r.instrumentationClass + ":"); 8395 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8396 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8397 Bundle info = new Bundle(); 8398 info.putString("shortMsg", shortMsg); 8399 info.putString("longMsg", longMsg); 8400 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8401 Binder.restoreCallingIdentity(origId); 8402 return; 8403 } 8404 8405 // If we can't identify the process or it's already exceeded its crash quota, 8406 // quit right away without showing a crash dialog. 8407 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8408 Binder.restoreCallingIdentity(origId); 8409 return; 8410 } 8411 8412 Message msg = Message.obtain(); 8413 msg.what = SHOW_ERROR_MSG; 8414 HashMap data = new HashMap(); 8415 data.put("result", result); 8416 data.put("app", r); 8417 msg.obj = data; 8418 mHandler.sendMessage(msg); 8419 8420 Binder.restoreCallingIdentity(origId); 8421 } 8422 8423 int res = result.get(); 8424 8425 Intent appErrorIntent = null; 8426 synchronized (this) { 8427 if (r != null && !r.isolated) { 8428 // XXX Can't keep track of crash time for isolated processes, 8429 // since they don't have a persistent identity. 8430 mProcessCrashTimes.put(r.info.processName, r.uid, 8431 SystemClock.uptimeMillis()); 8432 } 8433 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8434 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8435 } 8436 } 8437 8438 if (appErrorIntent != null) { 8439 try { 8440 mContext.startActivity(appErrorIntent); 8441 } catch (ActivityNotFoundException e) { 8442 Slog.w(TAG, "bug report receiver dissappeared", e); 8443 } 8444 } 8445 } 8446 8447 Intent createAppErrorIntentLocked(ProcessRecord r, 8448 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8449 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8450 if (report == null) { 8451 return null; 8452 } 8453 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8454 result.setComponent(r.errorReportReceiver); 8455 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8456 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8457 return result; 8458 } 8459 8460 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8461 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8462 if (r.errorReportReceiver == null) { 8463 return null; 8464 } 8465 8466 if (!r.crashing && !r.notResponding) { 8467 return null; 8468 } 8469 8470 ApplicationErrorReport report = new ApplicationErrorReport(); 8471 report.packageName = r.info.packageName; 8472 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8473 report.processName = r.processName; 8474 report.time = timeMillis; 8475 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8476 8477 if (r.crashing) { 8478 report.type = ApplicationErrorReport.TYPE_CRASH; 8479 report.crashInfo = crashInfo; 8480 } else if (r.notResponding) { 8481 report.type = ApplicationErrorReport.TYPE_ANR; 8482 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8483 8484 report.anrInfo.activity = r.notRespondingReport.tag; 8485 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8486 report.anrInfo.info = r.notRespondingReport.longMsg; 8487 } 8488 8489 return report; 8490 } 8491 8492 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8493 enforceNotIsolatedCaller("getProcessesInErrorState"); 8494 // assume our apps are happy - lazy create the list 8495 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8496 8497 final boolean allUsers = ActivityManager.checkUidPermission( 8498 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8499 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8500 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8501 8502 synchronized (this) { 8503 8504 // iterate across all processes 8505 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8506 ProcessRecord app = mLruProcesses.get(i); 8507 if (!allUsers && app.userId != userId) { 8508 continue; 8509 } 8510 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8511 // This one's in trouble, so we'll generate a report for it 8512 // crashes are higher priority (in case there's a crash *and* an anr) 8513 ActivityManager.ProcessErrorStateInfo report = null; 8514 if (app.crashing) { 8515 report = app.crashingReport; 8516 } else if (app.notResponding) { 8517 report = app.notRespondingReport; 8518 } 8519 8520 if (report != null) { 8521 if (errList == null) { 8522 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8523 } 8524 errList.add(report); 8525 } else { 8526 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8527 " crashing = " + app.crashing + 8528 " notResponding = " + app.notResponding); 8529 } 8530 } 8531 } 8532 } 8533 8534 return errList; 8535 } 8536 8537 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8538 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8539 if (currApp != null) { 8540 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8541 } 8542 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8543 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8544 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8545 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8546 if (currApp != null) { 8547 currApp.lru = 0; 8548 } 8549 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8550 } else if (adj >= ProcessList.SERVICE_ADJ) { 8551 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8552 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8553 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8554 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8555 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8556 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8557 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8558 } else { 8559 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8560 } 8561 } 8562 8563 private void fillInProcMemInfo(ProcessRecord app, 8564 ActivityManager.RunningAppProcessInfo outInfo) { 8565 outInfo.pid = app.pid; 8566 outInfo.uid = app.info.uid; 8567 if (mHeavyWeightProcess == app) { 8568 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8569 } 8570 if (app.persistent) { 8571 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8572 } 8573 if (app.hasActivities) { 8574 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8575 } 8576 outInfo.lastTrimLevel = app.trimMemoryLevel; 8577 int adj = app.curAdj; 8578 outInfo.importance = oomAdjToImportance(adj, outInfo); 8579 outInfo.importanceReasonCode = app.adjTypeCode; 8580 } 8581 8582 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8583 enforceNotIsolatedCaller("getRunningAppProcesses"); 8584 // Lazy instantiation of list 8585 List<ActivityManager.RunningAppProcessInfo> runList = null; 8586 final boolean allUsers = ActivityManager.checkUidPermission( 8587 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8588 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8589 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8590 synchronized (this) { 8591 // Iterate across all processes 8592 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8593 ProcessRecord app = mLruProcesses.get(i); 8594 if (!allUsers && app.userId != userId) { 8595 continue; 8596 } 8597 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8598 // Generate process state info for running application 8599 ActivityManager.RunningAppProcessInfo currApp = 8600 new ActivityManager.RunningAppProcessInfo(app.processName, 8601 app.pid, app.getPackageList()); 8602 fillInProcMemInfo(app, currApp); 8603 if (app.adjSource instanceof ProcessRecord) { 8604 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8605 currApp.importanceReasonImportance = oomAdjToImportance( 8606 app.adjSourceOom, null); 8607 } else if (app.adjSource instanceof ActivityRecord) { 8608 ActivityRecord r = (ActivityRecord)app.adjSource; 8609 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8610 } 8611 if (app.adjTarget instanceof ComponentName) { 8612 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8613 } 8614 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8615 // + " lru=" + currApp.lru); 8616 if (runList == null) { 8617 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8618 } 8619 runList.add(currApp); 8620 } 8621 } 8622 } 8623 return runList; 8624 } 8625 8626 public List<ApplicationInfo> getRunningExternalApplications() { 8627 enforceNotIsolatedCaller("getRunningExternalApplications"); 8628 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8629 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8630 if (runningApps != null && runningApps.size() > 0) { 8631 Set<String> extList = new HashSet<String>(); 8632 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8633 if (app.pkgList != null) { 8634 for (String pkg : app.pkgList) { 8635 extList.add(pkg); 8636 } 8637 } 8638 } 8639 IPackageManager pm = AppGlobals.getPackageManager(); 8640 for (String pkg : extList) { 8641 try { 8642 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8643 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8644 retList.add(info); 8645 } 8646 } catch (RemoteException e) { 8647 } 8648 } 8649 } 8650 return retList; 8651 } 8652 8653 @Override 8654 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8655 enforceNotIsolatedCaller("getMyMemoryState"); 8656 synchronized (this) { 8657 ProcessRecord proc; 8658 synchronized (mPidsSelfLocked) { 8659 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8660 } 8661 fillInProcMemInfo(proc, outInfo); 8662 } 8663 } 8664 8665 @Override 8666 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8667 if (checkCallingPermission(android.Manifest.permission.DUMP) 8668 != PackageManager.PERMISSION_GRANTED) { 8669 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8670 + Binder.getCallingPid() 8671 + ", uid=" + Binder.getCallingUid() 8672 + " without permission " 8673 + android.Manifest.permission.DUMP); 8674 return; 8675 } 8676 8677 boolean dumpAll = false; 8678 boolean dumpClient = false; 8679 String dumpPackage = null; 8680 8681 int opti = 0; 8682 while (opti < args.length) { 8683 String opt = args[opti]; 8684 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8685 break; 8686 } 8687 opti++; 8688 if ("-a".equals(opt)) { 8689 dumpAll = true; 8690 } else if ("-c".equals(opt)) { 8691 dumpClient = true; 8692 } else if ("-h".equals(opt)) { 8693 pw.println("Activity manager dump options:"); 8694 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8695 pw.println(" cmd may be one of:"); 8696 pw.println(" a[ctivities]: activity stack state"); 8697 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8698 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8699 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8700 pw.println(" o[om]: out of memory management"); 8701 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8702 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8703 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8704 pw.println(" service [COMP_SPEC]: service client-side state"); 8705 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8706 pw.println(" all: dump all activities"); 8707 pw.println(" top: dump the top activity"); 8708 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8709 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8710 pw.println(" a partial substring in a component name, a"); 8711 pw.println(" hex object identifier."); 8712 pw.println(" -a: include all available server state."); 8713 pw.println(" -c: include client state."); 8714 return; 8715 } else { 8716 pw.println("Unknown argument: " + opt + "; use -h for help"); 8717 } 8718 } 8719 8720 long origId = Binder.clearCallingIdentity(); 8721 boolean more = false; 8722 // Is the caller requesting to dump a particular piece of data? 8723 if (opti < args.length) { 8724 String cmd = args[opti]; 8725 opti++; 8726 if ("activities".equals(cmd) || "a".equals(cmd)) { 8727 synchronized (this) { 8728 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8729 } 8730 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8731 String[] newArgs; 8732 String name; 8733 if (opti >= args.length) { 8734 name = null; 8735 newArgs = EMPTY_STRING_ARRAY; 8736 } else { 8737 name = args[opti]; 8738 opti++; 8739 newArgs = new String[args.length - opti]; 8740 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8741 args.length - opti); 8742 } 8743 synchronized (this) { 8744 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8745 } 8746 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8747 String[] newArgs; 8748 String name; 8749 if (opti >= args.length) { 8750 name = null; 8751 newArgs = EMPTY_STRING_ARRAY; 8752 } else { 8753 name = args[opti]; 8754 opti++; 8755 newArgs = new String[args.length - opti]; 8756 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8757 args.length - opti); 8758 } 8759 synchronized (this) { 8760 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8761 } 8762 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8763 String[] newArgs; 8764 String name; 8765 if (opti >= args.length) { 8766 name = null; 8767 newArgs = EMPTY_STRING_ARRAY; 8768 } else { 8769 name = args[opti]; 8770 opti++; 8771 newArgs = new String[args.length - opti]; 8772 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8773 args.length - opti); 8774 } 8775 synchronized (this) { 8776 dumpProcessesLocked(fd, pw, args, opti, true, name); 8777 } 8778 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8779 synchronized (this) { 8780 dumpOomLocked(fd, pw, args, opti, true); 8781 } 8782 } else if ("provider".equals(cmd)) { 8783 String[] newArgs; 8784 String name; 8785 if (opti >= args.length) { 8786 name = null; 8787 newArgs = EMPTY_STRING_ARRAY; 8788 } else { 8789 name = args[opti]; 8790 opti++; 8791 newArgs = new String[args.length - opti]; 8792 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8793 } 8794 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8795 pw.println("No providers match: " + name); 8796 pw.println("Use -h for help."); 8797 } 8798 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8799 synchronized (this) { 8800 dumpProvidersLocked(fd, pw, args, opti, true, null); 8801 } 8802 } else if ("service".equals(cmd)) { 8803 String[] newArgs; 8804 String name; 8805 if (opti >= args.length) { 8806 name = null; 8807 newArgs = EMPTY_STRING_ARRAY; 8808 } else { 8809 name = args[opti]; 8810 opti++; 8811 newArgs = new String[args.length - opti]; 8812 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8813 args.length - opti); 8814 } 8815 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8816 pw.println("No services match: " + name); 8817 pw.println("Use -h for help."); 8818 } 8819 } else if ("package".equals(cmd)) { 8820 String[] newArgs; 8821 if (opti >= args.length) { 8822 pw.println("package: no package name specified"); 8823 pw.println("Use -h for help."); 8824 } else { 8825 dumpPackage = args[opti]; 8826 opti++; 8827 newArgs = new String[args.length - opti]; 8828 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8829 args.length - opti); 8830 args = newArgs; 8831 opti = 0; 8832 more = true; 8833 } 8834 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8835 synchronized (this) { 8836 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8837 } 8838 } else { 8839 // Dumping a single activity? 8840 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8841 pw.println("Bad activity command, or no activities match: " + cmd); 8842 pw.println("Use -h for help."); 8843 } 8844 } 8845 if (!more) { 8846 Binder.restoreCallingIdentity(origId); 8847 return; 8848 } 8849 } 8850 8851 // No piece of data specified, dump everything. 8852 synchronized (this) { 8853 boolean needSep; 8854 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8855 if (needSep) { 8856 pw.println(" "); 8857 } 8858 if (dumpAll) { 8859 pw.println("-------------------------------------------------------------------------------"); 8860 } 8861 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8862 if (needSep) { 8863 pw.println(" "); 8864 } 8865 if (dumpAll) { 8866 pw.println("-------------------------------------------------------------------------------"); 8867 } 8868 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8869 if (needSep) { 8870 pw.println(" "); 8871 } 8872 if (dumpAll) { 8873 pw.println("-------------------------------------------------------------------------------"); 8874 } 8875 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8876 if (needSep) { 8877 pw.println(" "); 8878 } 8879 if (dumpAll) { 8880 pw.println("-------------------------------------------------------------------------------"); 8881 } 8882 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8883 if (needSep) { 8884 pw.println(" "); 8885 } 8886 if (dumpAll) { 8887 pw.println("-------------------------------------------------------------------------------"); 8888 } 8889 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8890 } 8891 Binder.restoreCallingIdentity(origId); 8892 } 8893 8894 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8895 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8896 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8897 pw.println(" Main stack:"); 8898 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8899 dumpPackage); 8900 pw.println(" "); 8901 pw.println(" Running activities (most recent first):"); 8902 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8903 dumpPackage); 8904 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8905 pw.println(" "); 8906 pw.println(" Activities waiting for another to become visible:"); 8907 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8908 !dumpAll, false, dumpPackage); 8909 } 8910 if (mMainStack.mStoppingActivities.size() > 0) { 8911 pw.println(" "); 8912 pw.println(" Activities waiting to stop:"); 8913 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8914 !dumpAll, false, dumpPackage); 8915 } 8916 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8917 pw.println(" "); 8918 pw.println(" Activities waiting to sleep:"); 8919 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8920 !dumpAll, false, dumpPackage); 8921 } 8922 if (mMainStack.mFinishingActivities.size() > 0) { 8923 pw.println(" "); 8924 pw.println(" Activities waiting to finish:"); 8925 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8926 !dumpAll, false, dumpPackage); 8927 } 8928 8929 pw.println(" "); 8930 if (mMainStack.mPausingActivity != null) { 8931 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8932 } 8933 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8934 pw.println(" mFocusedActivity: " + mFocusedActivity); 8935 if (dumpAll) { 8936 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8937 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8938 pw.println(" mDismissKeyguardOnNextActivity: " 8939 + mMainStack.mDismissKeyguardOnNextActivity); 8940 } 8941 8942 if (mRecentTasks.size() > 0) { 8943 pw.println(); 8944 pw.println(" Recent tasks:"); 8945 8946 final int N = mRecentTasks.size(); 8947 for (int i=0; i<N; i++) { 8948 TaskRecord tr = mRecentTasks.get(i); 8949 if (dumpPackage != null) { 8950 if (tr.realActivity == null || 8951 !dumpPackage.equals(tr.realActivity)) { 8952 continue; 8953 } 8954 } 8955 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8956 pw.println(tr); 8957 if (dumpAll) { 8958 mRecentTasks.get(i).dump(pw, " "); 8959 } 8960 } 8961 } 8962 8963 if (dumpAll) { 8964 pw.println(" "); 8965 pw.println(" mCurTask: " + mCurTask); 8966 } 8967 8968 return true; 8969 } 8970 8971 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8972 int opti, boolean dumpAll, String dumpPackage) { 8973 boolean needSep = false; 8974 int numPers = 0; 8975 8976 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8977 8978 if (dumpAll) { 8979 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8980 final int NA = procs.size(); 8981 for (int ia=0; ia<NA; ia++) { 8982 ProcessRecord r = procs.valueAt(ia); 8983 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8984 continue; 8985 } 8986 if (!needSep) { 8987 pw.println(" All known processes:"); 8988 needSep = true; 8989 } 8990 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8991 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8992 pw.print(" "); pw.println(r); 8993 r.dump(pw, " "); 8994 if (r.persistent) { 8995 numPers++; 8996 } 8997 } 8998 } 8999 } 9000 9001 if (mIsolatedProcesses.size() > 0) { 9002 if (needSep) pw.println(" "); 9003 needSep = true; 9004 pw.println(" Isolated process list (sorted by uid):"); 9005 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9006 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9007 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9008 continue; 9009 } 9010 pw.println(String.format("%sIsolated #%2d: %s", 9011 " ", i, r.toString())); 9012 } 9013 } 9014 9015 if (mLruProcesses.size() > 0) { 9016 if (needSep) pw.println(" "); 9017 needSep = true; 9018 pw.println(" Process LRU list (sorted by oom_adj):"); 9019 dumpProcessOomList(pw, this, mLruProcesses, " ", 9020 "Proc", "PERS", false, dumpPackage); 9021 needSep = true; 9022 } 9023 9024 if (dumpAll) { 9025 synchronized (mPidsSelfLocked) { 9026 boolean printed = false; 9027 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9028 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9029 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9030 continue; 9031 } 9032 if (!printed) { 9033 if (needSep) pw.println(" "); 9034 needSep = true; 9035 pw.println(" PID mappings:"); 9036 printed = true; 9037 } 9038 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9039 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9040 } 9041 } 9042 } 9043 9044 if (mForegroundProcesses.size() > 0) { 9045 synchronized (mPidsSelfLocked) { 9046 boolean printed = false; 9047 for (int i=0; i<mForegroundProcesses.size(); i++) { 9048 ProcessRecord r = mPidsSelfLocked.get( 9049 mForegroundProcesses.valueAt(i).pid); 9050 if (dumpPackage != null && (r == null 9051 || !dumpPackage.equals(r.info.packageName))) { 9052 continue; 9053 } 9054 if (!printed) { 9055 if (needSep) pw.println(" "); 9056 needSep = true; 9057 pw.println(" Foreground Processes:"); 9058 printed = true; 9059 } 9060 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9061 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9062 } 9063 } 9064 } 9065 9066 if (mPersistentStartingProcesses.size() > 0) { 9067 if (needSep) pw.println(" "); 9068 needSep = true; 9069 pw.println(" Persisent processes that are starting:"); 9070 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9071 "Starting Norm", "Restarting PERS", dumpPackage); 9072 } 9073 9074 if (mRemovedProcesses.size() > 0) { 9075 if (needSep) pw.println(" "); 9076 needSep = true; 9077 pw.println(" Processes that are being removed:"); 9078 dumpProcessList(pw, this, mRemovedProcesses, " ", 9079 "Removed Norm", "Removed PERS", dumpPackage); 9080 } 9081 9082 if (mProcessesOnHold.size() > 0) { 9083 if (needSep) pw.println(" "); 9084 needSep = true; 9085 pw.println(" Processes that are on old until the system is ready:"); 9086 dumpProcessList(pw, this, mProcessesOnHold, " ", 9087 "OnHold Norm", "OnHold PERS", dumpPackage); 9088 } 9089 9090 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9091 9092 if (mProcessCrashTimes.getMap().size() > 0) { 9093 boolean printed = false; 9094 long now = SystemClock.uptimeMillis(); 9095 for (Map.Entry<String, SparseArray<Long>> procs 9096 : mProcessCrashTimes.getMap().entrySet()) { 9097 String pname = procs.getKey(); 9098 SparseArray<Long> uids = procs.getValue(); 9099 final int N = uids.size(); 9100 for (int i=0; i<N; i++) { 9101 int puid = uids.keyAt(i); 9102 ProcessRecord r = mProcessNames.get(pname, puid); 9103 if (dumpPackage != null && (r == null 9104 || !dumpPackage.equals(r.info.packageName))) { 9105 continue; 9106 } 9107 if (!printed) { 9108 if (needSep) pw.println(" "); 9109 needSep = true; 9110 pw.println(" Time since processes crashed:"); 9111 printed = true; 9112 } 9113 pw.print(" Process "); pw.print(pname); 9114 pw.print(" uid "); pw.print(puid); 9115 pw.print(": last crashed "); 9116 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9117 pw.println(" ago"); 9118 } 9119 } 9120 } 9121 9122 if (mBadProcesses.getMap().size() > 0) { 9123 boolean printed = false; 9124 for (Map.Entry<String, SparseArray<Long>> procs 9125 : mBadProcesses.getMap().entrySet()) { 9126 String pname = procs.getKey(); 9127 SparseArray<Long> uids = procs.getValue(); 9128 final int N = uids.size(); 9129 for (int i=0; i<N; i++) { 9130 int puid = uids.keyAt(i); 9131 ProcessRecord r = mProcessNames.get(pname, puid); 9132 if (dumpPackage != null && (r == null 9133 || !dumpPackage.equals(r.info.packageName))) { 9134 continue; 9135 } 9136 if (!printed) { 9137 if (needSep) pw.println(" "); 9138 needSep = true; 9139 pw.println(" Bad processes:"); 9140 } 9141 pw.print(" Bad process "); pw.print(pname); 9142 pw.print(" uid "); pw.print(puid); 9143 pw.print(": crashed at time "); 9144 pw.println(uids.valueAt(i)); 9145 } 9146 } 9147 } 9148 9149 pw.println(); 9150 pw.println(" mStartedUsers:"); 9151 for (int i=0; i<mStartedUsers.size(); i++) { 9152 UserStartedState uss = mStartedUsers.valueAt(i); 9153 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9154 pw.println(":"); 9155 uss.dump(" ", pw); 9156 } 9157 pw.println(" mHomeProcess: " + mHomeProcess); 9158 pw.println(" mPreviousProcess: " + mPreviousProcess); 9159 if (dumpAll) { 9160 StringBuilder sb = new StringBuilder(128); 9161 sb.append(" mPreviousProcessVisibleTime: "); 9162 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9163 pw.println(sb); 9164 } 9165 if (mHeavyWeightProcess != null) { 9166 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9167 } 9168 pw.println(" mConfiguration: " + mConfiguration); 9169 if (dumpAll) { 9170 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9171 if (mCompatModePackages.getPackages().size() > 0) { 9172 boolean printed = false; 9173 for (Map.Entry<String, Integer> entry 9174 : mCompatModePackages.getPackages().entrySet()) { 9175 String pkg = entry.getKey(); 9176 int mode = entry.getValue(); 9177 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9178 continue; 9179 } 9180 if (!printed) { 9181 pw.println(" mScreenCompatPackages:"); 9182 printed = true; 9183 } 9184 pw.print(" "); pw.print(pkg); pw.print(": "); 9185 pw.print(mode); pw.println(); 9186 } 9187 } 9188 } 9189 if (mSleeping || mWentToSleep || mLockScreenShown) { 9190 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9191 + " mLockScreenShown " + mLockScreenShown); 9192 } 9193 if (mShuttingDown) { 9194 pw.println(" mShuttingDown=" + mShuttingDown); 9195 } 9196 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9197 || mOrigWaitForDebugger) { 9198 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9199 + " mDebugTransient=" + mDebugTransient 9200 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9201 } 9202 if (mOpenGlTraceApp != null) { 9203 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9204 } 9205 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9206 || mProfileFd != null) { 9207 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9208 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9209 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9210 + mAutoStopProfiler); 9211 } 9212 if (mAlwaysFinishActivities || mController != null) { 9213 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9214 + " mController=" + mController); 9215 } 9216 if (dumpAll) { 9217 pw.println(" Total persistent processes: " + numPers); 9218 pw.println(" mStartRunning=" + mStartRunning 9219 + " mProcessesReady=" + mProcessesReady 9220 + " mSystemReady=" + mSystemReady); 9221 pw.println(" mBooting=" + mBooting 9222 + " mBooted=" + mBooted 9223 + " mFactoryTest=" + mFactoryTest); 9224 pw.print(" mLastPowerCheckRealtime="); 9225 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9226 pw.println(""); 9227 pw.print(" mLastPowerCheckUptime="); 9228 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9229 pw.println(""); 9230 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9231 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9232 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9233 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9234 + " mNumHiddenProcs=" + mNumHiddenProcs 9235 + " mNumServiceProcs=" + mNumServiceProcs 9236 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9237 } 9238 9239 return true; 9240 } 9241 9242 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9243 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9244 if (mProcessesToGc.size() > 0) { 9245 boolean printed = false; 9246 long now = SystemClock.uptimeMillis(); 9247 for (int i=0; i<mProcessesToGc.size(); i++) { 9248 ProcessRecord proc = mProcessesToGc.get(i); 9249 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9250 continue; 9251 } 9252 if (!printed) { 9253 if (needSep) pw.println(" "); 9254 needSep = true; 9255 pw.println(" Processes that are waiting to GC:"); 9256 printed = true; 9257 } 9258 pw.print(" Process "); pw.println(proc); 9259 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9260 pw.print(", last gced="); 9261 pw.print(now-proc.lastRequestedGc); 9262 pw.print(" ms ago, last lowMem="); 9263 pw.print(now-proc.lastLowMemory); 9264 pw.println(" ms ago"); 9265 9266 } 9267 } 9268 return needSep; 9269 } 9270 9271 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9272 int opti, boolean dumpAll) { 9273 boolean needSep = false; 9274 9275 if (mLruProcesses.size() > 0) { 9276 if (needSep) pw.println(" "); 9277 needSep = true; 9278 pw.println(" OOM levels:"); 9279 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9280 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9281 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9282 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9283 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9284 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9285 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9286 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9287 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9288 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9289 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9290 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9291 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9292 9293 if (needSep) pw.println(" "); 9294 needSep = true; 9295 pw.println(" Process OOM control:"); 9296 dumpProcessOomList(pw, this, mLruProcesses, " ", 9297 "Proc", "PERS", true, null); 9298 needSep = true; 9299 } 9300 9301 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9302 9303 pw.println(); 9304 pw.println(" mHomeProcess: " + mHomeProcess); 9305 pw.println(" mPreviousProcess: " + mPreviousProcess); 9306 if (mHeavyWeightProcess != null) { 9307 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9308 } 9309 9310 return true; 9311 } 9312 9313 /** 9314 * There are three ways to call this: 9315 * - no provider specified: dump all the providers 9316 * - a flattened component name that matched an existing provider was specified as the 9317 * first arg: dump that one provider 9318 * - the first arg isn't the flattened component name of an existing provider: 9319 * dump all providers whose component contains the first arg as a substring 9320 */ 9321 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9322 int opti, boolean dumpAll) { 9323 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9324 } 9325 9326 static class ItemMatcher { 9327 ArrayList<ComponentName> components; 9328 ArrayList<String> strings; 9329 ArrayList<Integer> objects; 9330 boolean all; 9331 9332 ItemMatcher() { 9333 all = true; 9334 } 9335 9336 void build(String name) { 9337 ComponentName componentName = ComponentName.unflattenFromString(name); 9338 if (componentName != null) { 9339 if (components == null) { 9340 components = new ArrayList<ComponentName>(); 9341 } 9342 components.add(componentName); 9343 all = false; 9344 } else { 9345 int objectId = 0; 9346 // Not a '/' separated full component name; maybe an object ID? 9347 try { 9348 objectId = Integer.parseInt(name, 16); 9349 if (objects == null) { 9350 objects = new ArrayList<Integer>(); 9351 } 9352 objects.add(objectId); 9353 all = false; 9354 } catch (RuntimeException e) { 9355 // Not an integer; just do string match. 9356 if (strings == null) { 9357 strings = new ArrayList<String>(); 9358 } 9359 strings.add(name); 9360 all = false; 9361 } 9362 } 9363 } 9364 9365 int build(String[] args, int opti) { 9366 for (; opti<args.length; opti++) { 9367 String name = args[opti]; 9368 if ("--".equals(name)) { 9369 return opti+1; 9370 } 9371 build(name); 9372 } 9373 return opti; 9374 } 9375 9376 boolean match(Object object, ComponentName comp) { 9377 if (all) { 9378 return true; 9379 } 9380 if (components != null) { 9381 for (int i=0; i<components.size(); i++) { 9382 if (components.get(i).equals(comp)) { 9383 return true; 9384 } 9385 } 9386 } 9387 if (objects != null) { 9388 for (int i=0; i<objects.size(); i++) { 9389 if (System.identityHashCode(object) == objects.get(i)) { 9390 return true; 9391 } 9392 } 9393 } 9394 if (strings != null) { 9395 String flat = comp.flattenToString(); 9396 for (int i=0; i<strings.size(); i++) { 9397 if (flat.contains(strings.get(i))) { 9398 return true; 9399 } 9400 } 9401 } 9402 return false; 9403 } 9404 } 9405 9406 /** 9407 * There are three things that cmd can be: 9408 * - a flattened component name that matches an existing activity 9409 * - the cmd arg isn't the flattened component name of an existing activity: 9410 * dump all activity whose component contains the cmd as a substring 9411 * - A hex number of the ActivityRecord object instance. 9412 */ 9413 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9414 int opti, boolean dumpAll) { 9415 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9416 9417 if ("all".equals(name)) { 9418 synchronized (this) { 9419 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9420 activities.add(r1); 9421 } 9422 } 9423 } else if ("top".equals(name)) { 9424 synchronized (this) { 9425 final int N = mMainStack.mHistory.size(); 9426 if (N > 0) { 9427 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9428 } 9429 } 9430 } else { 9431 ItemMatcher matcher = new ItemMatcher(); 9432 matcher.build(name); 9433 9434 synchronized (this) { 9435 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9436 if (matcher.match(r1, r1.intent.getComponent())) { 9437 activities.add(r1); 9438 } 9439 } 9440 } 9441 } 9442 9443 if (activities.size() <= 0) { 9444 return false; 9445 } 9446 9447 String[] newArgs = new String[args.length - opti]; 9448 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9449 9450 TaskRecord lastTask = null; 9451 boolean needSep = false; 9452 for (int i=activities.size()-1; i>=0; i--) { 9453 ActivityRecord r = (ActivityRecord)activities.get(i); 9454 if (needSep) { 9455 pw.println(); 9456 } 9457 needSep = true; 9458 synchronized (this) { 9459 if (lastTask != r.task) { 9460 lastTask = r.task; 9461 pw.print("TASK "); pw.print(lastTask.affinity); 9462 pw.print(" id="); pw.println(lastTask.taskId); 9463 if (dumpAll) { 9464 lastTask.dump(pw, " "); 9465 } 9466 } 9467 } 9468 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9469 } 9470 return true; 9471 } 9472 9473 /** 9474 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9475 * there is a thread associated with the activity. 9476 */ 9477 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9478 final ActivityRecord r, String[] args, boolean dumpAll) { 9479 String innerPrefix = prefix + " "; 9480 synchronized (this) { 9481 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9482 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9483 pw.print(" pid="); 9484 if (r.app != null) pw.println(r.app.pid); 9485 else pw.println("(not running)"); 9486 if (dumpAll) { 9487 r.dump(pw, innerPrefix); 9488 } 9489 } 9490 if (r.app != null && r.app.thread != null) { 9491 // flush anything that is already in the PrintWriter since the thread is going 9492 // to write to the file descriptor directly 9493 pw.flush(); 9494 try { 9495 TransferPipe tp = new TransferPipe(); 9496 try { 9497 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9498 r.appToken, innerPrefix, args); 9499 tp.go(fd); 9500 } finally { 9501 tp.kill(); 9502 } 9503 } catch (IOException e) { 9504 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9505 } catch (RemoteException e) { 9506 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9507 } 9508 } 9509 } 9510 9511 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9512 int opti, boolean dumpAll, String dumpPackage) { 9513 boolean needSep = false; 9514 boolean onlyHistory = false; 9515 9516 if ("history".equals(dumpPackage)) { 9517 onlyHistory = true; 9518 dumpPackage = null; 9519 } 9520 9521 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9522 if (!onlyHistory && dumpAll) { 9523 if (mRegisteredReceivers.size() > 0) { 9524 boolean printed = false; 9525 Iterator it = mRegisteredReceivers.values().iterator(); 9526 while (it.hasNext()) { 9527 ReceiverList r = (ReceiverList)it.next(); 9528 if (dumpPackage != null && (r.app == null || 9529 !dumpPackage.equals(r.app.info.packageName))) { 9530 continue; 9531 } 9532 if (!printed) { 9533 pw.println(" Registered Receivers:"); 9534 needSep = true; 9535 printed = true; 9536 } 9537 pw.print(" * "); pw.println(r); 9538 r.dump(pw, " "); 9539 } 9540 } 9541 9542 if (mReceiverResolver.dump(pw, needSep ? 9543 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9544 " ", dumpPackage, false)) { 9545 needSep = true; 9546 } 9547 } 9548 9549 for (BroadcastQueue q : mBroadcastQueues) { 9550 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9551 } 9552 9553 needSep = true; 9554 9555 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9556 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9557 if (needSep) { 9558 pw.println(); 9559 } 9560 needSep = true; 9561 pw.print(" Sticky broadcasts for user "); 9562 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9563 StringBuilder sb = new StringBuilder(128); 9564 for (Map.Entry<String, ArrayList<Intent>> ent 9565 : mStickyBroadcasts.valueAt(user).entrySet()) { 9566 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9567 if (dumpAll) { 9568 pw.println(":"); 9569 ArrayList<Intent> intents = ent.getValue(); 9570 final int N = intents.size(); 9571 for (int i=0; i<N; i++) { 9572 sb.setLength(0); 9573 sb.append(" Intent: "); 9574 intents.get(i).toShortString(sb, false, true, false, false); 9575 pw.println(sb.toString()); 9576 Bundle bundle = intents.get(i).getExtras(); 9577 if (bundle != null) { 9578 pw.print(" "); 9579 pw.println(bundle.toString()); 9580 } 9581 } 9582 } else { 9583 pw.println(""); 9584 } 9585 } 9586 } 9587 } 9588 9589 if (!onlyHistory && dumpAll) { 9590 pw.println(); 9591 for (BroadcastQueue queue : mBroadcastQueues) { 9592 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9593 + queue.mBroadcastsScheduled); 9594 } 9595 pw.println(" mHandler:"); 9596 mHandler.dump(new PrintWriterPrinter(pw), " "); 9597 needSep = true; 9598 } 9599 9600 return needSep; 9601 } 9602 9603 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9604 int opti, boolean dumpAll, String dumpPackage) { 9605 boolean needSep = true; 9606 9607 ItemMatcher matcher = new ItemMatcher(); 9608 matcher.build(args, opti); 9609 9610 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9611 9612 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9613 9614 if (mLaunchingProviders.size() > 0) { 9615 boolean printed = false; 9616 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9617 ContentProviderRecord r = mLaunchingProviders.get(i); 9618 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9619 continue; 9620 } 9621 if (!printed) { 9622 if (needSep) pw.println(" "); 9623 needSep = true; 9624 pw.println(" Launching content providers:"); 9625 printed = true; 9626 } 9627 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9628 pw.println(r); 9629 } 9630 } 9631 9632 if (mGrantedUriPermissions.size() > 0) { 9633 if (needSep) pw.println(); 9634 needSep = true; 9635 pw.println("Granted Uri Permissions:"); 9636 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9637 int uid = mGrantedUriPermissions.keyAt(i); 9638 HashMap<Uri, UriPermission> perms 9639 = mGrantedUriPermissions.valueAt(i); 9640 pw.print(" * UID "); pw.print(uid); 9641 pw.println(" holds:"); 9642 for (UriPermission perm : perms.values()) { 9643 pw.print(" "); pw.println(perm); 9644 if (dumpAll) { 9645 perm.dump(pw, " "); 9646 } 9647 } 9648 } 9649 needSep = true; 9650 } 9651 9652 return needSep; 9653 } 9654 9655 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9656 int opti, boolean dumpAll, String dumpPackage) { 9657 boolean needSep = false; 9658 9659 if (mIntentSenderRecords.size() > 0) { 9660 boolean printed = false; 9661 Iterator<WeakReference<PendingIntentRecord>> it 9662 = mIntentSenderRecords.values().iterator(); 9663 while (it.hasNext()) { 9664 WeakReference<PendingIntentRecord> ref = it.next(); 9665 PendingIntentRecord rec = ref != null ? ref.get(): null; 9666 if (dumpPackage != null && (rec == null 9667 || !dumpPackage.equals(rec.key.packageName))) { 9668 continue; 9669 } 9670 if (!printed) { 9671 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9672 printed = true; 9673 } 9674 needSep = true; 9675 if (rec != null) { 9676 pw.print(" * "); pw.println(rec); 9677 if (dumpAll) { 9678 rec.dump(pw, " "); 9679 } 9680 } else { 9681 pw.print(" * "); pw.println(ref); 9682 } 9683 } 9684 } 9685 9686 return needSep; 9687 } 9688 9689 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9690 String prefix, String label, boolean complete, boolean brief, boolean client, 9691 String dumpPackage) { 9692 TaskRecord lastTask = null; 9693 boolean needNL = false; 9694 final String innerPrefix = prefix + " "; 9695 final String[] args = new String[0]; 9696 for (int i=list.size()-1; i>=0; i--) { 9697 final ActivityRecord r = (ActivityRecord)list.get(i); 9698 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9699 continue; 9700 } 9701 final boolean full = !brief && (complete || !r.isInHistory()); 9702 if (needNL) { 9703 pw.println(" "); 9704 needNL = false; 9705 } 9706 if (lastTask != r.task) { 9707 lastTask = r.task; 9708 pw.print(prefix); 9709 pw.print(full ? "* " : " "); 9710 pw.println(lastTask); 9711 if (full) { 9712 lastTask.dump(pw, prefix + " "); 9713 } else if (complete) { 9714 // Complete + brief == give a summary. Isn't that obvious?!? 9715 if (lastTask.intent != null) { 9716 pw.print(prefix); pw.print(" "); 9717 pw.println(lastTask.intent.toInsecureStringWithClip()); 9718 } 9719 } 9720 } 9721 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9722 pw.print(" #"); pw.print(i); pw.print(": "); 9723 pw.println(r); 9724 if (full) { 9725 r.dump(pw, innerPrefix); 9726 } else if (complete) { 9727 // Complete + brief == give a summary. Isn't that obvious?!? 9728 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9729 if (r.app != null) { 9730 pw.print(innerPrefix); pw.println(r.app); 9731 } 9732 } 9733 if (client && r.app != null && r.app.thread != null) { 9734 // flush anything that is already in the PrintWriter since the thread is going 9735 // to write to the file descriptor directly 9736 pw.flush(); 9737 try { 9738 TransferPipe tp = new TransferPipe(); 9739 try { 9740 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9741 r.appToken, innerPrefix, args); 9742 // Short timeout, since blocking here can 9743 // deadlock with the application. 9744 tp.go(fd, 2000); 9745 } finally { 9746 tp.kill(); 9747 } 9748 } catch (IOException e) { 9749 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9750 } catch (RemoteException e) { 9751 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9752 } 9753 needNL = true; 9754 } 9755 } 9756 } 9757 9758 private static String buildOomTag(String prefix, String space, int val, int base) { 9759 if (val == base) { 9760 if (space == null) return prefix; 9761 return prefix + " "; 9762 } 9763 return prefix + "+" + Integer.toString(val-base); 9764 } 9765 9766 private static final int dumpProcessList(PrintWriter pw, 9767 ActivityManagerService service, List list, 9768 String prefix, String normalLabel, String persistentLabel, 9769 String dumpPackage) { 9770 int numPers = 0; 9771 final int N = list.size()-1; 9772 for (int i=N; i>=0; i--) { 9773 ProcessRecord r = (ProcessRecord)list.get(i); 9774 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9775 continue; 9776 } 9777 pw.println(String.format("%s%s #%2d: %s", 9778 prefix, (r.persistent ? persistentLabel : normalLabel), 9779 i, r.toString())); 9780 if (r.persistent) { 9781 numPers++; 9782 } 9783 } 9784 return numPers; 9785 } 9786 9787 private static final boolean dumpProcessOomList(PrintWriter pw, 9788 ActivityManagerService service, List<ProcessRecord> origList, 9789 String prefix, String normalLabel, String persistentLabel, 9790 boolean inclDetails, String dumpPackage) { 9791 9792 ArrayList<Pair<ProcessRecord, Integer>> list 9793 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9794 for (int i=0; i<origList.size(); i++) { 9795 ProcessRecord r = origList.get(i); 9796 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9797 continue; 9798 } 9799 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9800 } 9801 9802 if (list.size() <= 0) { 9803 return false; 9804 } 9805 9806 Comparator<Pair<ProcessRecord, Integer>> comparator 9807 = new Comparator<Pair<ProcessRecord, Integer>>() { 9808 @Override 9809 public int compare(Pair<ProcessRecord, Integer> object1, 9810 Pair<ProcessRecord, Integer> object2) { 9811 if (object1.first.setAdj != object2.first.setAdj) { 9812 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9813 } 9814 if (object1.second.intValue() != object2.second.intValue()) { 9815 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9816 } 9817 return 0; 9818 } 9819 }; 9820 9821 Collections.sort(list, comparator); 9822 9823 final long curRealtime = SystemClock.elapsedRealtime(); 9824 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9825 final long curUptime = SystemClock.uptimeMillis(); 9826 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9827 9828 for (int i=list.size()-1; i>=0; i--) { 9829 ProcessRecord r = list.get(i).first; 9830 String oomAdj; 9831 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9832 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9833 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9834 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9835 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9836 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9837 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9838 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9839 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9840 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9841 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9842 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9843 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9844 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9845 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9846 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9847 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9848 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9849 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9850 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9851 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9852 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9853 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9854 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9855 } else { 9856 oomAdj = Integer.toString(r.setAdj); 9857 } 9858 String schedGroup; 9859 switch (r.setSchedGroup) { 9860 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9861 schedGroup = "B"; 9862 break; 9863 case Process.THREAD_GROUP_DEFAULT: 9864 schedGroup = "F"; 9865 break; 9866 default: 9867 schedGroup = Integer.toString(r.setSchedGroup); 9868 break; 9869 } 9870 String foreground; 9871 if (r.foregroundActivities) { 9872 foreground = "A"; 9873 } else if (r.foregroundServices) { 9874 foreground = "S"; 9875 } else { 9876 foreground = " "; 9877 } 9878 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 9879 prefix, (r.persistent ? persistentLabel : normalLabel), 9880 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 9881 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 9882 if (r.adjSource != null || r.adjTarget != null) { 9883 pw.print(prefix); 9884 pw.print(" "); 9885 if (r.adjTarget instanceof ComponentName) { 9886 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 9887 } else if (r.adjTarget != null) { 9888 pw.print(r.adjTarget.toString()); 9889 } else { 9890 pw.print("{null}"); 9891 } 9892 pw.print("<="); 9893 if (r.adjSource instanceof ProcessRecord) { 9894 pw.print("Proc{"); 9895 pw.print(((ProcessRecord)r.adjSource).toShortString()); 9896 pw.println("}"); 9897 } else if (r.adjSource != null) { 9898 pw.println(r.adjSource.toString()); 9899 } else { 9900 pw.println("{null}"); 9901 } 9902 } 9903 if (inclDetails) { 9904 pw.print(prefix); 9905 pw.print(" "); 9906 pw.print("oom: max="); pw.print(r.maxAdj); 9907 pw.print(" hidden="); pw.print(r.hiddenAdj); 9908 pw.print(" empty="); pw.print(r.emptyAdj); 9909 pw.print(" curRaw="); pw.print(r.curRawAdj); 9910 pw.print(" setRaw="); pw.print(r.setRawAdj); 9911 pw.print(" cur="); pw.print(r.curAdj); 9912 pw.print(" set="); pw.println(r.setAdj); 9913 pw.print(prefix); 9914 pw.print(" "); 9915 pw.print("keeping="); pw.print(r.keeping); 9916 pw.print(" hidden="); pw.print(r.hidden); 9917 pw.print(" empty="); pw.print(r.empty); 9918 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 9919 9920 if (!r.keeping) { 9921 if (r.lastWakeTime != 0) { 9922 long wtime; 9923 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 9924 synchronized (stats) { 9925 wtime = stats.getProcessWakeTime(r.info.uid, 9926 r.pid, curRealtime); 9927 } 9928 long timeUsed = wtime - r.lastWakeTime; 9929 pw.print(prefix); 9930 pw.print(" "); 9931 pw.print("keep awake over "); 9932 TimeUtils.formatDuration(realtimeSince, pw); 9933 pw.print(" used "); 9934 TimeUtils.formatDuration(timeUsed, pw); 9935 pw.print(" ("); 9936 pw.print((timeUsed*100)/realtimeSince); 9937 pw.println("%)"); 9938 } 9939 if (r.lastCpuTime != 0) { 9940 long timeUsed = r.curCpuTime - r.lastCpuTime; 9941 pw.print(prefix); 9942 pw.print(" "); 9943 pw.print("run cpu over "); 9944 TimeUtils.formatDuration(uptimeSince, pw); 9945 pw.print(" used "); 9946 TimeUtils.formatDuration(timeUsed, pw); 9947 pw.print(" ("); 9948 pw.print((timeUsed*100)/uptimeSince); 9949 pw.println("%)"); 9950 } 9951 } 9952 } 9953 } 9954 return true; 9955 } 9956 9957 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 9958 ArrayList<ProcessRecord> procs; 9959 synchronized (this) { 9960 if (args != null && args.length > start 9961 && args[start].charAt(0) != '-') { 9962 procs = new ArrayList<ProcessRecord>(); 9963 int pid = -1; 9964 try { 9965 pid = Integer.parseInt(args[start]); 9966 } catch (NumberFormatException e) { 9967 9968 } 9969 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9970 ProcessRecord proc = mLruProcesses.get(i); 9971 if (proc.pid == pid) { 9972 procs.add(proc); 9973 } else if (proc.processName.equals(args[start])) { 9974 procs.add(proc); 9975 } 9976 } 9977 if (procs.size() <= 0) { 9978 pw.println("No process found for: " + args[start]); 9979 return null; 9980 } 9981 } else { 9982 procs = new ArrayList<ProcessRecord>(mLruProcesses); 9983 } 9984 } 9985 return procs; 9986 } 9987 9988 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 9989 PrintWriter pw, String[] args) { 9990 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 9991 if (procs == null) { 9992 return; 9993 } 9994 9995 long uptime = SystemClock.uptimeMillis(); 9996 long realtime = SystemClock.elapsedRealtime(); 9997 pw.println("Applications Graphics Acceleration Info:"); 9998 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9999 10000 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10001 ProcessRecord r = procs.get(i); 10002 if (r.thread != null) { 10003 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10004 pw.flush(); 10005 try { 10006 TransferPipe tp = new TransferPipe(); 10007 try { 10008 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10009 tp.go(fd); 10010 } finally { 10011 tp.kill(); 10012 } 10013 } catch (IOException e) { 10014 pw.println("Failure while dumping the app: " + r); 10015 pw.flush(); 10016 } catch (RemoteException e) { 10017 pw.println("Got a RemoteException while dumping the app " + r); 10018 pw.flush(); 10019 } 10020 } 10021 } 10022 } 10023 10024 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10025 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10026 if (procs == null) { 10027 return; 10028 } 10029 10030 pw.println("Applications Database Info:"); 10031 10032 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10033 ProcessRecord r = procs.get(i); 10034 if (r.thread != null) { 10035 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10036 pw.flush(); 10037 try { 10038 TransferPipe tp = new TransferPipe(); 10039 try { 10040 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10041 tp.go(fd); 10042 } finally { 10043 tp.kill(); 10044 } 10045 } catch (IOException e) { 10046 pw.println("Failure while dumping the app: " + r); 10047 pw.flush(); 10048 } catch (RemoteException e) { 10049 pw.println("Got a RemoteException while dumping the app " + r); 10050 pw.flush(); 10051 } 10052 } 10053 } 10054 } 10055 10056 final static class MemItem { 10057 final String label; 10058 final String shortLabel; 10059 final long pss; 10060 final int id; 10061 ArrayList<MemItem> subitems; 10062 10063 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10064 label = _label; 10065 shortLabel = _shortLabel; 10066 pss = _pss; 10067 id = _id; 10068 } 10069 } 10070 10071 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10072 boolean sort) { 10073 if (sort) { 10074 Collections.sort(items, new Comparator<MemItem>() { 10075 @Override 10076 public int compare(MemItem lhs, MemItem rhs) { 10077 if (lhs.pss < rhs.pss) { 10078 return 1; 10079 } else if (lhs.pss > rhs.pss) { 10080 return -1; 10081 } 10082 return 0; 10083 } 10084 }); 10085 } 10086 10087 for (int i=0; i<items.size(); i++) { 10088 MemItem mi = items.get(i); 10089 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10090 if (mi.subitems != null) { 10091 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10092 } 10093 } 10094 } 10095 10096 // These are in KB. 10097 static final long[] DUMP_MEM_BUCKETS = new long[] { 10098 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10099 120*1024, 160*1024, 200*1024, 10100 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10101 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10102 }; 10103 10104 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10105 boolean stackLike) { 10106 int start = label.lastIndexOf('.'); 10107 if (start >= 0) start++; 10108 else start = 0; 10109 int end = label.length(); 10110 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10111 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10112 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10113 out.append(bucket); 10114 out.append(stackLike ? "MB." : "MB "); 10115 out.append(label, start, end); 10116 return; 10117 } 10118 } 10119 out.append(memKB/1024); 10120 out.append(stackLike ? "MB." : "MB "); 10121 out.append(label, start, end); 10122 } 10123 10124 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10125 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10126 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10127 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10128 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10129 }; 10130 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10131 "System", "Persistent", "Foreground", 10132 "Visible", "Perceptible", "Heavy Weight", 10133 "Backup", "A Services", "Home", "Previous", 10134 "B Services", "Background" 10135 }; 10136 10137 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10138 PrintWriter pw, String prefix, String[] args, boolean brief, 10139 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10140 boolean dumpAll = false; 10141 boolean oomOnly = false; 10142 10143 int opti = 0; 10144 while (opti < args.length) { 10145 String opt = args[opti]; 10146 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10147 break; 10148 } 10149 opti++; 10150 if ("-a".equals(opt)) { 10151 dumpAll = true; 10152 } else if ("--oom".equals(opt)) { 10153 oomOnly = true; 10154 } else if ("-h".equals(opt)) { 10155 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10156 pw.println(" -a: include all available information for each process."); 10157 pw.println(" --oom: only show processes organized by oom adj."); 10158 pw.println("If [process] is specified it can be the name or "); 10159 pw.println("pid of a specific process to dump."); 10160 return; 10161 } else { 10162 pw.println("Unknown argument: " + opt + "; use -h for help"); 10163 } 10164 } 10165 10166 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10167 if (procs == null) { 10168 return; 10169 } 10170 10171 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10172 long uptime = SystemClock.uptimeMillis(); 10173 long realtime = SystemClock.elapsedRealtime(); 10174 10175 if (procs.size() == 1 || isCheckinRequest) { 10176 dumpAll = true; 10177 } 10178 10179 if (isCheckinRequest) { 10180 // short checkin version 10181 pw.println(uptime + "," + realtime); 10182 pw.flush(); 10183 } else { 10184 pw.println("Applications Memory Usage (kB):"); 10185 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10186 } 10187 10188 String[] innerArgs = new String[args.length-opti]; 10189 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10190 10191 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10192 long nativePss=0, dalvikPss=0, otherPss=0; 10193 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10194 10195 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10196 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10197 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10198 10199 long totalPss = 0; 10200 10201 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10202 ProcessRecord r = procs.get(i); 10203 if (r.thread != null) { 10204 if (!isCheckinRequest && dumpAll) { 10205 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10206 pw.flush(); 10207 } 10208 Debug.MemoryInfo mi = null; 10209 if (dumpAll) { 10210 try { 10211 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10212 } catch (RemoteException e) { 10213 if (!isCheckinRequest) { 10214 pw.println("Got RemoteException!"); 10215 pw.flush(); 10216 } 10217 } 10218 } else { 10219 mi = new Debug.MemoryInfo(); 10220 Debug.getMemoryInfo(r.pid, mi); 10221 } 10222 10223 if (!isCheckinRequest && mi != null) { 10224 long myTotalPss = mi.getTotalPss(); 10225 totalPss += myTotalPss; 10226 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10227 r.processName, myTotalPss, 0); 10228 procMems.add(pssItem); 10229 10230 nativePss += mi.nativePss; 10231 dalvikPss += mi.dalvikPss; 10232 otherPss += mi.otherPss; 10233 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10234 long mem = mi.getOtherPss(j); 10235 miscPss[j] += mem; 10236 otherPss -= mem; 10237 } 10238 10239 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10240 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10241 || oomIndex == (oomPss.length-1)) { 10242 oomPss[oomIndex] += myTotalPss; 10243 if (oomProcs[oomIndex] == null) { 10244 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10245 } 10246 oomProcs[oomIndex].add(pssItem); 10247 break; 10248 } 10249 } 10250 } 10251 } 10252 } 10253 10254 if (!isCheckinRequest && procs.size() > 1) { 10255 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10256 10257 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10258 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10259 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10260 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10261 String label = Debug.MemoryInfo.getOtherLabel(j); 10262 catMems.add(new MemItem(label, label, miscPss[j], j)); 10263 } 10264 10265 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10266 for (int j=0; j<oomPss.length; j++) { 10267 if (oomPss[j] != 0) { 10268 String label = DUMP_MEM_OOM_LABEL[j]; 10269 MemItem item = new MemItem(label, label, oomPss[j], 10270 DUMP_MEM_OOM_ADJ[j]); 10271 item.subitems = oomProcs[j]; 10272 oomMems.add(item); 10273 } 10274 } 10275 10276 if (outTag != null || outStack != null) { 10277 if (outTag != null) { 10278 appendMemBucket(outTag, totalPss, "total", false); 10279 } 10280 if (outStack != null) { 10281 appendMemBucket(outStack, totalPss, "total", true); 10282 } 10283 boolean firstLine = true; 10284 for (int i=0; i<oomMems.size(); i++) { 10285 MemItem miCat = oomMems.get(i); 10286 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10287 continue; 10288 } 10289 if (miCat.id < ProcessList.SERVICE_ADJ 10290 || miCat.id == ProcessList.HOME_APP_ADJ 10291 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10292 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10293 outTag.append(" / "); 10294 } 10295 if (outStack != null) { 10296 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10297 if (firstLine) { 10298 outStack.append(":"); 10299 firstLine = false; 10300 } 10301 outStack.append("\n\t at "); 10302 } else { 10303 outStack.append("$"); 10304 } 10305 } 10306 for (int j=0; j<miCat.subitems.size(); j++) { 10307 MemItem mi = miCat.subitems.get(j); 10308 if (j > 0) { 10309 if (outTag != null) { 10310 outTag.append(" "); 10311 } 10312 if (outStack != null) { 10313 outStack.append("$"); 10314 } 10315 } 10316 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10317 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10318 } 10319 if (outStack != null) { 10320 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10321 } 10322 } 10323 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10324 outStack.append("("); 10325 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10326 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10327 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10328 outStack.append(":"); 10329 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10330 } 10331 } 10332 outStack.append(")"); 10333 } 10334 } 10335 } 10336 } 10337 10338 if (!brief && !oomOnly) { 10339 pw.println(); 10340 pw.println("Total PSS by process:"); 10341 dumpMemItems(pw, " ", procMems, true); 10342 pw.println(); 10343 } 10344 pw.println("Total PSS by OOM adjustment:"); 10345 dumpMemItems(pw, " ", oomMems, false); 10346 if (!oomOnly) { 10347 PrintWriter out = categoryPw != null ? categoryPw : pw; 10348 out.println(); 10349 out.println("Total PSS by category:"); 10350 dumpMemItems(out, " ", catMems, true); 10351 } 10352 pw.println(); 10353 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10354 final int[] SINGLE_LONG_FORMAT = new int[] { 10355 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10356 }; 10357 long[] longOut = new long[1]; 10358 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10359 SINGLE_LONG_FORMAT, null, longOut, null); 10360 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10361 longOut[0] = 0; 10362 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10363 SINGLE_LONG_FORMAT, null, longOut, null); 10364 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10365 longOut[0] = 0; 10366 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10367 SINGLE_LONG_FORMAT, null, longOut, null); 10368 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10369 longOut[0] = 0; 10370 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10371 SINGLE_LONG_FORMAT, null, longOut, null); 10372 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10373 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10374 pw.print(shared); pw.println(" kB"); 10375 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10376 pw.print(voltile); pw.println(" kB volatile"); 10377 } 10378 } 10379 10380 /** 10381 * Searches array of arguments for the specified string 10382 * @param args array of argument strings 10383 * @param value value to search for 10384 * @return true if the value is contained in the array 10385 */ 10386 private static boolean scanArgs(String[] args, String value) { 10387 if (args != null) { 10388 for (String arg : args) { 10389 if (value.equals(arg)) { 10390 return true; 10391 } 10392 } 10393 } 10394 return false; 10395 } 10396 10397 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10398 ContentProviderRecord cpr, boolean always) { 10399 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10400 10401 if (!inLaunching || always) { 10402 synchronized (cpr) { 10403 cpr.launchingApp = null; 10404 cpr.notifyAll(); 10405 } 10406 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10407 String names[] = cpr.info.authority.split(";"); 10408 for (int j = 0; j < names.length; j++) { 10409 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10410 } 10411 } 10412 10413 for (int i=0; i<cpr.connections.size(); i++) { 10414 ContentProviderConnection conn = cpr.connections.get(i); 10415 if (conn.waiting) { 10416 // If this connection is waiting for the provider, then we don't 10417 // need to mess with its process unless we are always removing 10418 // or for some reason the provider is not currently launching. 10419 if (inLaunching && !always) { 10420 continue; 10421 } 10422 } 10423 ProcessRecord capp = conn.client; 10424 conn.dead = true; 10425 if (conn.stableCount > 0) { 10426 if (!capp.persistent && capp.thread != null 10427 && capp.pid != 0 10428 && capp.pid != MY_PID) { 10429 Slog.i(TAG, "Kill " + capp.processName 10430 + " (pid " + capp.pid + "): provider " + cpr.info.name 10431 + " in dying process " + (proc != null ? proc.processName : "??")); 10432 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10433 capp.processName, capp.setAdj, "dying provider " 10434 + cpr.name.toShortString()); 10435 Process.killProcessQuiet(capp.pid); 10436 } 10437 } else if (capp.thread != null && conn.provider.provider != null) { 10438 try { 10439 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10440 } catch (RemoteException e) { 10441 } 10442 // In the protocol here, we don't expect the client to correctly 10443 // clean up this connection, we'll just remove it. 10444 cpr.connections.remove(i); 10445 conn.client.conProviders.remove(conn); 10446 } 10447 } 10448 10449 if (inLaunching && always) { 10450 mLaunchingProviders.remove(cpr); 10451 } 10452 return inLaunching; 10453 } 10454 10455 /** 10456 * Main code for cleaning up a process when it has gone away. This is 10457 * called both as a result of the process dying, or directly when stopping 10458 * a process when running in single process mode. 10459 */ 10460 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10461 boolean restarting, boolean allowRestart, int index) { 10462 if (index >= 0) { 10463 mLruProcesses.remove(index); 10464 } 10465 10466 mProcessesToGc.remove(app); 10467 10468 // Dismiss any open dialogs. 10469 if (app.crashDialog != null) { 10470 app.crashDialog.dismiss(); 10471 app.crashDialog = null; 10472 } 10473 if (app.anrDialog != null) { 10474 app.anrDialog.dismiss(); 10475 app.anrDialog = null; 10476 } 10477 if (app.waitDialog != null) { 10478 app.waitDialog.dismiss(); 10479 app.waitDialog = null; 10480 } 10481 10482 app.crashing = false; 10483 app.notResponding = false; 10484 10485 app.resetPackageList(); 10486 app.unlinkDeathRecipient(); 10487 app.thread = null; 10488 app.forcingToForeground = null; 10489 app.foregroundServices = false; 10490 app.foregroundActivities = false; 10491 app.hasShownUi = false; 10492 app.hasAboveClient = false; 10493 10494 mServices.killServicesLocked(app, allowRestart); 10495 10496 boolean restart = false; 10497 10498 // Remove published content providers. 10499 if (!app.pubProviders.isEmpty()) { 10500 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10501 while (it.hasNext()) { 10502 ContentProviderRecord cpr = it.next(); 10503 10504 final boolean always = app.bad || !allowRestart; 10505 if (removeDyingProviderLocked(app, cpr, always) || always) { 10506 // We left the provider in the launching list, need to 10507 // restart it. 10508 restart = true; 10509 } 10510 10511 cpr.provider = null; 10512 cpr.proc = null; 10513 } 10514 app.pubProviders.clear(); 10515 } 10516 10517 // Take care of any launching providers waiting for this process. 10518 if (checkAppInLaunchingProvidersLocked(app, false)) { 10519 restart = true; 10520 } 10521 10522 // Unregister from connected content providers. 10523 if (!app.conProviders.isEmpty()) { 10524 for (int i=0; i<app.conProviders.size(); i++) { 10525 ContentProviderConnection conn = app.conProviders.get(i); 10526 conn.provider.connections.remove(conn); 10527 } 10528 app.conProviders.clear(); 10529 } 10530 10531 // At this point there may be remaining entries in mLaunchingProviders 10532 // where we were the only one waiting, so they are no longer of use. 10533 // Look for these and clean up if found. 10534 // XXX Commented out for now. Trying to figure out a way to reproduce 10535 // the actual situation to identify what is actually going on. 10536 if (false) { 10537 for (int i=0; i<mLaunchingProviders.size(); i++) { 10538 ContentProviderRecord cpr = (ContentProviderRecord) 10539 mLaunchingProviders.get(i); 10540 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10541 synchronized (cpr) { 10542 cpr.launchingApp = null; 10543 cpr.notifyAll(); 10544 } 10545 } 10546 } 10547 } 10548 10549 skipCurrentReceiverLocked(app); 10550 10551 // Unregister any receivers. 10552 if (app.receivers.size() > 0) { 10553 Iterator<ReceiverList> it = app.receivers.iterator(); 10554 while (it.hasNext()) { 10555 removeReceiverLocked(it.next()); 10556 } 10557 app.receivers.clear(); 10558 } 10559 10560 // If the app is undergoing backup, tell the backup manager about it 10561 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10562 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10563 try { 10564 IBackupManager bm = IBackupManager.Stub.asInterface( 10565 ServiceManager.getService(Context.BACKUP_SERVICE)); 10566 bm.agentDisconnected(app.info.packageName); 10567 } catch (RemoteException e) { 10568 // can't happen; backup manager is local 10569 } 10570 } 10571 10572 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10573 ProcessChangeItem item = mPendingProcessChanges.get(i); 10574 if (item.pid == app.pid) { 10575 mPendingProcessChanges.remove(i); 10576 mAvailProcessChanges.add(item); 10577 } 10578 } 10579 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10580 10581 // If the caller is restarting this app, then leave it in its 10582 // current lists and let the caller take care of it. 10583 if (restarting) { 10584 return; 10585 } 10586 10587 if (!app.persistent || app.isolated) { 10588 if (DEBUG_PROCESSES) Slog.v(TAG, 10589 "Removing non-persistent process during cleanup: " + app); 10590 mProcessNames.remove(app.processName, app.uid); 10591 mIsolatedProcesses.remove(app.uid); 10592 if (mHeavyWeightProcess == app) { 10593 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10594 mHeavyWeightProcess.userId, 0)); 10595 mHeavyWeightProcess = null; 10596 } 10597 } else if (!app.removed) { 10598 // This app is persistent, so we need to keep its record around. 10599 // If it is not already on the pending app list, add it there 10600 // and start a new process for it. 10601 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10602 mPersistentStartingProcesses.add(app); 10603 restart = true; 10604 } 10605 } 10606 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10607 "Clean-up removing on hold: " + app); 10608 mProcessesOnHold.remove(app); 10609 10610 if (app == mHomeProcess) { 10611 mHomeProcess = null; 10612 } 10613 if (app == mPreviousProcess) { 10614 mPreviousProcess = null; 10615 } 10616 10617 if (restart && !app.isolated) { 10618 // We have components that still need to be running in the 10619 // process, so re-launch it. 10620 mProcessNames.put(app.processName, app.uid, app); 10621 startProcessLocked(app, "restart", app.processName); 10622 } else if (app.pid > 0 && app.pid != MY_PID) { 10623 // Goodbye! 10624 synchronized (mPidsSelfLocked) { 10625 mPidsSelfLocked.remove(app.pid); 10626 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10627 } 10628 app.setPid(0); 10629 } 10630 } 10631 10632 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10633 // Look through the content providers we are waiting to have launched, 10634 // and if any run in this process then either schedule a restart of 10635 // the process or kill the client waiting for it if this process has 10636 // gone bad. 10637 int NL = mLaunchingProviders.size(); 10638 boolean restart = false; 10639 for (int i=0; i<NL; i++) { 10640 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10641 if (cpr.launchingApp == app) { 10642 if (!alwaysBad && !app.bad) { 10643 restart = true; 10644 } else { 10645 removeDyingProviderLocked(app, cpr, true); 10646 // cpr should have been removed from mLaunchingProviders 10647 NL = mLaunchingProviders.size(); 10648 i--; 10649 } 10650 } 10651 } 10652 return restart; 10653 } 10654 10655 // ========================================================= 10656 // SERVICES 10657 // ========================================================= 10658 10659 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10660 int flags) { 10661 enforceNotIsolatedCaller("getServices"); 10662 synchronized (this) { 10663 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10664 } 10665 } 10666 10667 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10668 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10669 synchronized (this) { 10670 return mServices.getRunningServiceControlPanelLocked(name); 10671 } 10672 } 10673 10674 public ComponentName startService(IApplicationThread caller, Intent service, 10675 String resolvedType, int userId) { 10676 enforceNotIsolatedCaller("startService"); 10677 // Refuse possible leaked file descriptors 10678 if (service != null && service.hasFileDescriptors() == true) { 10679 throw new IllegalArgumentException("File descriptors passed in Intent"); 10680 } 10681 10682 if (DEBUG_SERVICE) 10683 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10684 synchronized(this) { 10685 final int callingPid = Binder.getCallingPid(); 10686 final int callingUid = Binder.getCallingUid(); 10687 checkValidCaller(callingUid, userId); 10688 final long origId = Binder.clearCallingIdentity(); 10689 ComponentName res = mServices.startServiceLocked(caller, service, 10690 resolvedType, callingPid, callingUid, userId); 10691 Binder.restoreCallingIdentity(origId); 10692 return res; 10693 } 10694 } 10695 10696 ComponentName startServiceInPackage(int uid, 10697 Intent service, String resolvedType, int userId) { 10698 synchronized(this) { 10699 if (DEBUG_SERVICE) 10700 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10701 final long origId = Binder.clearCallingIdentity(); 10702 ComponentName res = mServices.startServiceLocked(null, service, 10703 resolvedType, -1, uid, userId); 10704 Binder.restoreCallingIdentity(origId); 10705 return res; 10706 } 10707 } 10708 10709 public int stopService(IApplicationThread caller, Intent service, 10710 String resolvedType, int userId) { 10711 enforceNotIsolatedCaller("stopService"); 10712 // Refuse possible leaked file descriptors 10713 if (service != null && service.hasFileDescriptors() == true) { 10714 throw new IllegalArgumentException("File descriptors passed in Intent"); 10715 } 10716 10717 checkValidCaller(Binder.getCallingUid(), userId); 10718 10719 synchronized(this) { 10720 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10721 } 10722 } 10723 10724 public IBinder peekService(Intent service, String resolvedType) { 10725 enforceNotIsolatedCaller("peekService"); 10726 // Refuse possible leaked file descriptors 10727 if (service != null && service.hasFileDescriptors() == true) { 10728 throw new IllegalArgumentException("File descriptors passed in Intent"); 10729 } 10730 synchronized(this) { 10731 return mServices.peekServiceLocked(service, resolvedType); 10732 } 10733 } 10734 10735 public boolean stopServiceToken(ComponentName className, IBinder token, 10736 int startId) { 10737 synchronized(this) { 10738 return mServices.stopServiceTokenLocked(className, token, startId); 10739 } 10740 } 10741 10742 public void setServiceForeground(ComponentName className, IBinder token, 10743 int id, Notification notification, boolean removeNotification) { 10744 synchronized(this) { 10745 mServices.setServiceForegroundLocked(className, token, id, notification, 10746 removeNotification); 10747 } 10748 } 10749 10750 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10751 boolean requireFull, String name, String callerPackage) { 10752 synchronized(this) { 10753 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10754 requireFull, name, callerPackage); 10755 } 10756 } 10757 10758 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10759 boolean requireFull, String name, String callerPackage) { 10760 final int callingUserId = UserHandle.getUserId(callingUid); 10761 if (callingUserId != userId) { 10762 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10763 if ((requireFull || checkComponentPermission( 10764 android.Manifest.permission.INTERACT_ACROSS_USERS, 10765 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10766 && checkComponentPermission( 10767 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10768 callingPid, callingUid, -1, true) 10769 != PackageManager.PERMISSION_GRANTED) { 10770 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10771 // In this case, they would like to just execute as their 10772 // owner user instead of failing. 10773 userId = callingUserId; 10774 } else { 10775 StringBuilder builder = new StringBuilder(128); 10776 builder.append("Permission Denial: "); 10777 builder.append(name); 10778 if (callerPackage != null) { 10779 builder.append(" from "); 10780 builder.append(callerPackage); 10781 } 10782 builder.append(" asks to run as user "); 10783 builder.append(userId); 10784 builder.append(" but is calling from user "); 10785 builder.append(UserHandle.getUserId(callingUid)); 10786 builder.append("; this requires "); 10787 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10788 if (!requireFull) { 10789 builder.append("or"); 10790 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10791 } 10792 String msg = builder.toString(); 10793 Slog.w(TAG, msg); 10794 throw new SecurityException(msg); 10795 } 10796 } 10797 } 10798 if (userId == UserHandle.USER_CURRENT 10799 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10800 userId = mCurrentUserId; 10801 } 10802 if (!allowAll && userId < 0) { 10803 throw new IllegalArgumentException( 10804 "Call does not support special user #" + userId); 10805 } 10806 } 10807 return userId; 10808 } 10809 10810 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10811 String className, int flags) { 10812 boolean result = false; 10813 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10814 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10815 if (ActivityManager.checkUidPermission( 10816 android.Manifest.permission.INTERACT_ACROSS_USERS, 10817 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10818 ComponentName comp = new ComponentName(aInfo.packageName, className); 10819 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10820 + " requests FLAG_SINGLE_USER, but app does not hold " 10821 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10822 Slog.w(TAG, msg); 10823 throw new SecurityException(msg); 10824 } 10825 result = true; 10826 } 10827 } else if (componentProcessName == aInfo.packageName) { 10828 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10829 } else if ("system".equals(componentProcessName)) { 10830 result = true; 10831 } 10832 if (DEBUG_MU) { 10833 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10834 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10835 } 10836 return result; 10837 } 10838 10839 public int bindService(IApplicationThread caller, IBinder token, 10840 Intent service, String resolvedType, 10841 IServiceConnection connection, int flags, int userId) { 10842 enforceNotIsolatedCaller("bindService"); 10843 // Refuse possible leaked file descriptors 10844 if (service != null && service.hasFileDescriptors() == true) { 10845 throw new IllegalArgumentException("File descriptors passed in Intent"); 10846 } 10847 10848 synchronized(this) { 10849 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10850 connection, flags, userId); 10851 } 10852 } 10853 10854 public boolean unbindService(IServiceConnection connection) { 10855 synchronized (this) { 10856 return mServices.unbindServiceLocked(connection); 10857 } 10858 } 10859 10860 public void publishService(IBinder token, Intent intent, IBinder service) { 10861 // Refuse possible leaked file descriptors 10862 if (intent != null && intent.hasFileDescriptors() == true) { 10863 throw new IllegalArgumentException("File descriptors passed in Intent"); 10864 } 10865 10866 synchronized(this) { 10867 if (!(token instanceof ServiceRecord)) { 10868 throw new IllegalArgumentException("Invalid service token"); 10869 } 10870 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 10871 } 10872 } 10873 10874 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10875 // Refuse possible leaked file descriptors 10876 if (intent != null && intent.hasFileDescriptors() == true) { 10877 throw new IllegalArgumentException("File descriptors passed in Intent"); 10878 } 10879 10880 synchronized(this) { 10881 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 10882 } 10883 } 10884 10885 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 10886 synchronized(this) { 10887 if (!(token instanceof ServiceRecord)) { 10888 throw new IllegalArgumentException("Invalid service token"); 10889 } 10890 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 10891 } 10892 } 10893 10894 // ========================================================= 10895 // BACKUP AND RESTORE 10896 // ========================================================= 10897 10898 // Cause the target app to be launched if necessary and its backup agent 10899 // instantiated. The backup agent will invoke backupAgentCreated() on the 10900 // activity manager to announce its creation. 10901 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10902 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10903 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10904 10905 synchronized(this) { 10906 // !!! TODO: currently no check here that we're already bound 10907 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10908 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10909 synchronized (stats) { 10910 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10911 } 10912 10913 // Backup agent is now in use, its package can't be stopped. 10914 try { 10915 AppGlobals.getPackageManager().setPackageStoppedState( 10916 app.packageName, false, UserHandle.getUserId(app.uid)); 10917 } catch (RemoteException e) { 10918 } catch (IllegalArgumentException e) { 10919 Slog.w(TAG, "Failed trying to unstop package " 10920 + app.packageName + ": " + e); 10921 } 10922 10923 BackupRecord r = new BackupRecord(ss, app, backupMode); 10924 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 10925 ? new ComponentName(app.packageName, app.backupAgentName) 10926 : new ComponentName("android", "FullBackupAgent"); 10927 // startProcessLocked() returns existing proc's record if it's already running 10928 ProcessRecord proc = startProcessLocked(app.processName, app, 10929 false, 0, "backup", hostingName, false, false); 10930 if (proc == null) { 10931 Slog.e(TAG, "Unable to start backup agent process " + r); 10932 return false; 10933 } 10934 10935 r.app = proc; 10936 mBackupTarget = r; 10937 mBackupAppName = app.packageName; 10938 10939 // Try not to kill the process during backup 10940 updateOomAdjLocked(proc); 10941 10942 // If the process is already attached, schedule the creation of the backup agent now. 10943 // If it is not yet live, this will be done when it attaches to the framework. 10944 if (proc.thread != null) { 10945 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 10946 try { 10947 proc.thread.scheduleCreateBackupAgent(app, 10948 compatibilityInfoForPackageLocked(app), backupMode); 10949 } catch (RemoteException e) { 10950 // Will time out on the backup manager side 10951 } 10952 } else { 10953 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 10954 } 10955 // Invariants: at this point, the target app process exists and the application 10956 // is either already running or in the process of coming up. mBackupTarget and 10957 // mBackupAppName describe the app, so that when it binds back to the AM we 10958 // know that it's scheduled for a backup-agent operation. 10959 } 10960 10961 return true; 10962 } 10963 10964 // A backup agent has just come up 10965 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10966 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 10967 + " = " + agent); 10968 10969 synchronized(this) { 10970 if (!agentPackageName.equals(mBackupAppName)) { 10971 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10972 return; 10973 } 10974 } 10975 10976 long oldIdent = Binder.clearCallingIdentity(); 10977 try { 10978 IBackupManager bm = IBackupManager.Stub.asInterface( 10979 ServiceManager.getService(Context.BACKUP_SERVICE)); 10980 bm.agentConnected(agentPackageName, agent); 10981 } catch (RemoteException e) { 10982 // can't happen; the backup manager service is local 10983 } catch (Exception e) { 10984 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10985 e.printStackTrace(); 10986 } finally { 10987 Binder.restoreCallingIdentity(oldIdent); 10988 } 10989 } 10990 10991 // done with this agent 10992 public void unbindBackupAgent(ApplicationInfo appInfo) { 10993 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 10994 if (appInfo == null) { 10995 Slog.w(TAG, "unbind backup agent for null app"); 10996 return; 10997 } 10998 10999 synchronized(this) { 11000 if (mBackupAppName == null) { 11001 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11002 return; 11003 } 11004 11005 if (!mBackupAppName.equals(appInfo.packageName)) { 11006 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11007 return; 11008 } 11009 11010 ProcessRecord proc = mBackupTarget.app; 11011 mBackupTarget = null; 11012 mBackupAppName = null; 11013 11014 // Not backing this app up any more; reset its OOM adjustment 11015 updateOomAdjLocked(proc); 11016 11017 // If the app crashed during backup, 'thread' will be null here 11018 if (proc.thread != null) { 11019 try { 11020 proc.thread.scheduleDestroyBackupAgent(appInfo, 11021 compatibilityInfoForPackageLocked(appInfo)); 11022 } catch (Exception e) { 11023 Slog.e(TAG, "Exception when unbinding backup agent:"); 11024 e.printStackTrace(); 11025 } 11026 } 11027 } 11028 } 11029 // ========================================================= 11030 // BROADCASTS 11031 // ========================================================= 11032 11033 private final List getStickiesLocked(String action, IntentFilter filter, 11034 List cur, int userId) { 11035 final ContentResolver resolver = mContext.getContentResolver(); 11036 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11037 if (stickies == null) { 11038 return cur; 11039 } 11040 final ArrayList<Intent> list = stickies.get(action); 11041 if (list == null) { 11042 return cur; 11043 } 11044 int N = list.size(); 11045 for (int i=0; i<N; i++) { 11046 Intent intent = list.get(i); 11047 if (filter.match(resolver, intent, true, TAG) >= 0) { 11048 if (cur == null) { 11049 cur = new ArrayList<Intent>(); 11050 } 11051 cur.add(intent); 11052 } 11053 } 11054 return cur; 11055 } 11056 11057 boolean isPendingBroadcastProcessLocked(int pid) { 11058 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11059 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11060 } 11061 11062 void skipPendingBroadcastLocked(int pid) { 11063 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11064 for (BroadcastQueue queue : mBroadcastQueues) { 11065 queue.skipPendingBroadcastLocked(pid); 11066 } 11067 } 11068 11069 // The app just attached; send any pending broadcasts that it should receive 11070 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11071 boolean didSomething = false; 11072 for (BroadcastQueue queue : mBroadcastQueues) { 11073 didSomething |= queue.sendPendingBroadcastsLocked(app); 11074 } 11075 return didSomething; 11076 } 11077 11078 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11079 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11080 enforceNotIsolatedCaller("registerReceiver"); 11081 int callingUid; 11082 int callingPid; 11083 synchronized(this) { 11084 ProcessRecord callerApp = null; 11085 if (caller != null) { 11086 callerApp = getRecordForAppLocked(caller); 11087 if (callerApp == null) { 11088 throw new SecurityException( 11089 "Unable to find app for caller " + caller 11090 + " (pid=" + Binder.getCallingPid() 11091 + ") when registering receiver " + receiver); 11092 } 11093 if (callerApp.info.uid != Process.SYSTEM_UID && 11094 !callerApp.pkgList.contains(callerPackage)) { 11095 throw new SecurityException("Given caller package " + callerPackage 11096 + " is not running in process " + callerApp); 11097 } 11098 callingUid = callerApp.info.uid; 11099 callingPid = callerApp.pid; 11100 } else { 11101 callerPackage = null; 11102 callingUid = Binder.getCallingUid(); 11103 callingPid = Binder.getCallingPid(); 11104 } 11105 11106 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11107 true, true, "registerReceiver", callerPackage); 11108 11109 List allSticky = null; 11110 11111 // Look for any matching sticky broadcasts... 11112 Iterator actions = filter.actionsIterator(); 11113 if (actions != null) { 11114 while (actions.hasNext()) { 11115 String action = (String)actions.next(); 11116 allSticky = getStickiesLocked(action, filter, allSticky, 11117 UserHandle.USER_ALL); 11118 allSticky = getStickiesLocked(action, filter, allSticky, 11119 UserHandle.getUserId(callingUid)); 11120 } 11121 } else { 11122 allSticky = getStickiesLocked(null, filter, allSticky, 11123 UserHandle.USER_ALL); 11124 allSticky = getStickiesLocked(null, filter, allSticky, 11125 UserHandle.getUserId(callingUid)); 11126 } 11127 11128 // The first sticky in the list is returned directly back to 11129 // the client. 11130 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11131 11132 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11133 + ": " + sticky); 11134 11135 if (receiver == null) { 11136 return sticky; 11137 } 11138 11139 ReceiverList rl 11140 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11141 if (rl == null) { 11142 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11143 userId, receiver); 11144 if (rl.app != null) { 11145 rl.app.receivers.add(rl); 11146 } else { 11147 try { 11148 receiver.asBinder().linkToDeath(rl, 0); 11149 } catch (RemoteException e) { 11150 return sticky; 11151 } 11152 rl.linkedToDeath = true; 11153 } 11154 mRegisteredReceivers.put(receiver.asBinder(), rl); 11155 } else if (rl.uid != callingUid) { 11156 throw new IllegalArgumentException( 11157 "Receiver requested to register for uid " + callingUid 11158 + " was previously registered for uid " + rl.uid); 11159 } else if (rl.pid != callingPid) { 11160 throw new IllegalArgumentException( 11161 "Receiver requested to register for pid " + callingPid 11162 + " was previously registered for pid " + rl.pid); 11163 } else if (rl.userId != userId) { 11164 throw new IllegalArgumentException( 11165 "Receiver requested to register for user " + userId 11166 + " was previously registered for user " + rl.userId); 11167 } 11168 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11169 permission, callingUid, userId); 11170 rl.add(bf); 11171 if (!bf.debugCheck()) { 11172 Slog.w(TAG, "==> For Dynamic broadast"); 11173 } 11174 mReceiverResolver.addFilter(bf); 11175 11176 // Enqueue broadcasts for all existing stickies that match 11177 // this filter. 11178 if (allSticky != null) { 11179 ArrayList receivers = new ArrayList(); 11180 receivers.add(bf); 11181 11182 int N = allSticky.size(); 11183 for (int i=0; i<N; i++) { 11184 Intent intent = (Intent)allSticky.get(i); 11185 BroadcastQueue queue = broadcastQueueForIntent(intent); 11186 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11187 null, -1, -1, null, receivers, null, 0, null, null, 11188 false, true, true, -1); 11189 queue.enqueueParallelBroadcastLocked(r); 11190 queue.scheduleBroadcastsLocked(); 11191 } 11192 } 11193 11194 return sticky; 11195 } 11196 } 11197 11198 public void unregisterReceiver(IIntentReceiver receiver) { 11199 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11200 11201 final long origId = Binder.clearCallingIdentity(); 11202 try { 11203 boolean doTrim = false; 11204 11205 synchronized(this) { 11206 ReceiverList rl 11207 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11208 if (rl != null) { 11209 if (rl.curBroadcast != null) { 11210 BroadcastRecord r = rl.curBroadcast; 11211 final boolean doNext = finishReceiverLocked( 11212 receiver.asBinder(), r.resultCode, r.resultData, 11213 r.resultExtras, r.resultAbort, true); 11214 if (doNext) { 11215 doTrim = true; 11216 r.queue.processNextBroadcast(false); 11217 } 11218 } 11219 11220 if (rl.app != null) { 11221 rl.app.receivers.remove(rl); 11222 } 11223 removeReceiverLocked(rl); 11224 if (rl.linkedToDeath) { 11225 rl.linkedToDeath = false; 11226 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11227 } 11228 } 11229 } 11230 11231 // If we actually concluded any broadcasts, we might now be able 11232 // to trim the recipients' apps from our working set 11233 if (doTrim) { 11234 trimApplications(); 11235 return; 11236 } 11237 11238 } finally { 11239 Binder.restoreCallingIdentity(origId); 11240 } 11241 } 11242 11243 void removeReceiverLocked(ReceiverList rl) { 11244 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11245 int N = rl.size(); 11246 for (int i=0; i<N; i++) { 11247 mReceiverResolver.removeFilter(rl.get(i)); 11248 } 11249 } 11250 11251 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11252 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11253 ProcessRecord r = mLruProcesses.get(i); 11254 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11255 try { 11256 r.thread.dispatchPackageBroadcast(cmd, packages); 11257 } catch (RemoteException ex) { 11258 } 11259 } 11260 } 11261 } 11262 11263 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11264 int[] users) { 11265 List<ResolveInfo> receivers = null; 11266 try { 11267 HashSet<ComponentName> singleUserReceivers = null; 11268 boolean scannedFirstReceivers = false; 11269 for (int user : users) { 11270 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11271 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11272 if (newReceivers != null && newReceivers.size() == 0) { 11273 newReceivers = null; 11274 } 11275 if (receivers == null) { 11276 receivers = newReceivers; 11277 } else if (newReceivers != null) { 11278 // We need to concatenate the additional receivers 11279 // found with what we have do far. This would be easy, 11280 // but we also need to de-dup any receivers that are 11281 // singleUser. 11282 if (!scannedFirstReceivers) { 11283 // Collect any single user receivers we had already retrieved. 11284 scannedFirstReceivers = true; 11285 for (int i=0; i<receivers.size(); i++) { 11286 ResolveInfo ri = receivers.get(i); 11287 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11288 ComponentName cn = new ComponentName( 11289 ri.activityInfo.packageName, ri.activityInfo.name); 11290 if (singleUserReceivers == null) { 11291 singleUserReceivers = new HashSet<ComponentName>(); 11292 } 11293 singleUserReceivers.add(cn); 11294 } 11295 } 11296 } 11297 // Add the new results to the existing results, tracking 11298 // and de-dupping single user receivers. 11299 for (int i=0; i<newReceivers.size(); i++) { 11300 ResolveInfo ri = receivers.get(i); 11301 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11302 ComponentName cn = new ComponentName( 11303 ri.activityInfo.packageName, ri.activityInfo.name); 11304 if (singleUserReceivers == null) { 11305 singleUserReceivers = new HashSet<ComponentName>(); 11306 } 11307 if (!singleUserReceivers.contains(cn)) { 11308 singleUserReceivers.add(cn); 11309 receivers.add(ri); 11310 } 11311 } else { 11312 receivers.add(ri); 11313 } 11314 } 11315 } 11316 } 11317 } catch (RemoteException ex) { 11318 // pm is in same process, this will never happen. 11319 } 11320 return receivers; 11321 } 11322 11323 private final int broadcastIntentLocked(ProcessRecord callerApp, 11324 String callerPackage, Intent intent, String resolvedType, 11325 IIntentReceiver resultTo, int resultCode, String resultData, 11326 Bundle map, String requiredPermission, 11327 boolean ordered, boolean sticky, int callingPid, int callingUid, 11328 int userId) { 11329 intent = new Intent(intent); 11330 11331 // By default broadcasts do not go to stopped apps. 11332 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11333 11334 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11335 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11336 + " ordered=" + ordered + " userid=" + userId); 11337 if ((resultTo != null) && !ordered) { 11338 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11339 } 11340 11341 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11342 true, false, "broadcast", callerPackage); 11343 11344 // Make sure that the user who is receiving this broadcast is started 11345 // If not, we will just skip it. 11346 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11347 Slog.w(TAG, "Skipping broadcast of " + intent 11348 + ": user " + userId + " is stopped"); 11349 return ActivityManager.BROADCAST_SUCCESS; 11350 } 11351 11352 /* 11353 * Prevent non-system code (defined here to be non-persistent 11354 * processes) from sending protected broadcasts. 11355 */ 11356 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11357 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11358 callingUid == 0) { 11359 // Always okay. 11360 } else if (callerApp == null || !callerApp.persistent) { 11361 try { 11362 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11363 intent.getAction())) { 11364 String msg = "Permission Denial: not allowed to send broadcast " 11365 + intent.getAction() + " from pid=" 11366 + callingPid + ", uid=" + callingUid; 11367 Slog.w(TAG, msg); 11368 throw new SecurityException(msg); 11369 } 11370 } catch (RemoteException e) { 11371 Slog.w(TAG, "Remote exception", e); 11372 return ActivityManager.BROADCAST_SUCCESS; 11373 } 11374 } 11375 11376 // Handle special intents: if this broadcast is from the package 11377 // manager about a package being removed, we need to remove all of 11378 // its activities from the history stack. 11379 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11380 intent.getAction()); 11381 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11382 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11383 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11384 || uidRemoved) { 11385 if (checkComponentPermission( 11386 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11387 callingPid, callingUid, -1, true) 11388 == PackageManager.PERMISSION_GRANTED) { 11389 if (uidRemoved) { 11390 final Bundle intentExtras = intent.getExtras(); 11391 final int uid = intentExtras != null 11392 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11393 if (uid >= 0) { 11394 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11395 synchronized (bs) { 11396 bs.removeUidStatsLocked(uid); 11397 } 11398 } 11399 } else { 11400 // If resources are unavailable just force stop all 11401 // those packages and flush the attribute cache as well. 11402 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11403 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11404 if (list != null && (list.length > 0)) { 11405 for (String pkg : list) { 11406 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11407 } 11408 sendPackageBroadcastLocked( 11409 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11410 } 11411 } else { 11412 Uri data = intent.getData(); 11413 String ssp; 11414 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11415 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11416 forceStopPackageLocked(ssp, 11417 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11418 false, userId); 11419 } 11420 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11421 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11422 new String[] {ssp}, userId); 11423 } 11424 } 11425 } 11426 } 11427 } else { 11428 String msg = "Permission Denial: " + intent.getAction() 11429 + " broadcast from " + callerPackage + " (pid=" + callingPid 11430 + ", uid=" + callingUid + ")" 11431 + " requires " 11432 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11433 Slog.w(TAG, msg); 11434 throw new SecurityException(msg); 11435 } 11436 11437 // Special case for adding a package: by default turn on compatibility 11438 // mode. 11439 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11440 Uri data = intent.getData(); 11441 String ssp; 11442 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11443 mCompatModePackages.handlePackageAddedLocked(ssp, 11444 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11445 } 11446 } 11447 11448 /* 11449 * If this is the time zone changed action, queue up a message that will reset the timezone 11450 * of all currently running processes. This message will get queued up before the broadcast 11451 * happens. 11452 */ 11453 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11454 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11455 } 11456 11457 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11458 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11459 } 11460 11461 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11462 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11463 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11464 } 11465 11466 // Add to the sticky list if requested. 11467 if (sticky) { 11468 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11469 callingPid, callingUid) 11470 != PackageManager.PERMISSION_GRANTED) { 11471 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11472 + callingPid + ", uid=" + callingUid 11473 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11474 Slog.w(TAG, msg); 11475 throw new SecurityException(msg); 11476 } 11477 if (requiredPermission != null) { 11478 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11479 + " and enforce permission " + requiredPermission); 11480 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11481 } 11482 if (intent.getComponent() != null) { 11483 throw new SecurityException( 11484 "Sticky broadcasts can't target a specific component"); 11485 } 11486 // We use userId directly here, since the "all" target is maintained 11487 // as a separate set of sticky broadcasts. 11488 if (userId != UserHandle.USER_ALL) { 11489 // But first, if this is not a broadcast to all users, then 11490 // make sure it doesn't conflict with an existing broadcast to 11491 // all users. 11492 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11493 UserHandle.USER_ALL); 11494 if (stickies != null) { 11495 ArrayList<Intent> list = stickies.get(intent.getAction()); 11496 if (list != null) { 11497 int N = list.size(); 11498 int i; 11499 for (i=0; i<N; i++) { 11500 if (intent.filterEquals(list.get(i))) { 11501 throw new IllegalArgumentException( 11502 "Sticky broadcast " + intent + " for user " 11503 + userId + " conflicts with existing global broadcast"); 11504 } 11505 } 11506 } 11507 } 11508 } 11509 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11510 if (stickies == null) { 11511 stickies = new HashMap<String, ArrayList<Intent>>(); 11512 mStickyBroadcasts.put(userId, stickies); 11513 } 11514 ArrayList<Intent> list = stickies.get(intent.getAction()); 11515 if (list == null) { 11516 list = new ArrayList<Intent>(); 11517 stickies.put(intent.getAction(), list); 11518 } 11519 int N = list.size(); 11520 int i; 11521 for (i=0; i<N; i++) { 11522 if (intent.filterEquals(list.get(i))) { 11523 // This sticky already exists, replace it. 11524 list.set(i, new Intent(intent)); 11525 break; 11526 } 11527 } 11528 if (i >= N) { 11529 list.add(new Intent(intent)); 11530 } 11531 } 11532 11533 int[] users; 11534 if (userId == UserHandle.USER_ALL) { 11535 // Caller wants broadcast to go to all started users. 11536 users = new int[mStartedUsers.size()]; 11537 for (int i=0; i<mStartedUsers.size(); i++) { 11538 users[i] = mStartedUsers.keyAt(i); 11539 } 11540 } else { 11541 // Caller wants broadcast to go to one specific user. 11542 users = new int[] {userId}; 11543 } 11544 11545 // Figure out who all will receive this broadcast. 11546 List receivers = null; 11547 List<BroadcastFilter> registeredReceivers = null; 11548 // Need to resolve the intent to interested receivers... 11549 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11550 == 0) { 11551 receivers = collectReceiverComponents(intent, resolvedType, users); 11552 } 11553 if (intent.getComponent() == null) { 11554 registeredReceivers = mReceiverResolver.queryIntent(intent, 11555 resolvedType, false, userId); 11556 } 11557 11558 final boolean replacePending = 11559 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11560 11561 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11562 + " replacePending=" + replacePending); 11563 11564 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11565 if (!ordered && NR > 0) { 11566 // If we are not serializing this broadcast, then send the 11567 // registered receivers separately so they don't wait for the 11568 // components to be launched. 11569 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11570 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11571 callerPackage, callingPid, callingUid, requiredPermission, 11572 registeredReceivers, resultTo, resultCode, resultData, map, 11573 ordered, sticky, false, userId); 11574 if (DEBUG_BROADCAST) Slog.v( 11575 TAG, "Enqueueing parallel broadcast " + r); 11576 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11577 if (!replaced) { 11578 queue.enqueueParallelBroadcastLocked(r); 11579 queue.scheduleBroadcastsLocked(); 11580 } 11581 registeredReceivers = null; 11582 NR = 0; 11583 } 11584 11585 // Merge into one list. 11586 int ir = 0; 11587 if (receivers != null) { 11588 // A special case for PACKAGE_ADDED: do not allow the package 11589 // being added to see this broadcast. This prevents them from 11590 // using this as a back door to get run as soon as they are 11591 // installed. Maybe in the future we want to have a special install 11592 // broadcast or such for apps, but we'd like to deliberately make 11593 // this decision. 11594 String skipPackages[] = null; 11595 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11596 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11597 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11598 Uri data = intent.getData(); 11599 if (data != null) { 11600 String pkgName = data.getSchemeSpecificPart(); 11601 if (pkgName != null) { 11602 skipPackages = new String[] { pkgName }; 11603 } 11604 } 11605 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11606 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11607 } 11608 if (skipPackages != null && (skipPackages.length > 0)) { 11609 for (String skipPackage : skipPackages) { 11610 if (skipPackage != null) { 11611 int NT = receivers.size(); 11612 for (int it=0; it<NT; it++) { 11613 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11614 if (curt.activityInfo.packageName.equals(skipPackage)) { 11615 receivers.remove(it); 11616 it--; 11617 NT--; 11618 } 11619 } 11620 } 11621 } 11622 } 11623 11624 int NT = receivers != null ? receivers.size() : 0; 11625 int it = 0; 11626 ResolveInfo curt = null; 11627 BroadcastFilter curr = null; 11628 while (it < NT && ir < NR) { 11629 if (curt == null) { 11630 curt = (ResolveInfo)receivers.get(it); 11631 } 11632 if (curr == null) { 11633 curr = registeredReceivers.get(ir); 11634 } 11635 if (curr.getPriority() >= curt.priority) { 11636 // Insert this broadcast record into the final list. 11637 receivers.add(it, curr); 11638 ir++; 11639 curr = null; 11640 it++; 11641 NT++; 11642 } else { 11643 // Skip to the next ResolveInfo in the final list. 11644 it++; 11645 curt = null; 11646 } 11647 } 11648 } 11649 while (ir < NR) { 11650 if (receivers == null) { 11651 receivers = new ArrayList(); 11652 } 11653 receivers.add(registeredReceivers.get(ir)); 11654 ir++; 11655 } 11656 11657 if ((receivers != null && receivers.size() > 0) 11658 || resultTo != null) { 11659 BroadcastQueue queue = broadcastQueueForIntent(intent); 11660 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11661 callerPackage, callingPid, callingUid, requiredPermission, 11662 receivers, resultTo, resultCode, resultData, map, ordered, 11663 sticky, false, userId); 11664 if (DEBUG_BROADCAST) Slog.v( 11665 TAG, "Enqueueing ordered broadcast " + r 11666 + ": prev had " + queue.mOrderedBroadcasts.size()); 11667 if (DEBUG_BROADCAST) { 11668 int seq = r.intent.getIntExtra("seq", -1); 11669 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11670 } 11671 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11672 if (!replaced) { 11673 queue.enqueueOrderedBroadcastLocked(r); 11674 queue.scheduleBroadcastsLocked(); 11675 } 11676 } 11677 11678 return ActivityManager.BROADCAST_SUCCESS; 11679 } 11680 11681 final Intent verifyBroadcastLocked(Intent intent) { 11682 // Refuse possible leaked file descriptors 11683 if (intent != null && intent.hasFileDescriptors() == true) { 11684 throw new IllegalArgumentException("File descriptors passed in Intent"); 11685 } 11686 11687 int flags = intent.getFlags(); 11688 11689 if (!mProcessesReady) { 11690 // if the caller really truly claims to know what they're doing, go 11691 // ahead and allow the broadcast without launching any receivers 11692 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11693 intent = new Intent(intent); 11694 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11695 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11696 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11697 + " before boot completion"); 11698 throw new IllegalStateException("Cannot broadcast before boot completed"); 11699 } 11700 } 11701 11702 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11703 throw new IllegalArgumentException( 11704 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11705 } 11706 11707 return intent; 11708 } 11709 11710 public final int broadcastIntent(IApplicationThread caller, 11711 Intent intent, String resolvedType, IIntentReceiver resultTo, 11712 int resultCode, String resultData, Bundle map, 11713 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11714 enforceNotIsolatedCaller("broadcastIntent"); 11715 synchronized(this) { 11716 intent = verifyBroadcastLocked(intent); 11717 11718 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11719 final int callingPid = Binder.getCallingPid(); 11720 final int callingUid = Binder.getCallingUid(); 11721 final long origId = Binder.clearCallingIdentity(); 11722 int res = broadcastIntentLocked(callerApp, 11723 callerApp != null ? callerApp.info.packageName : null, 11724 intent, resolvedType, resultTo, 11725 resultCode, resultData, map, requiredPermission, serialized, sticky, 11726 callingPid, callingUid, userId); 11727 Binder.restoreCallingIdentity(origId); 11728 return res; 11729 } 11730 } 11731 11732 int broadcastIntentInPackage(String packageName, int uid, 11733 Intent intent, String resolvedType, IIntentReceiver resultTo, 11734 int resultCode, String resultData, Bundle map, 11735 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11736 synchronized(this) { 11737 intent = verifyBroadcastLocked(intent); 11738 11739 final long origId = Binder.clearCallingIdentity(); 11740 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11741 resultTo, resultCode, resultData, map, requiredPermission, 11742 serialized, sticky, -1, uid, userId); 11743 Binder.restoreCallingIdentity(origId); 11744 return res; 11745 } 11746 } 11747 11748 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 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 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11755 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11756 11757 synchronized(this) { 11758 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11759 != PackageManager.PERMISSION_GRANTED) { 11760 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11761 + Binder.getCallingPid() 11762 + ", uid=" + Binder.getCallingUid() 11763 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11764 Slog.w(TAG, msg); 11765 throw new SecurityException(msg); 11766 } 11767 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11768 if (stickies != null) { 11769 ArrayList<Intent> list = stickies.get(intent.getAction()); 11770 if (list != null) { 11771 int N = list.size(); 11772 int i; 11773 for (i=0; i<N; i++) { 11774 if (intent.filterEquals(list.get(i))) { 11775 list.remove(i); 11776 break; 11777 } 11778 } 11779 if (list.size() <= 0) { 11780 stickies.remove(intent.getAction()); 11781 } 11782 } 11783 if (stickies.size() <= 0) { 11784 mStickyBroadcasts.remove(userId); 11785 } 11786 } 11787 } 11788 } 11789 11790 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11791 String resultData, Bundle resultExtras, boolean resultAbort, 11792 boolean explicit) { 11793 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11794 if (r == null) { 11795 Slog.w(TAG, "finishReceiver called but not found on queue"); 11796 return false; 11797 } 11798 11799 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11800 explicit); 11801 } 11802 11803 public void finishReceiver(IBinder who, int resultCode, String resultData, 11804 Bundle resultExtras, boolean resultAbort) { 11805 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11806 11807 // Refuse possible leaked file descriptors 11808 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11809 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11810 } 11811 11812 final long origId = Binder.clearCallingIdentity(); 11813 try { 11814 boolean doNext = false; 11815 BroadcastRecord r = null; 11816 11817 synchronized(this) { 11818 r = broadcastRecordForReceiverLocked(who); 11819 if (r != null) { 11820 doNext = r.queue.finishReceiverLocked(r, resultCode, 11821 resultData, resultExtras, resultAbort, true); 11822 } 11823 } 11824 11825 if (doNext) { 11826 r.queue.processNextBroadcast(false); 11827 } 11828 trimApplications(); 11829 } finally { 11830 Binder.restoreCallingIdentity(origId); 11831 } 11832 } 11833 11834 // ========================================================= 11835 // INSTRUMENTATION 11836 // ========================================================= 11837 11838 public boolean startInstrumentation(ComponentName className, 11839 String profileFile, int flags, Bundle arguments, 11840 IInstrumentationWatcher watcher) { 11841 enforceNotIsolatedCaller("startInstrumentation"); 11842 // Refuse possible leaked file descriptors 11843 if (arguments != null && arguments.hasFileDescriptors()) { 11844 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11845 } 11846 11847 synchronized(this) { 11848 InstrumentationInfo ii = null; 11849 ApplicationInfo ai = null; 11850 try { 11851 ii = mContext.getPackageManager().getInstrumentationInfo( 11852 className, STOCK_PM_FLAGS); 11853 ai = mContext.getPackageManager().getApplicationInfo( 11854 ii.targetPackage, STOCK_PM_FLAGS); 11855 } catch (PackageManager.NameNotFoundException e) { 11856 } 11857 if (ii == null) { 11858 reportStartInstrumentationFailure(watcher, className, 11859 "Unable to find instrumentation info for: " + className); 11860 return false; 11861 } 11862 if (ai == null) { 11863 reportStartInstrumentationFailure(watcher, className, 11864 "Unable to find instrumentation target package: " + ii.targetPackage); 11865 return false; 11866 } 11867 11868 int match = mContext.getPackageManager().checkSignatures( 11869 ii.targetPackage, ii.packageName); 11870 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11871 String msg = "Permission Denial: starting instrumentation " 11872 + className + " from pid=" 11873 + Binder.getCallingPid() 11874 + ", uid=" + Binder.getCallingPid() 11875 + " not allowed because package " + ii.packageName 11876 + " does not have a signature matching the target " 11877 + ii.targetPackage; 11878 reportStartInstrumentationFailure(watcher, className, msg); 11879 throw new SecurityException(msg); 11880 } 11881 11882 int userId = UserHandle.getCallingUserId(); 11883 final long origId = Binder.clearCallingIdentity(); 11884 // Instrumentation can kill and relaunch even persistent processes 11885 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 11886 ProcessRecord app = addAppLocked(ai, false); 11887 app.instrumentationClass = className; 11888 app.instrumentationInfo = ai; 11889 app.instrumentationProfileFile = profileFile; 11890 app.instrumentationArguments = arguments; 11891 app.instrumentationWatcher = watcher; 11892 app.instrumentationResultClass = className; 11893 Binder.restoreCallingIdentity(origId); 11894 } 11895 11896 return true; 11897 } 11898 11899 /** 11900 * Report errors that occur while attempting to start Instrumentation. Always writes the 11901 * error to the logs, but if somebody is watching, send the report there too. This enables 11902 * the "am" command to report errors with more information. 11903 * 11904 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11905 * @param cn The component name of the instrumentation. 11906 * @param report The error report. 11907 */ 11908 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11909 ComponentName cn, String report) { 11910 Slog.w(TAG, report); 11911 try { 11912 if (watcher != null) { 11913 Bundle results = new Bundle(); 11914 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11915 results.putString("Error", report); 11916 watcher.instrumentationStatus(cn, -1, results); 11917 } 11918 } catch (RemoteException e) { 11919 Slog.w(TAG, e); 11920 } 11921 } 11922 11923 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11924 if (app.instrumentationWatcher != null) { 11925 try { 11926 // NOTE: IInstrumentationWatcher *must* be oneway here 11927 app.instrumentationWatcher.instrumentationFinished( 11928 app.instrumentationClass, 11929 resultCode, 11930 results); 11931 } catch (RemoteException e) { 11932 } 11933 } 11934 app.instrumentationWatcher = null; 11935 app.instrumentationClass = null; 11936 app.instrumentationInfo = null; 11937 app.instrumentationProfileFile = null; 11938 app.instrumentationArguments = null; 11939 11940 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 11941 } 11942 11943 public void finishInstrumentation(IApplicationThread target, 11944 int resultCode, Bundle results) { 11945 int userId = UserHandle.getCallingUserId(); 11946 // Refuse possible leaked file descriptors 11947 if (results != null && results.hasFileDescriptors()) { 11948 throw new IllegalArgumentException("File descriptors passed in Intent"); 11949 } 11950 11951 synchronized(this) { 11952 ProcessRecord app = getRecordForAppLocked(target); 11953 if (app == null) { 11954 Slog.w(TAG, "finishInstrumentation: no app for " + target); 11955 return; 11956 } 11957 final long origId = Binder.clearCallingIdentity(); 11958 finishInstrumentationLocked(app, resultCode, results); 11959 Binder.restoreCallingIdentity(origId); 11960 } 11961 } 11962 11963 // ========================================================= 11964 // CONFIGURATION 11965 // ========================================================= 11966 11967 public ConfigurationInfo getDeviceConfigurationInfo() { 11968 ConfigurationInfo config = new ConfigurationInfo(); 11969 synchronized (this) { 11970 config.reqTouchScreen = mConfiguration.touchscreen; 11971 config.reqKeyboardType = mConfiguration.keyboard; 11972 config.reqNavigation = mConfiguration.navigation; 11973 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 11974 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 11975 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11976 } 11977 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 11978 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 11979 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11980 } 11981 config.reqGlEsVersion = GL_ES_VERSION; 11982 } 11983 return config; 11984 } 11985 11986 public Configuration getConfiguration() { 11987 Configuration ci; 11988 synchronized(this) { 11989 ci = new Configuration(mConfiguration); 11990 } 11991 return ci; 11992 } 11993 11994 public void updatePersistentConfiguration(Configuration values) { 11995 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11996 "updateConfiguration()"); 11997 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 11998 "updateConfiguration()"); 11999 if (values == null) { 12000 throw new NullPointerException("Configuration must not be null"); 12001 } 12002 12003 synchronized(this) { 12004 final long origId = Binder.clearCallingIdentity(); 12005 updateConfigurationLocked(values, null, true, false); 12006 Binder.restoreCallingIdentity(origId); 12007 } 12008 } 12009 12010 public void updateConfiguration(Configuration values) { 12011 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12012 "updateConfiguration()"); 12013 12014 synchronized(this) { 12015 if (values == null && mWindowManager != null) { 12016 // sentinel: fetch the current configuration from the window manager 12017 values = mWindowManager.computeNewConfiguration(); 12018 } 12019 12020 if (mWindowManager != null) { 12021 mProcessList.applyDisplaySize(mWindowManager); 12022 } 12023 12024 final long origId = Binder.clearCallingIdentity(); 12025 if (values != null) { 12026 Settings.System.clearConfiguration(values); 12027 } 12028 updateConfigurationLocked(values, null, false, false); 12029 Binder.restoreCallingIdentity(origId); 12030 } 12031 } 12032 12033 /** 12034 * Do either or both things: (1) change the current configuration, and (2) 12035 * make sure the given activity is running with the (now) current 12036 * configuration. Returns true if the activity has been left running, or 12037 * false if <var>starting</var> is being destroyed to match the new 12038 * configuration. 12039 * @param persistent TODO 12040 */ 12041 boolean updateConfigurationLocked(Configuration values, 12042 ActivityRecord starting, boolean persistent, boolean initLocale) { 12043 // do nothing if we are headless 12044 if (mHeadless) return true; 12045 12046 int changes = 0; 12047 12048 boolean kept = true; 12049 12050 if (values != null) { 12051 Configuration newConfig = new Configuration(mConfiguration); 12052 changes = newConfig.updateFrom(values); 12053 if (changes != 0) { 12054 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12055 Slog.i(TAG, "Updating configuration to: " + values); 12056 } 12057 12058 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12059 12060 if (values.locale != null && !initLocale) { 12061 saveLocaleLocked(values.locale, 12062 !values.locale.equals(mConfiguration.locale), 12063 values.userSetLocale); 12064 } 12065 12066 mConfigurationSeq++; 12067 if (mConfigurationSeq <= 0) { 12068 mConfigurationSeq = 1; 12069 } 12070 newConfig.seq = mConfigurationSeq; 12071 mConfiguration = newConfig; 12072 Slog.i(TAG, "Config changed: " + newConfig); 12073 12074 final Configuration configCopy = new Configuration(mConfiguration); 12075 12076 // TODO: If our config changes, should we auto dismiss any currently 12077 // showing dialogs? 12078 mShowDialogs = shouldShowDialogs(newConfig); 12079 12080 AttributeCache ac = AttributeCache.instance(); 12081 if (ac != null) { 12082 ac.updateConfiguration(configCopy); 12083 } 12084 12085 // Make sure all resources in our process are updated 12086 // right now, so that anyone who is going to retrieve 12087 // resource values after we return will be sure to get 12088 // the new ones. This is especially important during 12089 // boot, where the first config change needs to guarantee 12090 // all resources have that config before following boot 12091 // code is executed. 12092 mSystemThread.applyConfigurationToResources(configCopy); 12093 12094 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12095 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12096 msg.obj = new Configuration(configCopy); 12097 mHandler.sendMessage(msg); 12098 } 12099 12100 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12101 ProcessRecord app = mLruProcesses.get(i); 12102 try { 12103 if (app.thread != null) { 12104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12105 + app.processName + " new config " + mConfiguration); 12106 app.thread.scheduleConfigurationChanged(configCopy); 12107 } 12108 } catch (Exception e) { 12109 } 12110 } 12111 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12112 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12113 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12114 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12115 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12116 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12117 broadcastIntentLocked(null, null, 12118 new Intent(Intent.ACTION_LOCALE_CHANGED), 12119 null, null, 0, null, null, 12120 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12121 } 12122 } 12123 } 12124 12125 if (changes != 0 && starting == null) { 12126 // If the configuration changed, and the caller is not already 12127 // in the process of starting an activity, then find the top 12128 // activity to check if its configuration needs to change. 12129 starting = mMainStack.topRunningActivityLocked(null); 12130 } 12131 12132 if (starting != null) { 12133 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12134 // And we need to make sure at this point that all other activities 12135 // are made visible with the correct configuration. 12136 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12137 } 12138 12139 if (values != null && mWindowManager != null) { 12140 mWindowManager.setNewConfiguration(mConfiguration); 12141 } 12142 12143 return kept; 12144 } 12145 12146 /** 12147 * Decide based on the configuration whether we should shouw the ANR, 12148 * crash, etc dialogs. The idea is that if there is no affordnace to 12149 * press the on-screen buttons, we shouldn't show the dialog. 12150 * 12151 * A thought: SystemUI might also want to get told about this, the Power 12152 * dialog / global actions also might want different behaviors. 12153 */ 12154 private static final boolean shouldShowDialogs(Configuration config) { 12155 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12156 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12157 } 12158 12159 /** 12160 * Save the locale. You must be inside a synchronized (this) block. 12161 */ 12162 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12163 if(isDiff) { 12164 SystemProperties.set("user.language", l.getLanguage()); 12165 SystemProperties.set("user.region", l.getCountry()); 12166 } 12167 12168 if(isPersist) { 12169 SystemProperties.set("persist.sys.language", l.getLanguage()); 12170 SystemProperties.set("persist.sys.country", l.getCountry()); 12171 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12172 } 12173 } 12174 12175 @Override 12176 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12177 ActivityRecord srec = ActivityRecord.forToken(token); 12178 return srec != null && srec.task.affinity != null && 12179 srec.task.affinity.equals(destAffinity); 12180 } 12181 12182 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12183 Intent resultData) { 12184 ComponentName dest = destIntent.getComponent(); 12185 12186 synchronized (this) { 12187 ActivityRecord srec = ActivityRecord.forToken(token); 12188 if (srec == null) { 12189 return false; 12190 } 12191 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12192 final int start = history.indexOf(srec); 12193 if (start < 0) { 12194 // Current activity is not in history stack; do nothing. 12195 return false; 12196 } 12197 int finishTo = start - 1; 12198 ActivityRecord parent = null; 12199 boolean foundParentInTask = false; 12200 if (dest != null) { 12201 TaskRecord tr = srec.task; 12202 for (int i = start - 1; i >= 0; i--) { 12203 ActivityRecord r = history.get(i); 12204 if (tr != r.task) { 12205 // Couldn't find parent in the same task; stop at the one above this. 12206 // (Root of current task; in-app "home" behavior) 12207 // Always at least finish the current activity. 12208 finishTo = Math.min(start - 1, i + 1); 12209 parent = history.get(finishTo); 12210 break; 12211 } else if (r.info.packageName.equals(dest.getPackageName()) && 12212 r.info.name.equals(dest.getClassName())) { 12213 finishTo = i; 12214 parent = r; 12215 foundParentInTask = true; 12216 break; 12217 } 12218 } 12219 } 12220 12221 if (mController != null) { 12222 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12223 if (next != null) { 12224 // ask watcher if this is allowed 12225 boolean resumeOK = true; 12226 try { 12227 resumeOK = mController.activityResuming(next.packageName); 12228 } catch (RemoteException e) { 12229 mController = null; 12230 } 12231 12232 if (!resumeOK) { 12233 return false; 12234 } 12235 } 12236 } 12237 final long origId = Binder.clearCallingIdentity(); 12238 for (int i = start; i > finishTo; i--) { 12239 ActivityRecord r = history.get(i); 12240 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12241 "navigate-up"); 12242 // Only return the supplied result for the first activity finished 12243 resultCode = Activity.RESULT_CANCELED; 12244 resultData = null; 12245 } 12246 12247 if (parent != null && foundParentInTask) { 12248 final int parentLaunchMode = parent.info.launchMode; 12249 final int destIntentFlags = destIntent.getFlags(); 12250 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12251 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12252 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12253 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12254 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12255 } else { 12256 try { 12257 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12258 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12259 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12260 null, aInfo, parent.appToken, null, 12261 0, -1, parent.launchedFromUid, 0, null, true, null); 12262 foundParentInTask = res == ActivityManager.START_SUCCESS; 12263 } catch (RemoteException e) { 12264 foundParentInTask = false; 12265 } 12266 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12267 resultData, "navigate-up"); 12268 } 12269 } 12270 Binder.restoreCallingIdentity(origId); 12271 return foundParentInTask; 12272 } 12273 } 12274 12275 public int getLaunchedFromUid(IBinder activityToken) { 12276 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12277 if (srec == null) { 12278 return -1; 12279 } 12280 return srec.launchedFromUid; 12281 } 12282 12283 // ========================================================= 12284 // LIFETIME MANAGEMENT 12285 // ========================================================= 12286 12287 // Returns which broadcast queue the app is the current [or imminent] receiver 12288 // on, or 'null' if the app is not an active broadcast recipient. 12289 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12290 BroadcastRecord r = app.curReceiver; 12291 if (r != null) { 12292 return r.queue; 12293 } 12294 12295 // It's not the current receiver, but it might be starting up to become one 12296 synchronized (this) { 12297 for (BroadcastQueue queue : mBroadcastQueues) { 12298 r = queue.mPendingBroadcast; 12299 if (r != null && r.curApp == app) { 12300 // found it; report which queue it's in 12301 return queue; 12302 } 12303 } 12304 } 12305 12306 return null; 12307 } 12308 12309 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12310 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12311 if (mAdjSeq == app.adjSeq) { 12312 // This adjustment has already been computed. If we are calling 12313 // from the top, we may have already computed our adjustment with 12314 // an earlier hidden adjustment that isn't really for us... if 12315 // so, use the new hidden adjustment. 12316 if (!recursed && app.hidden) { 12317 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12318 app.hasActivities ? hiddenAdj : emptyAdj; 12319 } 12320 return app.curRawAdj; 12321 } 12322 12323 if (app.thread == null) { 12324 app.adjSeq = mAdjSeq; 12325 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12326 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12327 } 12328 12329 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12330 app.adjSource = null; 12331 app.adjTarget = null; 12332 app.empty = false; 12333 app.hidden = false; 12334 12335 final int activitiesSize = app.activities.size(); 12336 12337 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12338 // The max adjustment doesn't allow this app to be anything 12339 // below foreground, so it is not worth doing work for it. 12340 app.adjType = "fixed"; 12341 app.adjSeq = mAdjSeq; 12342 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12343 app.hasActivities = false; 12344 app.foregroundActivities = false; 12345 app.keeping = true; 12346 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12347 // System process can do UI, and when they do we want to have 12348 // them trim their memory after the user leaves the UI. To 12349 // facilitate this, here we need to determine whether or not it 12350 // is currently showing UI. 12351 app.systemNoUi = true; 12352 if (app == TOP_APP) { 12353 app.systemNoUi = false; 12354 app.hasActivities = true; 12355 } else if (activitiesSize > 0) { 12356 for (int j = 0; j < activitiesSize; j++) { 12357 final ActivityRecord r = app.activities.get(j); 12358 if (r.visible) { 12359 app.systemNoUi = false; 12360 } 12361 if (r.app == app) { 12362 app.hasActivities = true; 12363 } 12364 } 12365 } 12366 return (app.curAdj=app.maxAdj); 12367 } 12368 12369 app.keeping = false; 12370 app.systemNoUi = false; 12371 app.hasActivities = false; 12372 12373 // Determine the importance of the process, starting with most 12374 // important to least, and assign an appropriate OOM adjustment. 12375 int adj; 12376 int schedGroup; 12377 boolean foregroundActivities = false; 12378 boolean interesting = false; 12379 BroadcastQueue queue; 12380 if (app == TOP_APP) { 12381 // The last app on the list is the foreground app. 12382 adj = ProcessList.FOREGROUND_APP_ADJ; 12383 schedGroup = Process.THREAD_GROUP_DEFAULT; 12384 app.adjType = "top-activity"; 12385 foregroundActivities = true; 12386 interesting = true; 12387 app.hasActivities = true; 12388 } else if (app.instrumentationClass != null) { 12389 // Don't want to kill running instrumentation. 12390 adj = ProcessList.FOREGROUND_APP_ADJ; 12391 schedGroup = Process.THREAD_GROUP_DEFAULT; 12392 app.adjType = "instrumentation"; 12393 interesting = true; 12394 } else if ((queue = isReceivingBroadcast(app)) != null) { 12395 // An app that is currently receiving a broadcast also 12396 // counts as being in the foreground for OOM killer purposes. 12397 // It's placed in a sched group based on the nature of the 12398 // broadcast as reflected by which queue it's active in. 12399 adj = ProcessList.FOREGROUND_APP_ADJ; 12400 schedGroup = (queue == mFgBroadcastQueue) 12401 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12402 app.adjType = "broadcast"; 12403 } else if (app.executingServices.size() > 0) { 12404 // An app that is currently executing a service callback also 12405 // counts as being in the foreground. 12406 adj = ProcessList.FOREGROUND_APP_ADJ; 12407 schedGroup = Process.THREAD_GROUP_DEFAULT; 12408 app.adjType = "exec-service"; 12409 } else { 12410 // Assume process is hidden (has activities); we will correct 12411 // later if this is not the case. 12412 adj = hiddenAdj; 12413 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12414 app.hidden = true; 12415 app.adjType = "bg-activities"; 12416 } 12417 12418 boolean hasStoppingActivities = false; 12419 12420 // Examine all activities if not already foreground. 12421 if (!foregroundActivities && activitiesSize > 0) { 12422 for (int j = 0; j < activitiesSize; j++) { 12423 final ActivityRecord r = app.activities.get(j); 12424 if (r.visible) { 12425 // App has a visible activity; only upgrade adjustment. 12426 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12427 adj = ProcessList.VISIBLE_APP_ADJ; 12428 app.adjType = "visible"; 12429 } 12430 schedGroup = Process.THREAD_GROUP_DEFAULT; 12431 app.hidden = false; 12432 app.hasActivities = true; 12433 foregroundActivities = true; 12434 break; 12435 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12436 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12437 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12438 app.adjType = "pausing"; 12439 } 12440 app.hidden = false; 12441 foregroundActivities = true; 12442 } else if (r.state == ActivityState.STOPPING) { 12443 // We will apply the actual adjustment later, because 12444 // we want to allow this process to immediately go through 12445 // any memory trimming that is in effect. 12446 app.hidden = false; 12447 foregroundActivities = true; 12448 hasStoppingActivities = true; 12449 } 12450 if (r.app == app) { 12451 app.hasActivities = true; 12452 } 12453 } 12454 } 12455 12456 if (adj == hiddenAdj && !app.hasActivities) { 12457 // Whoops, this process is completely empty as far as we know 12458 // at this point. 12459 adj = emptyAdj; 12460 app.empty = true; 12461 app.adjType = "bg-empty"; 12462 } 12463 12464 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12465 if (app.foregroundServices) { 12466 // The user is aware of this app, so make it visible. 12467 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12468 app.hidden = false; 12469 app.adjType = "foreground-service"; 12470 schedGroup = Process.THREAD_GROUP_DEFAULT; 12471 } else if (app.forcingToForeground != null) { 12472 // The user is aware of this app, so make it visible. 12473 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12474 app.hidden = false; 12475 app.adjType = "force-foreground"; 12476 app.adjSource = app.forcingToForeground; 12477 schedGroup = Process.THREAD_GROUP_DEFAULT; 12478 } 12479 } 12480 12481 if (app.foregroundServices) { 12482 interesting = true; 12483 } 12484 12485 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12486 // We don't want to kill the current heavy-weight process. 12487 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12488 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12489 app.hidden = false; 12490 app.adjType = "heavy"; 12491 } 12492 12493 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12494 // This process is hosting what we currently consider to be the 12495 // home app, so we don't want to let it go into the background. 12496 adj = ProcessList.HOME_APP_ADJ; 12497 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12498 app.hidden = false; 12499 app.adjType = "home"; 12500 } 12501 12502 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12503 && app.activities.size() > 0) { 12504 // This was the previous process that showed UI to the user. 12505 // We want to try to keep it around more aggressively, to give 12506 // a good experience around switching between two apps. 12507 adj = ProcessList.PREVIOUS_APP_ADJ; 12508 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12509 app.hidden = false; 12510 app.adjType = "previous"; 12511 } 12512 12513 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12514 + " reason=" + app.adjType); 12515 12516 // By default, we use the computed adjustment. It may be changed if 12517 // there are applications dependent on our services or providers, but 12518 // this gives us a baseline and makes sure we don't get into an 12519 // infinite recursion. 12520 app.adjSeq = mAdjSeq; 12521 app.curRawAdj = app.nonStoppingAdj = adj; 12522 12523 if (mBackupTarget != null && app == mBackupTarget.app) { 12524 // If possible we want to avoid killing apps while they're being backed up 12525 if (adj > ProcessList.BACKUP_APP_ADJ) { 12526 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12527 adj = ProcessList.BACKUP_APP_ADJ; 12528 app.adjType = "backup"; 12529 app.hidden = false; 12530 } 12531 } 12532 12533 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12534 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12535 final long now = SystemClock.uptimeMillis(); 12536 // This process is more important if the top activity is 12537 // bound to the service. 12538 Iterator<ServiceRecord> jt = app.services.iterator(); 12539 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12540 ServiceRecord s = jt.next(); 12541 if (s.startRequested) { 12542 if (app.hasShownUi && app != mHomeProcess) { 12543 // If this process has shown some UI, let it immediately 12544 // go to the LRU list because it may be pretty heavy with 12545 // UI stuff. We'll tag it with a label just to help 12546 // debug and understand what is going on. 12547 if (adj > ProcessList.SERVICE_ADJ) { 12548 app.adjType = "started-bg-ui-services"; 12549 } 12550 } else { 12551 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12552 // This service has seen some activity within 12553 // recent memory, so we will keep its process ahead 12554 // of the background processes. 12555 if (adj > ProcessList.SERVICE_ADJ) { 12556 adj = ProcessList.SERVICE_ADJ; 12557 app.adjType = "started-services"; 12558 app.hidden = false; 12559 } 12560 } 12561 // If we have let the service slide into the background 12562 // state, still have some text describing what it is doing 12563 // even though the service no longer has an impact. 12564 if (adj > ProcessList.SERVICE_ADJ) { 12565 app.adjType = "started-bg-services"; 12566 } 12567 } 12568 // Don't kill this process because it is doing work; it 12569 // has said it is doing work. 12570 app.keeping = true; 12571 } 12572 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12573 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12574 Iterator<ArrayList<ConnectionRecord>> kt 12575 = s.connections.values().iterator(); 12576 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12577 ArrayList<ConnectionRecord> clist = kt.next(); 12578 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12579 // XXX should compute this based on the max of 12580 // all connected clients. 12581 ConnectionRecord cr = clist.get(i); 12582 if (cr.binding.client == app) { 12583 // Binding to ourself is not interesting. 12584 continue; 12585 } 12586 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12587 ProcessRecord client = cr.binding.client; 12588 int clientAdj = adj; 12589 int myHiddenAdj = hiddenAdj; 12590 if (myHiddenAdj > client.hiddenAdj) { 12591 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12592 myHiddenAdj = client.hiddenAdj; 12593 } else { 12594 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12595 } 12596 } 12597 int myEmptyAdj = emptyAdj; 12598 if (myEmptyAdj > client.emptyAdj) { 12599 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12600 myEmptyAdj = client.emptyAdj; 12601 } else { 12602 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12603 } 12604 } 12605 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12606 myEmptyAdj, TOP_APP, true, doingAll); 12607 String adjType = null; 12608 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12609 // Not doing bind OOM management, so treat 12610 // this guy more like a started service. 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 > clientAdj) { 12617 adjType = "bound-bg-ui-services"; 12618 } 12619 app.hidden = false; 12620 clientAdj = adj; 12621 } else { 12622 if (now >= (s.lastActivity 12623 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12624 // This service has not seen activity within 12625 // recent memory, so allow it to drop to the 12626 // LRU list if there is no other reason to keep 12627 // it around. We'll also tag it with a label just 12628 // to help debug and undertand what is going on. 12629 if (adj > clientAdj) { 12630 adjType = "bound-bg-services"; 12631 } 12632 clientAdj = adj; 12633 } 12634 } 12635 } 12636 if (adj > clientAdj) { 12637 // If this process has recently shown UI, and 12638 // the process that is binding to it is less 12639 // important than being visible, then we don't 12640 // care about the binding as much as we care 12641 // about letting this process get into the LRU 12642 // list to be killed and restarted if needed for 12643 // memory. 12644 if (app.hasShownUi && app != mHomeProcess 12645 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12646 adjType = "bound-bg-ui-services"; 12647 } else { 12648 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12649 |Context.BIND_IMPORTANT)) != 0) { 12650 adj = clientAdj; 12651 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12652 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12653 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12654 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12655 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12656 adj = clientAdj; 12657 } else { 12658 app.pendingUiClean = true; 12659 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12660 adj = ProcessList.VISIBLE_APP_ADJ; 12661 } 12662 } 12663 if (!client.hidden) { 12664 app.hidden = false; 12665 } 12666 if (client.keeping) { 12667 app.keeping = true; 12668 } 12669 adjType = "service"; 12670 } 12671 } 12672 if (adjType != null) { 12673 app.adjType = adjType; 12674 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12675 .REASON_SERVICE_IN_USE; 12676 app.adjSource = cr.binding.client; 12677 app.adjSourceOom = clientAdj; 12678 app.adjTarget = s.name; 12679 } 12680 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12681 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12682 schedGroup = Process.THREAD_GROUP_DEFAULT; 12683 } 12684 } 12685 } 12686 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12687 ActivityRecord a = cr.activity; 12688 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12689 (a.visible || a.state == ActivityState.RESUMED 12690 || a.state == ActivityState.PAUSING)) { 12691 adj = ProcessList.FOREGROUND_APP_ADJ; 12692 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12693 schedGroup = Process.THREAD_GROUP_DEFAULT; 12694 } 12695 app.hidden = false; 12696 app.adjType = "service"; 12697 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12698 .REASON_SERVICE_IN_USE; 12699 app.adjSource = a; 12700 app.adjSourceOom = adj; 12701 app.adjTarget = s.name; 12702 } 12703 } 12704 } 12705 } 12706 } 12707 } 12708 12709 // Finally, if this process has active services running in it, we 12710 // would like to avoid killing it unless it would prevent the current 12711 // application from running. By default we put the process in 12712 // with the rest of the background processes; as we scan through 12713 // its services we may bump it up from there. 12714 if (adj > hiddenAdj) { 12715 adj = hiddenAdj; 12716 app.hidden = false; 12717 app.adjType = "bg-services"; 12718 } 12719 } 12720 12721 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12722 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12723 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12724 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12725 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12726 ContentProviderRecord cpr = jt.next(); 12727 for (int i = cpr.connections.size()-1; 12728 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12729 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12730 i--) { 12731 ContentProviderConnection conn = cpr.connections.get(i); 12732 ProcessRecord client = conn.client; 12733 if (client == app) { 12734 // Being our own client is not interesting. 12735 continue; 12736 } 12737 int myHiddenAdj = hiddenAdj; 12738 if (myHiddenAdj > client.hiddenAdj) { 12739 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12740 myHiddenAdj = client.hiddenAdj; 12741 } else { 12742 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12743 } 12744 } 12745 int myEmptyAdj = emptyAdj; 12746 if (myEmptyAdj > client.emptyAdj) { 12747 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12748 myEmptyAdj = client.emptyAdj; 12749 } else { 12750 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12751 } 12752 } 12753 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12754 myEmptyAdj, TOP_APP, true, doingAll); 12755 if (adj > clientAdj) { 12756 if (app.hasShownUi && app != mHomeProcess 12757 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12758 app.adjType = "bg-ui-provider"; 12759 } else { 12760 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12761 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12762 app.adjType = "provider"; 12763 } 12764 if (!client.hidden) { 12765 app.hidden = false; 12766 } 12767 if (client.keeping) { 12768 app.keeping = true; 12769 } 12770 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12771 .REASON_PROVIDER_IN_USE; 12772 app.adjSource = client; 12773 app.adjSourceOom = clientAdj; 12774 app.adjTarget = cpr.name; 12775 } 12776 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12777 schedGroup = Process.THREAD_GROUP_DEFAULT; 12778 } 12779 } 12780 // If the provider has external (non-framework) process 12781 // dependencies, ensure that its adjustment is at least 12782 // FOREGROUND_APP_ADJ. 12783 if (cpr.hasExternalProcessHandles()) { 12784 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12785 adj = ProcessList.FOREGROUND_APP_ADJ; 12786 schedGroup = Process.THREAD_GROUP_DEFAULT; 12787 app.hidden = false; 12788 app.keeping = true; 12789 app.adjType = "provider"; 12790 app.adjTarget = cpr.name; 12791 } 12792 } 12793 } 12794 } 12795 12796 if (adj == ProcessList.SERVICE_ADJ) { 12797 if (doingAll) { 12798 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12799 mNewNumServiceProcs++; 12800 } 12801 if (app.serviceb) { 12802 adj = ProcessList.SERVICE_B_ADJ; 12803 } 12804 } else { 12805 app.serviceb = false; 12806 } 12807 12808 app.nonStoppingAdj = adj; 12809 12810 if (hasStoppingActivities) { 12811 // Only upgrade adjustment. 12812 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12813 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12814 app.adjType = "stopping"; 12815 } 12816 } 12817 12818 app.curRawAdj = adj; 12819 12820 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12821 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12822 if (adj > app.maxAdj) { 12823 adj = app.maxAdj; 12824 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12825 schedGroup = Process.THREAD_GROUP_DEFAULT; 12826 } 12827 } 12828 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12829 app.keeping = true; 12830 } 12831 12832 if (app.hasAboveClient) { 12833 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12834 // then we need to drop its adjustment to be lower than the service's 12835 // in order to honor the request. We want to drop it by one adjustment 12836 // level... but there is special meaning applied to various levels so 12837 // we will skip some of them. 12838 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12839 // System process will not get dropped, ever 12840 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12841 adj = ProcessList.VISIBLE_APP_ADJ; 12842 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12843 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12844 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12845 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12846 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12847 adj++; 12848 } 12849 } 12850 12851 int importance = app.memImportance; 12852 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12853 app.curAdj = adj; 12854 app.curSchedGroup = schedGroup; 12855 if (!interesting) { 12856 // For this reporting, if there is not something explicitly 12857 // interesting in this process then we will push it to the 12858 // background importance. 12859 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12860 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 12861 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12862 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 12863 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12864 } else if (adj >= ProcessList.HOME_APP_ADJ) { 12865 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 12866 } else if (adj >= ProcessList.SERVICE_ADJ) { 12867 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 12868 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 12869 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 12870 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 12871 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 12872 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 12873 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 12874 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 12875 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 12876 } else { 12877 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 12878 } 12879 } 12880 12881 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 12882 if (foregroundActivities != app.foregroundActivities) { 12883 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 12884 } 12885 if (changes != 0) { 12886 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 12887 app.memImportance = importance; 12888 app.foregroundActivities = foregroundActivities; 12889 int i = mPendingProcessChanges.size()-1; 12890 ProcessChangeItem item = null; 12891 while (i >= 0) { 12892 item = mPendingProcessChanges.get(i); 12893 if (item.pid == app.pid) { 12894 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 12895 break; 12896 } 12897 i--; 12898 } 12899 if (i < 0) { 12900 // No existing item in pending changes; need a new one. 12901 final int NA = mAvailProcessChanges.size(); 12902 if (NA > 0) { 12903 item = mAvailProcessChanges.remove(NA-1); 12904 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 12905 } else { 12906 item = new ProcessChangeItem(); 12907 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 12908 } 12909 item.changes = 0; 12910 item.pid = app.pid; 12911 item.uid = app.info.uid; 12912 if (mPendingProcessChanges.size() == 0) { 12913 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 12914 "*** Enqueueing dispatch processes changed!"); 12915 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 12916 } 12917 mPendingProcessChanges.add(item); 12918 } 12919 item.changes |= changes; 12920 item.importance = importance; 12921 item.foregroundActivities = foregroundActivities; 12922 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 12923 + Integer.toHexString(System.identityHashCode(item)) 12924 + " " + app.toShortString() + ": changes=" + item.changes 12925 + " importance=" + item.importance 12926 + " foreground=" + item.foregroundActivities 12927 + " type=" + app.adjType + " source=" + app.adjSource 12928 + " target=" + app.adjTarget); 12929 } 12930 12931 return app.curRawAdj; 12932 } 12933 12934 /** 12935 * Ask a given process to GC right now. 12936 */ 12937 final void performAppGcLocked(ProcessRecord app) { 12938 try { 12939 app.lastRequestedGc = SystemClock.uptimeMillis(); 12940 if (app.thread != null) { 12941 if (app.reportLowMemory) { 12942 app.reportLowMemory = false; 12943 app.thread.scheduleLowMemory(); 12944 } else { 12945 app.thread.processInBackground(); 12946 } 12947 } 12948 } catch (Exception e) { 12949 // whatever. 12950 } 12951 } 12952 12953 /** 12954 * Returns true if things are idle enough to perform GCs. 12955 */ 12956 private final boolean canGcNowLocked() { 12957 boolean processingBroadcasts = false; 12958 for (BroadcastQueue q : mBroadcastQueues) { 12959 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 12960 processingBroadcasts = true; 12961 } 12962 } 12963 return !processingBroadcasts 12964 && (mSleeping || (mMainStack.mResumedActivity != null && 12965 mMainStack.mResumedActivity.idle)); 12966 } 12967 12968 /** 12969 * Perform GCs on all processes that are waiting for it, but only 12970 * if things are idle. 12971 */ 12972 final void performAppGcsLocked() { 12973 final int N = mProcessesToGc.size(); 12974 if (N <= 0) { 12975 return; 12976 } 12977 if (canGcNowLocked()) { 12978 while (mProcessesToGc.size() > 0) { 12979 ProcessRecord proc = mProcessesToGc.remove(0); 12980 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 12981 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 12982 <= SystemClock.uptimeMillis()) { 12983 // To avoid spamming the system, we will GC processes one 12984 // at a time, waiting a few seconds between each. 12985 performAppGcLocked(proc); 12986 scheduleAppGcsLocked(); 12987 return; 12988 } else { 12989 // It hasn't been long enough since we last GCed this 12990 // process... put it in the list to wait for its time. 12991 addProcessToGcListLocked(proc); 12992 break; 12993 } 12994 } 12995 } 12996 12997 scheduleAppGcsLocked(); 12998 } 12999 } 13000 13001 /** 13002 * If all looks good, perform GCs on all processes waiting for them. 13003 */ 13004 final void performAppGcsIfAppropriateLocked() { 13005 if (canGcNowLocked()) { 13006 performAppGcsLocked(); 13007 return; 13008 } 13009 // Still not idle, wait some more. 13010 scheduleAppGcsLocked(); 13011 } 13012 13013 /** 13014 * Schedule the execution of all pending app GCs. 13015 */ 13016 final void scheduleAppGcsLocked() { 13017 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13018 13019 if (mProcessesToGc.size() > 0) { 13020 // Schedule a GC for the time to the next process. 13021 ProcessRecord proc = mProcessesToGc.get(0); 13022 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13023 13024 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13025 long now = SystemClock.uptimeMillis(); 13026 if (when < (now+GC_TIMEOUT)) { 13027 when = now + GC_TIMEOUT; 13028 } 13029 mHandler.sendMessageAtTime(msg, when); 13030 } 13031 } 13032 13033 /** 13034 * Add a process to the array of processes waiting to be GCed. Keeps the 13035 * list in sorted order by the last GC time. The process can't already be 13036 * on the list. 13037 */ 13038 final void addProcessToGcListLocked(ProcessRecord proc) { 13039 boolean added = false; 13040 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13041 if (mProcessesToGc.get(i).lastRequestedGc < 13042 proc.lastRequestedGc) { 13043 added = true; 13044 mProcessesToGc.add(i+1, proc); 13045 break; 13046 } 13047 } 13048 if (!added) { 13049 mProcessesToGc.add(0, proc); 13050 } 13051 } 13052 13053 /** 13054 * Set up to ask a process to GC itself. This will either do it 13055 * immediately, or put it on the list of processes to gc the next 13056 * time things are idle. 13057 */ 13058 final void scheduleAppGcLocked(ProcessRecord app) { 13059 long now = SystemClock.uptimeMillis(); 13060 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13061 return; 13062 } 13063 if (!mProcessesToGc.contains(app)) { 13064 addProcessToGcListLocked(app); 13065 scheduleAppGcsLocked(); 13066 } 13067 } 13068 13069 final void checkExcessivePowerUsageLocked(boolean doKills) { 13070 updateCpuStatsNow(); 13071 13072 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13073 boolean doWakeKills = doKills; 13074 boolean doCpuKills = doKills; 13075 if (mLastPowerCheckRealtime == 0) { 13076 doWakeKills = false; 13077 } 13078 if (mLastPowerCheckUptime == 0) { 13079 doCpuKills = false; 13080 } 13081 if (stats.isScreenOn()) { 13082 doWakeKills = false; 13083 } 13084 final long curRealtime = SystemClock.elapsedRealtime(); 13085 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13086 final long curUptime = SystemClock.uptimeMillis(); 13087 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13088 mLastPowerCheckRealtime = curRealtime; 13089 mLastPowerCheckUptime = curUptime; 13090 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13091 doWakeKills = false; 13092 } 13093 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13094 doCpuKills = false; 13095 } 13096 int i = mLruProcesses.size(); 13097 while (i > 0) { 13098 i--; 13099 ProcessRecord app = mLruProcesses.get(i); 13100 if (!app.keeping) { 13101 long wtime; 13102 synchronized (stats) { 13103 wtime = stats.getProcessWakeTime(app.info.uid, 13104 app.pid, curRealtime); 13105 } 13106 long wtimeUsed = wtime - app.lastWakeTime; 13107 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13108 if (DEBUG_POWER) { 13109 StringBuilder sb = new StringBuilder(128); 13110 sb.append("Wake for "); 13111 app.toShortString(sb); 13112 sb.append(": over "); 13113 TimeUtils.formatDuration(realtimeSince, sb); 13114 sb.append(" used "); 13115 TimeUtils.formatDuration(wtimeUsed, sb); 13116 sb.append(" ("); 13117 sb.append((wtimeUsed*100)/realtimeSince); 13118 sb.append("%)"); 13119 Slog.i(TAG, sb.toString()); 13120 sb.setLength(0); 13121 sb.append("CPU for "); 13122 app.toShortString(sb); 13123 sb.append(": over "); 13124 TimeUtils.formatDuration(uptimeSince, sb); 13125 sb.append(" used "); 13126 TimeUtils.formatDuration(cputimeUsed, sb); 13127 sb.append(" ("); 13128 sb.append((cputimeUsed*100)/uptimeSince); 13129 sb.append("%)"); 13130 Slog.i(TAG, sb.toString()); 13131 } 13132 // If a process has held a wake lock for more 13133 // than 50% of the time during this period, 13134 // that sounds bad. Kill! 13135 if (doWakeKills && realtimeSince > 0 13136 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13137 synchronized (stats) { 13138 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13139 realtimeSince, wtimeUsed); 13140 } 13141 Slog.w(TAG, "Excessive wake lock in " + app.processName 13142 + " (pid " + app.pid + "): held " + wtimeUsed 13143 + " during " + realtimeSince); 13144 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13145 app.processName, app.setAdj, "excessive wake lock"); 13146 Process.killProcessQuiet(app.pid); 13147 } else if (doCpuKills && uptimeSince > 0 13148 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13149 synchronized (stats) { 13150 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13151 uptimeSince, cputimeUsed); 13152 } 13153 Slog.w(TAG, "Excessive CPU in " + app.processName 13154 + " (pid " + app.pid + "): used " + cputimeUsed 13155 + " during " + uptimeSince); 13156 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13157 app.processName, app.setAdj, "excessive cpu"); 13158 Process.killProcessQuiet(app.pid); 13159 } else { 13160 app.lastWakeTime = wtime; 13161 app.lastCpuTime = app.curCpuTime; 13162 } 13163 } 13164 } 13165 } 13166 13167 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13168 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13169 app.hiddenAdj = hiddenAdj; 13170 app.emptyAdj = emptyAdj; 13171 13172 if (app.thread == null) { 13173 return false; 13174 } 13175 13176 final boolean wasKeeping = app.keeping; 13177 13178 boolean success = true; 13179 13180 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13181 13182 if (app.curRawAdj != app.setRawAdj) { 13183 if (wasKeeping && !app.keeping) { 13184 // This app is no longer something we want to keep. Note 13185 // its current wake lock time to later know to kill it if 13186 // it is not behaving well. 13187 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13188 synchronized (stats) { 13189 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13190 app.pid, SystemClock.elapsedRealtime()); 13191 } 13192 app.lastCpuTime = app.curCpuTime; 13193 } 13194 13195 app.setRawAdj = app.curRawAdj; 13196 } 13197 13198 if (app.curAdj != app.setAdj) { 13199 if (Process.setOomAdj(app.pid, app.curAdj)) { 13200 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13201 TAG, "Set " + app.pid + " " + app.processName + 13202 " adj " + app.curAdj + ": " + app.adjType); 13203 app.setAdj = app.curAdj; 13204 } else { 13205 success = false; 13206 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13207 } 13208 } 13209 if (app.setSchedGroup != app.curSchedGroup) { 13210 app.setSchedGroup = app.curSchedGroup; 13211 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13212 "Setting process group of " + app.processName 13213 + " to " + app.curSchedGroup); 13214 if (app.waitingToKill != null && 13215 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13216 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13217 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13218 app.processName, app.setAdj, app.waitingToKill); 13219 app.killedBackground = true; 13220 Process.killProcessQuiet(app.pid); 13221 success = false; 13222 } else { 13223 if (true) { 13224 long oldId = Binder.clearCallingIdentity(); 13225 try { 13226 Process.setProcessGroup(app.pid, app.curSchedGroup); 13227 } catch (Exception e) { 13228 Slog.w(TAG, "Failed setting process group of " + app.pid 13229 + " to " + app.curSchedGroup); 13230 e.printStackTrace(); 13231 } finally { 13232 Binder.restoreCallingIdentity(oldId); 13233 } 13234 } else { 13235 if (app.thread != null) { 13236 try { 13237 app.thread.setSchedulingGroup(app.curSchedGroup); 13238 } catch (RemoteException e) { 13239 } 13240 } 13241 } 13242 } 13243 } 13244 return success; 13245 } 13246 13247 private final ActivityRecord resumedAppLocked() { 13248 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13249 if (resumedActivity == null || resumedActivity.app == null) { 13250 resumedActivity = mMainStack.mPausingActivity; 13251 if (resumedActivity == null || resumedActivity.app == null) { 13252 resumedActivity = mMainStack.topRunningActivityLocked(null); 13253 } 13254 } 13255 return resumedActivity; 13256 } 13257 13258 final boolean updateOomAdjLocked(ProcessRecord app) { 13259 final ActivityRecord TOP_ACT = resumedAppLocked(); 13260 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13261 int curAdj = app.curAdj; 13262 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13263 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13264 13265 mAdjSeq++; 13266 13267 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13268 TOP_APP, false); 13269 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13270 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13271 if (nowHidden != wasHidden) { 13272 // Changed to/from hidden state, so apps after it in the LRU 13273 // list may also be changed. 13274 updateOomAdjLocked(); 13275 } 13276 return success; 13277 } 13278 13279 final void updateOomAdjLocked() { 13280 final ActivityRecord TOP_ACT = resumedAppLocked(); 13281 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13282 13283 if (false) { 13284 RuntimeException e = new RuntimeException(); 13285 e.fillInStackTrace(); 13286 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13287 } 13288 13289 mAdjSeq++; 13290 mNewNumServiceProcs = 0; 13291 13292 // Let's determine how many processes we have running vs. 13293 // how many slots we have for background processes; we may want 13294 // to put multiple processes in a slot of there are enough of 13295 // them. 13296 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13297 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13298 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13299 if (emptyFactor < 1) emptyFactor = 1; 13300 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13301 if (hiddenFactor < 1) hiddenFactor = 1; 13302 int stepHidden = 0; 13303 int stepEmpty = 0; 13304 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13305 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13306 int numHidden = 0; 13307 int numEmpty = 0; 13308 int numTrimming = 0; 13309 13310 mNumNonHiddenProcs = 0; 13311 mNumHiddenProcs = 0; 13312 13313 // First update the OOM adjustment for each of the 13314 // application processes based on their current state. 13315 int i = mLruProcesses.size(); 13316 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13317 int nextHiddenAdj = curHiddenAdj+1; 13318 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13319 int nextEmptyAdj = curEmptyAdj+2; 13320 while (i > 0) { 13321 i--; 13322 ProcessRecord app = mLruProcesses.get(i); 13323 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13324 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13325 if (!app.killedBackground) { 13326 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13327 // This process was assigned as a hidden process... step the 13328 // hidden level. 13329 mNumHiddenProcs++; 13330 if (curHiddenAdj != nextHiddenAdj) { 13331 stepHidden++; 13332 if (stepHidden >= hiddenFactor) { 13333 stepHidden = 0; 13334 curHiddenAdj = nextHiddenAdj; 13335 nextHiddenAdj += 2; 13336 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13337 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13338 } 13339 } 13340 } 13341 numHidden++; 13342 if (numHidden > hiddenProcessLimit) { 13343 Slog.i(TAG, "No longer want " + app.processName 13344 + " (pid " + app.pid + "): hidden #" + numHidden); 13345 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13346 app.processName, app.setAdj, "too many background"); 13347 app.killedBackground = true; 13348 Process.killProcessQuiet(app.pid); 13349 } 13350 } else { 13351 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13352 // This process was assigned as an empty process... step the 13353 // empty level. 13354 if (curEmptyAdj != nextEmptyAdj) { 13355 stepEmpty++; 13356 if (stepEmpty >= emptyFactor) { 13357 stepEmpty = 0; 13358 curEmptyAdj = nextEmptyAdj; 13359 nextEmptyAdj += 2; 13360 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13361 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13362 } 13363 } 13364 } 13365 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13366 mNumNonHiddenProcs++; 13367 } 13368 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13369 numEmpty++; 13370 if (numEmpty > emptyProcessLimit) { 13371 Slog.i(TAG, "No longer want " + app.processName 13372 + " (pid " + app.pid + "): empty #" + numEmpty); 13373 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13374 app.processName, app.setAdj, "too many background"); 13375 app.killedBackground = true; 13376 Process.killProcessQuiet(app.pid); 13377 } 13378 } 13379 } 13380 if (app.isolated && app.services.size() <= 0) { 13381 // If this is an isolated process, and there are no 13382 // services running in it, then the process is no longer 13383 // needed. We agressively kill these because we can by 13384 // definition not re-use the same process again, and it is 13385 // good to avoid having whatever code was running in them 13386 // left sitting around after no longer needed. 13387 Slog.i(TAG, "Isolated process " + app.processName 13388 + " (pid " + app.pid + ") no longer needed"); 13389 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13390 app.processName, app.setAdj, "isolated not needed"); 13391 app.killedBackground = true; 13392 Process.killProcessQuiet(app.pid); 13393 } 13394 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13395 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13396 && !app.killedBackground) { 13397 numTrimming++; 13398 } 13399 } 13400 } 13401 13402 mNumServiceProcs = mNewNumServiceProcs; 13403 13404 // Now determine the memory trimming level of background processes. 13405 // Unfortunately we need to start at the back of the list to do this 13406 // properly. We only do this if the number of background apps we 13407 // are managing to keep around is less than half the maximum we desire; 13408 // if we are keeping a good number around, we'll let them use whatever 13409 // memory they want. 13410 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13411 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13412 final int numHiddenAndEmpty = numHidden + numEmpty; 13413 final int N = mLruProcesses.size(); 13414 int factor = numTrimming/3; 13415 int minFactor = 2; 13416 if (mHomeProcess != null) minFactor++; 13417 if (mPreviousProcess != null) minFactor++; 13418 if (factor < minFactor) factor = minFactor; 13419 int step = 0; 13420 int fgTrimLevel; 13421 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13422 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13423 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13424 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13425 } else { 13426 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13427 } 13428 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13429 for (i=0; i<N; i++) { 13430 ProcessRecord app = mLruProcesses.get(i); 13431 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13432 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13433 && !app.killedBackground) { 13434 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13435 try { 13436 app.thread.scheduleTrimMemory(curLevel); 13437 } catch (RemoteException e) { 13438 } 13439 if (false) { 13440 // For now we won't do this; our memory trimming seems 13441 // to be good enough at this point that destroying 13442 // activities causes more harm than good. 13443 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13444 && app != mHomeProcess && app != mPreviousProcess) { 13445 // Need to do this on its own message because the stack may not 13446 // be in a consistent state at this point. 13447 // For these apps we will also finish their activities 13448 // to help them free memory. 13449 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13450 } 13451 } 13452 } 13453 app.trimMemoryLevel = curLevel; 13454 step++; 13455 if (step >= factor) { 13456 step = 0; 13457 switch (curLevel) { 13458 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13459 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13460 break; 13461 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13462 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13463 break; 13464 } 13465 } 13466 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13467 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13468 && app.thread != null) { 13469 try { 13470 app.thread.scheduleTrimMemory( 13471 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13472 } catch (RemoteException e) { 13473 } 13474 } 13475 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13476 } else { 13477 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13478 && app.pendingUiClean) { 13479 // If this application is now in the background and it 13480 // had done UI, then give it the special trim level to 13481 // have it free UI resources. 13482 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13483 if (app.trimMemoryLevel < level && app.thread != null) { 13484 try { 13485 app.thread.scheduleTrimMemory(level); 13486 } catch (RemoteException e) { 13487 } 13488 } 13489 app.pendingUiClean = false; 13490 } 13491 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13492 try { 13493 app.thread.scheduleTrimMemory(fgTrimLevel); 13494 } catch (RemoteException e) { 13495 } 13496 } 13497 app.trimMemoryLevel = fgTrimLevel; 13498 } 13499 } 13500 } else { 13501 final int N = mLruProcesses.size(); 13502 for (i=0; i<N; i++) { 13503 ProcessRecord app = mLruProcesses.get(i); 13504 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13505 && app.pendingUiClean) { 13506 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13507 && app.thread != null) { 13508 try { 13509 app.thread.scheduleTrimMemory( 13510 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13511 } catch (RemoteException e) { 13512 } 13513 } 13514 app.pendingUiClean = false; 13515 } 13516 app.trimMemoryLevel = 0; 13517 } 13518 } 13519 13520 if (mAlwaysFinishActivities) { 13521 // Need to do this on its own message because the stack may not 13522 // be in a consistent state at this point. 13523 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13524 } 13525 } 13526 13527 final void trimApplications() { 13528 synchronized (this) { 13529 int i; 13530 13531 // First remove any unused application processes whose package 13532 // has been removed. 13533 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13534 final ProcessRecord app = mRemovedProcesses.get(i); 13535 if (app.activities.size() == 0 13536 && app.curReceiver == null && app.services.size() == 0) { 13537 Slog.i( 13538 TAG, "Exiting empty application process " 13539 + app.processName + " (" 13540 + (app.thread != null ? app.thread.asBinder() : null) 13541 + ")\n"); 13542 if (app.pid > 0 && app.pid != MY_PID) { 13543 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13544 app.processName, app.setAdj, "empty"); 13545 Process.killProcessQuiet(app.pid); 13546 } else { 13547 try { 13548 app.thread.scheduleExit(); 13549 } catch (Exception e) { 13550 // Ignore exceptions. 13551 } 13552 } 13553 cleanUpApplicationRecordLocked(app, false, true, -1); 13554 mRemovedProcesses.remove(i); 13555 13556 if (app.persistent) { 13557 if (app.persistent) { 13558 addAppLocked(app.info, false); 13559 } 13560 } 13561 } 13562 } 13563 13564 // Now update the oom adj for all processes. 13565 updateOomAdjLocked(); 13566 } 13567 } 13568 13569 /** This method sends the specified signal to each of the persistent apps */ 13570 public void signalPersistentProcesses(int sig) throws RemoteException { 13571 if (sig != Process.SIGNAL_USR1) { 13572 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13573 } 13574 13575 synchronized (this) { 13576 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13577 != PackageManager.PERMISSION_GRANTED) { 13578 throw new SecurityException("Requires permission " 13579 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13580 } 13581 13582 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13583 ProcessRecord r = mLruProcesses.get(i); 13584 if (r.thread != null && r.persistent) { 13585 Process.sendSignal(r.pid, sig); 13586 } 13587 } 13588 } 13589 } 13590 13591 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13592 if (proc == null || proc == mProfileProc) { 13593 proc = mProfileProc; 13594 path = mProfileFile; 13595 profileType = mProfileType; 13596 clearProfilerLocked(); 13597 } 13598 if (proc == null) { 13599 return; 13600 } 13601 try { 13602 proc.thread.profilerControl(false, path, null, profileType); 13603 } catch (RemoteException e) { 13604 throw new IllegalStateException("Process disappeared"); 13605 } 13606 } 13607 13608 private void clearProfilerLocked() { 13609 if (mProfileFd != null) { 13610 try { 13611 mProfileFd.close(); 13612 } catch (IOException e) { 13613 } 13614 } 13615 mProfileApp = null; 13616 mProfileProc = null; 13617 mProfileFile = null; 13618 mProfileType = 0; 13619 mAutoStopProfiler = false; 13620 } 13621 13622 public boolean profileControl(String process, boolean start, 13623 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13624 13625 try { 13626 synchronized (this) { 13627 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13628 // its own permission. 13629 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13630 != PackageManager.PERMISSION_GRANTED) { 13631 throw new SecurityException("Requires permission " 13632 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13633 } 13634 13635 if (start && fd == null) { 13636 throw new IllegalArgumentException("null fd"); 13637 } 13638 13639 ProcessRecord proc = null; 13640 if (process != null) { 13641 try { 13642 int pid = Integer.parseInt(process); 13643 synchronized (mPidsSelfLocked) { 13644 proc = mPidsSelfLocked.get(pid); 13645 } 13646 } catch (NumberFormatException e) { 13647 } 13648 13649 if (proc == null) { 13650 HashMap<String, SparseArray<ProcessRecord>> all 13651 = mProcessNames.getMap(); 13652 SparseArray<ProcessRecord> procs = all.get(process); 13653 if (procs != null && procs.size() > 0) { 13654 proc = procs.valueAt(0); 13655 } 13656 } 13657 } 13658 13659 if (start && (proc == null || proc.thread == null)) { 13660 throw new IllegalArgumentException("Unknown process: " + process); 13661 } 13662 13663 if (start) { 13664 stopProfilerLocked(null, null, 0); 13665 setProfileApp(proc.info, proc.processName, path, fd, false); 13666 mProfileProc = proc; 13667 mProfileType = profileType; 13668 try { 13669 fd = fd.dup(); 13670 } catch (IOException e) { 13671 fd = null; 13672 } 13673 proc.thread.profilerControl(start, path, fd, profileType); 13674 fd = null; 13675 mProfileFd = null; 13676 } else { 13677 stopProfilerLocked(proc, path, profileType); 13678 if (fd != null) { 13679 try { 13680 fd.close(); 13681 } catch (IOException e) { 13682 } 13683 } 13684 } 13685 13686 return true; 13687 } 13688 } catch (RemoteException e) { 13689 throw new IllegalStateException("Process disappeared"); 13690 } finally { 13691 if (fd != null) { 13692 try { 13693 fd.close(); 13694 } catch (IOException e) { 13695 } 13696 } 13697 } 13698 } 13699 13700 public boolean dumpHeap(String process, boolean managed, 13701 String path, ParcelFileDescriptor fd) throws RemoteException { 13702 13703 try { 13704 synchronized (this) { 13705 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13706 // its own permission (same as profileControl). 13707 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13708 != PackageManager.PERMISSION_GRANTED) { 13709 throw new SecurityException("Requires permission " 13710 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13711 } 13712 13713 if (fd == null) { 13714 throw new IllegalArgumentException("null fd"); 13715 } 13716 13717 ProcessRecord proc = null; 13718 try { 13719 int pid = Integer.parseInt(process); 13720 synchronized (mPidsSelfLocked) { 13721 proc = mPidsSelfLocked.get(pid); 13722 } 13723 } catch (NumberFormatException e) { 13724 } 13725 13726 if (proc == null) { 13727 HashMap<String, SparseArray<ProcessRecord>> all 13728 = mProcessNames.getMap(); 13729 SparseArray<ProcessRecord> procs = all.get(process); 13730 if (procs != null && procs.size() > 0) { 13731 proc = procs.valueAt(0); 13732 } 13733 } 13734 13735 if (proc == null || proc.thread == null) { 13736 throw new IllegalArgumentException("Unknown process: " + process); 13737 } 13738 13739 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13740 if (!isDebuggable) { 13741 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13742 throw new SecurityException("Process not debuggable: " + proc); 13743 } 13744 } 13745 13746 proc.thread.dumpHeap(managed, path, fd); 13747 fd = null; 13748 return true; 13749 } 13750 } catch (RemoteException e) { 13751 throw new IllegalStateException("Process disappeared"); 13752 } finally { 13753 if (fd != null) { 13754 try { 13755 fd.close(); 13756 } catch (IOException e) { 13757 } 13758 } 13759 } 13760 } 13761 13762 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13763 public void monitor() { 13764 synchronized (this) { } 13765 } 13766 13767 void onCoreSettingsChange(Bundle settings) { 13768 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13769 ProcessRecord processRecord = mLruProcesses.get(i); 13770 try { 13771 if (processRecord.thread != null) { 13772 processRecord.thread.setCoreSettings(settings); 13773 } 13774 } catch (RemoteException re) { 13775 /* ignore */ 13776 } 13777 } 13778 } 13779 13780 // Multi-user methods 13781 13782 @Override 13783 public boolean switchUser(int userId) { 13784 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13785 != PackageManager.PERMISSION_GRANTED) { 13786 String msg = "Permission Denial: switchUser() from pid=" 13787 + Binder.getCallingPid() 13788 + ", uid=" + Binder.getCallingUid() 13789 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13790 Slog.w(TAG, msg); 13791 throw new SecurityException(msg); 13792 } 13793 synchronized (this) { 13794 if (mCurrentUserId == userId) { 13795 return true; 13796 } 13797 13798 // If the user we are switching to is not currently started, then 13799 // we need to start it now. 13800 if (mStartedUsers.get(userId) == null) { 13801 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13802 } 13803 13804 mCurrentUserId = userId; 13805 boolean haveActivities = mMainStack.switchUser(userId); 13806 if (!haveActivities) { 13807 startHomeActivityLocked(userId, mStartedUsers.get(userId)); 13808 } 13809 } 13810 13811 long ident = Binder.clearCallingIdentity(); 13812 try { 13813 // Inform of user switch 13814 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 13815 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13816 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL, 13817 android.Manifest.permission.MANAGE_USERS); 13818 } finally { 13819 Binder.restoreCallingIdentity(ident); 13820 } 13821 13822 return true; 13823 } 13824 13825 void finishUserSwitch(UserStartedState uss) { 13826 synchronized (this) { 13827 if (uss.mState == UserStartedState.STATE_BOOTING 13828 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 13829 uss.mState = UserStartedState.STATE_RUNNING; 13830 final int userId = uss.mHandle.getIdentifier(); 13831 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 13832 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13833 broadcastIntentLocked(null, null, intent, 13834 null, null, 0, null, null, 13835 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 13836 false, false, MY_PID, Process.SYSTEM_UID, userId); 13837 } 13838 } 13839 } 13840 13841 @Override 13842 public int stopUser(final int userId, final IStopUserCallback callback) { 13843 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13844 != PackageManager.PERMISSION_GRANTED) { 13845 String msg = "Permission Denial: switchUser() from pid=" 13846 + Binder.getCallingPid() 13847 + ", uid=" + Binder.getCallingUid() 13848 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13849 Slog.w(TAG, msg); 13850 throw new SecurityException(msg); 13851 } 13852 if (userId <= 0) { 13853 throw new IllegalArgumentException("Can't stop primary user " + userId); 13854 } 13855 synchronized (this) { 13856 if (mCurrentUserId == userId) { 13857 return ActivityManager.USER_OP_IS_CURRENT; 13858 } 13859 13860 final UserStartedState uss = mStartedUsers.get(userId); 13861 if (uss == null) { 13862 // User is not started, nothing to do... but we do need to 13863 // callback if requested. 13864 if (callback != null) { 13865 mHandler.post(new Runnable() { 13866 @Override 13867 public void run() { 13868 try { 13869 callback.userStopped(userId); 13870 } catch (RemoteException e) { 13871 } 13872 } 13873 }); 13874 } 13875 return ActivityManager.USER_OP_SUCCESS; 13876 } 13877 13878 if (callback != null) { 13879 uss.mStopCallbacks.add(callback); 13880 } 13881 13882 if (uss.mState != UserStartedState.STATE_STOPPING) { 13883 uss.mState = UserStartedState.STATE_STOPPING; 13884 13885 long ident = Binder.clearCallingIdentity(); 13886 try { 13887 // Inform of user switch 13888 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13889 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 13890 @Override 13891 public void performReceive(Intent intent, int resultCode, String data, 13892 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 13893 finishUserStop(uss); 13894 } 13895 }; 13896 broadcastIntentLocked(null, null, intent, 13897 null, resultReceiver, 0, null, null, null, 13898 true, false, MY_PID, Process.SYSTEM_UID, userId); 13899 } finally { 13900 Binder.restoreCallingIdentity(ident); 13901 } 13902 } 13903 } 13904 13905 return ActivityManager.USER_OP_SUCCESS; 13906 } 13907 13908 void finishUserStop(UserStartedState uss) { 13909 final int userId = uss.mHandle.getIdentifier(); 13910 boolean stopped; 13911 ArrayList<IStopUserCallback> callbacks; 13912 synchronized (this) { 13913 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 13914 if (uss.mState != UserStartedState.STATE_STOPPING 13915 || mStartedUsers.get(userId) != uss) { 13916 stopped = false; 13917 } else { 13918 stopped = true; 13919 // User can no longer run. 13920 mStartedUsers.remove(userId); 13921 13922 // Clean up all state and processes associated with the user. 13923 // Kill all the processes for the user. 13924 forceStopUserLocked(userId); 13925 } 13926 } 13927 13928 for (int i=0; i<callbacks.size(); i++) { 13929 try { 13930 if (stopped) callbacks.get(i).userStopped(userId); 13931 else callbacks.get(i).userStopAborted(userId); 13932 } catch (RemoteException e) { 13933 } 13934 } 13935 } 13936 13937 @Override 13938 public UserInfo getCurrentUser() { 13939 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13940 != PackageManager.PERMISSION_GRANTED) { 13941 String msg = "Permission Denial: getCurrentUser() from pid=" 13942 + Binder.getCallingPid() 13943 + ", uid=" + Binder.getCallingUid() 13944 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13945 Slog.w(TAG, msg); 13946 throw new SecurityException(msg); 13947 } 13948 synchronized (this) { 13949 return getUserManager().getUserInfo(mCurrentUserId); 13950 } 13951 } 13952 13953 private boolean userExists(int userId) { 13954 UserInfo user = getUserManager().getUserInfo(userId); 13955 return user != null; 13956 } 13957 13958 UserManager getUserManager() { 13959 if (mUserManager == null) { 13960 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13961 } 13962 return mUserManager; 13963 } 13964 13965 private void checkValidCaller(int uid, int userId) { 13966 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 13967 13968 throw new SecurityException("Caller uid=" + uid 13969 + " is not privileged to communicate with user=" + userId); 13970 } 13971 13972 private int applyUserId(int uid, int userId) { 13973 return UserHandle.getUid(userId, uid); 13974 } 13975 13976 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 13977 if (info == null) return null; 13978 ApplicationInfo newInfo = new ApplicationInfo(info); 13979 newInfo.uid = applyUserId(info.uid, userId); 13980 newInfo.dataDir = USER_DATA_DIR + userId + "/" 13981 + info.packageName; 13982 return newInfo; 13983 } 13984 13985 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 13986 if (aInfo == null 13987 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 13988 return aInfo; 13989 } 13990 13991 ActivityInfo info = new ActivityInfo(aInfo); 13992 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 13993 return info; 13994 } 13995} 13996