ActivityManagerService.java revision 5962b12bedc4a1d0354816c1cd6b06ba04f6d807
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Arrays; 151import java.util.Collections; 152import java.util.Comparator; 153import java.util.HashMap; 154import java.util.HashSet; 155import java.util.Iterator; 156import java.util.List; 157import java.util.Locale; 158import java.util.Map; 159import java.util.Set; 160import java.util.concurrent.atomic.AtomicBoolean; 161import java.util.concurrent.atomic.AtomicLong; 162 163public final class ActivityManagerService extends ActivityManagerNative 164 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 165 private static final String USER_DATA_DIR = "/data/user/"; 166 static final String TAG = "ActivityManager"; 167 static final String TAG_MU = "ActivityManagerServiceMU"; 168 static final boolean DEBUG = false; 169 static final boolean localLOGV = DEBUG; 170 static final boolean DEBUG_SWITCH = localLOGV || false; 171 static final boolean DEBUG_TASKS = localLOGV || false; 172 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 173 static final boolean DEBUG_PAUSE = localLOGV || false; 174 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 175 static final boolean DEBUG_TRANSITION = localLOGV || false; 176 static final boolean DEBUG_BROADCAST = localLOGV || false; 177 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_SERVICE = localLOGV || false; 180 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 181 static final boolean DEBUG_VISBILITY = localLOGV || false; 182 static final boolean DEBUG_PROCESSES = localLOGV || false; 183 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 184 static final boolean DEBUG_CLEANUP = localLOGV || false; 185 static final boolean DEBUG_PROVIDER = localLOGV || false; 186 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 187 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 188 static final boolean DEBUG_RESULTS = localLOGV || false; 189 static final boolean DEBUG_BACKUP = localLOGV || false; 190 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 191 static final boolean DEBUG_POWER = localLOGV || false; 192 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 193 static final boolean DEBUG_MU = localLOGV || false; 194 static final boolean VALIDATE_TOKENS = false; 195 static final boolean SHOW_ACTIVITY_START_TIME = true; 196 197 // Control over CPU and battery monitoring. 198 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 199 static final boolean MONITOR_CPU_USAGE = true; 200 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 201 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 202 static final boolean MONITOR_THREAD_CPU_USAGE = false; 203 204 // The flags that are set for all calls we make to the package manager. 205 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 206 207 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 208 209 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 210 211 // Maximum number of recent tasks that we can remember. 212 static final int MAX_RECENT_TASKS = 20; 213 214 // Amount of time after a call to stopAppSwitches() during which we will 215 // prevent further untrusted switches from happening. 216 static final long APP_SWITCH_DELAY_TIME = 5*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. 220 static final int PROC_START_TIMEOUT = 10*1000; 221 222 // How long we wait for a launched process to attach to the activity manager 223 // before we decide it's never going to come up for real, when the process was 224 // started with a wrapper for instrumentation (such as Valgrind) because it 225 // could take much longer than usual. 226 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 227 228 // How long to wait after going idle before forcing apps to GC. 229 static final int GC_TIMEOUT = 5*1000; 230 231 // The minimum amount of time between successive GC requests for a process. 232 static final int GC_MIN_INTERVAL = 60*1000; 233 234 // The rate at which we check for apps using excessive power -- 15 mins. 235 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on wake locks to start killing things. 239 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // The minimum sample duration we will allow before deciding we have 242 // enough data on CPU usage to start killing things. 243 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 244 245 // How long we allow a receiver to run before giving up on it. 246 static final int BROADCAST_FG_TIMEOUT = 10*1000; 247 static final int BROADCAST_BG_TIMEOUT = 60*1000; 248 249 // How long we wait until we timeout on key dispatching. 250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 251 252 // How long we wait until we timeout on key dispatching during instrumentation. 253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 254 255 // Amount of time we wait for observers to handle a user switch before 256 // giving up on them and unfreezing the screen. 257 static final int USER_SWITCH_TIMEOUT = 2*1000; 258 259 // Maximum number of users we allow to be running at a time. 260 static final int MAX_RUNNING_USERS = 3; 261 262 static final int MY_PID = Process.myPid(); 263 264 static final String[] EMPTY_STRING_ARRAY = new String[0]; 265 266 public ActivityStack mMainStack; 267 268 private final boolean mHeadless; 269 270 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 271 // default actuion automatically. Important for devices without direct input 272 // devices. 273 private boolean mShowDialogs = true; 274 275 /** 276 * Description of a request to start a new activity, which has been held 277 * due to app switches being disabled. 278 */ 279 static class PendingActivityLaunch { 280 ActivityRecord r; 281 ActivityRecord sourceRecord; 282 int startFlags; 283 } 284 285 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 286 = new ArrayList<PendingActivityLaunch>(); 287 288 289 BroadcastQueue mFgBroadcastQueue; 290 BroadcastQueue mBgBroadcastQueue; 291 // Convenient for easy iteration over the queues. Foreground is first 292 // so that dispatch of foreground broadcasts gets precedence. 293 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 294 295 BroadcastQueue broadcastQueueForIntent(Intent intent) { 296 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 297 if (DEBUG_BACKGROUND_BROADCAST) { 298 Slog.i(TAG, "Broadcast intent " + intent + " on " 299 + (isFg ? "foreground" : "background") 300 + " queue"); 301 } 302 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 303 } 304 305 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 306 for (BroadcastQueue queue : mBroadcastQueues) { 307 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 308 if (r != null) { 309 return r; 310 } 311 } 312 return null; 313 } 314 315 /** 316 * Activity we have told the window manager to have key focus. 317 */ 318 ActivityRecord mFocusedActivity = null; 319 /** 320 * List of intents that were used to start the most recent tasks. 321 */ 322 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 323 324 /** 325 * Process management. 326 */ 327 final ProcessList mProcessList = new ProcessList(); 328 329 /** 330 * All of the applications we currently have running organized by name. 331 * The keys are strings of the application package name (as 332 * returned by the package manager), and the keys are ApplicationRecord 333 * objects. 334 */ 335 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 336 337 /** 338 * The currently running isolated processes. 339 */ 340 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 341 342 /** 343 * Counter for assigning isolated process uids, to avoid frequently reusing the 344 * same ones. 345 */ 346 int mNextIsolatedProcessUid = 0; 347 348 /** 349 * The currently running heavy-weight process, if any. 350 */ 351 ProcessRecord mHeavyWeightProcess = null; 352 353 /** 354 * The last time that various processes have crashed. 355 */ 356 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 357 358 /** 359 * Set of applications that we consider to be bad, and will reject 360 * incoming broadcasts from (which the user has no control over). 361 * Processes are added to this set when they have crashed twice within 362 * a minimum amount of time; they are removed from it when they are 363 * later restarted (hopefully due to some user action). The value is the 364 * time it was added to the list. 365 */ 366 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 367 368 /** 369 * All of the processes we currently have running organized by pid. 370 * The keys are the pid running the application. 371 * 372 * <p>NOTE: This object is protected by its own lock, NOT the global 373 * activity manager lock! 374 */ 375 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 376 377 /** 378 * All of the processes that have been forced to be foreground. The key 379 * is the pid of the caller who requested it (we hold a death 380 * link on it). 381 */ 382 abstract class ForegroundToken implements IBinder.DeathRecipient { 383 int pid; 384 IBinder token; 385 } 386 final SparseArray<ForegroundToken> mForegroundProcesses 387 = new SparseArray<ForegroundToken>(); 388 389 /** 390 * List of records for processes that someone had tried to start before the 391 * system was ready. We don't start them at that point, but ensure they 392 * are started by the time booting is complete. 393 */ 394 final ArrayList<ProcessRecord> mProcessesOnHold 395 = new ArrayList<ProcessRecord>(); 396 397 /** 398 * List of persistent applications that are in the process 399 * of being started. 400 */ 401 final ArrayList<ProcessRecord> mPersistentStartingProcesses 402 = new ArrayList<ProcessRecord>(); 403 404 /** 405 * Processes that are being forcibly torn down. 406 */ 407 final ArrayList<ProcessRecord> mRemovedProcesses 408 = new ArrayList<ProcessRecord>(); 409 410 /** 411 * List of running applications, sorted by recent usage. 412 * The first entry in the list is the least recently used. 413 * It contains ApplicationRecord objects. This list does NOT include 414 * any persistent application records (since we never want to exit them). 415 */ 416 final ArrayList<ProcessRecord> mLruProcesses 417 = new ArrayList<ProcessRecord>(); 418 419 /** 420 * List of processes that should gc as soon as things are idle. 421 */ 422 final ArrayList<ProcessRecord> mProcessesToGc 423 = new ArrayList<ProcessRecord>(); 424 425 /** 426 * This is the process holding what we currently consider to be 427 * the "home" activity. 428 */ 429 ProcessRecord mHomeProcess; 430 431 /** 432 * This is the process holding the activity the user last visited that 433 * is in a different process from the one they are currently in. 434 */ 435 ProcessRecord mPreviousProcess; 436 437 /** 438 * The time at which the previous process was last visible. 439 */ 440 long mPreviousProcessVisibleTime; 441 442 /** 443 * Which uses have been started, so are allowed to run code. 444 */ 445 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 446 447 /** 448 * LRU list of history of current users. Most recently current is at the end. 449 */ 450 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 451 452 /** 453 * Constant array of the users that are currently started. 454 */ 455 int[] mStartedUserArray = new int[] { 0 }; 456 457 /** 458 * Registered observers of the user switching mechanics. 459 */ 460 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 461 = new RemoteCallbackList<IUserSwitchObserver>(); 462 463 /** 464 * Currently active user switch. 465 */ 466 Object mCurUserSwitchCallback; 467 468 /** 469 * Packages that the user has asked to have run in screen size 470 * compatibility mode instead of filling the screen. 471 */ 472 final CompatModePackages mCompatModePackages; 473 474 /** 475 * Set of PendingResultRecord objects that are currently active. 476 */ 477 final HashSet mPendingResultRecords = new HashSet(); 478 479 /** 480 * Set of IntentSenderRecord objects that are currently active. 481 */ 482 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 483 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 484 485 /** 486 * Fingerprints (hashCode()) of stack traces that we've 487 * already logged DropBox entries for. Guarded by itself. If 488 * something (rogue user app) forces this over 489 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 490 */ 491 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 492 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 493 494 /** 495 * Strict Mode background batched logging state. 496 * 497 * The string buffer is guarded by itself, and its lock is also 498 * used to determine if another batched write is already 499 * in-flight. 500 */ 501 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 502 503 /** 504 * Keeps track of all IIntentReceivers that have been registered for 505 * broadcasts. Hash keys are the receiver IBinder, hash value is 506 * a ReceiverList. 507 */ 508 final HashMap mRegisteredReceivers = new HashMap(); 509 510 /** 511 * Resolver for broadcast intents to registered receivers. 512 * Holds BroadcastFilter (subclass of IntentFilter). 513 */ 514 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 515 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 516 @Override 517 protected boolean allowFilterResult( 518 BroadcastFilter filter, List<BroadcastFilter> dest) { 519 IBinder target = filter.receiverList.receiver.asBinder(); 520 for (int i=dest.size()-1; i>=0; i--) { 521 if (dest.get(i).receiverList.receiver.asBinder() == target) { 522 return false; 523 } 524 } 525 return true; 526 } 527 528 @Override 529 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 530 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 531 || userId == filter.owningUserId) { 532 return super.newResult(filter, match, userId); 533 } 534 return null; 535 } 536 537 @Override 538 protected BroadcastFilter[] newArray(int size) { 539 return new BroadcastFilter[size]; 540 } 541 542 @Override 543 protected String packageForFilter(BroadcastFilter filter) { 544 return filter.packageName; 545 } 546 }; 547 548 /** 549 * State of all active sticky broadcasts per user. Keys are the action of the 550 * sticky Intent, values are an ArrayList of all broadcasted intents with 551 * that action (which should usually be one). The SparseArray is keyed 552 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 553 * for stickies that are sent to all users. 554 */ 555 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 556 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 557 558 final ActiveServices mServices; 559 560 /** 561 * Backup/restore process management 562 */ 563 String mBackupAppName = null; 564 BackupRecord mBackupTarget = null; 565 566 /** 567 * List of PendingThumbnailsRecord objects of clients who are still 568 * waiting to receive all of the thumbnails for a task. 569 */ 570 final ArrayList mPendingThumbnails = new ArrayList(); 571 572 /** 573 * List of HistoryRecord objects that have been finished and must 574 * still report back to a pending thumbnail receiver. 575 */ 576 final ArrayList mCancelledThumbnails = new ArrayList(); 577 578 final ProviderMap mProviderMap; 579 580 /** 581 * List of content providers who have clients waiting for them. The 582 * application is currently being launched and the provider will be 583 * removed from this list once it is published. 584 */ 585 final ArrayList<ContentProviderRecord> mLaunchingProviders 586 = new ArrayList<ContentProviderRecord>(); 587 588 /** 589 * Global set of specific Uri permissions that have been granted. 590 */ 591 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 592 = new SparseArray<HashMap<Uri, UriPermission>>(); 593 594 CoreSettingsObserver mCoreSettingsObserver; 595 596 /** 597 * Thread-local storage used to carry caller permissions over through 598 * indirect content-provider access. 599 * @see #ActivityManagerService.openContentUri() 600 */ 601 private class Identity { 602 public int pid; 603 public int uid; 604 605 Identity(int _pid, int _uid) { 606 pid = _pid; 607 uid = _uid; 608 } 609 } 610 611 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 612 613 /** 614 * All information we have collected about the runtime performance of 615 * any user id that can impact battery performance. 616 */ 617 final BatteryStatsService mBatteryStatsService; 618 619 /** 620 * information about component usage 621 */ 622 final UsageStatsService mUsageStatsService; 623 624 /** 625 * Current configuration information. HistoryRecord objects are given 626 * a reference to this object to indicate which configuration they are 627 * currently running in, so this object must be kept immutable. 628 */ 629 Configuration mConfiguration = new Configuration(); 630 631 /** 632 * Current sequencing integer of the configuration, for skipping old 633 * configurations. 634 */ 635 int mConfigurationSeq = 0; 636 637 /** 638 * Hardware-reported OpenGLES version. 639 */ 640 final int GL_ES_VERSION; 641 642 /** 643 * List of initialization arguments to pass to all processes when binding applications to them. 644 * For example, references to the commonly used services. 645 */ 646 HashMap<String, IBinder> mAppBindArgs; 647 648 /** 649 * Temporary to avoid allocations. Protected by main lock. 650 */ 651 final StringBuilder mStringBuilder = new StringBuilder(256); 652 653 /** 654 * Used to control how we initialize the service. 655 */ 656 boolean mStartRunning = false; 657 ComponentName mTopComponent; 658 String mTopAction; 659 String mTopData; 660 boolean mProcessesReady = false; 661 boolean mSystemReady = false; 662 boolean mBooting = false; 663 boolean mWaitingUpdate = false; 664 boolean mDidUpdate = false; 665 boolean mOnBattery = false; 666 boolean mLaunchWarningShown = false; 667 668 Context mContext; 669 670 int mFactoryTest; 671 672 boolean mCheckedForSetup; 673 674 /** 675 * The time at which we will allow normal application switches again, 676 * after a call to {@link #stopAppSwitches()}. 677 */ 678 long mAppSwitchesAllowedTime; 679 680 /** 681 * This is set to true after the first switch after mAppSwitchesAllowedTime 682 * is set; any switches after that will clear the time. 683 */ 684 boolean mDidAppSwitch; 685 686 /** 687 * Last time (in realtime) at which we checked for power usage. 688 */ 689 long mLastPowerCheckRealtime; 690 691 /** 692 * Last time (in uptime) at which we checked for power usage. 693 */ 694 long mLastPowerCheckUptime; 695 696 /** 697 * Set while we are wanting to sleep, to prevent any 698 * activities from being started/resumed. 699 */ 700 boolean mSleeping = false; 701 702 /** 703 * State of external calls telling us if the device is asleep. 704 */ 705 boolean mWentToSleep = false; 706 707 /** 708 * State of external call telling us if the lock screen is shown. 709 */ 710 boolean mLockScreenShown = false; 711 712 /** 713 * Set if we are shutting down the system, similar to sleeping. 714 */ 715 boolean mShuttingDown = false; 716 717 /** 718 * Task identifier that activities are currently being started 719 * in. Incremented each time a new task is created. 720 * todo: Replace this with a TokenSpace class that generates non-repeating 721 * integers that won't wrap. 722 */ 723 int mCurTask = 1; 724 725 /** 726 * Current sequence id for oom_adj computation traversal. 727 */ 728 int mAdjSeq = 0; 729 730 /** 731 * Current sequence id for process LRU updating. 732 */ 733 int mLruSeq = 0; 734 735 /** 736 * Keep track of the non-hidden/empty process we last found, to help 737 * determine how to distribute hidden/empty processes next time. 738 */ 739 int mNumNonHiddenProcs = 0; 740 741 /** 742 * Keep track of the number of hidden procs, to balance oom adj 743 * distribution between those and empty procs. 744 */ 745 int mNumHiddenProcs = 0; 746 747 /** 748 * Keep track of the number of service processes we last found, to 749 * determine on the next iteration which should be B services. 750 */ 751 int mNumServiceProcs = 0; 752 int mNewNumServiceProcs = 0; 753 754 /** 755 * System monitoring: number of processes that died since the last 756 * N procs were started. 757 */ 758 int[] mProcDeaths = new int[20]; 759 760 /** 761 * This is set if we had to do a delayed dexopt of an app before launching 762 * it, to increasing the ANR timeouts in that case. 763 */ 764 boolean mDidDexOpt; 765 766 String mDebugApp = null; 767 boolean mWaitForDebugger = false; 768 boolean mDebugTransient = false; 769 String mOrigDebugApp = null; 770 boolean mOrigWaitForDebugger = false; 771 boolean mAlwaysFinishActivities = false; 772 IActivityController mController = null; 773 String mProfileApp = null; 774 ProcessRecord mProfileProc = null; 775 String mProfileFile; 776 ParcelFileDescriptor mProfileFd; 777 int mProfileType = 0; 778 boolean mAutoStopProfiler = false; 779 String mOpenGlTraceApp = null; 780 781 static class ProcessChangeItem { 782 static final int CHANGE_ACTIVITIES = 1<<0; 783 static final int CHANGE_IMPORTANCE= 1<<1; 784 int changes; 785 int uid; 786 int pid; 787 int importance; 788 boolean foregroundActivities; 789 } 790 791 final RemoteCallbackList<IProcessObserver> mProcessObservers 792 = new RemoteCallbackList<IProcessObserver>(); 793 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 794 795 final ArrayList<ProcessChangeItem> mPendingProcessChanges 796 = new ArrayList<ProcessChangeItem>(); 797 final ArrayList<ProcessChangeItem> mAvailProcessChanges 798 = new ArrayList<ProcessChangeItem>(); 799 800 /** 801 * Callback of last caller to {@link #requestPss}. 802 */ 803 Runnable mRequestPssCallback; 804 805 /** 806 * Remaining processes for which we are waiting results from the last 807 * call to {@link #requestPss}. 808 */ 809 final ArrayList<ProcessRecord> mRequestPssList 810 = new ArrayList<ProcessRecord>(); 811 812 /** 813 * Runtime statistics collection thread. This object's lock is used to 814 * protect all related state. 815 */ 816 final Thread mProcessStatsThread; 817 818 /** 819 * Used to collect process stats when showing not responding dialog. 820 * Protected by mProcessStatsThread. 821 */ 822 final ProcessStats mProcessStats = new ProcessStats( 823 MONITOR_THREAD_CPU_USAGE); 824 final AtomicLong mLastCpuTime = new AtomicLong(0); 825 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 826 827 long mLastWriteTime = 0; 828 829 /** 830 * Set to true after the system has finished booting. 831 */ 832 boolean mBooted = false; 833 834 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 835 int mProcessLimitOverride = -1; 836 837 WindowManagerService mWindowManager; 838 839 static ActivityManagerService mSelf; 840 static ActivityThread mSystemThread; 841 842 private int mCurrentUserId = 0; 843 private int[] mCurrentUserArray = new int[] { 0 }; 844 private UserManagerService mUserManager; 845 846 private final class AppDeathRecipient implements IBinder.DeathRecipient { 847 final ProcessRecord mApp; 848 final int mPid; 849 final IApplicationThread mAppThread; 850 851 AppDeathRecipient(ProcessRecord app, int pid, 852 IApplicationThread thread) { 853 if (localLOGV) Slog.v( 854 TAG, "New death recipient " + this 855 + " for thread " + thread.asBinder()); 856 mApp = app; 857 mPid = pid; 858 mAppThread = thread; 859 } 860 861 public void binderDied() { 862 if (localLOGV) Slog.v( 863 TAG, "Death received in " + this 864 + " for thread " + mAppThread.asBinder()); 865 synchronized(ActivityManagerService.this) { 866 appDiedLocked(mApp, mPid, mAppThread); 867 } 868 } 869 } 870 871 static final int SHOW_ERROR_MSG = 1; 872 static final int SHOW_NOT_RESPONDING_MSG = 2; 873 static final int SHOW_FACTORY_ERROR_MSG = 3; 874 static final int UPDATE_CONFIGURATION_MSG = 4; 875 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 876 static final int WAIT_FOR_DEBUGGER_MSG = 6; 877 static final int SERVICE_TIMEOUT_MSG = 12; 878 static final int UPDATE_TIME_ZONE = 13; 879 static final int SHOW_UID_ERROR_MSG = 14; 880 static final int IM_FEELING_LUCKY_MSG = 15; 881 static final int PROC_START_TIMEOUT_MSG = 20; 882 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 883 static final int KILL_APPLICATION_MSG = 22; 884 static final int FINALIZE_PENDING_INTENT_MSG = 23; 885 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 886 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 887 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 888 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 889 static final int CLEAR_DNS_CACHE = 28; 890 static final int UPDATE_HTTP_PROXY = 29; 891 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 892 static final int DISPATCH_PROCESSES_CHANGED = 31; 893 static final int DISPATCH_PROCESS_DIED = 32; 894 static final int REPORT_MEM_USAGE = 33; 895 static final int REPORT_USER_SWITCH_MSG = 34; 896 static final int CONTINUE_USER_SWITCH_MSG = 35; 897 static final int USER_SWITCH_TIMEOUT_MSG = 36; 898 899 static final int FIRST_ACTIVITY_STACK_MSG = 100; 900 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 901 static final int FIRST_COMPAT_MODE_MSG = 300; 902 903 AlertDialog mUidAlert; 904 CompatModeDialog mCompatModeDialog; 905 long mLastMemUsageReportTime = 0; 906 907 final Handler mHandler = new Handler() { 908 //public Handler() { 909 // if (localLOGV) Slog.v(TAG, "Handler started!"); 910 //} 911 912 public void handleMessage(Message msg) { 913 switch (msg.what) { 914 case SHOW_ERROR_MSG: { 915 HashMap data = (HashMap) msg.obj; 916 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 917 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 918 synchronized (ActivityManagerService.this) { 919 ProcessRecord proc = (ProcessRecord)data.get("app"); 920 AppErrorResult res = (AppErrorResult) data.get("result"); 921 if (proc != null && proc.crashDialog != null) { 922 Slog.e(TAG, "App already has crash dialog: " + proc); 923 if (res != null) { 924 res.set(0); 925 } 926 return; 927 } 928 if (!showBackground && UserHandle.getAppId(proc.uid) 929 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 930 && proc.pid != MY_PID) { 931 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 932 if (res != null) { 933 res.set(0); 934 } 935 return; 936 } 937 if (mShowDialogs && !mSleeping && !mShuttingDown) { 938 Dialog d = new AppErrorDialog(mContext, 939 ActivityManagerService.this, res, proc); 940 d.show(); 941 proc.crashDialog = d; 942 } else { 943 // The device is asleep, so just pretend that the user 944 // saw a crash dialog and hit "force quit". 945 if (res != null) { 946 res.set(0); 947 } 948 } 949 } 950 951 ensureBootCompleted(); 952 } break; 953 case SHOW_NOT_RESPONDING_MSG: { 954 synchronized (ActivityManagerService.this) { 955 HashMap data = (HashMap) msg.obj; 956 ProcessRecord proc = (ProcessRecord)data.get("app"); 957 if (proc != null && proc.anrDialog != null) { 958 Slog.e(TAG, "App already has anr dialog: " + proc); 959 return; 960 } 961 962 Intent intent = new Intent("android.intent.action.ANR"); 963 if (!mProcessesReady) { 964 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 965 | Intent.FLAG_RECEIVER_FOREGROUND); 966 } 967 broadcastIntentLocked(null, null, intent, 968 null, null, 0, null, null, null, 969 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 970 971 if (mShowDialogs) { 972 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 973 mContext, proc, (ActivityRecord)data.get("activity"), 974 msg.arg1 != 0); 975 d.show(); 976 proc.anrDialog = d; 977 } else { 978 // Just kill the app if there is no dialog to be shown. 979 killAppAtUsersRequest(proc, null); 980 } 981 } 982 983 ensureBootCompleted(); 984 } break; 985 case SHOW_STRICT_MODE_VIOLATION_MSG: { 986 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 987 synchronized (ActivityManagerService.this) { 988 ProcessRecord proc = (ProcessRecord) data.get("app"); 989 if (proc == null) { 990 Slog.e(TAG, "App not found when showing strict mode dialog."); 991 break; 992 } 993 if (proc.crashDialog != null) { 994 Slog.e(TAG, "App already has strict mode dialog: " + proc); 995 return; 996 } 997 AppErrorResult res = (AppErrorResult) data.get("result"); 998 if (mShowDialogs && !mSleeping && !mShuttingDown) { 999 Dialog d = new StrictModeViolationDialog(mContext, 1000 ActivityManagerService.this, res, proc); 1001 d.show(); 1002 proc.crashDialog = d; 1003 } else { 1004 // The device is asleep, so just pretend that the user 1005 // saw a crash dialog and hit "force quit". 1006 res.set(0); 1007 } 1008 } 1009 ensureBootCompleted(); 1010 } break; 1011 case SHOW_FACTORY_ERROR_MSG: { 1012 Dialog d = new FactoryErrorDialog( 1013 mContext, msg.getData().getCharSequence("msg")); 1014 d.show(); 1015 ensureBootCompleted(); 1016 } break; 1017 case UPDATE_CONFIGURATION_MSG: { 1018 final ContentResolver resolver = mContext.getContentResolver(); 1019 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1020 } break; 1021 case GC_BACKGROUND_PROCESSES_MSG: { 1022 synchronized (ActivityManagerService.this) { 1023 performAppGcsIfAppropriateLocked(); 1024 } 1025 } break; 1026 case WAIT_FOR_DEBUGGER_MSG: { 1027 synchronized (ActivityManagerService.this) { 1028 ProcessRecord app = (ProcessRecord)msg.obj; 1029 if (msg.arg1 != 0) { 1030 if (!app.waitedForDebugger) { 1031 Dialog d = new AppWaitingForDebuggerDialog( 1032 ActivityManagerService.this, 1033 mContext, app); 1034 app.waitDialog = d; 1035 app.waitedForDebugger = true; 1036 d.show(); 1037 } 1038 } else { 1039 if (app.waitDialog != null) { 1040 app.waitDialog.dismiss(); 1041 app.waitDialog = null; 1042 } 1043 } 1044 } 1045 } break; 1046 case SERVICE_TIMEOUT_MSG: { 1047 if (mDidDexOpt) { 1048 mDidDexOpt = false; 1049 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1050 nmsg.obj = msg.obj; 1051 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1052 return; 1053 } 1054 mServices.serviceTimeout((ProcessRecord)msg.obj); 1055 } break; 1056 case UPDATE_TIME_ZONE: { 1057 synchronized (ActivityManagerService.this) { 1058 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1059 ProcessRecord r = mLruProcesses.get(i); 1060 if (r.thread != null) { 1061 try { 1062 r.thread.updateTimeZone(); 1063 } catch (RemoteException ex) { 1064 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1065 } 1066 } 1067 } 1068 } 1069 } break; 1070 case CLEAR_DNS_CACHE: { 1071 synchronized (ActivityManagerService.this) { 1072 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1073 ProcessRecord r = mLruProcesses.get(i); 1074 if (r.thread != null) { 1075 try { 1076 r.thread.clearDnsCache(); 1077 } catch (RemoteException ex) { 1078 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1079 } 1080 } 1081 } 1082 } 1083 } break; 1084 case UPDATE_HTTP_PROXY: { 1085 ProxyProperties proxy = (ProxyProperties)msg.obj; 1086 String host = ""; 1087 String port = ""; 1088 String exclList = ""; 1089 if (proxy != null) { 1090 host = proxy.getHost(); 1091 port = Integer.toString(proxy.getPort()); 1092 exclList = proxy.getExclusionList(); 1093 } 1094 synchronized (ActivityManagerService.this) { 1095 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1096 ProcessRecord r = mLruProcesses.get(i); 1097 if (r.thread != null) { 1098 try { 1099 r.thread.setHttpProxy(host, port, exclList); 1100 } catch (RemoteException ex) { 1101 Slog.w(TAG, "Failed to update http proxy for: " + 1102 r.info.processName); 1103 } 1104 } 1105 } 1106 } 1107 } break; 1108 case SHOW_UID_ERROR_MSG: { 1109 String title = "System UIDs Inconsistent"; 1110 String text = "UIDs on the system are inconsistent, you need to wipe your" 1111 + " data partition or your device will be unstable."; 1112 Log.e(TAG, title + ": " + text); 1113 if (mShowDialogs) { 1114 // XXX This is a temporary dialog, no need to localize. 1115 AlertDialog d = new BaseErrorDialog(mContext); 1116 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1117 d.setCancelable(false); 1118 d.setTitle(title); 1119 d.setMessage(text); 1120 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1121 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1122 mUidAlert = d; 1123 d.show(); 1124 } 1125 } break; 1126 case IM_FEELING_LUCKY_MSG: { 1127 if (mUidAlert != null) { 1128 mUidAlert.dismiss(); 1129 mUidAlert = null; 1130 } 1131 } break; 1132 case PROC_START_TIMEOUT_MSG: { 1133 if (mDidDexOpt) { 1134 mDidDexOpt = false; 1135 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1136 nmsg.obj = msg.obj; 1137 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1138 return; 1139 } 1140 ProcessRecord app = (ProcessRecord)msg.obj; 1141 synchronized (ActivityManagerService.this) { 1142 processStartTimedOutLocked(app); 1143 } 1144 } break; 1145 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 doPendingActivityLaunchesLocked(true); 1148 } 1149 } break; 1150 case KILL_APPLICATION_MSG: { 1151 synchronized (ActivityManagerService.this) { 1152 int appid = msg.arg1; 1153 boolean restart = (msg.arg2 == 1); 1154 String pkg = (String) msg.obj; 1155 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1156 UserHandle.USER_ALL); 1157 } 1158 } break; 1159 case FINALIZE_PENDING_INTENT_MSG: { 1160 ((PendingIntentRecord)msg.obj).completeFinalize(); 1161 } break; 1162 case POST_HEAVY_NOTIFICATION_MSG: { 1163 INotificationManager inm = NotificationManager.getService(); 1164 if (inm == null) { 1165 return; 1166 } 1167 1168 ActivityRecord root = (ActivityRecord)msg.obj; 1169 ProcessRecord process = root.app; 1170 if (process == null) { 1171 return; 1172 } 1173 1174 try { 1175 Context context = mContext.createPackageContext(process.info.packageName, 0); 1176 String text = mContext.getString(R.string.heavy_weight_notification, 1177 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1178 Notification notification = new Notification(); 1179 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1180 notification.when = 0; 1181 notification.flags = Notification.FLAG_ONGOING_EVENT; 1182 notification.tickerText = text; 1183 notification.defaults = 0; // please be quiet 1184 notification.sound = null; 1185 notification.vibrate = null; 1186 notification.setLatestEventInfo(context, text, 1187 mContext.getText(R.string.heavy_weight_notification_detail), 1188 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1189 PendingIntent.FLAG_CANCEL_CURRENT, null, 1190 new UserHandle(root.userId))); 1191 1192 try { 1193 int[] outId = new int[1]; 1194 inm.enqueueNotificationWithTag("android", null, 1195 R.string.heavy_weight_notification, 1196 notification, outId, root.userId); 1197 } catch (RuntimeException e) { 1198 Slog.w(ActivityManagerService.TAG, 1199 "Error showing notification for heavy-weight app", e); 1200 } catch (RemoteException e) { 1201 } 1202 } catch (NameNotFoundException e) { 1203 Slog.w(TAG, "Unable to create context for heavy notification", e); 1204 } 1205 } break; 1206 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1207 INotificationManager inm = NotificationManager.getService(); 1208 if (inm == null) { 1209 return; 1210 } 1211 try { 1212 inm.cancelNotificationWithTag("android", null, 1213 R.string.heavy_weight_notification, msg.arg1); 1214 } catch (RuntimeException e) { 1215 Slog.w(ActivityManagerService.TAG, 1216 "Error canceling notification for service", e); 1217 } catch (RemoteException e) { 1218 } 1219 } break; 1220 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1221 synchronized (ActivityManagerService.this) { 1222 checkExcessivePowerUsageLocked(true); 1223 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1224 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1225 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1226 } 1227 } break; 1228 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1229 synchronized (ActivityManagerService.this) { 1230 ActivityRecord ar = (ActivityRecord)msg.obj; 1231 if (mCompatModeDialog != null) { 1232 if (mCompatModeDialog.mAppInfo.packageName.equals( 1233 ar.info.applicationInfo.packageName)) { 1234 return; 1235 } 1236 mCompatModeDialog.dismiss(); 1237 mCompatModeDialog = null; 1238 } 1239 if (ar != null && false) { 1240 if (mCompatModePackages.getPackageAskCompatModeLocked( 1241 ar.packageName)) { 1242 int mode = mCompatModePackages.computeCompatModeLocked( 1243 ar.info.applicationInfo); 1244 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1245 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1246 mCompatModeDialog = new CompatModeDialog( 1247 ActivityManagerService.this, mContext, 1248 ar.info.applicationInfo); 1249 mCompatModeDialog.show(); 1250 } 1251 } 1252 } 1253 } 1254 break; 1255 } 1256 case DISPATCH_PROCESSES_CHANGED: { 1257 dispatchProcessesChanged(); 1258 break; 1259 } 1260 case DISPATCH_PROCESS_DIED: { 1261 final int pid = msg.arg1; 1262 final int uid = msg.arg2; 1263 dispatchProcessDied(pid, uid); 1264 break; 1265 } 1266 case REPORT_MEM_USAGE: { 1267 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1268 if (!isDebuggable) { 1269 return; 1270 } 1271 synchronized (ActivityManagerService.this) { 1272 long now = SystemClock.uptimeMillis(); 1273 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1274 // Don't report more than every 5 minutes to somewhat 1275 // avoid spamming. 1276 return; 1277 } 1278 mLastMemUsageReportTime = now; 1279 } 1280 Thread thread = new Thread() { 1281 @Override public void run() { 1282 StringBuilder dropBuilder = new StringBuilder(1024); 1283 StringBuilder logBuilder = new StringBuilder(1024); 1284 StringWriter oomSw = new StringWriter(); 1285 PrintWriter oomPw = new PrintWriter(oomSw); 1286 StringWriter catSw = new StringWriter(); 1287 PrintWriter catPw = new PrintWriter(catSw); 1288 String[] emptyArgs = new String[] { }; 1289 StringBuilder tag = new StringBuilder(128); 1290 StringBuilder stack = new StringBuilder(128); 1291 tag.append("Low on memory -- "); 1292 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1293 tag, stack); 1294 dropBuilder.append(stack); 1295 dropBuilder.append('\n'); 1296 dropBuilder.append('\n'); 1297 String oomString = oomSw.toString(); 1298 dropBuilder.append(oomString); 1299 dropBuilder.append('\n'); 1300 logBuilder.append(oomString); 1301 try { 1302 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1303 "procrank", }); 1304 final InputStreamReader converter = new InputStreamReader( 1305 proc.getInputStream()); 1306 BufferedReader in = new BufferedReader(converter); 1307 String line; 1308 while (true) { 1309 line = in.readLine(); 1310 if (line == null) { 1311 break; 1312 } 1313 if (line.length() > 0) { 1314 logBuilder.append(line); 1315 logBuilder.append('\n'); 1316 } 1317 dropBuilder.append(line); 1318 dropBuilder.append('\n'); 1319 } 1320 converter.close(); 1321 } catch (IOException e) { 1322 } 1323 synchronized (ActivityManagerService.this) { 1324 catPw.println(); 1325 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1326 catPw.println(); 1327 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1328 false, false, null); 1329 catPw.println(); 1330 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1331 } 1332 dropBuilder.append(catSw.toString()); 1333 addErrorToDropBox("lowmem", null, "system_server", null, 1334 null, tag.toString(), dropBuilder.toString(), null, null); 1335 Slog.i(TAG, logBuilder.toString()); 1336 synchronized (ActivityManagerService.this) { 1337 long now = SystemClock.uptimeMillis(); 1338 if (mLastMemUsageReportTime < now) { 1339 mLastMemUsageReportTime = now; 1340 } 1341 } 1342 } 1343 }; 1344 thread.start(); 1345 break; 1346 } 1347 case REPORT_USER_SWITCH_MSG: { 1348 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1349 break; 1350 } 1351 case CONTINUE_USER_SWITCH_MSG: { 1352 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1353 break; 1354 } 1355 case USER_SWITCH_TIMEOUT_MSG: { 1356 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1357 break; 1358 } 1359 } 1360 } 1361 }; 1362 1363 public static void setSystemProcess() { 1364 try { 1365 ActivityManagerService m = mSelf; 1366 1367 ServiceManager.addService("activity", m, true); 1368 ServiceManager.addService("meminfo", new MemBinder(m)); 1369 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1370 ServiceManager.addService("dbinfo", new DbBinder(m)); 1371 if (MONITOR_CPU_USAGE) { 1372 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1373 } 1374 ServiceManager.addService("permission", new PermissionController(m)); 1375 1376 ApplicationInfo info = 1377 mSelf.mContext.getPackageManager().getApplicationInfo( 1378 "android", STOCK_PM_FLAGS); 1379 mSystemThread.installSystemApplicationInfo(info); 1380 1381 synchronized (mSelf) { 1382 ProcessRecord app = mSelf.newProcessRecordLocked( 1383 mSystemThread.getApplicationThread(), info, 1384 info.processName, false); 1385 app.persistent = true; 1386 app.pid = MY_PID; 1387 app.maxAdj = ProcessList.SYSTEM_ADJ; 1388 mSelf.mProcessNames.put(app.processName, app.uid, app); 1389 synchronized (mSelf.mPidsSelfLocked) { 1390 mSelf.mPidsSelfLocked.put(app.pid, app); 1391 } 1392 mSelf.updateLruProcessLocked(app, true); 1393 } 1394 } catch (PackageManager.NameNotFoundException e) { 1395 throw new RuntimeException( 1396 "Unable to find android system package", e); 1397 } 1398 } 1399 1400 public void setWindowManager(WindowManagerService wm) { 1401 mWindowManager = wm; 1402 } 1403 1404 public static final Context main(int factoryTest) { 1405 AThread thr = new AThread(); 1406 thr.start(); 1407 1408 synchronized (thr) { 1409 while (thr.mService == null) { 1410 try { 1411 thr.wait(); 1412 } catch (InterruptedException e) { 1413 } 1414 } 1415 } 1416 1417 ActivityManagerService m = thr.mService; 1418 mSelf = m; 1419 ActivityThread at = ActivityThread.systemMain(); 1420 mSystemThread = at; 1421 Context context = at.getSystemContext(); 1422 context.setTheme(android.R.style.Theme_Holo); 1423 m.mContext = context; 1424 m.mFactoryTest = factoryTest; 1425 m.mMainStack = new ActivityStack(m, context, true); 1426 1427 m.mBatteryStatsService.publish(context); 1428 m.mUsageStatsService.publish(context); 1429 1430 synchronized (thr) { 1431 thr.mReady = true; 1432 thr.notifyAll(); 1433 } 1434 1435 m.startRunning(null, null, null, null); 1436 1437 return context; 1438 } 1439 1440 public static ActivityManagerService self() { 1441 return mSelf; 1442 } 1443 1444 static class AThread extends Thread { 1445 ActivityManagerService mService; 1446 boolean mReady = false; 1447 1448 public AThread() { 1449 super("ActivityManager"); 1450 } 1451 1452 public void run() { 1453 Looper.prepare(); 1454 1455 android.os.Process.setThreadPriority( 1456 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1457 android.os.Process.setCanSelfBackground(false); 1458 1459 ActivityManagerService m = new ActivityManagerService(); 1460 1461 synchronized (this) { 1462 mService = m; 1463 notifyAll(); 1464 } 1465 1466 synchronized (this) { 1467 while (!mReady) { 1468 try { 1469 wait(); 1470 } catch (InterruptedException e) { 1471 } 1472 } 1473 } 1474 1475 // For debug builds, log event loop stalls to dropbox for analysis. 1476 if (StrictMode.conditionallyEnableDebugLogging()) { 1477 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1478 } 1479 1480 Looper.loop(); 1481 } 1482 } 1483 1484 static class MemBinder extends Binder { 1485 ActivityManagerService mActivityManagerService; 1486 MemBinder(ActivityManagerService activityManagerService) { 1487 mActivityManagerService = activityManagerService; 1488 } 1489 1490 @Override 1491 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1492 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1493 != PackageManager.PERMISSION_GRANTED) { 1494 pw.println("Permission Denial: can't dump meminfo from from pid=" 1495 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1496 + " without permission " + android.Manifest.permission.DUMP); 1497 return; 1498 } 1499 1500 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1501 false, null, null, null); 1502 } 1503 } 1504 1505 static class GraphicsBinder extends Binder { 1506 ActivityManagerService mActivityManagerService; 1507 GraphicsBinder(ActivityManagerService activityManagerService) { 1508 mActivityManagerService = activityManagerService; 1509 } 1510 1511 @Override 1512 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1513 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1514 != PackageManager.PERMISSION_GRANTED) { 1515 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1516 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1517 + " without permission " + android.Manifest.permission.DUMP); 1518 return; 1519 } 1520 1521 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1522 } 1523 } 1524 1525 static class DbBinder extends Binder { 1526 ActivityManagerService mActivityManagerService; 1527 DbBinder(ActivityManagerService activityManagerService) { 1528 mActivityManagerService = activityManagerService; 1529 } 1530 1531 @Override 1532 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1533 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1534 != PackageManager.PERMISSION_GRANTED) { 1535 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1536 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1537 + " without permission " + android.Manifest.permission.DUMP); 1538 return; 1539 } 1540 1541 mActivityManagerService.dumpDbInfo(fd, pw, args); 1542 } 1543 } 1544 1545 static class CpuBinder extends Binder { 1546 ActivityManagerService mActivityManagerService; 1547 CpuBinder(ActivityManagerService activityManagerService) { 1548 mActivityManagerService = activityManagerService; 1549 } 1550 1551 @Override 1552 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1553 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1554 != PackageManager.PERMISSION_GRANTED) { 1555 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1556 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1557 + " without permission " + android.Manifest.permission.DUMP); 1558 return; 1559 } 1560 1561 synchronized (mActivityManagerService.mProcessStatsThread) { 1562 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1563 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1564 SystemClock.uptimeMillis())); 1565 } 1566 } 1567 } 1568 1569 private ActivityManagerService() { 1570 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1571 1572 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1573 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1574 mBroadcastQueues[0] = mFgBroadcastQueue; 1575 mBroadcastQueues[1] = mBgBroadcastQueue; 1576 1577 mServices = new ActiveServices(this); 1578 mProviderMap = new ProviderMap(this); 1579 1580 File dataDir = Environment.getDataDirectory(); 1581 File systemDir = new File(dataDir, "system"); 1582 systemDir.mkdirs(); 1583 mBatteryStatsService = new BatteryStatsService(new File( 1584 systemDir, "batterystats.bin").toString()); 1585 mBatteryStatsService.getActiveStatistics().readLocked(); 1586 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1587 mOnBattery = DEBUG_POWER ? true 1588 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1589 mBatteryStatsService.getActiveStatistics().setCallback(this); 1590 1591 mUsageStatsService = new UsageStatsService(new File( 1592 systemDir, "usagestats").toString()); 1593 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1594 1595 // User 0 is the first and only user that runs at boot. 1596 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1597 mUserLru.add(Integer.valueOf(0)); 1598 updateStartedUserArrayLocked(); 1599 1600 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1601 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1602 1603 mConfiguration.setToDefaults(); 1604 mConfiguration.setLocale(Locale.getDefault()); 1605 1606 mConfigurationSeq = mConfiguration.seq = 1; 1607 mProcessStats.init(); 1608 1609 mCompatModePackages = new CompatModePackages(this, systemDir); 1610 1611 // Add ourself to the Watchdog monitors. 1612 Watchdog.getInstance().addMonitor(this); 1613 1614 mProcessStatsThread = new Thread("ProcessStats") { 1615 public void run() { 1616 while (true) { 1617 try { 1618 try { 1619 synchronized(this) { 1620 final long now = SystemClock.uptimeMillis(); 1621 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1622 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1623 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1624 // + ", write delay=" + nextWriteDelay); 1625 if (nextWriteDelay < nextCpuDelay) { 1626 nextCpuDelay = nextWriteDelay; 1627 } 1628 if (nextCpuDelay > 0) { 1629 mProcessStatsMutexFree.set(true); 1630 this.wait(nextCpuDelay); 1631 } 1632 } 1633 } catch (InterruptedException e) { 1634 } 1635 updateCpuStatsNow(); 1636 } catch (Exception e) { 1637 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1638 } 1639 } 1640 } 1641 }; 1642 mProcessStatsThread.start(); 1643 } 1644 1645 @Override 1646 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1647 throws RemoteException { 1648 if (code == SYSPROPS_TRANSACTION) { 1649 // We need to tell all apps about the system property change. 1650 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1651 synchronized(this) { 1652 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1653 final int NA = apps.size(); 1654 for (int ia=0; ia<NA; ia++) { 1655 ProcessRecord app = apps.valueAt(ia); 1656 if (app.thread != null) { 1657 procs.add(app.thread.asBinder()); 1658 } 1659 } 1660 } 1661 } 1662 1663 int N = procs.size(); 1664 for (int i=0; i<N; i++) { 1665 Parcel data2 = Parcel.obtain(); 1666 try { 1667 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1668 } catch (RemoteException e) { 1669 } 1670 data2.recycle(); 1671 } 1672 } 1673 try { 1674 return super.onTransact(code, data, reply, flags); 1675 } catch (RuntimeException e) { 1676 // The activity manager only throws security exceptions, so let's 1677 // log all others. 1678 if (!(e instanceof SecurityException)) { 1679 Slog.e(TAG, "Activity Manager Crash", e); 1680 } 1681 throw e; 1682 } 1683 } 1684 1685 void updateCpuStats() { 1686 final long now = SystemClock.uptimeMillis(); 1687 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1688 return; 1689 } 1690 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1691 synchronized (mProcessStatsThread) { 1692 mProcessStatsThread.notify(); 1693 } 1694 } 1695 } 1696 1697 void updateCpuStatsNow() { 1698 synchronized (mProcessStatsThread) { 1699 mProcessStatsMutexFree.set(false); 1700 final long now = SystemClock.uptimeMillis(); 1701 boolean haveNewCpuStats = false; 1702 1703 if (MONITOR_CPU_USAGE && 1704 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1705 mLastCpuTime.set(now); 1706 haveNewCpuStats = true; 1707 mProcessStats.update(); 1708 //Slog.i(TAG, mProcessStats.printCurrentState()); 1709 //Slog.i(TAG, "Total CPU usage: " 1710 // + mProcessStats.getTotalCpuPercent() + "%"); 1711 1712 // Slog the cpu usage if the property is set. 1713 if ("true".equals(SystemProperties.get("events.cpu"))) { 1714 int user = mProcessStats.getLastUserTime(); 1715 int system = mProcessStats.getLastSystemTime(); 1716 int iowait = mProcessStats.getLastIoWaitTime(); 1717 int irq = mProcessStats.getLastIrqTime(); 1718 int softIrq = mProcessStats.getLastSoftIrqTime(); 1719 int idle = mProcessStats.getLastIdleTime(); 1720 1721 int total = user + system + iowait + irq + softIrq + idle; 1722 if (total == 0) total = 1; 1723 1724 EventLog.writeEvent(EventLogTags.CPU, 1725 ((user+system+iowait+irq+softIrq) * 100) / total, 1726 (user * 100) / total, 1727 (system * 100) / total, 1728 (iowait * 100) / total, 1729 (irq * 100) / total, 1730 (softIrq * 100) / total); 1731 } 1732 } 1733 1734 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1735 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1736 synchronized(bstats) { 1737 synchronized(mPidsSelfLocked) { 1738 if (haveNewCpuStats) { 1739 if (mOnBattery) { 1740 int perc = bstats.startAddingCpuLocked(); 1741 int totalUTime = 0; 1742 int totalSTime = 0; 1743 final int N = mProcessStats.countStats(); 1744 for (int i=0; i<N; i++) { 1745 ProcessStats.Stats st = mProcessStats.getStats(i); 1746 if (!st.working) { 1747 continue; 1748 } 1749 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1750 int otherUTime = (st.rel_utime*perc)/100; 1751 int otherSTime = (st.rel_stime*perc)/100; 1752 totalUTime += otherUTime; 1753 totalSTime += otherSTime; 1754 if (pr != null) { 1755 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1756 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1757 st.rel_stime-otherSTime); 1758 ps.addSpeedStepTimes(cpuSpeedTimes); 1759 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1760 } else { 1761 BatteryStatsImpl.Uid.Proc ps = 1762 bstats.getProcessStatsLocked(st.name, st.pid); 1763 if (ps != null) { 1764 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1765 st.rel_stime-otherSTime); 1766 ps.addSpeedStepTimes(cpuSpeedTimes); 1767 } 1768 } 1769 } 1770 bstats.finishAddingCpuLocked(perc, totalUTime, 1771 totalSTime, cpuSpeedTimes); 1772 } 1773 } 1774 } 1775 1776 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1777 mLastWriteTime = now; 1778 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1779 } 1780 } 1781 } 1782 } 1783 1784 @Override 1785 public void batteryNeedsCpuUpdate() { 1786 updateCpuStatsNow(); 1787 } 1788 1789 @Override 1790 public void batteryPowerChanged(boolean onBattery) { 1791 // When plugging in, update the CPU stats first before changing 1792 // the plug state. 1793 updateCpuStatsNow(); 1794 synchronized (this) { 1795 synchronized(mPidsSelfLocked) { 1796 mOnBattery = DEBUG_POWER ? true : onBattery; 1797 } 1798 } 1799 } 1800 1801 /** 1802 * Initialize the application bind args. These are passed to each 1803 * process when the bindApplication() IPC is sent to the process. They're 1804 * lazily setup to make sure the services are running when they're asked for. 1805 */ 1806 private HashMap<String, IBinder> getCommonServicesLocked() { 1807 if (mAppBindArgs == null) { 1808 mAppBindArgs = new HashMap<String, IBinder>(); 1809 1810 // Setup the application init args 1811 mAppBindArgs.put("package", ServiceManager.getService("package")); 1812 mAppBindArgs.put("window", ServiceManager.getService("window")); 1813 mAppBindArgs.put(Context.ALARM_SERVICE, 1814 ServiceManager.getService(Context.ALARM_SERVICE)); 1815 } 1816 return mAppBindArgs; 1817 } 1818 1819 final void setFocusedActivityLocked(ActivityRecord r) { 1820 if (mFocusedActivity != r) { 1821 mFocusedActivity = r; 1822 if (r != null) { 1823 mWindowManager.setFocusedApp(r.appToken, true); 1824 } 1825 } 1826 } 1827 1828 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1829 // put it on the LRU to keep track of when it should be exited. 1830 int lrui = mLruProcesses.indexOf(app); 1831 if (lrui >= 0) mLruProcesses.remove(lrui); 1832 1833 int i = mLruProcesses.size()-1; 1834 int skipTop = 0; 1835 1836 app.lruSeq = mLruSeq; 1837 1838 // compute the new weight for this process. 1839 app.lastActivityTime = SystemClock.uptimeMillis(); 1840 if (app.activities.size() > 0) { 1841 // If this process has activities, we more strongly want to keep 1842 // it around. 1843 app.lruWeight = app.lastActivityTime; 1844 } else if (app.pubProviders.size() > 0) { 1845 // If this process contains content providers, we want to keep 1846 // it a little more strongly. 1847 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1848 // Also don't let it kick out the first few "real" hidden processes. 1849 skipTop = ProcessList.MIN_HIDDEN_APPS; 1850 } else { 1851 // If this process doesn't have activities, we less strongly 1852 // want to keep it around, and generally want to avoid getting 1853 // in front of any very recently used activities. 1854 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1855 // Also don't let it kick out the first few "real" hidden processes. 1856 skipTop = ProcessList.MIN_HIDDEN_APPS; 1857 } 1858 1859 while (i >= 0) { 1860 ProcessRecord p = mLruProcesses.get(i); 1861 // If this app shouldn't be in front of the first N background 1862 // apps, then skip over that many that are currently hidden. 1863 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1864 skipTop--; 1865 } 1866 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1867 mLruProcesses.add(i+1, app); 1868 break; 1869 } 1870 i--; 1871 } 1872 if (i < 0) { 1873 mLruProcesses.add(0, app); 1874 } 1875 1876 // If the app is currently using a content provider or service, 1877 // bump those processes as well. 1878 if (app.connections.size() > 0) { 1879 for (ConnectionRecord cr : app.connections) { 1880 if (cr.binding != null && cr.binding.service != null 1881 && cr.binding.service.app != null 1882 && cr.binding.service.app.lruSeq != mLruSeq) { 1883 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1884 } 1885 } 1886 } 1887 for (int j=app.conProviders.size()-1; j>=0; j--) { 1888 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1889 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1890 updateLruProcessInternalLocked(cpr.proc, i+1); 1891 } 1892 } 1893 } 1894 1895 final void updateLruProcessLocked(ProcessRecord app, 1896 boolean oomAdj) { 1897 mLruSeq++; 1898 updateLruProcessInternalLocked(app, 0); 1899 1900 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1901 if (oomAdj) { 1902 updateOomAdjLocked(); 1903 } 1904 } 1905 1906 final ProcessRecord getProcessRecordLocked( 1907 String processName, int uid) { 1908 if (uid == Process.SYSTEM_UID) { 1909 // The system gets to run in any process. If there are multiple 1910 // processes with the same uid, just pick the first (this 1911 // should never happen). 1912 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1913 processName); 1914 if (procs == null) return null; 1915 final int N = procs.size(); 1916 for (int i = 0; i < N; i++) { 1917 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1918 } 1919 } 1920 ProcessRecord proc = mProcessNames.get(processName, uid); 1921 return proc; 1922 } 1923 1924 void ensurePackageDexOpt(String packageName) { 1925 IPackageManager pm = AppGlobals.getPackageManager(); 1926 try { 1927 if (pm.performDexOpt(packageName)) { 1928 mDidDexOpt = true; 1929 } 1930 } catch (RemoteException e) { 1931 } 1932 } 1933 1934 boolean isNextTransitionForward() { 1935 int transit = mWindowManager.getPendingAppTransition(); 1936 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1937 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1938 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1939 } 1940 1941 final ProcessRecord startProcessLocked(String processName, 1942 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1943 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1944 boolean isolated) { 1945 ProcessRecord app; 1946 if (!isolated) { 1947 app = getProcessRecordLocked(processName, info.uid); 1948 } else { 1949 // If this is an isolated process, it can't re-use an existing process. 1950 app = null; 1951 } 1952 // We don't have to do anything more if: 1953 // (1) There is an existing application record; and 1954 // (2) The caller doesn't think it is dead, OR there is no thread 1955 // object attached to it so we know it couldn't have crashed; and 1956 // (3) There is a pid assigned to it, so it is either starting or 1957 // already running. 1958 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1959 + " app=" + app + " knownToBeDead=" + knownToBeDead 1960 + " thread=" + (app != null ? app.thread : null) 1961 + " pid=" + (app != null ? app.pid : -1)); 1962 if (app != null && app.pid > 0) { 1963 if (!knownToBeDead || app.thread == null) { 1964 // We already have the app running, or are waiting for it to 1965 // come up (we have a pid but not yet its thread), so keep it. 1966 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1967 // If this is a new package in the process, add the package to the list 1968 app.addPackage(info.packageName); 1969 return app; 1970 } else { 1971 // An application record is attached to a previous process, 1972 // clean it up now. 1973 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 1974 handleAppDiedLocked(app, true, true); 1975 } 1976 } 1977 1978 String hostingNameStr = hostingName != null 1979 ? hostingName.flattenToShortString() : null; 1980 1981 if (!isolated) { 1982 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1983 // If we are in the background, then check to see if this process 1984 // is bad. If so, we will just silently fail. 1985 if (mBadProcesses.get(info.processName, info.uid) != null) { 1986 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1987 + "/" + info.processName); 1988 return null; 1989 } 1990 } else { 1991 // When the user is explicitly starting a process, then clear its 1992 // crash count so that we won't make it bad until they see at 1993 // least one crash dialog again, and make the process good again 1994 // if it had been bad. 1995 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1996 + "/" + info.processName); 1997 mProcessCrashTimes.remove(info.processName, info.uid); 1998 if (mBadProcesses.get(info.processName, info.uid) != null) { 1999 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2000 UserHandle.getUserId(info.uid), info.uid, 2001 info.processName); 2002 mBadProcesses.remove(info.processName, info.uid); 2003 if (app != null) { 2004 app.bad = false; 2005 } 2006 } 2007 } 2008 } 2009 2010 if (app == null) { 2011 app = newProcessRecordLocked(null, info, processName, isolated); 2012 if (app == null) { 2013 Slog.w(TAG, "Failed making new process record for " 2014 + processName + "/" + info.uid + " isolated=" + isolated); 2015 return null; 2016 } 2017 mProcessNames.put(processName, app.uid, app); 2018 if (isolated) { 2019 mIsolatedProcesses.put(app.uid, app); 2020 } 2021 } else { 2022 // If this is a new package in the process, add the package to the list 2023 app.addPackage(info.packageName); 2024 } 2025 2026 // If the system is not ready yet, then hold off on starting this 2027 // process until it is. 2028 if (!mProcessesReady 2029 && !isAllowedWhileBooting(info) 2030 && !allowWhileBooting) { 2031 if (!mProcessesOnHold.contains(app)) { 2032 mProcessesOnHold.add(app); 2033 } 2034 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2035 return app; 2036 } 2037 2038 startProcessLocked(app, hostingType, hostingNameStr); 2039 return (app.pid != 0) ? app : null; 2040 } 2041 2042 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2043 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2044 } 2045 2046 private final void startProcessLocked(ProcessRecord app, 2047 String hostingType, String hostingNameStr) { 2048 if (app.pid > 0 && app.pid != MY_PID) { 2049 synchronized (mPidsSelfLocked) { 2050 mPidsSelfLocked.remove(app.pid); 2051 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2052 } 2053 app.setPid(0); 2054 } 2055 2056 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2057 "startProcessLocked removing on hold: " + app); 2058 mProcessesOnHold.remove(app); 2059 2060 updateCpuStats(); 2061 2062 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2063 mProcDeaths[0] = 0; 2064 2065 try { 2066 int uid = app.uid; 2067 2068 int[] gids = null; 2069 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2070 if (!app.isolated) { 2071 int[] permGids = null; 2072 try { 2073 final PackageManager pm = mContext.getPackageManager(); 2074 permGids = pm.getPackageGids(app.info.packageName); 2075 2076 if (Environment.isExternalStorageEmulated()) { 2077 if (pm.checkPermission( 2078 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2079 app.info.packageName) == PERMISSION_GRANTED) { 2080 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2081 } else { 2082 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2083 } 2084 } 2085 } catch (PackageManager.NameNotFoundException e) { 2086 Slog.w(TAG, "Unable to retrieve gids", e); 2087 } 2088 2089 /* 2090 * Add shared application GID so applications can share some 2091 * resources like shared libraries 2092 */ 2093 if (permGids == null) { 2094 gids = new int[1]; 2095 } else { 2096 gids = new int[permGids.length + 1]; 2097 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2098 } 2099 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2100 } 2101 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2102 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2103 && mTopComponent != null 2104 && app.processName.equals(mTopComponent.getPackageName())) { 2105 uid = 0; 2106 } 2107 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2108 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2109 uid = 0; 2110 } 2111 } 2112 int debugFlags = 0; 2113 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2114 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2115 // Also turn on CheckJNI for debuggable apps. It's quite 2116 // awkward to turn on otherwise. 2117 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2118 } 2119 // Run the app in safe mode if its manifest requests so or the 2120 // system is booted in safe mode. 2121 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2122 Zygote.systemInSafeMode == true) { 2123 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2124 } 2125 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2126 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2127 } 2128 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2129 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2130 } 2131 if ("1".equals(SystemProperties.get("debug.assert"))) { 2132 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2133 } 2134 2135 // Start the process. It will either succeed and return a result containing 2136 // the PID of the new process, or else throw a RuntimeException. 2137 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2138 app.processName, uid, uid, gids, debugFlags, mountExternal, 2139 app.info.targetSdkVersion, null, null); 2140 2141 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2142 synchronized (bs) { 2143 if (bs.isOnBattery()) { 2144 app.batteryStats.incStartsLocked(); 2145 } 2146 } 2147 2148 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2149 UserHandle.getUserId(uid), startResult.pid, uid, 2150 app.processName, hostingType, 2151 hostingNameStr != null ? hostingNameStr : ""); 2152 2153 if (app.persistent) { 2154 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2155 } 2156 2157 StringBuilder buf = mStringBuilder; 2158 buf.setLength(0); 2159 buf.append("Start proc "); 2160 buf.append(app.processName); 2161 buf.append(" for "); 2162 buf.append(hostingType); 2163 if (hostingNameStr != null) { 2164 buf.append(" "); 2165 buf.append(hostingNameStr); 2166 } 2167 buf.append(": pid="); 2168 buf.append(startResult.pid); 2169 buf.append(" uid="); 2170 buf.append(uid); 2171 buf.append(" gids={"); 2172 if (gids != null) { 2173 for (int gi=0; gi<gids.length; gi++) { 2174 if (gi != 0) buf.append(", "); 2175 buf.append(gids[gi]); 2176 2177 } 2178 } 2179 buf.append("}"); 2180 Slog.i(TAG, buf.toString()); 2181 app.setPid(startResult.pid); 2182 app.usingWrapper = startResult.usingWrapper; 2183 app.removed = false; 2184 synchronized (mPidsSelfLocked) { 2185 this.mPidsSelfLocked.put(startResult.pid, app); 2186 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2187 msg.obj = app; 2188 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2189 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2190 } 2191 } catch (RuntimeException e) { 2192 // XXX do better error recovery. 2193 app.setPid(0); 2194 Slog.e(TAG, "Failure starting process " + app.processName, e); 2195 } 2196 } 2197 2198 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2199 if (resumed) { 2200 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2201 } else { 2202 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2203 } 2204 } 2205 2206 boolean startHomeActivityLocked(int userId) { 2207 if (mHeadless) { 2208 // Added because none of the other calls to ensureBootCompleted seem to fire 2209 // when running headless. 2210 ensureBootCompleted(); 2211 return false; 2212 } 2213 2214 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2215 && mTopAction == null) { 2216 // We are running in factory test mode, but unable to find 2217 // the factory test app, so just sit around displaying the 2218 // error message and don't try to start anything. 2219 return false; 2220 } 2221 Intent intent = new Intent( 2222 mTopAction, 2223 mTopData != null ? Uri.parse(mTopData) : null); 2224 intent.setComponent(mTopComponent); 2225 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2226 intent.addCategory(Intent.CATEGORY_HOME); 2227 } 2228 ActivityInfo aInfo = 2229 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2230 if (aInfo != null) { 2231 intent.setComponent(new ComponentName( 2232 aInfo.applicationInfo.packageName, aInfo.name)); 2233 // Don't do this if the home app is currently being 2234 // instrumented. 2235 aInfo = new ActivityInfo(aInfo); 2236 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2237 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2238 aInfo.applicationInfo.uid); 2239 if (app == null || app.instrumentationClass == null) { 2240 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2241 mMainStack.startActivityLocked(null, intent, null, aInfo, 2242 null, null, 0, 0, 0, 0, null, false, null); 2243 } 2244 } 2245 2246 return true; 2247 } 2248 2249 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2250 ActivityInfo ai = null; 2251 ComponentName comp = intent.getComponent(); 2252 try { 2253 if (comp != null) { 2254 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2255 } else { 2256 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2257 intent, 2258 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2259 flags, userId); 2260 2261 if (info != null) { 2262 ai = info.activityInfo; 2263 } 2264 } 2265 } catch (RemoteException e) { 2266 // ignore 2267 } 2268 2269 return ai; 2270 } 2271 2272 /** 2273 * Starts the "new version setup screen" if appropriate. 2274 */ 2275 void startSetupActivityLocked() { 2276 // Only do this once per boot. 2277 if (mCheckedForSetup) { 2278 return; 2279 } 2280 2281 // We will show this screen if the current one is a different 2282 // version than the last one shown, and we are not running in 2283 // low-level factory test mode. 2284 final ContentResolver resolver = mContext.getContentResolver(); 2285 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2286 Settings.Global.getInt(resolver, 2287 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2288 mCheckedForSetup = true; 2289 2290 // See if we should be showing the platform update setup UI. 2291 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2292 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2293 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2294 2295 // We don't allow third party apps to replace this. 2296 ResolveInfo ri = null; 2297 for (int i=0; ris != null && i<ris.size(); i++) { 2298 if ((ris.get(i).activityInfo.applicationInfo.flags 2299 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2300 ri = ris.get(i); 2301 break; 2302 } 2303 } 2304 2305 if (ri != null) { 2306 String vers = ri.activityInfo.metaData != null 2307 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2308 : null; 2309 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2310 vers = ri.activityInfo.applicationInfo.metaData.getString( 2311 Intent.METADATA_SETUP_VERSION); 2312 } 2313 String lastVers = Settings.Secure.getString( 2314 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2315 if (vers != null && !vers.equals(lastVers)) { 2316 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2317 intent.setComponent(new ComponentName( 2318 ri.activityInfo.packageName, ri.activityInfo.name)); 2319 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2320 null, null, 0, 0, 0, 0, null, false, null); 2321 } 2322 } 2323 } 2324 } 2325 2326 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2327 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2328 } 2329 2330 void enforceNotIsolatedCaller(String caller) { 2331 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2332 throw new SecurityException("Isolated process not allowed to call " + caller); 2333 } 2334 } 2335 2336 public int getFrontActivityScreenCompatMode() { 2337 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2338 synchronized (this) { 2339 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2340 } 2341 } 2342 2343 public void setFrontActivityScreenCompatMode(int mode) { 2344 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2345 "setFrontActivityScreenCompatMode"); 2346 synchronized (this) { 2347 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2348 } 2349 } 2350 2351 public int getPackageScreenCompatMode(String packageName) { 2352 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2353 synchronized (this) { 2354 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2355 } 2356 } 2357 2358 public void setPackageScreenCompatMode(String packageName, int mode) { 2359 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2360 "setPackageScreenCompatMode"); 2361 synchronized (this) { 2362 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2363 } 2364 } 2365 2366 public boolean getPackageAskScreenCompat(String packageName) { 2367 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2368 synchronized (this) { 2369 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2370 } 2371 } 2372 2373 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2374 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2375 "setPackageAskScreenCompat"); 2376 synchronized (this) { 2377 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2378 } 2379 } 2380 2381 void reportResumedActivityLocked(ActivityRecord r) { 2382 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2383 updateUsageStats(r, true); 2384 } 2385 2386 private void dispatchProcessesChanged() { 2387 int N; 2388 synchronized (this) { 2389 N = mPendingProcessChanges.size(); 2390 if (mActiveProcessChanges.length < N) { 2391 mActiveProcessChanges = new ProcessChangeItem[N]; 2392 } 2393 mPendingProcessChanges.toArray(mActiveProcessChanges); 2394 mAvailProcessChanges.addAll(mPendingProcessChanges); 2395 mPendingProcessChanges.clear(); 2396 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2397 } 2398 int i = mProcessObservers.beginBroadcast(); 2399 while (i > 0) { 2400 i--; 2401 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2402 if (observer != null) { 2403 try { 2404 for (int j=0; j<N; j++) { 2405 ProcessChangeItem item = mActiveProcessChanges[j]; 2406 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2407 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2408 + item.pid + " uid=" + item.uid + ": " 2409 + item.foregroundActivities); 2410 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2411 item.foregroundActivities); 2412 } 2413 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2414 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2415 + item.pid + " uid=" + item.uid + ": " + item.importance); 2416 observer.onImportanceChanged(item.pid, item.uid, 2417 item.importance); 2418 } 2419 } 2420 } catch (RemoteException e) { 2421 } 2422 } 2423 } 2424 mProcessObservers.finishBroadcast(); 2425 } 2426 2427 private void dispatchProcessDied(int pid, int uid) { 2428 int i = mProcessObservers.beginBroadcast(); 2429 while (i > 0) { 2430 i--; 2431 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2432 if (observer != null) { 2433 try { 2434 observer.onProcessDied(pid, uid); 2435 } catch (RemoteException e) { 2436 } 2437 } 2438 } 2439 mProcessObservers.finishBroadcast(); 2440 } 2441 2442 final void doPendingActivityLaunchesLocked(boolean doResume) { 2443 final int N = mPendingActivityLaunches.size(); 2444 if (N <= 0) { 2445 return; 2446 } 2447 for (int i=0; i<N; i++) { 2448 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2449 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2450 pal.startFlags, doResume && i == (N-1), null); 2451 } 2452 mPendingActivityLaunches.clear(); 2453 } 2454 2455 public final int startActivity(IApplicationThread caller, 2456 Intent intent, String resolvedType, IBinder resultTo, 2457 String resultWho, int requestCode, int startFlags, 2458 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2459 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2460 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2461 } 2462 2463 public final int startActivityAsUser(IApplicationThread caller, 2464 Intent intent, String resolvedType, IBinder resultTo, 2465 String resultWho, int requestCode, int startFlags, 2466 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2467 enforceNotIsolatedCaller("startActivity"); 2468 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2469 false, true, "startActivity", null); 2470 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2471 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2472 null, null, options, userId); 2473 } 2474 2475 public final WaitResult startActivityAndWait(IApplicationThread caller, 2476 Intent intent, String resolvedType, IBinder resultTo, 2477 String resultWho, int requestCode, int startFlags, String profileFile, 2478 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2479 enforceNotIsolatedCaller("startActivityAndWait"); 2480 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2481 false, true, "startActivityAndWait", null); 2482 WaitResult res = new WaitResult(); 2483 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2484 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2485 res, null, options, UserHandle.getCallingUserId()); 2486 return res; 2487 } 2488 2489 public final int startActivityWithConfig(IApplicationThread caller, 2490 Intent intent, String resolvedType, IBinder resultTo, 2491 String resultWho, int requestCode, int startFlags, Configuration config, 2492 Bundle options, int userId) { 2493 enforceNotIsolatedCaller("startActivityWithConfig"); 2494 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2495 false, true, "startActivityWithConfig", null); 2496 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2497 resultTo, resultWho, requestCode, startFlags, 2498 null, null, null, config, options, userId); 2499 return ret; 2500 } 2501 2502 public int startActivityIntentSender(IApplicationThread caller, 2503 IntentSender intent, Intent fillInIntent, String resolvedType, 2504 IBinder resultTo, String resultWho, int requestCode, 2505 int flagsMask, int flagsValues, Bundle options) { 2506 enforceNotIsolatedCaller("startActivityIntentSender"); 2507 // Refuse possible leaked file descriptors 2508 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2509 throw new IllegalArgumentException("File descriptors passed in Intent"); 2510 } 2511 2512 IIntentSender sender = intent.getTarget(); 2513 if (!(sender instanceof PendingIntentRecord)) { 2514 throw new IllegalArgumentException("Bad PendingIntent object"); 2515 } 2516 2517 PendingIntentRecord pir = (PendingIntentRecord)sender; 2518 2519 synchronized (this) { 2520 // If this is coming from the currently resumed activity, it is 2521 // effectively saying that app switches are allowed at this point. 2522 if (mMainStack.mResumedActivity != null 2523 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2524 Binder.getCallingUid()) { 2525 mAppSwitchesAllowedTime = 0; 2526 } 2527 } 2528 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2529 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2530 return ret; 2531 } 2532 2533 public boolean startNextMatchingActivity(IBinder callingActivity, 2534 Intent intent, Bundle options) { 2535 // Refuse possible leaked file descriptors 2536 if (intent != null && intent.hasFileDescriptors() == true) { 2537 throw new IllegalArgumentException("File descriptors passed in Intent"); 2538 } 2539 2540 synchronized (this) { 2541 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2542 if (r == null) { 2543 ActivityOptions.abort(options); 2544 return false; 2545 } 2546 if (r.app == null || r.app.thread == null) { 2547 // The caller is not running... d'oh! 2548 ActivityOptions.abort(options); 2549 return false; 2550 } 2551 intent = new Intent(intent); 2552 // The caller is not allowed to change the data. 2553 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2554 // And we are resetting to find the next component... 2555 intent.setComponent(null); 2556 2557 ActivityInfo aInfo = null; 2558 try { 2559 List<ResolveInfo> resolves = 2560 AppGlobals.getPackageManager().queryIntentActivities( 2561 intent, r.resolvedType, 2562 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2563 UserHandle.getCallingUserId()); 2564 2565 // Look for the original activity in the list... 2566 final int N = resolves != null ? resolves.size() : 0; 2567 for (int i=0; i<N; i++) { 2568 ResolveInfo rInfo = resolves.get(i); 2569 if (rInfo.activityInfo.packageName.equals(r.packageName) 2570 && rInfo.activityInfo.name.equals(r.info.name)) { 2571 // We found the current one... the next matching is 2572 // after it. 2573 i++; 2574 if (i<N) { 2575 aInfo = resolves.get(i).activityInfo; 2576 } 2577 break; 2578 } 2579 } 2580 } catch (RemoteException e) { 2581 } 2582 2583 if (aInfo == null) { 2584 // Nobody who is next! 2585 ActivityOptions.abort(options); 2586 return false; 2587 } 2588 2589 intent.setComponent(new ComponentName( 2590 aInfo.applicationInfo.packageName, aInfo.name)); 2591 intent.setFlags(intent.getFlags()&~( 2592 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2593 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2594 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2595 Intent.FLAG_ACTIVITY_NEW_TASK)); 2596 2597 // Okay now we need to start the new activity, replacing the 2598 // currently running activity. This is a little tricky because 2599 // we want to start the new one as if the current one is finished, 2600 // but not finish the current one first so that there is no flicker. 2601 // And thus... 2602 final boolean wasFinishing = r.finishing; 2603 r.finishing = true; 2604 2605 // Propagate reply information over to the new activity. 2606 final ActivityRecord resultTo = r.resultTo; 2607 final String resultWho = r.resultWho; 2608 final int requestCode = r.requestCode; 2609 r.resultTo = null; 2610 if (resultTo != null) { 2611 resultTo.removeResultsLocked(r, resultWho, requestCode); 2612 } 2613 2614 final long origId = Binder.clearCallingIdentity(); 2615 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2616 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2617 resultWho, requestCode, -1, r.launchedFromUid, 0, 2618 options, false, null); 2619 Binder.restoreCallingIdentity(origId); 2620 2621 r.finishing = wasFinishing; 2622 if (res != ActivityManager.START_SUCCESS) { 2623 return false; 2624 } 2625 return true; 2626 } 2627 } 2628 2629 final int startActivityInPackage(int uid, 2630 Intent intent, String resolvedType, IBinder resultTo, 2631 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2632 2633 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2634 false, true, "startActivityInPackage", null); 2635 2636 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2637 resultTo, resultWho, requestCode, startFlags, 2638 null, null, null, null, options, userId); 2639 return ret; 2640 } 2641 2642 public final int startActivities(IApplicationThread caller, 2643 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2644 int userId) { 2645 enforceNotIsolatedCaller("startActivities"); 2646 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2647 false, true, "startActivity", null); 2648 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2649 options, userId); 2650 return ret; 2651 } 2652 2653 final int startActivitiesInPackage(int uid, 2654 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2655 Bundle options, int userId) { 2656 2657 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2658 false, true, "startActivityInPackage", null); 2659 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2660 options, userId); 2661 return ret; 2662 } 2663 2664 final void addRecentTaskLocked(TaskRecord task) { 2665 int N = mRecentTasks.size(); 2666 // Quick case: check if the top-most recent task is the same. 2667 if (N > 0 && mRecentTasks.get(0) == task) { 2668 return; 2669 } 2670 // Remove any existing entries that are the same kind of task. 2671 for (int i=0; i<N; i++) { 2672 TaskRecord tr = mRecentTasks.get(i); 2673 if (task.userId == tr.userId 2674 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2675 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2676 mRecentTasks.remove(i); 2677 i--; 2678 N--; 2679 if (task.intent == null) { 2680 // If the new recent task we are adding is not fully 2681 // specified, then replace it with the existing recent task. 2682 task = tr; 2683 } 2684 } 2685 } 2686 if (N >= MAX_RECENT_TASKS) { 2687 mRecentTasks.remove(N-1); 2688 } 2689 mRecentTasks.add(0, task); 2690 } 2691 2692 public void setRequestedOrientation(IBinder token, 2693 int requestedOrientation) { 2694 synchronized (this) { 2695 ActivityRecord r = mMainStack.isInStackLocked(token); 2696 if (r == null) { 2697 return; 2698 } 2699 final long origId = Binder.clearCallingIdentity(); 2700 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2701 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2702 mConfiguration, 2703 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2704 if (config != null) { 2705 r.frozenBeforeDestroy = true; 2706 if (!updateConfigurationLocked(config, r, false, false)) { 2707 mMainStack.resumeTopActivityLocked(null); 2708 } 2709 } 2710 Binder.restoreCallingIdentity(origId); 2711 } 2712 } 2713 2714 public int getRequestedOrientation(IBinder token) { 2715 synchronized (this) { 2716 ActivityRecord r = mMainStack.isInStackLocked(token); 2717 if (r == null) { 2718 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2719 } 2720 return mWindowManager.getAppOrientation(r.appToken); 2721 } 2722 } 2723 2724 /** 2725 * This is the internal entry point for handling Activity.finish(). 2726 * 2727 * @param token The Binder token referencing the Activity we want to finish. 2728 * @param resultCode Result code, if any, from this Activity. 2729 * @param resultData Result data (Intent), if any, from this Activity. 2730 * 2731 * @return Returns true if the activity successfully finished, or false if it is still running. 2732 */ 2733 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2734 // Refuse possible leaked file descriptors 2735 if (resultData != null && resultData.hasFileDescriptors() == true) { 2736 throw new IllegalArgumentException("File descriptors passed in Intent"); 2737 } 2738 2739 synchronized(this) { 2740 if (mController != null) { 2741 // Find the first activity that is not finishing. 2742 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2743 if (next != null) { 2744 // ask watcher if this is allowed 2745 boolean resumeOK = true; 2746 try { 2747 resumeOK = mController.activityResuming(next.packageName); 2748 } catch (RemoteException e) { 2749 mController = null; 2750 } 2751 2752 if (!resumeOK) { 2753 return false; 2754 } 2755 } 2756 } 2757 final long origId = Binder.clearCallingIdentity(); 2758 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2759 resultData, "app-request", true); 2760 Binder.restoreCallingIdentity(origId); 2761 return res; 2762 } 2763 } 2764 2765 public final void finishHeavyWeightApp() { 2766 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2767 != PackageManager.PERMISSION_GRANTED) { 2768 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2769 + Binder.getCallingPid() 2770 + ", uid=" + Binder.getCallingUid() 2771 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2772 Slog.w(TAG, msg); 2773 throw new SecurityException(msg); 2774 } 2775 2776 synchronized(this) { 2777 if (mHeavyWeightProcess == null) { 2778 return; 2779 } 2780 2781 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2782 mHeavyWeightProcess.activities); 2783 for (int i=0; i<activities.size(); i++) { 2784 ActivityRecord r = activities.get(i); 2785 if (!r.finishing) { 2786 int index = mMainStack.indexOfTokenLocked(r.appToken); 2787 if (index >= 0) { 2788 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2789 null, "finish-heavy", true); 2790 } 2791 } 2792 } 2793 2794 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2795 mHeavyWeightProcess.userId, 0)); 2796 mHeavyWeightProcess = null; 2797 } 2798 } 2799 2800 public void crashApplication(int uid, int initialPid, String packageName, 2801 String message) { 2802 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2803 != PackageManager.PERMISSION_GRANTED) { 2804 String msg = "Permission Denial: crashApplication() from pid=" 2805 + Binder.getCallingPid() 2806 + ", uid=" + Binder.getCallingUid() 2807 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2808 Slog.w(TAG, msg); 2809 throw new SecurityException(msg); 2810 } 2811 2812 synchronized(this) { 2813 ProcessRecord proc = null; 2814 2815 // Figure out which process to kill. We don't trust that initialPid 2816 // still has any relation to current pids, so must scan through the 2817 // list. 2818 synchronized (mPidsSelfLocked) { 2819 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2820 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2821 if (p.uid != uid) { 2822 continue; 2823 } 2824 if (p.pid == initialPid) { 2825 proc = p; 2826 break; 2827 } 2828 for (String str : p.pkgList) { 2829 if (str.equals(packageName)) { 2830 proc = p; 2831 } 2832 } 2833 } 2834 } 2835 2836 if (proc == null) { 2837 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2838 + " initialPid=" + initialPid 2839 + " packageName=" + packageName); 2840 return; 2841 } 2842 2843 if (proc.thread != null) { 2844 if (proc.pid == Process.myPid()) { 2845 Log.w(TAG, "crashApplication: trying to crash self!"); 2846 return; 2847 } 2848 long ident = Binder.clearCallingIdentity(); 2849 try { 2850 proc.thread.scheduleCrash(message); 2851 } catch (RemoteException e) { 2852 } 2853 Binder.restoreCallingIdentity(ident); 2854 } 2855 } 2856 } 2857 2858 public final void finishSubActivity(IBinder token, String resultWho, 2859 int requestCode) { 2860 synchronized(this) { 2861 final long origId = Binder.clearCallingIdentity(); 2862 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2863 Binder.restoreCallingIdentity(origId); 2864 } 2865 } 2866 2867 public boolean finishActivityAffinity(IBinder token) { 2868 synchronized(this) { 2869 final long origId = Binder.clearCallingIdentity(); 2870 boolean res = mMainStack.finishActivityAffinityLocked(token); 2871 Binder.restoreCallingIdentity(origId); 2872 return res; 2873 } 2874 } 2875 2876 public boolean willActivityBeVisible(IBinder token) { 2877 synchronized(this) { 2878 int i; 2879 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2880 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2881 if (r.appToken == token) { 2882 return true; 2883 } 2884 if (r.fullscreen && !r.finishing) { 2885 return false; 2886 } 2887 } 2888 return true; 2889 } 2890 } 2891 2892 public void overridePendingTransition(IBinder token, String packageName, 2893 int enterAnim, int exitAnim) { 2894 synchronized(this) { 2895 ActivityRecord self = mMainStack.isInStackLocked(token); 2896 if (self == null) { 2897 return; 2898 } 2899 2900 final long origId = Binder.clearCallingIdentity(); 2901 2902 if (self.state == ActivityState.RESUMED 2903 || self.state == ActivityState.PAUSING) { 2904 mWindowManager.overridePendingAppTransition(packageName, 2905 enterAnim, exitAnim, null); 2906 } 2907 2908 Binder.restoreCallingIdentity(origId); 2909 } 2910 } 2911 2912 /** 2913 * Main function for removing an existing process from the activity manager 2914 * as a result of that process going away. Clears out all connections 2915 * to the process. 2916 */ 2917 private final void handleAppDiedLocked(ProcessRecord app, 2918 boolean restarting, boolean allowRestart) { 2919 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2920 if (!restarting) { 2921 mLruProcesses.remove(app); 2922 } 2923 2924 if (mProfileProc == app) { 2925 clearProfilerLocked(); 2926 } 2927 2928 // Just in case... 2929 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2930 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 2931 "App died while pausing: " + mMainStack.mPausingActivity); 2932 mMainStack.mPausingActivity = null; 2933 } 2934 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2935 mMainStack.mLastPausedActivity = null; 2936 } 2937 2938 // Remove this application's activities from active lists. 2939 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 2940 2941 app.activities.clear(); 2942 2943 if (app.instrumentationClass != null) { 2944 Slog.w(TAG, "Crash of app " + app.processName 2945 + " running instrumentation " + app.instrumentationClass); 2946 Bundle info = new Bundle(); 2947 info.putString("shortMsg", "Process crashed."); 2948 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2949 } 2950 2951 if (!restarting) { 2952 if (!mMainStack.resumeTopActivityLocked(null)) { 2953 // If there was nothing to resume, and we are not already 2954 // restarting this process, but there is a visible activity that 2955 // is hosted by the process... then make sure all visible 2956 // activities are running, taking care of restarting this 2957 // process. 2958 if (hasVisibleActivities) { 2959 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2960 } 2961 } 2962 } 2963 } 2964 2965 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2966 IBinder threadBinder = thread.asBinder(); 2967 // Find the application record. 2968 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2969 ProcessRecord rec = mLruProcesses.get(i); 2970 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2971 return i; 2972 } 2973 } 2974 return -1; 2975 } 2976 2977 final ProcessRecord getRecordForAppLocked( 2978 IApplicationThread thread) { 2979 if (thread == null) { 2980 return null; 2981 } 2982 2983 int appIndex = getLRURecordIndexForAppLocked(thread); 2984 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2985 } 2986 2987 final void appDiedLocked(ProcessRecord app, int pid, 2988 IApplicationThread thread) { 2989 2990 mProcDeaths[0]++; 2991 2992 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2993 synchronized (stats) { 2994 stats.noteProcessDiedLocked(app.info.uid, pid); 2995 } 2996 2997 // Clean up already done if the process has been re-started. 2998 if (app.pid == pid && app.thread != null && 2999 app.thread.asBinder() == thread.asBinder()) { 3000 if (!app.killedBackground) { 3001 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3002 + ") has died."); 3003 } 3004 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3005 if (DEBUG_CLEANUP) Slog.v( 3006 TAG, "Dying app: " + app + ", pid: " + pid 3007 + ", thread: " + thread.asBinder()); 3008 boolean doLowMem = app.instrumentationClass == null; 3009 handleAppDiedLocked(app, false, true); 3010 3011 if (doLowMem) { 3012 // If there are no longer any background processes running, 3013 // and the app that died was not running instrumentation, 3014 // then tell everyone we are now low on memory. 3015 boolean haveBg = false; 3016 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3017 ProcessRecord rec = mLruProcesses.get(i); 3018 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3019 haveBg = true; 3020 break; 3021 } 3022 } 3023 3024 if (!haveBg) { 3025 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3026 long now = SystemClock.uptimeMillis(); 3027 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3028 ProcessRecord rec = mLruProcesses.get(i); 3029 if (rec != app && rec.thread != null && 3030 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3031 // The low memory report is overriding any current 3032 // state for a GC request. Make sure to do 3033 // heavy/important/visible/foreground processes first. 3034 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3035 rec.lastRequestedGc = 0; 3036 } else { 3037 rec.lastRequestedGc = rec.lastLowMemory; 3038 } 3039 rec.reportLowMemory = true; 3040 rec.lastLowMemory = now; 3041 mProcessesToGc.remove(rec); 3042 addProcessToGcListLocked(rec); 3043 } 3044 } 3045 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3046 scheduleAppGcsLocked(); 3047 } 3048 } 3049 } else if (app.pid != pid) { 3050 // A new process has already been started. 3051 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3052 + ") has died and restarted (pid " + app.pid + ")."); 3053 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3054 } else if (DEBUG_PROCESSES) { 3055 Slog.d(TAG, "Received spurious death notification for thread " 3056 + thread.asBinder()); 3057 } 3058 } 3059 3060 /** 3061 * If a stack trace dump file is configured, dump process stack traces. 3062 * @param clearTraces causes the dump file to be erased prior to the new 3063 * traces being written, if true; when false, the new traces will be 3064 * appended to any existing file content. 3065 * @param firstPids of dalvik VM processes to dump stack traces for first 3066 * @param lastPids of dalvik VM processes to dump stack traces for last 3067 * @param nativeProcs optional list of native process names to dump stack crawls 3068 * @return file containing stack traces, or null if no dump file is configured 3069 */ 3070 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3071 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3072 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3073 if (tracesPath == null || tracesPath.length() == 0) { 3074 return null; 3075 } 3076 3077 File tracesFile = new File(tracesPath); 3078 try { 3079 File tracesDir = tracesFile.getParentFile(); 3080 if (!tracesDir.exists()) { 3081 tracesFile.mkdirs(); 3082 if (!SELinux.restorecon(tracesDir)) { 3083 return null; 3084 } 3085 } 3086 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3087 3088 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3089 tracesFile.createNewFile(); 3090 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3091 } catch (IOException e) { 3092 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3093 return null; 3094 } 3095 3096 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3097 return tracesFile; 3098 } 3099 3100 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3101 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3102 // Use a FileObserver to detect when traces finish writing. 3103 // The order of traces is considered important to maintain for legibility. 3104 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3105 public synchronized void onEvent(int event, String path) { notify(); } 3106 }; 3107 3108 try { 3109 observer.startWatching(); 3110 3111 // First collect all of the stacks of the most important pids. 3112 if (firstPids != null) { 3113 try { 3114 int num = firstPids.size(); 3115 for (int i = 0; i < num; i++) { 3116 synchronized (observer) { 3117 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3118 observer.wait(200); // Wait for write-close, give up after 200msec 3119 } 3120 } 3121 } catch (InterruptedException e) { 3122 Log.wtf(TAG, e); 3123 } 3124 } 3125 3126 // Next measure CPU usage. 3127 if (processStats != null) { 3128 processStats.init(); 3129 System.gc(); 3130 processStats.update(); 3131 try { 3132 synchronized (processStats) { 3133 processStats.wait(500); // measure over 1/2 second. 3134 } 3135 } catch (InterruptedException e) { 3136 } 3137 processStats.update(); 3138 3139 // We'll take the stack crawls of just the top apps using CPU. 3140 final int N = processStats.countWorkingStats(); 3141 int numProcs = 0; 3142 for (int i=0; i<N && numProcs<5; i++) { 3143 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3144 if (lastPids.indexOfKey(stats.pid) >= 0) { 3145 numProcs++; 3146 try { 3147 synchronized (observer) { 3148 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3149 observer.wait(200); // Wait for write-close, give up after 200msec 3150 } 3151 } catch (InterruptedException e) { 3152 Log.wtf(TAG, e); 3153 } 3154 3155 } 3156 } 3157 } 3158 3159 } finally { 3160 observer.stopWatching(); 3161 } 3162 3163 if (nativeProcs != null) { 3164 int[] pids = Process.getPidsForCommands(nativeProcs); 3165 if (pids != null) { 3166 for (int pid : pids) { 3167 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3168 } 3169 } 3170 } 3171 } 3172 3173 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3174 if (true || IS_USER_BUILD) { 3175 return; 3176 } 3177 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3178 if (tracesPath == null || tracesPath.length() == 0) { 3179 return; 3180 } 3181 3182 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3183 StrictMode.allowThreadDiskWrites(); 3184 try { 3185 final File tracesFile = new File(tracesPath); 3186 final File tracesDir = tracesFile.getParentFile(); 3187 final File tracesTmp = new File(tracesDir, "__tmp__"); 3188 try { 3189 if (!tracesDir.exists()) { 3190 tracesFile.mkdirs(); 3191 if (!SELinux.restorecon(tracesDir.getPath())) { 3192 return; 3193 } 3194 } 3195 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3196 3197 if (tracesFile.exists()) { 3198 tracesTmp.delete(); 3199 tracesFile.renameTo(tracesTmp); 3200 } 3201 StringBuilder sb = new StringBuilder(); 3202 Time tobj = new Time(); 3203 tobj.set(System.currentTimeMillis()); 3204 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3205 sb.append(": "); 3206 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3207 sb.append(" since "); 3208 sb.append(msg); 3209 FileOutputStream fos = new FileOutputStream(tracesFile); 3210 fos.write(sb.toString().getBytes()); 3211 if (app == null) { 3212 fos.write("\n*** No application process!".getBytes()); 3213 } 3214 fos.close(); 3215 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3216 } catch (IOException e) { 3217 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3218 return; 3219 } 3220 3221 if (app != null) { 3222 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3223 firstPids.add(app.pid); 3224 dumpStackTraces(tracesPath, firstPids, null, null, null); 3225 } 3226 3227 File lastTracesFile = null; 3228 File curTracesFile = null; 3229 for (int i=9; i>=0; i--) { 3230 String name = String.format("slow%02d.txt", i); 3231 curTracesFile = new File(tracesDir, name); 3232 if (curTracesFile.exists()) { 3233 if (lastTracesFile != null) { 3234 curTracesFile.renameTo(lastTracesFile); 3235 } else { 3236 curTracesFile.delete(); 3237 } 3238 } 3239 lastTracesFile = curTracesFile; 3240 } 3241 tracesFile.renameTo(curTracesFile); 3242 if (tracesTmp.exists()) { 3243 tracesTmp.renameTo(tracesFile); 3244 } 3245 } finally { 3246 StrictMode.setThreadPolicy(oldPolicy); 3247 } 3248 } 3249 3250 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3251 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3252 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3253 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3254 3255 if (mController != null) { 3256 try { 3257 // 0 == continue, -1 = kill process immediately 3258 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3259 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3260 } catch (RemoteException e) { 3261 mController = null; 3262 } 3263 } 3264 3265 long anrTime = SystemClock.uptimeMillis(); 3266 if (MONITOR_CPU_USAGE) { 3267 updateCpuStatsNow(); 3268 } 3269 3270 synchronized (this) { 3271 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3272 if (mShuttingDown) { 3273 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3274 return; 3275 } else if (app.notResponding) { 3276 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3277 return; 3278 } else if (app.crashing) { 3279 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3280 return; 3281 } 3282 3283 // In case we come through here for the same app before completing 3284 // this one, mark as anring now so we will bail out. 3285 app.notResponding = true; 3286 3287 // Log the ANR to the event log. 3288 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3289 app.processName, app.info.flags, annotation); 3290 3291 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3292 firstPids.add(app.pid); 3293 3294 int parentPid = app.pid; 3295 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3296 if (parentPid != app.pid) firstPids.add(parentPid); 3297 3298 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3299 3300 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3301 ProcessRecord r = mLruProcesses.get(i); 3302 if (r != null && r.thread != null) { 3303 int pid = r.pid; 3304 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3305 if (r.persistent) { 3306 firstPids.add(pid); 3307 } else { 3308 lastPids.put(pid, Boolean.TRUE); 3309 } 3310 } 3311 } 3312 } 3313 } 3314 3315 // Log the ANR to the main log. 3316 StringBuilder info = new StringBuilder(); 3317 info.setLength(0); 3318 info.append("ANR in ").append(app.processName); 3319 if (activity != null && activity.shortComponentName != null) { 3320 info.append(" (").append(activity.shortComponentName).append(")"); 3321 } 3322 info.append("\n"); 3323 if (annotation != null) { 3324 info.append("Reason: ").append(annotation).append("\n"); 3325 } 3326 if (parent != null && parent != activity) { 3327 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3328 } 3329 3330 final ProcessStats processStats = new ProcessStats(true); 3331 3332 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3333 3334 String cpuInfo = null; 3335 if (MONITOR_CPU_USAGE) { 3336 updateCpuStatsNow(); 3337 synchronized (mProcessStatsThread) { 3338 cpuInfo = mProcessStats.printCurrentState(anrTime); 3339 } 3340 info.append(processStats.printCurrentLoad()); 3341 info.append(cpuInfo); 3342 } 3343 3344 info.append(processStats.printCurrentState(anrTime)); 3345 3346 Slog.e(TAG, info.toString()); 3347 if (tracesFile == null) { 3348 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3349 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3350 } 3351 3352 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3353 cpuInfo, tracesFile, null); 3354 3355 if (mController != null) { 3356 try { 3357 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3358 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3359 if (res != 0) { 3360 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3361 return; 3362 } 3363 } catch (RemoteException e) { 3364 mController = null; 3365 } 3366 } 3367 3368 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3369 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3370 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3371 3372 synchronized (this) { 3373 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3374 Slog.w(TAG, "Killing " + app + ": background ANR"); 3375 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3376 app.processName, app.setAdj, "background ANR"); 3377 Process.killProcessQuiet(app.pid); 3378 return; 3379 } 3380 3381 // Set the app's notResponding state, and look up the errorReportReceiver 3382 makeAppNotRespondingLocked(app, 3383 activity != null ? activity.shortComponentName : null, 3384 annotation != null ? "ANR " + annotation : "ANR", 3385 info.toString()); 3386 3387 // Bring up the infamous App Not Responding dialog 3388 Message msg = Message.obtain(); 3389 HashMap map = new HashMap(); 3390 msg.what = SHOW_NOT_RESPONDING_MSG; 3391 msg.obj = map; 3392 msg.arg1 = aboveSystem ? 1 : 0; 3393 map.put("app", app); 3394 if (activity != null) { 3395 map.put("activity", activity); 3396 } 3397 3398 mHandler.sendMessage(msg); 3399 } 3400 } 3401 3402 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3403 if (!mLaunchWarningShown) { 3404 mLaunchWarningShown = true; 3405 mHandler.post(new Runnable() { 3406 @Override 3407 public void run() { 3408 synchronized (ActivityManagerService.this) { 3409 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3410 d.show(); 3411 mHandler.postDelayed(new Runnable() { 3412 @Override 3413 public void run() { 3414 synchronized (ActivityManagerService.this) { 3415 d.dismiss(); 3416 mLaunchWarningShown = false; 3417 } 3418 } 3419 }, 4000); 3420 } 3421 } 3422 }); 3423 } 3424 } 3425 3426 public boolean clearApplicationUserData(final String packageName, 3427 final IPackageDataObserver observer, int userId) { 3428 enforceNotIsolatedCaller("clearApplicationUserData"); 3429 int uid = Binder.getCallingUid(); 3430 int pid = Binder.getCallingPid(); 3431 userId = handleIncomingUser(pid, uid, 3432 userId, false, true, "clearApplicationUserData", null); 3433 long callingId = Binder.clearCallingIdentity(); 3434 try { 3435 IPackageManager pm = AppGlobals.getPackageManager(); 3436 int pkgUid = -1; 3437 synchronized(this) { 3438 try { 3439 pkgUid = pm.getPackageUid(packageName, userId); 3440 } catch (RemoteException e) { 3441 } 3442 if (pkgUid == -1) { 3443 Slog.w(TAG, "Invalid packageName:" + packageName); 3444 return false; 3445 } 3446 if (uid == pkgUid || checkComponentPermission( 3447 android.Manifest.permission.CLEAR_APP_USER_DATA, 3448 pid, uid, -1, true) 3449 == PackageManager.PERMISSION_GRANTED) { 3450 forceStopPackageLocked(packageName, pkgUid); 3451 } else { 3452 throw new SecurityException(pid+" does not have permission:"+ 3453 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3454 "for process:"+packageName); 3455 } 3456 } 3457 3458 try { 3459 //clear application user data 3460 pm.clearApplicationUserData(packageName, observer, userId); 3461 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3462 Uri.fromParts("package", packageName, null)); 3463 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3464 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3465 null, null, 0, null, null, null, false, false, userId); 3466 } catch (RemoteException e) { 3467 } 3468 } finally { 3469 Binder.restoreCallingIdentity(callingId); 3470 } 3471 return true; 3472 } 3473 3474 public void killBackgroundProcesses(final String packageName, int userId) { 3475 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3476 != PackageManager.PERMISSION_GRANTED && 3477 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3478 != PackageManager.PERMISSION_GRANTED) { 3479 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3480 + Binder.getCallingPid() 3481 + ", uid=" + Binder.getCallingUid() 3482 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3483 Slog.w(TAG, msg); 3484 throw new SecurityException(msg); 3485 } 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3488 userId, true, true, "killBackgroundProcesses", null); 3489 long callingId = Binder.clearCallingIdentity(); 3490 try { 3491 IPackageManager pm = AppGlobals.getPackageManager(); 3492 synchronized(this) { 3493 int appId = -1; 3494 try { 3495 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3496 } catch (RemoteException e) { 3497 } 3498 if (appId == -1) { 3499 Slog.w(TAG, "Invalid packageName: " + packageName); 3500 return; 3501 } 3502 killPackageProcessesLocked(packageName, appId, userId, 3503 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3504 } 3505 } finally { 3506 Binder.restoreCallingIdentity(callingId); 3507 } 3508 } 3509 3510 public void killAllBackgroundProcesses() { 3511 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3512 != PackageManager.PERMISSION_GRANTED) { 3513 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3514 + Binder.getCallingPid() 3515 + ", uid=" + Binder.getCallingUid() 3516 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3517 Slog.w(TAG, msg); 3518 throw new SecurityException(msg); 3519 } 3520 3521 long callingId = Binder.clearCallingIdentity(); 3522 try { 3523 synchronized(this) { 3524 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3525 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3526 final int NA = apps.size(); 3527 for (int ia=0; ia<NA; ia++) { 3528 ProcessRecord app = apps.valueAt(ia); 3529 if (app.persistent) { 3530 // we don't kill persistent processes 3531 continue; 3532 } 3533 if (app.removed) { 3534 procs.add(app); 3535 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3536 app.removed = true; 3537 procs.add(app); 3538 } 3539 } 3540 } 3541 3542 int N = procs.size(); 3543 for (int i=0; i<N; i++) { 3544 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3545 } 3546 } 3547 } finally { 3548 Binder.restoreCallingIdentity(callingId); 3549 } 3550 } 3551 3552 public void forceStopPackage(final String packageName, int userId) { 3553 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3554 != PackageManager.PERMISSION_GRANTED) { 3555 String msg = "Permission Denial: forceStopPackage() from pid=" 3556 + Binder.getCallingPid() 3557 + ", uid=" + Binder.getCallingUid() 3558 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3559 Slog.w(TAG, msg); 3560 throw new SecurityException(msg); 3561 } 3562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3563 userId, true, true, "forceStopPackage", null); 3564 long callingId = Binder.clearCallingIdentity(); 3565 try { 3566 IPackageManager pm = AppGlobals.getPackageManager(); 3567 synchronized(this) { 3568 int[] users = userId == UserHandle.USER_ALL 3569 ? getUsersLocked() : new int[] { userId }; 3570 for (int user : users) { 3571 int pkgUid = -1; 3572 try { 3573 pkgUid = pm.getPackageUid(packageName, user); 3574 } catch (RemoteException e) { 3575 } 3576 if (pkgUid == -1) { 3577 Slog.w(TAG, "Invalid packageName: " + packageName); 3578 continue; 3579 } 3580 try { 3581 pm.setPackageStoppedState(packageName, true, user); 3582 } catch (RemoteException e) { 3583 } catch (IllegalArgumentException e) { 3584 Slog.w(TAG, "Failed trying to unstop package " 3585 + packageName + ": " + e); 3586 } 3587 if (isUserRunningLocked(user)) { 3588 forceStopPackageLocked(packageName, pkgUid); 3589 } 3590 } 3591 } 3592 } finally { 3593 Binder.restoreCallingIdentity(callingId); 3594 } 3595 } 3596 3597 /* 3598 * The pkg name and app id have to be specified. 3599 */ 3600 public void killApplicationWithAppId(String pkg, int appid) { 3601 if (pkg == null) { 3602 return; 3603 } 3604 // Make sure the uid is valid. 3605 if (appid < 0) { 3606 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3607 return; 3608 } 3609 int callerUid = Binder.getCallingUid(); 3610 // Only the system server can kill an application 3611 if (callerUid == Process.SYSTEM_UID) { 3612 // Post an aysnc message to kill the application 3613 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3614 msg.arg1 = appid; 3615 msg.arg2 = 0; 3616 msg.obj = pkg; 3617 mHandler.sendMessage(msg); 3618 } else { 3619 throw new SecurityException(callerUid + " cannot kill pkg: " + 3620 pkg); 3621 } 3622 } 3623 3624 public void closeSystemDialogs(String reason) { 3625 enforceNotIsolatedCaller("closeSystemDialogs"); 3626 3627 final int pid = Binder.getCallingPid(); 3628 final int uid = Binder.getCallingUid(); 3629 final long origId = Binder.clearCallingIdentity(); 3630 try { 3631 synchronized (this) { 3632 // Only allow this from foreground processes, so that background 3633 // applications can't abuse it to prevent system UI from being shown. 3634 if (uid >= Process.FIRST_APPLICATION_UID) { 3635 ProcessRecord proc; 3636 synchronized (mPidsSelfLocked) { 3637 proc = mPidsSelfLocked.get(pid); 3638 } 3639 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3640 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3641 + " from background process " + proc); 3642 return; 3643 } 3644 } 3645 closeSystemDialogsLocked(reason); 3646 } 3647 } finally { 3648 Binder.restoreCallingIdentity(origId); 3649 } 3650 } 3651 3652 void closeSystemDialogsLocked(String reason) { 3653 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3655 | Intent.FLAG_RECEIVER_FOREGROUND); 3656 if (reason != null) { 3657 intent.putExtra("reason", reason); 3658 } 3659 mWindowManager.closeSystemDialogs(reason); 3660 3661 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3662 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3663 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3664 r.stack.finishActivityLocked(r, i, 3665 Activity.RESULT_CANCELED, null, "close-sys", true); 3666 } 3667 } 3668 3669 broadcastIntentLocked(null, null, intent, null, 3670 null, 0, null, null, null, false, false, -1, 3671 Process.SYSTEM_UID, UserHandle.USER_ALL); 3672 } 3673 3674 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3675 throws RemoteException { 3676 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3677 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3678 for (int i=pids.length-1; i>=0; i--) { 3679 infos[i] = new Debug.MemoryInfo(); 3680 Debug.getMemoryInfo(pids[i], infos[i]); 3681 } 3682 return infos; 3683 } 3684 3685 public long[] getProcessPss(int[] pids) throws RemoteException { 3686 enforceNotIsolatedCaller("getProcessPss"); 3687 long[] pss = new long[pids.length]; 3688 for (int i=pids.length-1; i>=0; i--) { 3689 pss[i] = Debug.getPss(pids[i]); 3690 } 3691 return pss; 3692 } 3693 3694 public void killApplicationProcess(String processName, int uid) { 3695 if (processName == null) { 3696 return; 3697 } 3698 3699 int callerUid = Binder.getCallingUid(); 3700 // Only the system server can kill an application 3701 if (callerUid == Process.SYSTEM_UID) { 3702 synchronized (this) { 3703 ProcessRecord app = getProcessRecordLocked(processName, uid); 3704 if (app != null && app.thread != null) { 3705 try { 3706 app.thread.scheduleSuicide(); 3707 } catch (RemoteException e) { 3708 // If the other end already died, then our work here is done. 3709 } 3710 } else { 3711 Slog.w(TAG, "Process/uid not found attempting kill of " 3712 + processName + " / " + uid); 3713 } 3714 } 3715 } else { 3716 throw new SecurityException(callerUid + " cannot kill app process: " + 3717 processName); 3718 } 3719 } 3720 3721 private void forceStopPackageLocked(final String packageName, int uid) { 3722 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3723 false, true, false, UserHandle.getUserId(uid)); 3724 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3725 Uri.fromParts("package", packageName, null)); 3726 if (!mProcessesReady) { 3727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3728 | Intent.FLAG_RECEIVER_FOREGROUND); 3729 } 3730 intent.putExtra(Intent.EXTRA_UID, uid); 3731 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3732 broadcastIntentLocked(null, null, intent, 3733 null, null, 0, null, null, null, 3734 false, false, 3735 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3736 } 3737 3738 private void forceStopUserLocked(int userId) { 3739 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3740 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3741 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3742 | Intent.FLAG_RECEIVER_FOREGROUND); 3743 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3744 broadcastIntentLocked(null, null, intent, 3745 null, null, 0, null, null, null, 3746 false, false, 3747 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3748 } 3749 3750 private final boolean killPackageProcessesLocked(String packageName, int appId, 3751 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3752 boolean doit, boolean evenPersistent, String reason) { 3753 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3754 3755 // Remove all processes this package may have touched: all with the 3756 // same UID (except for the system or root user), and all whose name 3757 // matches the package name. 3758 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3759 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3760 final int NA = apps.size(); 3761 for (int ia=0; ia<NA; ia++) { 3762 ProcessRecord app = apps.valueAt(ia); 3763 if (app.persistent && !evenPersistent) { 3764 // we don't kill persistent processes 3765 continue; 3766 } 3767 if (app.removed) { 3768 if (doit) { 3769 procs.add(app); 3770 } 3771 continue; 3772 } 3773 3774 // Skip process if it doesn't meet our oom adj requirement. 3775 if (app.setAdj < minOomAdj) { 3776 continue; 3777 } 3778 3779 // If no package is specified, we call all processes under the 3780 // give user id. 3781 if (packageName == null) { 3782 if (app.userId != userId) { 3783 continue; 3784 } 3785 // Package has been specified, we want to hit all processes 3786 // that match it. We need to qualify this by the processes 3787 // that are running under the specified app and user ID. 3788 } else { 3789 if (UserHandle.getAppId(app.uid) != appId) { 3790 continue; 3791 } 3792 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3793 continue; 3794 } 3795 if (!app.pkgList.contains(packageName)) { 3796 continue; 3797 } 3798 } 3799 3800 // Process has passed all conditions, kill it! 3801 if (!doit) { 3802 return true; 3803 } 3804 app.removed = true; 3805 procs.add(app); 3806 } 3807 } 3808 3809 int N = procs.size(); 3810 for (int i=0; i<N; i++) { 3811 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3812 } 3813 return N > 0; 3814 } 3815 3816 private final boolean forceStopPackageLocked(String name, int appId, 3817 boolean callerWillRestart, boolean purgeCache, boolean doit, 3818 boolean evenPersistent, int userId) { 3819 int i; 3820 int N; 3821 3822 if (userId == UserHandle.USER_ALL && name == null) { 3823 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3824 } 3825 3826 if (appId < 0 && name != null) { 3827 try { 3828 appId = UserHandle.getAppId( 3829 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3830 } catch (RemoteException e) { 3831 } 3832 } 3833 3834 if (doit) { 3835 if (name != null) { 3836 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3837 + " user=" + userId); 3838 } else { 3839 Slog.i(TAG, "Force stopping user " + userId); 3840 } 3841 3842 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3843 while (badApps.hasNext()) { 3844 SparseArray<Long> ba = badApps.next(); 3845 for (i=ba.size()-1; i>=0; i--) { 3846 boolean remove = false; 3847 final int entUid = ba.keyAt(i); 3848 if (name != null) { 3849 if (userId == UserHandle.USER_ALL) { 3850 if (UserHandle.getAppId(entUid) == appId) { 3851 remove = true; 3852 } 3853 } else { 3854 if (entUid == UserHandle.getUid(userId, appId)) { 3855 remove = true; 3856 } 3857 } 3858 } else if (UserHandle.getUserId(entUid) == userId) { 3859 remove = true; 3860 } 3861 if (remove) { 3862 ba.removeAt(i); 3863 } 3864 } 3865 if (ba.size() == 0) { 3866 badApps.remove(); 3867 } 3868 } 3869 } 3870 3871 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3872 -100, callerWillRestart, false, doit, evenPersistent, 3873 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3874 3875 TaskRecord lastTask = null; 3876 for (i=0; i<mMainStack.mHistory.size(); i++) { 3877 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3878 final boolean samePackage = r.packageName.equals(name) 3879 || (name == null && r.userId == userId); 3880 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3881 && (samePackage || r.task == lastTask) 3882 && (r.app == null || evenPersistent || !r.app.persistent)) { 3883 if (!doit) { 3884 if (r.finishing) { 3885 // If this activity is just finishing, then it is not 3886 // interesting as far as something to stop. 3887 continue; 3888 } 3889 return true; 3890 } 3891 didSomething = true; 3892 Slog.i(TAG, " Force finishing activity " + r); 3893 if (samePackage) { 3894 if (r.app != null) { 3895 r.app.removed = true; 3896 } 3897 r.app = null; 3898 } 3899 lastTask = r.task; 3900 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3901 null, "force-stop", true)) { 3902 i--; 3903 } 3904 } 3905 } 3906 3907 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3908 if (!doit) { 3909 return true; 3910 } 3911 didSomething = true; 3912 } 3913 3914 if (name == null) { 3915 // Remove all sticky broadcasts from this user. 3916 mStickyBroadcasts.remove(userId); 3917 } 3918 3919 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3920 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3921 userId, providers)) { 3922 if (!doit) { 3923 return true; 3924 } 3925 didSomething = true; 3926 } 3927 N = providers.size(); 3928 for (i=0; i<N; i++) { 3929 removeDyingProviderLocked(null, providers.get(i), true); 3930 } 3931 3932 if (mIntentSenderRecords.size() > 0) { 3933 Iterator<WeakReference<PendingIntentRecord>> it 3934 = mIntentSenderRecords.values().iterator(); 3935 while (it.hasNext()) { 3936 WeakReference<PendingIntentRecord> wpir = it.next(); 3937 if (wpir == null) { 3938 it.remove(); 3939 continue; 3940 } 3941 PendingIntentRecord pir = wpir.get(); 3942 if (pir == null) { 3943 it.remove(); 3944 continue; 3945 } 3946 if (name == null) { 3947 // Stopping user, remove all objects for the user. 3948 if (pir.key.userId != userId) { 3949 // Not the same user, skip it. 3950 continue; 3951 } 3952 } else { 3953 if (UserHandle.getAppId(pir.uid) != appId) { 3954 // Different app id, skip it. 3955 continue; 3956 } 3957 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3958 // Different user, skip it. 3959 continue; 3960 } 3961 if (!pir.key.packageName.equals(name)) { 3962 // Different package, skip it. 3963 continue; 3964 } 3965 } 3966 if (!doit) { 3967 return true; 3968 } 3969 didSomething = true; 3970 it.remove(); 3971 pir.canceled = true; 3972 if (pir.key.activity != null) { 3973 pir.key.activity.pendingResults.remove(pir.ref); 3974 } 3975 } 3976 } 3977 3978 if (doit) { 3979 if (purgeCache && name != null) { 3980 AttributeCache ac = AttributeCache.instance(); 3981 if (ac != null) { 3982 ac.removePackage(name); 3983 } 3984 } 3985 if (mBooted) { 3986 mMainStack.resumeTopActivityLocked(null); 3987 mMainStack.scheduleIdleLocked(); 3988 } 3989 } 3990 3991 return didSomething; 3992 } 3993 3994 private final boolean removeProcessLocked(ProcessRecord app, 3995 boolean callerWillRestart, boolean allowRestart, String reason) { 3996 final String name = app.processName; 3997 final int uid = app.uid; 3998 if (DEBUG_PROCESSES) Slog.d( 3999 TAG, "Force removing proc " + app.toShortString() + " (" + name 4000 + "/" + uid + ")"); 4001 4002 mProcessNames.remove(name, uid); 4003 mIsolatedProcesses.remove(app.uid); 4004 if (mHeavyWeightProcess == app) { 4005 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4006 mHeavyWeightProcess.userId, 0)); 4007 mHeavyWeightProcess = null; 4008 } 4009 boolean needRestart = false; 4010 if (app.pid > 0 && app.pid != MY_PID) { 4011 int pid = app.pid; 4012 synchronized (mPidsSelfLocked) { 4013 mPidsSelfLocked.remove(pid); 4014 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4015 } 4016 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4017 handleAppDiedLocked(app, true, allowRestart); 4018 mLruProcesses.remove(app); 4019 Process.killProcessQuiet(pid); 4020 4021 if (app.persistent && !app.isolated) { 4022 if (!callerWillRestart) { 4023 addAppLocked(app.info, false); 4024 } else { 4025 needRestart = true; 4026 } 4027 } 4028 } else { 4029 mRemovedProcesses.add(app); 4030 } 4031 4032 return needRestart; 4033 } 4034 4035 private final void processStartTimedOutLocked(ProcessRecord app) { 4036 final int pid = app.pid; 4037 boolean gone = false; 4038 synchronized (mPidsSelfLocked) { 4039 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4040 if (knownApp != null && knownApp.thread == null) { 4041 mPidsSelfLocked.remove(pid); 4042 gone = true; 4043 } 4044 } 4045 4046 if (gone) { 4047 Slog.w(TAG, "Process " + app + " failed to attach"); 4048 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4049 pid, app.uid, app.processName); 4050 mProcessNames.remove(app.processName, app.uid); 4051 mIsolatedProcesses.remove(app.uid); 4052 if (mHeavyWeightProcess == app) { 4053 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4054 mHeavyWeightProcess.userId, 0)); 4055 mHeavyWeightProcess = null; 4056 } 4057 // Take care of any launching providers waiting for this process. 4058 checkAppInLaunchingProvidersLocked(app, true); 4059 // Take care of any services that are waiting for the process. 4060 mServices.processStartTimedOutLocked(app); 4061 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4062 app.processName, app.setAdj, "start timeout"); 4063 Process.killProcessQuiet(pid); 4064 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4065 Slog.w(TAG, "Unattached app died before backup, skipping"); 4066 try { 4067 IBackupManager bm = IBackupManager.Stub.asInterface( 4068 ServiceManager.getService(Context.BACKUP_SERVICE)); 4069 bm.agentDisconnected(app.info.packageName); 4070 } catch (RemoteException e) { 4071 // Can't happen; the backup manager is local 4072 } 4073 } 4074 if (isPendingBroadcastProcessLocked(pid)) { 4075 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4076 skipPendingBroadcastLocked(pid); 4077 } 4078 } else { 4079 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4080 } 4081 } 4082 4083 private final boolean attachApplicationLocked(IApplicationThread thread, 4084 int pid) { 4085 4086 // Find the application record that is being attached... either via 4087 // the pid if we are running in multiple processes, or just pull the 4088 // next app record if we are emulating process with anonymous threads. 4089 ProcessRecord app; 4090 if (pid != MY_PID && pid >= 0) { 4091 synchronized (mPidsSelfLocked) { 4092 app = mPidsSelfLocked.get(pid); 4093 } 4094 } else { 4095 app = null; 4096 } 4097 4098 if (app == null) { 4099 Slog.w(TAG, "No pending application record for pid " + pid 4100 + " (IApplicationThread " + thread + "); dropping process"); 4101 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4102 if (pid > 0 && pid != MY_PID) { 4103 Process.killProcessQuiet(pid); 4104 } else { 4105 try { 4106 thread.scheduleExit(); 4107 } catch (Exception e) { 4108 // Ignore exceptions. 4109 } 4110 } 4111 return false; 4112 } 4113 4114 // If this application record is still attached to a previous 4115 // process, clean it up now. 4116 if (app.thread != null) { 4117 handleAppDiedLocked(app, true, true); 4118 } 4119 4120 // Tell the process all about itself. 4121 4122 if (localLOGV) Slog.v( 4123 TAG, "Binding process pid " + pid + " to record " + app); 4124 4125 String processName = app.processName; 4126 try { 4127 AppDeathRecipient adr = new AppDeathRecipient( 4128 app, pid, thread); 4129 thread.asBinder().linkToDeath(adr, 0); 4130 app.deathRecipient = adr; 4131 } catch (RemoteException e) { 4132 app.resetPackageList(); 4133 startProcessLocked(app, "link fail", processName); 4134 return false; 4135 } 4136 4137 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4138 4139 app.thread = thread; 4140 app.curAdj = app.setAdj = -100; 4141 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4142 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4143 app.forcingToForeground = null; 4144 app.foregroundServices = false; 4145 app.hasShownUi = false; 4146 app.debugging = false; 4147 4148 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4149 4150 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4151 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4152 4153 if (!normalMode) { 4154 Slog.i(TAG, "Launching preboot mode app: " + app); 4155 } 4156 4157 if (localLOGV) Slog.v( 4158 TAG, "New app record " + app 4159 + " thread=" + thread.asBinder() + " pid=" + pid); 4160 try { 4161 int testMode = IApplicationThread.DEBUG_OFF; 4162 if (mDebugApp != null && mDebugApp.equals(processName)) { 4163 testMode = mWaitForDebugger 4164 ? IApplicationThread.DEBUG_WAIT 4165 : IApplicationThread.DEBUG_ON; 4166 app.debugging = true; 4167 if (mDebugTransient) { 4168 mDebugApp = mOrigDebugApp; 4169 mWaitForDebugger = mOrigWaitForDebugger; 4170 } 4171 } 4172 String profileFile = app.instrumentationProfileFile; 4173 ParcelFileDescriptor profileFd = null; 4174 boolean profileAutoStop = false; 4175 if (mProfileApp != null && mProfileApp.equals(processName)) { 4176 mProfileProc = app; 4177 profileFile = mProfileFile; 4178 profileFd = mProfileFd; 4179 profileAutoStop = mAutoStopProfiler; 4180 } 4181 boolean enableOpenGlTrace = false; 4182 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4183 enableOpenGlTrace = true; 4184 mOpenGlTraceApp = null; 4185 } 4186 4187 // If the app is being launched for restore or full backup, set it up specially 4188 boolean isRestrictedBackupMode = false; 4189 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4190 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4191 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4192 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4193 } 4194 4195 ensurePackageDexOpt(app.instrumentationInfo != null 4196 ? app.instrumentationInfo.packageName 4197 : app.info.packageName); 4198 if (app.instrumentationClass != null) { 4199 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4200 } 4201 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4202 + processName + " with config " + mConfiguration); 4203 ApplicationInfo appInfo = app.instrumentationInfo != null 4204 ? app.instrumentationInfo : app.info; 4205 app.compat = compatibilityInfoForPackageLocked(appInfo); 4206 if (profileFd != null) { 4207 profileFd = profileFd.dup(); 4208 } 4209 thread.bindApplication(processName, appInfo, providers, 4210 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4211 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4212 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4213 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4214 mCoreSettingsObserver.getCoreSettingsLocked()); 4215 updateLruProcessLocked(app, false); 4216 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4217 } catch (Exception e) { 4218 // todo: Yikes! What should we do? For now we will try to 4219 // start another process, but that could easily get us in 4220 // an infinite loop of restarting processes... 4221 Slog.w(TAG, "Exception thrown during bind!", e); 4222 4223 app.resetPackageList(); 4224 app.unlinkDeathRecipient(); 4225 startProcessLocked(app, "bind fail", processName); 4226 return false; 4227 } 4228 4229 // Remove this record from the list of starting applications. 4230 mPersistentStartingProcesses.remove(app); 4231 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4232 "Attach application locked removing on hold: " + app); 4233 mProcessesOnHold.remove(app); 4234 4235 boolean badApp = false; 4236 boolean didSomething = false; 4237 4238 // See if the top visible activity is waiting to run in this process... 4239 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4240 if (hr != null && normalMode) { 4241 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4242 && processName.equals(hr.processName)) { 4243 try { 4244 if (mHeadless) { 4245 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4246 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4247 didSomething = true; 4248 } 4249 } catch (Exception e) { 4250 Slog.w(TAG, "Exception in new application when starting activity " 4251 + hr.intent.getComponent().flattenToShortString(), e); 4252 badApp = true; 4253 } 4254 } else { 4255 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4256 } 4257 } 4258 4259 // Find any services that should be running in this process... 4260 if (!badApp) { 4261 try { 4262 didSomething |= mServices.attachApplicationLocked(app, processName); 4263 } catch (Exception e) { 4264 badApp = true; 4265 } 4266 } 4267 4268 // Check if a next-broadcast receiver is in this process... 4269 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4270 try { 4271 didSomething = sendPendingBroadcastsLocked(app); 4272 } catch (Exception e) { 4273 // If the app died trying to launch the receiver we declare it 'bad' 4274 badApp = true; 4275 } 4276 } 4277 4278 // Check whether the next backup agent is in this process... 4279 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4280 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4281 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4282 try { 4283 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4284 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4285 mBackupTarget.backupMode); 4286 } catch (Exception e) { 4287 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4288 e.printStackTrace(); 4289 } 4290 } 4291 4292 if (badApp) { 4293 // todo: Also need to kill application to deal with all 4294 // kinds of exceptions. 4295 handleAppDiedLocked(app, false, true); 4296 return false; 4297 } 4298 4299 if (!didSomething) { 4300 updateOomAdjLocked(); 4301 } 4302 4303 return true; 4304 } 4305 4306 public final void attachApplication(IApplicationThread thread) { 4307 synchronized (this) { 4308 int callingPid = Binder.getCallingPid(); 4309 final long origId = Binder.clearCallingIdentity(); 4310 attachApplicationLocked(thread, callingPid); 4311 Binder.restoreCallingIdentity(origId); 4312 } 4313 } 4314 4315 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4316 final long origId = Binder.clearCallingIdentity(); 4317 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4318 if (stopProfiling) { 4319 synchronized (this) { 4320 if (mProfileProc == r.app) { 4321 if (mProfileFd != null) { 4322 try { 4323 mProfileFd.close(); 4324 } catch (IOException e) { 4325 } 4326 clearProfilerLocked(); 4327 } 4328 } 4329 } 4330 } 4331 Binder.restoreCallingIdentity(origId); 4332 } 4333 4334 void enableScreenAfterBoot() { 4335 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4336 SystemClock.uptimeMillis()); 4337 mWindowManager.enableScreenAfterBoot(); 4338 4339 synchronized (this) { 4340 updateEventDispatchingLocked(); 4341 } 4342 } 4343 4344 public void showBootMessage(final CharSequence msg, final boolean always) { 4345 enforceNotIsolatedCaller("showBootMessage"); 4346 mWindowManager.showBootMessage(msg, always); 4347 } 4348 4349 public void dismissKeyguardOnNextActivity() { 4350 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4351 final long token = Binder.clearCallingIdentity(); 4352 try { 4353 synchronized (this) { 4354 if (mLockScreenShown) { 4355 mLockScreenShown = false; 4356 comeOutOfSleepIfNeededLocked(); 4357 } 4358 mMainStack.dismissKeyguardOnNextActivityLocked(); 4359 } 4360 } finally { 4361 Binder.restoreCallingIdentity(token); 4362 } 4363 } 4364 4365 final void finishBooting() { 4366 IntentFilter pkgFilter = new IntentFilter(); 4367 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4368 pkgFilter.addDataScheme("package"); 4369 mContext.registerReceiver(new BroadcastReceiver() { 4370 @Override 4371 public void onReceive(Context context, Intent intent) { 4372 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4373 if (pkgs != null) { 4374 for (String pkg : pkgs) { 4375 synchronized (ActivityManagerService.this) { 4376 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4377 setResultCode(Activity.RESULT_OK); 4378 return; 4379 } 4380 } 4381 } 4382 } 4383 } 4384 }, pkgFilter); 4385 4386 synchronized (this) { 4387 // Ensure that any processes we had put on hold are now started 4388 // up. 4389 final int NP = mProcessesOnHold.size(); 4390 if (NP > 0) { 4391 ArrayList<ProcessRecord> procs = 4392 new ArrayList<ProcessRecord>(mProcessesOnHold); 4393 for (int ip=0; ip<NP; ip++) { 4394 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4395 + procs.get(ip)); 4396 startProcessLocked(procs.get(ip), "on-hold", null); 4397 } 4398 } 4399 4400 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4401 // Start looking for apps that are abusing wake locks. 4402 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4403 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4404 // Tell anyone interested that we are done booting! 4405 SystemProperties.set("sys.boot_completed", "1"); 4406 SystemProperties.set("dev.bootcomplete", "1"); 4407 for (int i=0; i<mStartedUsers.size(); i++) { 4408 UserStartedState uss = mStartedUsers.valueAt(i); 4409 if (uss.mState == UserStartedState.STATE_BOOTING) { 4410 uss.mState = UserStartedState.STATE_RUNNING; 4411 final int userId = mStartedUsers.keyAt(i); 4412 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4413 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4414 broadcastIntentLocked(null, null, intent, 4415 null, null, 0, null, null, 4416 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4417 false, false, MY_PID, Process.SYSTEM_UID, userId); 4418 } 4419 } 4420 } 4421 } 4422 } 4423 4424 final void ensureBootCompleted() { 4425 boolean booting; 4426 boolean enableScreen; 4427 synchronized (this) { 4428 booting = mBooting; 4429 mBooting = false; 4430 enableScreen = !mBooted; 4431 mBooted = true; 4432 } 4433 4434 if (booting) { 4435 finishBooting(); 4436 } 4437 4438 if (enableScreen) { 4439 enableScreenAfterBoot(); 4440 } 4441 } 4442 4443 public final void activityResumed(IBinder token) { 4444 final long origId = Binder.clearCallingIdentity(); 4445 mMainStack.activityResumed(token); 4446 Binder.restoreCallingIdentity(origId); 4447 } 4448 4449 public final void activityPaused(IBinder token) { 4450 final long origId = Binder.clearCallingIdentity(); 4451 mMainStack.activityPaused(token, false); 4452 Binder.restoreCallingIdentity(origId); 4453 } 4454 4455 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4456 CharSequence description) { 4457 if (localLOGV) Slog.v( 4458 TAG, "Activity stopped: token=" + token); 4459 4460 // Refuse possible leaked file descriptors 4461 if (icicle != null && icicle.hasFileDescriptors()) { 4462 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4463 } 4464 4465 ActivityRecord r = null; 4466 4467 final long origId = Binder.clearCallingIdentity(); 4468 4469 synchronized (this) { 4470 r = mMainStack.isInStackLocked(token); 4471 if (r != null) { 4472 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4473 } 4474 } 4475 4476 if (r != null) { 4477 sendPendingThumbnail(r, null, null, null, false); 4478 } 4479 4480 trimApplications(); 4481 4482 Binder.restoreCallingIdentity(origId); 4483 } 4484 4485 public final void activityDestroyed(IBinder token) { 4486 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4487 mMainStack.activityDestroyed(token); 4488 } 4489 4490 public String getCallingPackage(IBinder token) { 4491 synchronized (this) { 4492 ActivityRecord r = getCallingRecordLocked(token); 4493 return r != null && r.app != null ? r.info.packageName : null; 4494 } 4495 } 4496 4497 public ComponentName getCallingActivity(IBinder token) { 4498 synchronized (this) { 4499 ActivityRecord r = getCallingRecordLocked(token); 4500 return r != null ? r.intent.getComponent() : null; 4501 } 4502 } 4503 4504 private ActivityRecord getCallingRecordLocked(IBinder token) { 4505 ActivityRecord r = mMainStack.isInStackLocked(token); 4506 if (r == null) { 4507 return null; 4508 } 4509 return r.resultTo; 4510 } 4511 4512 public ComponentName getActivityClassForToken(IBinder token) { 4513 synchronized(this) { 4514 ActivityRecord r = mMainStack.isInStackLocked(token); 4515 if (r == null) { 4516 return null; 4517 } 4518 return r.intent.getComponent(); 4519 } 4520 } 4521 4522 public String getPackageForToken(IBinder token) { 4523 synchronized(this) { 4524 ActivityRecord r = mMainStack.isInStackLocked(token); 4525 if (r == null) { 4526 return null; 4527 } 4528 return r.packageName; 4529 } 4530 } 4531 4532 public IIntentSender getIntentSender(int type, 4533 String packageName, IBinder token, String resultWho, 4534 int requestCode, Intent[] intents, String[] resolvedTypes, 4535 int flags, Bundle options, int userId) { 4536 enforceNotIsolatedCaller("getIntentSender"); 4537 // Refuse possible leaked file descriptors 4538 if (intents != null) { 4539 if (intents.length < 1) { 4540 throw new IllegalArgumentException("Intents array length must be >= 1"); 4541 } 4542 for (int i=0; i<intents.length; i++) { 4543 Intent intent = intents[i]; 4544 if (intent != null) { 4545 if (intent.hasFileDescriptors()) { 4546 throw new IllegalArgumentException("File descriptors passed in Intent"); 4547 } 4548 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4549 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4550 throw new IllegalArgumentException( 4551 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4552 } 4553 intents[i] = new Intent(intent); 4554 } 4555 } 4556 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4557 throw new IllegalArgumentException( 4558 "Intent array length does not match resolvedTypes length"); 4559 } 4560 } 4561 if (options != null) { 4562 if (options.hasFileDescriptors()) { 4563 throw new IllegalArgumentException("File descriptors passed in options"); 4564 } 4565 } 4566 4567 synchronized(this) { 4568 int callingUid = Binder.getCallingUid(); 4569 int origUserId = userId; 4570 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4571 type == ActivityManager.INTENT_SENDER_BROADCAST, true, 4572 "getIntentSender", null); 4573 if (origUserId == UserHandle.USER_CURRENT) { 4574 // We don't want to evaluate this until the pending intent is 4575 // actually executed. However, we do want to always do the 4576 // security checking for it above. 4577 userId = UserHandle.USER_CURRENT; 4578 } 4579 try { 4580 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4581 int uid = AppGlobals.getPackageManager() 4582 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4583 if (!UserHandle.isSameApp(callingUid, uid)) { 4584 String msg = "Permission Denial: getIntentSender() from pid=" 4585 + Binder.getCallingPid() 4586 + ", uid=" + Binder.getCallingUid() 4587 + ", (need uid=" + uid + ")" 4588 + " is not allowed to send as package " + packageName; 4589 Slog.w(TAG, msg); 4590 throw new SecurityException(msg); 4591 } 4592 } 4593 4594 return getIntentSenderLocked(type, packageName, callingUid, userId, 4595 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4596 4597 } catch (RemoteException e) { 4598 throw new SecurityException(e); 4599 } 4600 } 4601 } 4602 4603 IIntentSender getIntentSenderLocked(int type, String packageName, 4604 int callingUid, int userId, IBinder token, String resultWho, 4605 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4606 Bundle options) { 4607 if (DEBUG_MU) 4608 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4609 ActivityRecord activity = null; 4610 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4611 activity = mMainStack.isInStackLocked(token); 4612 if (activity == null) { 4613 return null; 4614 } 4615 if (activity.finishing) { 4616 return null; 4617 } 4618 } 4619 4620 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4621 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4622 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4623 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4624 |PendingIntent.FLAG_UPDATE_CURRENT); 4625 4626 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4627 type, packageName, activity, resultWho, 4628 requestCode, intents, resolvedTypes, flags, options, userId); 4629 WeakReference<PendingIntentRecord> ref; 4630 ref = mIntentSenderRecords.get(key); 4631 PendingIntentRecord rec = ref != null ? ref.get() : null; 4632 if (rec != null) { 4633 if (!cancelCurrent) { 4634 if (updateCurrent) { 4635 if (rec.key.requestIntent != null) { 4636 rec.key.requestIntent.replaceExtras(intents != null ? 4637 intents[intents.length - 1] : null); 4638 } 4639 if (intents != null) { 4640 intents[intents.length-1] = rec.key.requestIntent; 4641 rec.key.allIntents = intents; 4642 rec.key.allResolvedTypes = resolvedTypes; 4643 } else { 4644 rec.key.allIntents = null; 4645 rec.key.allResolvedTypes = null; 4646 } 4647 } 4648 return rec; 4649 } 4650 rec.canceled = true; 4651 mIntentSenderRecords.remove(key); 4652 } 4653 if (noCreate) { 4654 return rec; 4655 } 4656 rec = new PendingIntentRecord(this, key, callingUid); 4657 mIntentSenderRecords.put(key, rec.ref); 4658 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4659 if (activity.pendingResults == null) { 4660 activity.pendingResults 4661 = new HashSet<WeakReference<PendingIntentRecord>>(); 4662 } 4663 activity.pendingResults.add(rec.ref); 4664 } 4665 return rec; 4666 } 4667 4668 public void cancelIntentSender(IIntentSender sender) { 4669 if (!(sender instanceof PendingIntentRecord)) { 4670 return; 4671 } 4672 synchronized(this) { 4673 PendingIntentRecord rec = (PendingIntentRecord)sender; 4674 try { 4675 int uid = AppGlobals.getPackageManager() 4676 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4677 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4678 String msg = "Permission Denial: cancelIntentSender() from pid=" 4679 + Binder.getCallingPid() 4680 + ", uid=" + Binder.getCallingUid() 4681 + " is not allowed to cancel packges " 4682 + rec.key.packageName; 4683 Slog.w(TAG, msg); 4684 throw new SecurityException(msg); 4685 } 4686 } catch (RemoteException e) { 4687 throw new SecurityException(e); 4688 } 4689 cancelIntentSenderLocked(rec, true); 4690 } 4691 } 4692 4693 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4694 rec.canceled = true; 4695 mIntentSenderRecords.remove(rec.key); 4696 if (cleanActivity && rec.key.activity != null) { 4697 rec.key.activity.pendingResults.remove(rec.ref); 4698 } 4699 } 4700 4701 public String getPackageForIntentSender(IIntentSender pendingResult) { 4702 if (!(pendingResult instanceof PendingIntentRecord)) { 4703 return null; 4704 } 4705 try { 4706 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4707 return res.key.packageName; 4708 } catch (ClassCastException e) { 4709 } 4710 return null; 4711 } 4712 4713 public int getUidForIntentSender(IIntentSender sender) { 4714 if (sender instanceof PendingIntentRecord) { 4715 try { 4716 PendingIntentRecord res = (PendingIntentRecord)sender; 4717 return res.uid; 4718 } catch (ClassCastException e) { 4719 } 4720 } 4721 return -1; 4722 } 4723 4724 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4725 if (!(pendingResult instanceof PendingIntentRecord)) { 4726 return false; 4727 } 4728 try { 4729 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4730 if (res.key.allIntents == null) { 4731 return false; 4732 } 4733 for (int i=0; i<res.key.allIntents.length; i++) { 4734 Intent intent = res.key.allIntents[i]; 4735 if (intent.getPackage() != null && intent.getComponent() != null) { 4736 return false; 4737 } 4738 } 4739 return true; 4740 } catch (ClassCastException e) { 4741 } 4742 return false; 4743 } 4744 4745 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4746 if (!(pendingResult instanceof PendingIntentRecord)) { 4747 return false; 4748 } 4749 try { 4750 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4751 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4752 return true; 4753 } 4754 return false; 4755 } catch (ClassCastException e) { 4756 } 4757 return false; 4758 } 4759 4760 public void setProcessLimit(int max) { 4761 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4762 "setProcessLimit()"); 4763 synchronized (this) { 4764 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4765 mProcessLimitOverride = max; 4766 } 4767 trimApplications(); 4768 } 4769 4770 public int getProcessLimit() { 4771 synchronized (this) { 4772 return mProcessLimitOverride; 4773 } 4774 } 4775 4776 void foregroundTokenDied(ForegroundToken token) { 4777 synchronized (ActivityManagerService.this) { 4778 synchronized (mPidsSelfLocked) { 4779 ForegroundToken cur 4780 = mForegroundProcesses.get(token.pid); 4781 if (cur != token) { 4782 return; 4783 } 4784 mForegroundProcesses.remove(token.pid); 4785 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4786 if (pr == null) { 4787 return; 4788 } 4789 pr.forcingToForeground = null; 4790 pr.foregroundServices = false; 4791 } 4792 updateOomAdjLocked(); 4793 } 4794 } 4795 4796 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4797 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4798 "setProcessForeground()"); 4799 synchronized(this) { 4800 boolean changed = false; 4801 4802 synchronized (mPidsSelfLocked) { 4803 ProcessRecord pr = mPidsSelfLocked.get(pid); 4804 if (pr == null && isForeground) { 4805 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4806 return; 4807 } 4808 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4809 if (oldToken != null) { 4810 oldToken.token.unlinkToDeath(oldToken, 0); 4811 mForegroundProcesses.remove(pid); 4812 if (pr != null) { 4813 pr.forcingToForeground = null; 4814 } 4815 changed = true; 4816 } 4817 if (isForeground && token != null) { 4818 ForegroundToken newToken = new ForegroundToken() { 4819 public void binderDied() { 4820 foregroundTokenDied(this); 4821 } 4822 }; 4823 newToken.pid = pid; 4824 newToken.token = token; 4825 try { 4826 token.linkToDeath(newToken, 0); 4827 mForegroundProcesses.put(pid, newToken); 4828 pr.forcingToForeground = token; 4829 changed = true; 4830 } catch (RemoteException e) { 4831 // If the process died while doing this, we will later 4832 // do the cleanup with the process death link. 4833 } 4834 } 4835 } 4836 4837 if (changed) { 4838 updateOomAdjLocked(); 4839 } 4840 } 4841 } 4842 4843 // ========================================================= 4844 // PERMISSIONS 4845 // ========================================================= 4846 4847 static class PermissionController extends IPermissionController.Stub { 4848 ActivityManagerService mActivityManagerService; 4849 PermissionController(ActivityManagerService activityManagerService) { 4850 mActivityManagerService = activityManagerService; 4851 } 4852 4853 public boolean checkPermission(String permission, int pid, int uid) { 4854 return mActivityManagerService.checkPermission(permission, pid, 4855 uid) == PackageManager.PERMISSION_GRANTED; 4856 } 4857 } 4858 4859 /** 4860 * This can be called with or without the global lock held. 4861 */ 4862 int checkComponentPermission(String permission, int pid, int uid, 4863 int owningUid, boolean exported) { 4864 // We might be performing an operation on behalf of an indirect binder 4865 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4866 // client identity accordingly before proceeding. 4867 Identity tlsIdentity = sCallerIdentity.get(); 4868 if (tlsIdentity != null) { 4869 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4870 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4871 uid = tlsIdentity.uid; 4872 pid = tlsIdentity.pid; 4873 } 4874 4875 if (pid == MY_PID) { 4876 return PackageManager.PERMISSION_GRANTED; 4877 } 4878 4879 return ActivityManager.checkComponentPermission(permission, uid, 4880 owningUid, exported); 4881 } 4882 4883 /** 4884 * As the only public entry point for permissions checking, this method 4885 * can enforce the semantic that requesting a check on a null global 4886 * permission is automatically denied. (Internally a null permission 4887 * string is used when calling {@link #checkComponentPermission} in cases 4888 * when only uid-based security is needed.) 4889 * 4890 * This can be called with or without the global lock held. 4891 */ 4892 public int checkPermission(String permission, int pid, int uid) { 4893 if (permission == null) { 4894 return PackageManager.PERMISSION_DENIED; 4895 } 4896 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4897 } 4898 4899 /** 4900 * Binder IPC calls go through the public entry point. 4901 * This can be called with or without the global lock held. 4902 */ 4903 int checkCallingPermission(String permission) { 4904 return checkPermission(permission, 4905 Binder.getCallingPid(), 4906 UserHandle.getAppId(Binder.getCallingUid())); 4907 } 4908 4909 /** 4910 * This can be called with or without the global lock held. 4911 */ 4912 void enforceCallingPermission(String permission, String func) { 4913 if (checkCallingPermission(permission) 4914 == PackageManager.PERMISSION_GRANTED) { 4915 return; 4916 } 4917 4918 String msg = "Permission Denial: " + func + " from pid=" 4919 + Binder.getCallingPid() 4920 + ", uid=" + Binder.getCallingUid() 4921 + " requires " + permission; 4922 Slog.w(TAG, msg); 4923 throw new SecurityException(msg); 4924 } 4925 4926 /** 4927 * Determine if UID is holding permissions required to access {@link Uri} in 4928 * the given {@link ProviderInfo}. Final permission checking is always done 4929 * in {@link ContentProvider}. 4930 */ 4931 private final boolean checkHoldingPermissionsLocked( 4932 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4934 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4935 4936 if (pi.applicationInfo.uid == uid) { 4937 return true; 4938 } else if (!pi.exported) { 4939 return false; 4940 } 4941 4942 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4943 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4944 try { 4945 // check if target holds top-level <provider> permissions 4946 if (!readMet && pi.readPermission != null 4947 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4948 readMet = true; 4949 } 4950 if (!writeMet && pi.writePermission != null 4951 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4952 writeMet = true; 4953 } 4954 4955 // track if unprotected read/write is allowed; any denied 4956 // <path-permission> below removes this ability 4957 boolean allowDefaultRead = pi.readPermission == null; 4958 boolean allowDefaultWrite = pi.writePermission == null; 4959 4960 // check if target holds any <path-permission> that match uri 4961 final PathPermission[] pps = pi.pathPermissions; 4962 if (pps != null) { 4963 final String path = uri.getPath(); 4964 int i = pps.length; 4965 while (i > 0 && (!readMet || !writeMet)) { 4966 i--; 4967 PathPermission pp = pps[i]; 4968 if (pp.match(path)) { 4969 if (!readMet) { 4970 final String pprperm = pp.getReadPermission(); 4971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4972 + pprperm + " for " + pp.getPath() 4973 + ": match=" + pp.match(path) 4974 + " check=" + pm.checkUidPermission(pprperm, uid)); 4975 if (pprperm != null) { 4976 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4977 readMet = true; 4978 } else { 4979 allowDefaultRead = false; 4980 } 4981 } 4982 } 4983 if (!writeMet) { 4984 final String ppwperm = pp.getWritePermission(); 4985 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4986 + ppwperm + " for " + pp.getPath() 4987 + ": match=" + pp.match(path) 4988 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4989 if (ppwperm != null) { 4990 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4991 writeMet = true; 4992 } else { 4993 allowDefaultWrite = false; 4994 } 4995 } 4996 } 4997 } 4998 } 4999 } 5000 5001 // grant unprotected <provider> read/write, if not blocked by 5002 // <path-permission> above 5003 if (allowDefaultRead) readMet = true; 5004 if (allowDefaultWrite) writeMet = true; 5005 5006 } catch (RemoteException e) { 5007 return false; 5008 } 5009 5010 return readMet && writeMet; 5011 } 5012 5013 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5014 int modeFlags) { 5015 // Root gets to do everything. 5016 if (uid == 0) { 5017 return true; 5018 } 5019 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5020 if (perms == null) return false; 5021 UriPermission perm = perms.get(uri); 5022 if (perm == null) return false; 5023 return (modeFlags&perm.modeFlags) == modeFlags; 5024 } 5025 5026 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5027 enforceNotIsolatedCaller("checkUriPermission"); 5028 5029 // Another redirected-binder-call permissions check as in 5030 // {@link checkComponentPermission}. 5031 Identity tlsIdentity = sCallerIdentity.get(); 5032 if (tlsIdentity != null) { 5033 uid = tlsIdentity.uid; 5034 pid = tlsIdentity.pid; 5035 } 5036 5037 // Our own process gets to do everything. 5038 if (pid == MY_PID) { 5039 return PackageManager.PERMISSION_GRANTED; 5040 } 5041 synchronized(this) { 5042 return checkUriPermissionLocked(uri, uid, modeFlags) 5043 ? PackageManager.PERMISSION_GRANTED 5044 : PackageManager.PERMISSION_DENIED; 5045 } 5046 } 5047 5048 /** 5049 * Check if the targetPkg can be granted permission to access uri by 5050 * the callingUid using the given modeFlags. Throws a security exception 5051 * if callingUid is not allowed to do this. Returns the uid of the target 5052 * if the URI permission grant should be performed; returns -1 if it is not 5053 * needed (for example targetPkg already has permission to access the URI). 5054 * If you already know the uid of the target, you can supply it in 5055 * lastTargetUid else set that to -1. 5056 */ 5057 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5058 Uri uri, int modeFlags, int lastTargetUid) { 5059 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5060 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5061 if (modeFlags == 0) { 5062 return -1; 5063 } 5064 5065 if (targetPkg != null) { 5066 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5067 "Checking grant " + targetPkg + " permission to " + uri); 5068 } 5069 5070 final IPackageManager pm = AppGlobals.getPackageManager(); 5071 5072 // If this is not a content: uri, we can't do anything with it. 5073 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5074 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5075 "Can't grant URI permission for non-content URI: " + uri); 5076 return -1; 5077 } 5078 5079 String name = uri.getAuthority(); 5080 ProviderInfo pi = null; 5081 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5082 UserHandle.getUserId(callingUid)); 5083 if (cpr != null) { 5084 pi = cpr.info; 5085 } else { 5086 try { 5087 pi = pm.resolveContentProvider(name, 5088 PackageManager.GET_URI_PERMISSION_PATTERNS, 5089 UserHandle.getUserId(callingUid)); 5090 } catch (RemoteException ex) { 5091 } 5092 } 5093 if (pi == null) { 5094 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5095 return -1; 5096 } 5097 5098 int targetUid = lastTargetUid; 5099 if (targetUid < 0 && targetPkg != null) { 5100 try { 5101 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5102 if (targetUid < 0) { 5103 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5104 "Can't grant URI permission no uid for: " + targetPkg); 5105 return -1; 5106 } 5107 } catch (RemoteException ex) { 5108 return -1; 5109 } 5110 } 5111 5112 if (targetUid >= 0) { 5113 // First... does the target actually need this permission? 5114 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5115 // No need to grant the target this permission. 5116 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5117 "Target " + targetPkg + " already has full permission to " + uri); 5118 return -1; 5119 } 5120 } else { 5121 // First... there is no target package, so can anyone access it? 5122 boolean allowed = pi.exported; 5123 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5124 if (pi.readPermission != null) { 5125 allowed = false; 5126 } 5127 } 5128 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5129 if (pi.writePermission != null) { 5130 allowed = false; 5131 } 5132 } 5133 if (allowed) { 5134 return -1; 5135 } 5136 } 5137 5138 // Second... is the provider allowing granting of URI permissions? 5139 if (!pi.grantUriPermissions) { 5140 throw new SecurityException("Provider " + pi.packageName 5141 + "/" + pi.name 5142 + " does not allow granting of Uri permissions (uri " 5143 + uri + ")"); 5144 } 5145 if (pi.uriPermissionPatterns != null) { 5146 final int N = pi.uriPermissionPatterns.length; 5147 boolean allowed = false; 5148 for (int i=0; i<N; i++) { 5149 if (pi.uriPermissionPatterns[i] != null 5150 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5151 allowed = true; 5152 break; 5153 } 5154 } 5155 if (!allowed) { 5156 throw new SecurityException("Provider " + pi.packageName 5157 + "/" + pi.name 5158 + " does not allow granting of permission to path of Uri " 5159 + uri); 5160 } 5161 } 5162 5163 // Third... does the caller itself have permission to access 5164 // this uri? 5165 if (callingUid != Process.myUid()) { 5166 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5167 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5168 throw new SecurityException("Uid " + callingUid 5169 + " does not have permission to uri " + uri); 5170 } 5171 } 5172 } 5173 5174 return targetUid; 5175 } 5176 5177 public int checkGrantUriPermission(int callingUid, String targetPkg, 5178 Uri uri, int modeFlags) { 5179 enforceNotIsolatedCaller("checkGrantUriPermission"); 5180 synchronized(this) { 5181 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5182 } 5183 } 5184 5185 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5186 Uri uri, int modeFlags, UriPermissionOwner owner) { 5187 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5188 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5189 if (modeFlags == 0) { 5190 return; 5191 } 5192 5193 // So here we are: the caller has the assumed permission 5194 // to the uri, and the target doesn't. Let's now give this to 5195 // the target. 5196 5197 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5198 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5199 5200 HashMap<Uri, UriPermission> targetUris 5201 = mGrantedUriPermissions.get(targetUid); 5202 if (targetUris == null) { 5203 targetUris = new HashMap<Uri, UriPermission>(); 5204 mGrantedUriPermissions.put(targetUid, targetUris); 5205 } 5206 5207 UriPermission perm = targetUris.get(uri); 5208 if (perm == null) { 5209 perm = new UriPermission(targetUid, uri); 5210 targetUris.put(uri, perm); 5211 } 5212 5213 perm.modeFlags |= modeFlags; 5214 if (owner == null) { 5215 perm.globalModeFlags |= modeFlags; 5216 } else { 5217 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5218 perm.readOwners.add(owner); 5219 owner.addReadPermission(perm); 5220 } 5221 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5222 perm.writeOwners.add(owner); 5223 owner.addWritePermission(perm); 5224 } 5225 } 5226 } 5227 5228 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5229 int modeFlags, UriPermissionOwner owner) { 5230 if (targetPkg == null) { 5231 throw new NullPointerException("targetPkg"); 5232 } 5233 5234 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5235 if (targetUid < 0) { 5236 return; 5237 } 5238 5239 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5240 } 5241 5242 static class NeededUriGrants extends ArrayList<Uri> { 5243 final String targetPkg; 5244 final int targetUid; 5245 final int flags; 5246 5247 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5248 targetPkg = _targetPkg; 5249 targetUid = _targetUid; 5250 flags = _flags; 5251 } 5252 } 5253 5254 /** 5255 * Like checkGrantUriPermissionLocked, but takes an Intent. 5256 */ 5257 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5258 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5259 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5260 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5261 + " clip=" + (intent != null ? intent.getClipData() : null) 5262 + " from " + intent + "; flags=0x" 5263 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5264 5265 if (targetPkg == null) { 5266 throw new NullPointerException("targetPkg"); 5267 } 5268 5269 if (intent == null) { 5270 return null; 5271 } 5272 Uri data = intent.getData(); 5273 ClipData clip = intent.getClipData(); 5274 if (data == null && clip == null) { 5275 return null; 5276 } 5277 if (data != null) { 5278 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5279 mode, needed != null ? needed.targetUid : -1); 5280 if (target > 0) { 5281 if (needed == null) { 5282 needed = new NeededUriGrants(targetPkg, target, mode); 5283 } 5284 needed.add(data); 5285 } 5286 } 5287 if (clip != null) { 5288 for (int i=0; i<clip.getItemCount(); i++) { 5289 Uri uri = clip.getItemAt(i).getUri(); 5290 if (uri != null) { 5291 int target = -1; 5292 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5293 mode, needed != null ? needed.targetUid : -1); 5294 if (target > 0) { 5295 if (needed == null) { 5296 needed = new NeededUriGrants(targetPkg, target, mode); 5297 } 5298 needed.add(uri); 5299 } 5300 } else { 5301 Intent clipIntent = clip.getItemAt(i).getIntent(); 5302 if (clipIntent != null) { 5303 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5304 callingUid, targetPkg, clipIntent, mode, needed); 5305 if (newNeeded != null) { 5306 needed = newNeeded; 5307 } 5308 } 5309 } 5310 } 5311 } 5312 5313 return needed; 5314 } 5315 5316 /** 5317 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5318 */ 5319 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5320 UriPermissionOwner owner) { 5321 if (needed != null) { 5322 for (int i=0; i<needed.size(); i++) { 5323 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5324 needed.get(i), needed.flags, owner); 5325 } 5326 } 5327 } 5328 5329 void grantUriPermissionFromIntentLocked(int callingUid, 5330 String targetPkg, Intent intent, UriPermissionOwner owner) { 5331 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5332 intent, intent != null ? intent.getFlags() : 0, null); 5333 if (needed == null) { 5334 return; 5335 } 5336 5337 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5338 } 5339 5340 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5341 Uri uri, int modeFlags) { 5342 enforceNotIsolatedCaller("grantUriPermission"); 5343 synchronized(this) { 5344 final ProcessRecord r = getRecordForAppLocked(caller); 5345 if (r == null) { 5346 throw new SecurityException("Unable to find app for caller " 5347 + caller 5348 + " when granting permission to uri " + uri); 5349 } 5350 if (targetPkg == null) { 5351 throw new IllegalArgumentException("null target"); 5352 } 5353 if (uri == null) { 5354 throw new IllegalArgumentException("null uri"); 5355 } 5356 5357 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5358 null); 5359 } 5360 } 5361 5362 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5363 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5364 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5365 HashMap<Uri, UriPermission> perms 5366 = mGrantedUriPermissions.get(perm.uid); 5367 if (perms != null) { 5368 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5369 "Removing " + perm.uid + " permission to " + perm.uri); 5370 perms.remove(perm.uri); 5371 if (perms.size() == 0) { 5372 mGrantedUriPermissions.remove(perm.uid); 5373 } 5374 } 5375 } 5376 } 5377 5378 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5379 int modeFlags) { 5380 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5381 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5382 if (modeFlags == 0) { 5383 return; 5384 } 5385 5386 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5387 "Revoking all granted permissions to " + uri); 5388 5389 final IPackageManager pm = AppGlobals.getPackageManager(); 5390 5391 final String authority = uri.getAuthority(); 5392 ProviderInfo pi = null; 5393 int userId = UserHandle.getUserId(callingUid); 5394 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5395 if (cpr != null) { 5396 pi = cpr.info; 5397 } else { 5398 try { 5399 pi = pm.resolveContentProvider(authority, 5400 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5401 } catch (RemoteException ex) { 5402 } 5403 } 5404 if (pi == null) { 5405 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5406 return; 5407 } 5408 5409 // Does the caller have this permission on the URI? 5410 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5411 // Right now, if you are not the original owner of the permission, 5412 // you are not allowed to revoke it. 5413 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5414 throw new SecurityException("Uid " + callingUid 5415 + " does not have permission to uri " + uri); 5416 //} 5417 } 5418 5419 // Go through all of the permissions and remove any that match. 5420 final List<String> SEGMENTS = uri.getPathSegments(); 5421 if (SEGMENTS != null) { 5422 final int NS = SEGMENTS.size(); 5423 int N = mGrantedUriPermissions.size(); 5424 for (int i=0; i<N; i++) { 5425 HashMap<Uri, UriPermission> perms 5426 = mGrantedUriPermissions.valueAt(i); 5427 Iterator<UriPermission> it = perms.values().iterator(); 5428 toploop: 5429 while (it.hasNext()) { 5430 UriPermission perm = it.next(); 5431 Uri targetUri = perm.uri; 5432 if (!authority.equals(targetUri.getAuthority())) { 5433 continue; 5434 } 5435 List<String> targetSegments = targetUri.getPathSegments(); 5436 if (targetSegments == null) { 5437 continue; 5438 } 5439 if (targetSegments.size() < NS) { 5440 continue; 5441 } 5442 for (int j=0; j<NS; j++) { 5443 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5444 continue toploop; 5445 } 5446 } 5447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5448 "Revoking " + perm.uid + " permission to " + perm.uri); 5449 perm.clearModes(modeFlags); 5450 if (perm.modeFlags == 0) { 5451 it.remove(); 5452 } 5453 } 5454 if (perms.size() == 0) { 5455 mGrantedUriPermissions.remove( 5456 mGrantedUriPermissions.keyAt(i)); 5457 N--; 5458 i--; 5459 } 5460 } 5461 } 5462 } 5463 5464 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5465 int modeFlags) { 5466 enforceNotIsolatedCaller("revokeUriPermission"); 5467 synchronized(this) { 5468 final ProcessRecord r = getRecordForAppLocked(caller); 5469 if (r == null) { 5470 throw new SecurityException("Unable to find app for caller " 5471 + caller 5472 + " when revoking permission to uri " + uri); 5473 } 5474 if (uri == null) { 5475 Slog.w(TAG, "revokeUriPermission: null uri"); 5476 return; 5477 } 5478 5479 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5480 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5481 if (modeFlags == 0) { 5482 return; 5483 } 5484 5485 final IPackageManager pm = AppGlobals.getPackageManager(); 5486 5487 final String authority = uri.getAuthority(); 5488 ProviderInfo pi = null; 5489 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5490 if (cpr != null) { 5491 pi = cpr.info; 5492 } else { 5493 try { 5494 pi = pm.resolveContentProvider(authority, 5495 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5496 } catch (RemoteException ex) { 5497 } 5498 } 5499 if (pi == null) { 5500 Slog.w(TAG, "No content provider found for permission revoke: " 5501 + uri.toSafeString()); 5502 return; 5503 } 5504 5505 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5506 } 5507 } 5508 5509 @Override 5510 public IBinder newUriPermissionOwner(String name) { 5511 enforceNotIsolatedCaller("newUriPermissionOwner"); 5512 synchronized(this) { 5513 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5514 return owner.getExternalTokenLocked(); 5515 } 5516 } 5517 5518 @Override 5519 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5520 Uri uri, int modeFlags) { 5521 synchronized(this) { 5522 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5523 if (owner == null) { 5524 throw new IllegalArgumentException("Unknown owner: " + token); 5525 } 5526 if (fromUid != Binder.getCallingUid()) { 5527 if (Binder.getCallingUid() != Process.myUid()) { 5528 // Only system code can grant URI permissions on behalf 5529 // of other users. 5530 throw new SecurityException("nice try"); 5531 } 5532 } 5533 if (targetPkg == null) { 5534 throw new IllegalArgumentException("null target"); 5535 } 5536 if (uri == null) { 5537 throw new IllegalArgumentException("null uri"); 5538 } 5539 5540 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5541 } 5542 } 5543 5544 @Override 5545 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5546 synchronized(this) { 5547 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5548 if (owner == null) { 5549 throw new IllegalArgumentException("Unknown owner: " + token); 5550 } 5551 5552 if (uri == null) { 5553 owner.removeUriPermissionsLocked(mode); 5554 } else { 5555 owner.removeUriPermissionLocked(uri, mode); 5556 } 5557 } 5558 } 5559 5560 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5561 synchronized (this) { 5562 ProcessRecord app = 5563 who != null ? getRecordForAppLocked(who) : null; 5564 if (app == null) return; 5565 5566 Message msg = Message.obtain(); 5567 msg.what = WAIT_FOR_DEBUGGER_MSG; 5568 msg.obj = app; 5569 msg.arg1 = waiting ? 1 : 0; 5570 mHandler.sendMessage(msg); 5571 } 5572 } 5573 5574 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5575 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5576 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5577 outInfo.availMem = Process.getFreeMemory(); 5578 outInfo.totalMem = Process.getTotalMemory(); 5579 outInfo.threshold = homeAppMem; 5580 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5581 outInfo.hiddenAppThreshold = hiddenAppMem; 5582 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5583 ProcessList.SERVICE_ADJ); 5584 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5585 ProcessList.VISIBLE_APP_ADJ); 5586 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5587 ProcessList.FOREGROUND_APP_ADJ); 5588 } 5589 5590 // ========================================================= 5591 // TASK MANAGEMENT 5592 // ========================================================= 5593 5594 public List getTasks(int maxNum, int flags, 5595 IThumbnailReceiver receiver) { 5596 ArrayList list = new ArrayList(); 5597 5598 PendingThumbnailsRecord pending = null; 5599 IApplicationThread topThumbnail = null; 5600 ActivityRecord topRecord = null; 5601 5602 synchronized(this) { 5603 if (localLOGV) Slog.v( 5604 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5605 + ", receiver=" + receiver); 5606 5607 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5608 != PackageManager.PERMISSION_GRANTED) { 5609 if (receiver != null) { 5610 // If the caller wants to wait for pending thumbnails, 5611 // it ain't gonna get them. 5612 try { 5613 receiver.finished(); 5614 } catch (RemoteException ex) { 5615 } 5616 } 5617 String msg = "Permission Denial: getTasks() from pid=" 5618 + Binder.getCallingPid() 5619 + ", uid=" + Binder.getCallingUid() 5620 + " requires " + android.Manifest.permission.GET_TASKS; 5621 Slog.w(TAG, msg); 5622 throw new SecurityException(msg); 5623 } 5624 5625 int pos = mMainStack.mHistory.size()-1; 5626 ActivityRecord next = 5627 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5628 ActivityRecord top = null; 5629 TaskRecord curTask = null; 5630 int numActivities = 0; 5631 int numRunning = 0; 5632 while (pos >= 0 && maxNum > 0) { 5633 final ActivityRecord r = next; 5634 pos--; 5635 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5636 5637 // Initialize state for next task if needed. 5638 if (top == null || 5639 (top.state == ActivityState.INITIALIZING 5640 && top.task == r.task)) { 5641 top = r; 5642 curTask = r.task; 5643 numActivities = numRunning = 0; 5644 } 5645 5646 // Add 'r' into the current task. 5647 numActivities++; 5648 if (r.app != null && r.app.thread != null) { 5649 numRunning++; 5650 } 5651 5652 if (localLOGV) Slog.v( 5653 TAG, r.intent.getComponent().flattenToShortString() 5654 + ": task=" + r.task); 5655 5656 // If the next one is a different task, generate a new 5657 // TaskInfo entry for what we have. 5658 if (next == null || next.task != curTask) { 5659 ActivityManager.RunningTaskInfo ci 5660 = new ActivityManager.RunningTaskInfo(); 5661 ci.id = curTask.taskId; 5662 ci.baseActivity = r.intent.getComponent(); 5663 ci.topActivity = top.intent.getComponent(); 5664 if (top.thumbHolder != null) { 5665 ci.description = top.thumbHolder.lastDescription; 5666 } 5667 ci.numActivities = numActivities; 5668 ci.numRunning = numRunning; 5669 //System.out.println( 5670 // "#" + maxNum + ": " + " descr=" + ci.description); 5671 if (ci.thumbnail == null && receiver != null) { 5672 if (localLOGV) Slog.v( 5673 TAG, "State=" + top.state + "Idle=" + top.idle 5674 + " app=" + top.app 5675 + " thr=" + (top.app != null ? top.app.thread : null)); 5676 if (top.state == ActivityState.RESUMED 5677 || top.state == ActivityState.PAUSING) { 5678 if (top.idle && top.app != null 5679 && top.app.thread != null) { 5680 topRecord = top; 5681 topThumbnail = top.app.thread; 5682 } else { 5683 top.thumbnailNeeded = true; 5684 } 5685 } 5686 if (pending == null) { 5687 pending = new PendingThumbnailsRecord(receiver); 5688 } 5689 pending.pendingRecords.add(top); 5690 } 5691 list.add(ci); 5692 maxNum--; 5693 top = null; 5694 } 5695 } 5696 5697 if (pending != null) { 5698 mPendingThumbnails.add(pending); 5699 } 5700 } 5701 5702 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5703 5704 if (topThumbnail != null) { 5705 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5706 try { 5707 topThumbnail.requestThumbnail(topRecord.appToken); 5708 } catch (Exception e) { 5709 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5710 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5711 } 5712 } 5713 5714 if (pending == null && receiver != null) { 5715 // In this case all thumbnails were available and the client 5716 // is being asked to be told when the remaining ones come in... 5717 // which is unusually, since the top-most currently running 5718 // activity should never have a canned thumbnail! Oh well. 5719 try { 5720 receiver.finished(); 5721 } catch (RemoteException ex) { 5722 } 5723 } 5724 5725 return list; 5726 } 5727 5728 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5729 int flags, int userId) { 5730 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5731 false, true, "getRecentTasks", null); 5732 5733 synchronized (this) { 5734 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5735 "getRecentTasks()"); 5736 final boolean detailed = checkCallingPermission( 5737 android.Manifest.permission.GET_DETAILED_TASKS) 5738 == PackageManager.PERMISSION_GRANTED; 5739 5740 IPackageManager pm = AppGlobals.getPackageManager(); 5741 5742 final int N = mRecentTasks.size(); 5743 ArrayList<ActivityManager.RecentTaskInfo> res 5744 = new ArrayList<ActivityManager.RecentTaskInfo>( 5745 maxNum < N ? maxNum : N); 5746 for (int i=0; i<N && maxNum > 0; i++) { 5747 TaskRecord tr = mRecentTasks.get(i); 5748 // Only add calling user's recent tasks 5749 if (tr.userId != userId) continue; 5750 // Return the entry if desired by the caller. We always return 5751 // the first entry, because callers always expect this to be the 5752 // foreground app. We may filter others if the caller has 5753 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5754 // we should exclude the entry. 5755 5756 if (i == 0 5757 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5758 || (tr.intent == null) 5759 || ((tr.intent.getFlags() 5760 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5761 ActivityManager.RecentTaskInfo rti 5762 = new ActivityManager.RecentTaskInfo(); 5763 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5764 rti.persistentId = tr.taskId; 5765 rti.baseIntent = new Intent( 5766 tr.intent != null ? tr.intent : tr.affinityIntent); 5767 if (!detailed) { 5768 rti.baseIntent.replaceExtras((Bundle)null); 5769 } 5770 rti.origActivity = tr.origActivity; 5771 rti.description = tr.lastDescription; 5772 5773 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5774 // Check whether this activity is currently available. 5775 try { 5776 if (rti.origActivity != null) { 5777 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5778 == null) { 5779 continue; 5780 } 5781 } else if (rti.baseIntent != null) { 5782 if (pm.queryIntentActivities(rti.baseIntent, 5783 null, 0, userId) == null) { 5784 continue; 5785 } 5786 } 5787 } catch (RemoteException e) { 5788 // Will never happen. 5789 } 5790 } 5791 5792 res.add(rti); 5793 maxNum--; 5794 } 5795 } 5796 return res; 5797 } 5798 } 5799 5800 private TaskRecord taskForIdLocked(int id) { 5801 final int N = mRecentTasks.size(); 5802 for (int i=0; i<N; i++) { 5803 TaskRecord tr = mRecentTasks.get(i); 5804 if (tr.taskId == id) { 5805 return tr; 5806 } 5807 } 5808 return null; 5809 } 5810 5811 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5812 synchronized (this) { 5813 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5814 "getTaskThumbnails()"); 5815 TaskRecord tr = taskForIdLocked(id); 5816 if (tr != null) { 5817 return mMainStack.getTaskThumbnailsLocked(tr); 5818 } 5819 } 5820 return null; 5821 } 5822 5823 public Bitmap getTaskTopThumbnail(int id) { 5824 synchronized (this) { 5825 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5826 "getTaskTopThumbnail()"); 5827 TaskRecord tr = taskForIdLocked(id); 5828 if (tr != null) { 5829 return mMainStack.getTaskTopThumbnailLocked(tr); 5830 } 5831 } 5832 return null; 5833 } 5834 5835 public boolean removeSubTask(int taskId, int subTaskIndex) { 5836 synchronized (this) { 5837 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5838 "removeSubTask()"); 5839 long ident = Binder.clearCallingIdentity(); 5840 try { 5841 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5842 true) != null; 5843 } finally { 5844 Binder.restoreCallingIdentity(ident); 5845 } 5846 } 5847 } 5848 5849 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5850 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5851 Intent baseIntent = new Intent( 5852 tr.intent != null ? tr.intent : tr.affinityIntent); 5853 ComponentName component = baseIntent.getComponent(); 5854 if (component == null) { 5855 Slog.w(TAG, "Now component for base intent of task: " + tr); 5856 return; 5857 } 5858 5859 // Find any running services associated with this app. 5860 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5861 5862 if (killProcesses) { 5863 // Find any running processes associated with this app. 5864 final String pkg = component.getPackageName(); 5865 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5866 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5867 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5868 for (int i=0; i<uids.size(); i++) { 5869 ProcessRecord proc = uids.valueAt(i); 5870 if (proc.userId != tr.userId) { 5871 continue; 5872 } 5873 if (!proc.pkgList.contains(pkg)) { 5874 continue; 5875 } 5876 procs.add(proc); 5877 } 5878 } 5879 5880 // Kill the running processes. 5881 for (int i=0; i<procs.size(); i++) { 5882 ProcessRecord pr = procs.get(i); 5883 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5884 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5885 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 5886 pr.processName, pr.setAdj, "remove task"); 5887 pr.killedBackground = true; 5888 Process.killProcessQuiet(pr.pid); 5889 } else { 5890 pr.waitingToKill = "remove task"; 5891 } 5892 } 5893 } 5894 } 5895 5896 public boolean removeTask(int taskId, int flags) { 5897 synchronized (this) { 5898 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5899 "removeTask()"); 5900 long ident = Binder.clearCallingIdentity(); 5901 try { 5902 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5903 false); 5904 if (r != null) { 5905 mRecentTasks.remove(r.task); 5906 cleanUpRemovedTaskLocked(r.task, flags); 5907 return true; 5908 } else { 5909 TaskRecord tr = null; 5910 int i=0; 5911 while (i < mRecentTasks.size()) { 5912 TaskRecord t = mRecentTasks.get(i); 5913 if (t.taskId == taskId) { 5914 tr = t; 5915 break; 5916 } 5917 i++; 5918 } 5919 if (tr != null) { 5920 if (tr.numActivities <= 0) { 5921 // Caller is just removing a recent task that is 5922 // not actively running. That is easy! 5923 mRecentTasks.remove(i); 5924 cleanUpRemovedTaskLocked(tr, flags); 5925 return true; 5926 } else { 5927 Slog.w(TAG, "removeTask: task " + taskId 5928 + " does not have activities to remove, " 5929 + " but numActivities=" + tr.numActivities 5930 + ": " + tr); 5931 } 5932 } 5933 } 5934 } finally { 5935 Binder.restoreCallingIdentity(ident); 5936 } 5937 } 5938 return false; 5939 } 5940 5941 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5942 int j; 5943 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5944 TaskRecord jt = startTask; 5945 5946 // First look backwards 5947 for (j=startIndex-1; j>=0; j--) { 5948 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5949 if (r.task != jt) { 5950 jt = r.task; 5951 if (affinity.equals(jt.affinity)) { 5952 return j; 5953 } 5954 } 5955 } 5956 5957 // Now look forwards 5958 final int N = mMainStack.mHistory.size(); 5959 jt = startTask; 5960 for (j=startIndex+1; j<N; j++) { 5961 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5962 if (r.task != jt) { 5963 if (affinity.equals(jt.affinity)) { 5964 return j; 5965 } 5966 jt = r.task; 5967 } 5968 } 5969 5970 // Might it be at the top? 5971 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5972 return N-1; 5973 } 5974 5975 return -1; 5976 } 5977 5978 /** 5979 * TODO: Add mController hook 5980 */ 5981 public void moveTaskToFront(int task, int flags, Bundle options) { 5982 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5983 "moveTaskToFront()"); 5984 5985 synchronized(this) { 5986 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5987 Binder.getCallingUid(), "Task to front")) { 5988 ActivityOptions.abort(options); 5989 return; 5990 } 5991 final long origId = Binder.clearCallingIdentity(); 5992 try { 5993 TaskRecord tr = taskForIdLocked(task); 5994 if (tr != null) { 5995 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5996 mMainStack.mUserLeaving = true; 5997 } 5998 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5999 // Caller wants the home activity moved with it. To accomplish this, 6000 // we'll just move the home task to the top first. 6001 mMainStack.moveHomeToFrontLocked(); 6002 } 6003 mMainStack.moveTaskToFrontLocked(tr, null, options); 6004 return; 6005 } 6006 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6007 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6008 if (hr.task.taskId == task) { 6009 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6010 mMainStack.mUserLeaving = true; 6011 } 6012 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6013 // Caller wants the home activity moved with it. To accomplish this, 6014 // we'll just move the home task to the top first. 6015 mMainStack.moveHomeToFrontLocked(); 6016 } 6017 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6018 return; 6019 } 6020 } 6021 } finally { 6022 Binder.restoreCallingIdentity(origId); 6023 } 6024 ActivityOptions.abort(options); 6025 } 6026 } 6027 6028 public void moveTaskToBack(int task) { 6029 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6030 "moveTaskToBack()"); 6031 6032 synchronized(this) { 6033 if (mMainStack.mResumedActivity != null 6034 && mMainStack.mResumedActivity.task.taskId == task) { 6035 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6036 Binder.getCallingUid(), "Task to back")) { 6037 return; 6038 } 6039 } 6040 final long origId = Binder.clearCallingIdentity(); 6041 mMainStack.moveTaskToBackLocked(task, null); 6042 Binder.restoreCallingIdentity(origId); 6043 } 6044 } 6045 6046 /** 6047 * Moves an activity, and all of the other activities within the same task, to the bottom 6048 * of the history stack. The activity's order within the task is unchanged. 6049 * 6050 * @param token A reference to the activity we wish to move 6051 * @param nonRoot If false then this only works if the activity is the root 6052 * of a task; if true it will work for any activity in a task. 6053 * @return Returns true if the move completed, false if not. 6054 */ 6055 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6056 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6057 synchronized(this) { 6058 final long origId = Binder.clearCallingIdentity(); 6059 int taskId = getTaskForActivityLocked(token, !nonRoot); 6060 if (taskId >= 0) { 6061 return mMainStack.moveTaskToBackLocked(taskId, null); 6062 } 6063 Binder.restoreCallingIdentity(origId); 6064 } 6065 return false; 6066 } 6067 6068 public void moveTaskBackwards(int task) { 6069 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6070 "moveTaskBackwards()"); 6071 6072 synchronized(this) { 6073 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6074 Binder.getCallingUid(), "Task backwards")) { 6075 return; 6076 } 6077 final long origId = Binder.clearCallingIdentity(); 6078 moveTaskBackwardsLocked(task); 6079 Binder.restoreCallingIdentity(origId); 6080 } 6081 } 6082 6083 private final void moveTaskBackwardsLocked(int task) { 6084 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6085 } 6086 6087 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6088 synchronized(this) { 6089 return getTaskForActivityLocked(token, onlyRoot); 6090 } 6091 } 6092 6093 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6094 final int N = mMainStack.mHistory.size(); 6095 TaskRecord lastTask = null; 6096 for (int i=0; i<N; i++) { 6097 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6098 if (r.appToken == token) { 6099 if (!onlyRoot || lastTask != r.task) { 6100 return r.task.taskId; 6101 } 6102 return -1; 6103 } 6104 lastTask = r.task; 6105 } 6106 6107 return -1; 6108 } 6109 6110 // ========================================================= 6111 // THUMBNAILS 6112 // ========================================================= 6113 6114 public void reportThumbnail(IBinder token, 6115 Bitmap thumbnail, CharSequence description) { 6116 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6117 final long origId = Binder.clearCallingIdentity(); 6118 sendPendingThumbnail(null, token, thumbnail, description, true); 6119 Binder.restoreCallingIdentity(origId); 6120 } 6121 6122 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6123 Bitmap thumbnail, CharSequence description, boolean always) { 6124 TaskRecord task = null; 6125 ArrayList receivers = null; 6126 6127 //System.out.println("Send pending thumbnail: " + r); 6128 6129 synchronized(this) { 6130 if (r == null) { 6131 r = mMainStack.isInStackLocked(token); 6132 if (r == null) { 6133 return; 6134 } 6135 } 6136 if (thumbnail == null && r.thumbHolder != null) { 6137 thumbnail = r.thumbHolder.lastThumbnail; 6138 description = r.thumbHolder.lastDescription; 6139 } 6140 if (thumbnail == null && !always) { 6141 // If there is no thumbnail, and this entry is not actually 6142 // going away, then abort for now and pick up the next 6143 // thumbnail we get. 6144 return; 6145 } 6146 task = r.task; 6147 6148 int N = mPendingThumbnails.size(); 6149 int i=0; 6150 while (i<N) { 6151 PendingThumbnailsRecord pr = 6152 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6153 //System.out.println("Looking in " + pr.pendingRecords); 6154 if (pr.pendingRecords.remove(r)) { 6155 if (receivers == null) { 6156 receivers = new ArrayList(); 6157 } 6158 receivers.add(pr); 6159 if (pr.pendingRecords.size() == 0) { 6160 pr.finished = true; 6161 mPendingThumbnails.remove(i); 6162 N--; 6163 continue; 6164 } 6165 } 6166 i++; 6167 } 6168 } 6169 6170 if (receivers != null) { 6171 final int N = receivers.size(); 6172 for (int i=0; i<N; i++) { 6173 try { 6174 PendingThumbnailsRecord pr = 6175 (PendingThumbnailsRecord)receivers.get(i); 6176 pr.receiver.newThumbnail( 6177 task != null ? task.taskId : -1, thumbnail, description); 6178 if (pr.finished) { 6179 pr.receiver.finished(); 6180 } 6181 } catch (Exception e) { 6182 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6183 } 6184 } 6185 } 6186 } 6187 6188 // ========================================================= 6189 // CONTENT PROVIDERS 6190 // ========================================================= 6191 6192 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6193 List<ProviderInfo> providers = null; 6194 try { 6195 providers = AppGlobals.getPackageManager(). 6196 queryContentProviders(app.processName, app.uid, 6197 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6198 } catch (RemoteException ex) { 6199 } 6200 if (DEBUG_MU) 6201 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6202 int userId = app.userId; 6203 if (providers != null) { 6204 int N = providers.size(); 6205 for (int i=0; i<N; i++) { 6206 ProviderInfo cpi = 6207 (ProviderInfo)providers.get(i); 6208 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6209 cpi.name, cpi.flags); 6210 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6211 // This is a singleton provider, but a user besides the 6212 // default user is asking to initialize a process it runs 6213 // in... well, no, it doesn't actually run in this process, 6214 // it runs in the process of the default user. Get rid of it. 6215 providers.remove(i); 6216 N--; 6217 continue; 6218 } 6219 6220 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6221 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6222 if (cpr == null) { 6223 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6224 mProviderMap.putProviderByClass(comp, cpr); 6225 } 6226 if (DEBUG_MU) 6227 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6228 app.pubProviders.put(cpi.name, cpr); 6229 app.addPackage(cpi.applicationInfo.packageName); 6230 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6231 } 6232 } 6233 return providers; 6234 } 6235 6236 /** 6237 * Check if {@link ProcessRecord} has a possible chance at accessing the 6238 * given {@link ProviderInfo}. Final permission checking is always done 6239 * in {@link ContentProvider}. 6240 */ 6241 private final String checkContentProviderPermissionLocked( 6242 ProviderInfo cpi, ProcessRecord r) { 6243 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6244 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6245 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6246 cpi.applicationInfo.uid, cpi.exported) 6247 == PackageManager.PERMISSION_GRANTED) { 6248 return null; 6249 } 6250 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6251 cpi.applicationInfo.uid, cpi.exported) 6252 == PackageManager.PERMISSION_GRANTED) { 6253 return null; 6254 } 6255 6256 PathPermission[] pps = cpi.pathPermissions; 6257 if (pps != null) { 6258 int i = pps.length; 6259 while (i > 0) { 6260 i--; 6261 PathPermission pp = pps[i]; 6262 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6263 cpi.applicationInfo.uid, cpi.exported) 6264 == PackageManager.PERMISSION_GRANTED) { 6265 return null; 6266 } 6267 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6268 cpi.applicationInfo.uid, cpi.exported) 6269 == PackageManager.PERMISSION_GRANTED) { 6270 return null; 6271 } 6272 } 6273 } 6274 6275 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6276 if (perms != null) { 6277 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6278 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6279 return null; 6280 } 6281 } 6282 } 6283 6284 String msg; 6285 if (!cpi.exported) { 6286 msg = "Permission Denial: opening provider " + cpi.name 6287 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6288 + ", uid=" + callingUid + ") that is not exported from uid " 6289 + cpi.applicationInfo.uid; 6290 } else { 6291 msg = "Permission Denial: opening provider " + cpi.name 6292 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6293 + ", uid=" + callingUid + ") requires " 6294 + cpi.readPermission + " or " + cpi.writePermission; 6295 } 6296 Slog.w(TAG, msg); 6297 return msg; 6298 } 6299 6300 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6301 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6302 if (r != null) { 6303 for (int i=0; i<r.conProviders.size(); i++) { 6304 ContentProviderConnection conn = r.conProviders.get(i); 6305 if (conn.provider == cpr) { 6306 if (DEBUG_PROVIDER) Slog.v(TAG, 6307 "Adding provider requested by " 6308 + r.processName + " from process " 6309 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6310 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6311 if (stable) { 6312 conn.stableCount++; 6313 conn.numStableIncs++; 6314 } else { 6315 conn.unstableCount++; 6316 conn.numUnstableIncs++; 6317 } 6318 return conn; 6319 } 6320 } 6321 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6322 if (stable) { 6323 conn.stableCount = 1; 6324 conn.numStableIncs = 1; 6325 } else { 6326 conn.unstableCount = 1; 6327 conn.numUnstableIncs = 1; 6328 } 6329 cpr.connections.add(conn); 6330 r.conProviders.add(conn); 6331 return conn; 6332 } 6333 cpr.addExternalProcessHandleLocked(externalProcessToken); 6334 return null; 6335 } 6336 6337 boolean decProviderCountLocked(ContentProviderConnection conn, 6338 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6339 if (conn != null) { 6340 cpr = conn.provider; 6341 if (DEBUG_PROVIDER) Slog.v(TAG, 6342 "Removing provider requested by " 6343 + conn.client.processName + " from process " 6344 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6345 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6346 if (stable) { 6347 conn.stableCount--; 6348 } else { 6349 conn.unstableCount--; 6350 } 6351 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6352 cpr.connections.remove(conn); 6353 conn.client.conProviders.remove(conn); 6354 return true; 6355 } 6356 return false; 6357 } 6358 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6359 return false; 6360 } 6361 6362 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6363 String name, IBinder token, boolean stable, int userId) { 6364 ContentProviderRecord cpr; 6365 ContentProviderConnection conn = null; 6366 ProviderInfo cpi = null; 6367 6368 synchronized(this) { 6369 ProcessRecord r = null; 6370 if (caller != null) { 6371 r = getRecordForAppLocked(caller); 6372 if (r == null) { 6373 throw new SecurityException( 6374 "Unable to find app for caller " + caller 6375 + " (pid=" + Binder.getCallingPid() 6376 + ") when getting content provider " + name); 6377 } 6378 } 6379 6380 // First check if this content provider has been published... 6381 cpr = mProviderMap.getProviderByName(name, userId); 6382 boolean providerRunning = cpr != null; 6383 if (providerRunning) { 6384 cpi = cpr.info; 6385 String msg; 6386 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6387 throw new SecurityException(msg); 6388 } 6389 6390 if (r != null && cpr.canRunHere(r)) { 6391 // This provider has been published or is in the process 6392 // of being published... but it is also allowed to run 6393 // in the caller's process, so don't make a connection 6394 // and just let the caller instantiate its own instance. 6395 ContentProviderHolder holder = cpr.newHolder(null); 6396 // don't give caller the provider object, it needs 6397 // to make its own. 6398 holder.provider = null; 6399 return holder; 6400 } 6401 6402 final long origId = Binder.clearCallingIdentity(); 6403 6404 // In this case the provider instance already exists, so we can 6405 // return it right away. 6406 conn = incProviderCountLocked(r, cpr, token, stable); 6407 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6408 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6409 // If this is a perceptible app accessing the provider, 6410 // make sure to count it as being accessed and thus 6411 // back up on the LRU list. This is good because 6412 // content providers are often expensive to start. 6413 updateLruProcessLocked(cpr.proc, false); 6414 } 6415 } 6416 6417 if (cpr.proc != null) { 6418 if (false) { 6419 if (cpr.name.flattenToShortString().equals( 6420 "com.android.providers.calendar/.CalendarProvider2")) { 6421 Slog.v(TAG, "****************** KILLING " 6422 + cpr.name.flattenToShortString()); 6423 Process.killProcess(cpr.proc.pid); 6424 } 6425 } 6426 boolean success = updateOomAdjLocked(cpr.proc); 6427 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6428 // NOTE: there is still a race here where a signal could be 6429 // pending on the process even though we managed to update its 6430 // adj level. Not sure what to do about this, but at least 6431 // the race is now smaller. 6432 if (!success) { 6433 // Uh oh... it looks like the provider's process 6434 // has been killed on us. We need to wait for a new 6435 // process to be started, and make sure its death 6436 // doesn't kill our process. 6437 Slog.i(TAG, 6438 "Existing provider " + cpr.name.flattenToShortString() 6439 + " is crashing; detaching " + r); 6440 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6441 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6442 if (!lastRef) { 6443 // This wasn't the last ref our process had on 6444 // the provider... we have now been killed, bail. 6445 return null; 6446 } 6447 providerRunning = false; 6448 conn = null; 6449 } 6450 } 6451 6452 Binder.restoreCallingIdentity(origId); 6453 } 6454 6455 boolean singleton; 6456 if (!providerRunning) { 6457 try { 6458 cpi = AppGlobals.getPackageManager(). 6459 resolveContentProvider(name, 6460 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6461 } catch (RemoteException ex) { 6462 } 6463 if (cpi == null) { 6464 return null; 6465 } 6466 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6467 cpi.name, cpi.flags); 6468 if (singleton) { 6469 userId = 0; 6470 } 6471 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6472 6473 String msg; 6474 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6475 throw new SecurityException(msg); 6476 } 6477 6478 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6479 && !cpi.processName.equals("system")) { 6480 // If this content provider does not run in the system 6481 // process, and the system is not yet ready to run other 6482 // processes, then fail fast instead of hanging. 6483 throw new IllegalArgumentException( 6484 "Attempt to launch content provider before system ready"); 6485 } 6486 6487 // Make sure that the user who owns this provider is started. If not, 6488 // we don't want to allow it to run. 6489 if (mStartedUsers.get(userId) == null) { 6490 Slog.w(TAG, "Unable to launch app " 6491 + cpi.applicationInfo.packageName + "/" 6492 + cpi.applicationInfo.uid + " for provider " 6493 + name + ": user " + userId + " is stopped"); 6494 return null; 6495 } 6496 6497 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6498 cpr = mProviderMap.getProviderByClass(comp, userId); 6499 final boolean firstClass = cpr == null; 6500 if (firstClass) { 6501 try { 6502 ApplicationInfo ai = 6503 AppGlobals.getPackageManager(). 6504 getApplicationInfo( 6505 cpi.applicationInfo.packageName, 6506 STOCK_PM_FLAGS, userId); 6507 if (ai == null) { 6508 Slog.w(TAG, "No package info for content provider " 6509 + cpi.name); 6510 return null; 6511 } 6512 ai = getAppInfoForUser(ai, userId); 6513 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6514 } catch (RemoteException ex) { 6515 // pm is in same process, this will never happen. 6516 } 6517 } 6518 6519 if (r != null && cpr.canRunHere(r)) { 6520 // If this is a multiprocess provider, then just return its 6521 // info and allow the caller to instantiate it. Only do 6522 // this if the provider is the same user as the caller's 6523 // process, or can run as root (so can be in any process). 6524 return cpr.newHolder(null); 6525 } 6526 6527 if (DEBUG_PROVIDER) { 6528 RuntimeException e = new RuntimeException("here"); 6529 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6530 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6531 } 6532 6533 // This is single process, and our app is now connecting to it. 6534 // See if we are already in the process of launching this 6535 // provider. 6536 final int N = mLaunchingProviders.size(); 6537 int i; 6538 for (i=0; i<N; i++) { 6539 if (mLaunchingProviders.get(i) == cpr) { 6540 break; 6541 } 6542 } 6543 6544 // If the provider is not already being launched, then get it 6545 // started. 6546 if (i >= N) { 6547 final long origId = Binder.clearCallingIdentity(); 6548 6549 try { 6550 // Content provider is now in use, its package can't be stopped. 6551 try { 6552 AppGlobals.getPackageManager().setPackageStoppedState( 6553 cpr.appInfo.packageName, false, userId); 6554 } catch (RemoteException e) { 6555 } catch (IllegalArgumentException e) { 6556 Slog.w(TAG, "Failed trying to unstop package " 6557 + cpr.appInfo.packageName + ": " + e); 6558 } 6559 6560 ProcessRecord proc = startProcessLocked(cpi.processName, 6561 cpr.appInfo, false, 0, "content provider", 6562 new ComponentName(cpi.applicationInfo.packageName, 6563 cpi.name), false, false); 6564 if (proc == null) { 6565 Slog.w(TAG, "Unable to launch app " 6566 + cpi.applicationInfo.packageName + "/" 6567 + cpi.applicationInfo.uid + " for provider " 6568 + name + ": process is bad"); 6569 return null; 6570 } 6571 cpr.launchingApp = proc; 6572 mLaunchingProviders.add(cpr); 6573 } finally { 6574 Binder.restoreCallingIdentity(origId); 6575 } 6576 } 6577 6578 // Make sure the provider is published (the same provider class 6579 // may be published under multiple names). 6580 if (firstClass) { 6581 mProviderMap.putProviderByClass(comp, cpr); 6582 } 6583 6584 mProviderMap.putProviderByName(name, cpr); 6585 conn = incProviderCountLocked(r, cpr, token, stable); 6586 if (conn != null) { 6587 conn.waiting = true; 6588 } 6589 } 6590 } 6591 6592 // Wait for the provider to be published... 6593 synchronized (cpr) { 6594 while (cpr.provider == null) { 6595 if (cpr.launchingApp == null) { 6596 Slog.w(TAG, "Unable to launch app " 6597 + cpi.applicationInfo.packageName + "/" 6598 + cpi.applicationInfo.uid + " for provider " 6599 + name + ": launching app became null"); 6600 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6601 UserHandle.getUserId(cpi.applicationInfo.uid), 6602 cpi.applicationInfo.packageName, 6603 cpi.applicationInfo.uid, name); 6604 return null; 6605 } 6606 try { 6607 if (DEBUG_MU) { 6608 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6609 + cpr.launchingApp); 6610 } 6611 if (conn != null) { 6612 conn.waiting = true; 6613 } 6614 cpr.wait(); 6615 } catch (InterruptedException ex) { 6616 } finally { 6617 if (conn != null) { 6618 conn.waiting = false; 6619 } 6620 } 6621 } 6622 } 6623 return cpr != null ? cpr.newHolder(conn) : null; 6624 } 6625 6626 public final ContentProviderHolder getContentProvider( 6627 IApplicationThread caller, String name, int userId, boolean stable) { 6628 enforceNotIsolatedCaller("getContentProvider"); 6629 if (caller == null) { 6630 String msg = "null IApplicationThread when getting content provider " 6631 + name; 6632 Slog.w(TAG, msg); 6633 throw new SecurityException(msg); 6634 } 6635 6636 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6637 false, true, "getContentProvider", null); 6638 return getContentProviderImpl(caller, name, null, stable, userId); 6639 } 6640 6641 public ContentProviderHolder getContentProviderExternal( 6642 String name, int userId, IBinder token) { 6643 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6644 "Do not have permission in call getContentProviderExternal()"); 6645 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6646 false, true, "getContentProvider", null); 6647 return getContentProviderExternalUnchecked(name, token, userId); 6648 } 6649 6650 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6651 IBinder token, int userId) { 6652 return getContentProviderImpl(null, name, token, true, userId); 6653 } 6654 6655 /** 6656 * Drop a content provider from a ProcessRecord's bookkeeping 6657 * @param cpr 6658 */ 6659 public void removeContentProvider(IBinder connection, boolean stable) { 6660 enforceNotIsolatedCaller("removeContentProvider"); 6661 synchronized (this) { 6662 ContentProviderConnection conn; 6663 try { 6664 conn = (ContentProviderConnection)connection; 6665 } catch (ClassCastException e) { 6666 String msg ="removeContentProvider: " + connection 6667 + " not a ContentProviderConnection"; 6668 Slog.w(TAG, msg); 6669 throw new IllegalArgumentException(msg); 6670 } 6671 if (conn == null) { 6672 throw new NullPointerException("connection is null"); 6673 } 6674 if (decProviderCountLocked(conn, null, null, stable)) { 6675 updateOomAdjLocked(); 6676 } 6677 } 6678 } 6679 6680 public void removeContentProviderExternal(String name, IBinder token) { 6681 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6682 "Do not have permission in call removeContentProviderExternal()"); 6683 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6684 } 6685 6686 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6687 synchronized (this) { 6688 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6689 if(cpr == null) { 6690 //remove from mProvidersByClass 6691 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6692 return; 6693 } 6694 6695 //update content provider record entry info 6696 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6697 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6698 if (localCpr.hasExternalProcessHandles()) { 6699 if (localCpr.removeExternalProcessHandleLocked(token)) { 6700 updateOomAdjLocked(); 6701 } else { 6702 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6703 + " with no external reference for token: " 6704 + token + "."); 6705 } 6706 } else { 6707 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6708 + " with no external references."); 6709 } 6710 } 6711 } 6712 6713 public final void publishContentProviders(IApplicationThread caller, 6714 List<ContentProviderHolder> providers) { 6715 if (providers == null) { 6716 return; 6717 } 6718 6719 enforceNotIsolatedCaller("publishContentProviders"); 6720 synchronized (this) { 6721 final ProcessRecord r = getRecordForAppLocked(caller); 6722 if (DEBUG_MU) 6723 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6724 if (r == null) { 6725 throw new SecurityException( 6726 "Unable to find app for caller " + caller 6727 + " (pid=" + Binder.getCallingPid() 6728 + ") when publishing content providers"); 6729 } 6730 6731 final long origId = Binder.clearCallingIdentity(); 6732 6733 final int N = providers.size(); 6734 for (int i=0; i<N; i++) { 6735 ContentProviderHolder src = providers.get(i); 6736 if (src == null || src.info == null || src.provider == null) { 6737 continue; 6738 } 6739 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6740 if (DEBUG_MU) 6741 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6742 if (dst != null) { 6743 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6744 mProviderMap.putProviderByClass(comp, dst); 6745 String names[] = dst.info.authority.split(";"); 6746 for (int j = 0; j < names.length; j++) { 6747 mProviderMap.putProviderByName(names[j], dst); 6748 } 6749 6750 int NL = mLaunchingProviders.size(); 6751 int j; 6752 for (j=0; j<NL; j++) { 6753 if (mLaunchingProviders.get(j) == dst) { 6754 mLaunchingProviders.remove(j); 6755 j--; 6756 NL--; 6757 } 6758 } 6759 synchronized (dst) { 6760 dst.provider = src.provider; 6761 dst.proc = r; 6762 dst.notifyAll(); 6763 } 6764 updateOomAdjLocked(r); 6765 } 6766 } 6767 6768 Binder.restoreCallingIdentity(origId); 6769 } 6770 } 6771 6772 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6773 ContentProviderConnection conn; 6774 try { 6775 conn = (ContentProviderConnection)connection; 6776 } catch (ClassCastException e) { 6777 String msg ="refContentProvider: " + connection 6778 + " not a ContentProviderConnection"; 6779 Slog.w(TAG, msg); 6780 throw new IllegalArgumentException(msg); 6781 } 6782 if (conn == null) { 6783 throw new NullPointerException("connection is null"); 6784 } 6785 6786 synchronized (this) { 6787 if (stable > 0) { 6788 conn.numStableIncs += stable; 6789 } 6790 stable = conn.stableCount + stable; 6791 if (stable < 0) { 6792 throw new IllegalStateException("stableCount < 0: " + stable); 6793 } 6794 6795 if (unstable > 0) { 6796 conn.numUnstableIncs += unstable; 6797 } 6798 unstable = conn.unstableCount + unstable; 6799 if (unstable < 0) { 6800 throw new IllegalStateException("unstableCount < 0: " + unstable); 6801 } 6802 6803 if ((stable+unstable) <= 0) { 6804 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6805 + stable + " unstable=" + unstable); 6806 } 6807 conn.stableCount = stable; 6808 conn.unstableCount = unstable; 6809 return !conn.dead; 6810 } 6811 } 6812 6813 public void unstableProviderDied(IBinder connection) { 6814 ContentProviderConnection conn; 6815 try { 6816 conn = (ContentProviderConnection)connection; 6817 } catch (ClassCastException e) { 6818 String msg ="refContentProvider: " + connection 6819 + " not a ContentProviderConnection"; 6820 Slog.w(TAG, msg); 6821 throw new IllegalArgumentException(msg); 6822 } 6823 if (conn == null) { 6824 throw new NullPointerException("connection is null"); 6825 } 6826 6827 // Safely retrieve the content provider associated with the connection. 6828 IContentProvider provider; 6829 synchronized (this) { 6830 provider = conn.provider.provider; 6831 } 6832 6833 if (provider == null) { 6834 // Um, yeah, we're way ahead of you. 6835 return; 6836 } 6837 6838 // Make sure the caller is being honest with us. 6839 if (provider.asBinder().pingBinder()) { 6840 // Er, no, still looks good to us. 6841 synchronized (this) { 6842 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6843 + " says " + conn + " died, but we don't agree"); 6844 return; 6845 } 6846 } 6847 6848 // Well look at that! It's dead! 6849 synchronized (this) { 6850 if (conn.provider.provider != provider) { 6851 // But something changed... good enough. 6852 return; 6853 } 6854 6855 ProcessRecord proc = conn.provider.proc; 6856 if (proc == null || proc.thread == null) { 6857 // Seems like the process is already cleaned up. 6858 return; 6859 } 6860 6861 // As far as we're concerned, this is just like receiving a 6862 // death notification... just a bit prematurely. 6863 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6864 + ") early provider death"); 6865 final long ident = Binder.clearCallingIdentity(); 6866 try { 6867 appDiedLocked(proc, proc.pid, proc.thread); 6868 } finally { 6869 Binder.restoreCallingIdentity(ident); 6870 } 6871 } 6872 } 6873 6874 public static final void installSystemProviders() { 6875 List<ProviderInfo> providers; 6876 synchronized (mSelf) { 6877 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6878 providers = mSelf.generateApplicationProvidersLocked(app); 6879 if (providers != null) { 6880 for (int i=providers.size()-1; i>=0; i--) { 6881 ProviderInfo pi = (ProviderInfo)providers.get(i); 6882 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6883 Slog.w(TAG, "Not installing system proc provider " + pi.name 6884 + ": not system .apk"); 6885 providers.remove(i); 6886 } 6887 } 6888 } 6889 } 6890 if (providers != null) { 6891 mSystemThread.installSystemProviders(providers); 6892 } 6893 6894 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6895 6896 mSelf.mUsageStatsService.monitorPackages(); 6897 } 6898 6899 /** 6900 * Allows app to retrieve the MIME type of a URI without having permission 6901 * to access its content provider. 6902 * 6903 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6904 * 6905 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6906 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6907 */ 6908 public String getProviderMimeType(Uri uri, int userId) { 6909 enforceNotIsolatedCaller("getProviderMimeType"); 6910 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6911 userId, false, true, "getProviderMimeType", null); 6912 final String name = uri.getAuthority(); 6913 final long ident = Binder.clearCallingIdentity(); 6914 ContentProviderHolder holder = null; 6915 6916 try { 6917 holder = getContentProviderExternalUnchecked(name, null, userId); 6918 if (holder != null) { 6919 return holder.provider.getType(uri); 6920 } 6921 } catch (RemoteException e) { 6922 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6923 return null; 6924 } finally { 6925 if (holder != null) { 6926 removeContentProviderExternalUnchecked(name, null, userId); 6927 } 6928 Binder.restoreCallingIdentity(ident); 6929 } 6930 6931 return null; 6932 } 6933 6934 // ========================================================= 6935 // GLOBAL MANAGEMENT 6936 // ========================================================= 6937 6938 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6939 ApplicationInfo info, String customProcess, boolean isolated) { 6940 String proc = customProcess != null ? customProcess : info.processName; 6941 BatteryStatsImpl.Uid.Proc ps = null; 6942 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6943 int uid = info.uid; 6944 if (isolated) { 6945 int userId = UserHandle.getUserId(uid); 6946 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6947 uid = 0; 6948 while (true) { 6949 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6950 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6951 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6952 } 6953 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6954 mNextIsolatedProcessUid++; 6955 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6956 // No process for this uid, use it. 6957 break; 6958 } 6959 stepsLeft--; 6960 if (stepsLeft <= 0) { 6961 return null; 6962 } 6963 } 6964 } 6965 synchronized (stats) { 6966 ps = stats.getProcessStatsLocked(info.uid, proc); 6967 } 6968 return new ProcessRecord(ps, thread, info, proc, uid); 6969 } 6970 6971 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6972 ProcessRecord app; 6973 if (!isolated) { 6974 app = getProcessRecordLocked(info.processName, info.uid); 6975 } else { 6976 app = null; 6977 } 6978 6979 if (app == null) { 6980 app = newProcessRecordLocked(null, info, null, isolated); 6981 mProcessNames.put(info.processName, app.uid, app); 6982 if (isolated) { 6983 mIsolatedProcesses.put(app.uid, app); 6984 } 6985 updateLruProcessLocked(app, true); 6986 } 6987 6988 // This package really, really can not be stopped. 6989 try { 6990 AppGlobals.getPackageManager().setPackageStoppedState( 6991 info.packageName, false, UserHandle.getUserId(app.uid)); 6992 } catch (RemoteException e) { 6993 } catch (IllegalArgumentException e) { 6994 Slog.w(TAG, "Failed trying to unstop package " 6995 + info.packageName + ": " + e); 6996 } 6997 6998 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6999 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7000 app.persistent = true; 7001 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7002 } 7003 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7004 mPersistentStartingProcesses.add(app); 7005 startProcessLocked(app, "added application", app.processName); 7006 } 7007 7008 return app; 7009 } 7010 7011 public void unhandledBack() { 7012 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7013 "unhandledBack()"); 7014 7015 synchronized(this) { 7016 int count = mMainStack.mHistory.size(); 7017 if (DEBUG_SWITCH) Slog.d( 7018 TAG, "Performing unhandledBack(): stack size = " + count); 7019 if (count > 1) { 7020 final long origId = Binder.clearCallingIdentity(); 7021 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7022 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7023 Binder.restoreCallingIdentity(origId); 7024 } 7025 } 7026 } 7027 7028 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7029 enforceNotIsolatedCaller("openContentUri"); 7030 final int userId = UserHandle.getCallingUserId(); 7031 String name = uri.getAuthority(); 7032 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7033 ParcelFileDescriptor pfd = null; 7034 if (cph != null) { 7035 // We record the binder invoker's uid in thread-local storage before 7036 // going to the content provider to open the file. Later, in the code 7037 // that handles all permissions checks, we look for this uid and use 7038 // that rather than the Activity Manager's own uid. The effect is that 7039 // we do the check against the caller's permissions even though it looks 7040 // to the content provider like the Activity Manager itself is making 7041 // the request. 7042 sCallerIdentity.set(new Identity( 7043 Binder.getCallingPid(), Binder.getCallingUid())); 7044 try { 7045 pfd = cph.provider.openFile(uri, "r"); 7046 } catch (FileNotFoundException e) { 7047 // do nothing; pfd will be returned null 7048 } finally { 7049 // Ensure that whatever happens, we clean up the identity state 7050 sCallerIdentity.remove(); 7051 } 7052 7053 // We've got the fd now, so we're done with the provider. 7054 removeContentProviderExternalUnchecked(name, null, userId); 7055 } else { 7056 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7057 } 7058 return pfd; 7059 } 7060 7061 // Actually is sleeping or shutting down or whatever else in the future 7062 // is an inactive state. 7063 public boolean isSleeping() { 7064 return mSleeping || mShuttingDown; 7065 } 7066 7067 public void goingToSleep() { 7068 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7069 != PackageManager.PERMISSION_GRANTED) { 7070 throw new SecurityException("Requires permission " 7071 + android.Manifest.permission.DEVICE_POWER); 7072 } 7073 7074 synchronized(this) { 7075 mWentToSleep = true; 7076 updateEventDispatchingLocked(); 7077 7078 if (!mSleeping) { 7079 mSleeping = true; 7080 mMainStack.stopIfSleepingLocked(); 7081 7082 // Initialize the wake times of all processes. 7083 checkExcessivePowerUsageLocked(false); 7084 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7085 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7086 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7087 } 7088 } 7089 } 7090 7091 public boolean shutdown(int timeout) { 7092 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7093 != PackageManager.PERMISSION_GRANTED) { 7094 throw new SecurityException("Requires permission " 7095 + android.Manifest.permission.SHUTDOWN); 7096 } 7097 7098 boolean timedout = false; 7099 7100 synchronized(this) { 7101 mShuttingDown = true; 7102 updateEventDispatchingLocked(); 7103 7104 if (mMainStack.mResumedActivity != null) { 7105 mMainStack.stopIfSleepingLocked(); 7106 final long endTime = System.currentTimeMillis() + timeout; 7107 while (mMainStack.mResumedActivity != null 7108 || mMainStack.mPausingActivity != null) { 7109 long delay = endTime - System.currentTimeMillis(); 7110 if (delay <= 0) { 7111 Slog.w(TAG, "Activity manager shutdown timed out"); 7112 timedout = true; 7113 break; 7114 } 7115 try { 7116 this.wait(); 7117 } catch (InterruptedException e) { 7118 } 7119 } 7120 } 7121 } 7122 7123 mUsageStatsService.shutdown(); 7124 mBatteryStatsService.shutdown(); 7125 7126 return timedout; 7127 } 7128 7129 public final void activitySlept(IBinder token) { 7130 if (localLOGV) Slog.v( 7131 TAG, "Activity slept: token=" + token); 7132 7133 ActivityRecord r = null; 7134 7135 final long origId = Binder.clearCallingIdentity(); 7136 7137 synchronized (this) { 7138 r = mMainStack.isInStackLocked(token); 7139 if (r != null) { 7140 mMainStack.activitySleptLocked(r); 7141 } 7142 } 7143 7144 Binder.restoreCallingIdentity(origId); 7145 } 7146 7147 private void comeOutOfSleepIfNeededLocked() { 7148 if (!mWentToSleep && !mLockScreenShown) { 7149 if (mSleeping) { 7150 mSleeping = false; 7151 mMainStack.awakeFromSleepingLocked(); 7152 mMainStack.resumeTopActivityLocked(null); 7153 } 7154 } 7155 } 7156 7157 public void wakingUp() { 7158 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7159 != PackageManager.PERMISSION_GRANTED) { 7160 throw new SecurityException("Requires permission " 7161 + android.Manifest.permission.DEVICE_POWER); 7162 } 7163 7164 synchronized(this) { 7165 mWentToSleep = false; 7166 updateEventDispatchingLocked(); 7167 comeOutOfSleepIfNeededLocked(); 7168 } 7169 } 7170 7171 private void updateEventDispatchingLocked() { 7172 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7173 } 7174 7175 public void setLockScreenShown(boolean shown) { 7176 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7177 != PackageManager.PERMISSION_GRANTED) { 7178 throw new SecurityException("Requires permission " 7179 + android.Manifest.permission.DEVICE_POWER); 7180 } 7181 7182 synchronized(this) { 7183 mLockScreenShown = shown; 7184 comeOutOfSleepIfNeededLocked(); 7185 } 7186 } 7187 7188 public void stopAppSwitches() { 7189 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7190 != PackageManager.PERMISSION_GRANTED) { 7191 throw new SecurityException("Requires permission " 7192 + android.Manifest.permission.STOP_APP_SWITCHES); 7193 } 7194 7195 synchronized(this) { 7196 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7197 + APP_SWITCH_DELAY_TIME; 7198 mDidAppSwitch = false; 7199 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7200 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7201 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7202 } 7203 } 7204 7205 public void resumeAppSwitches() { 7206 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7207 != PackageManager.PERMISSION_GRANTED) { 7208 throw new SecurityException("Requires permission " 7209 + android.Manifest.permission.STOP_APP_SWITCHES); 7210 } 7211 7212 synchronized(this) { 7213 // Note that we don't execute any pending app switches... we will 7214 // let those wait until either the timeout, or the next start 7215 // activity request. 7216 mAppSwitchesAllowedTime = 0; 7217 } 7218 } 7219 7220 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7221 String name) { 7222 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7223 return true; 7224 } 7225 7226 final int perm = checkComponentPermission( 7227 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7228 callingUid, -1, true); 7229 if (perm == PackageManager.PERMISSION_GRANTED) { 7230 return true; 7231 } 7232 7233 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7234 return false; 7235 } 7236 7237 public void setDebugApp(String packageName, boolean waitForDebugger, 7238 boolean persistent) { 7239 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7240 "setDebugApp()"); 7241 7242 // Note that this is not really thread safe if there are multiple 7243 // callers into it at the same time, but that's not a situation we 7244 // care about. 7245 if (persistent) { 7246 final ContentResolver resolver = mContext.getContentResolver(); 7247 Settings.System.putString( 7248 resolver, Settings.System.DEBUG_APP, 7249 packageName); 7250 Settings.System.putInt( 7251 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7252 waitForDebugger ? 1 : 0); 7253 } 7254 7255 synchronized (this) { 7256 if (!persistent) { 7257 mOrigDebugApp = mDebugApp; 7258 mOrigWaitForDebugger = mWaitForDebugger; 7259 } 7260 mDebugApp = packageName; 7261 mWaitForDebugger = waitForDebugger; 7262 mDebugTransient = !persistent; 7263 if (packageName != null) { 7264 final long origId = Binder.clearCallingIdentity(); 7265 forceStopPackageLocked(packageName, -1, false, false, true, true, 7266 UserHandle.USER_ALL); 7267 Binder.restoreCallingIdentity(origId); 7268 } 7269 } 7270 } 7271 7272 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7273 synchronized (this) { 7274 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7275 if (!isDebuggable) { 7276 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7277 throw new SecurityException("Process not debuggable: " + app.packageName); 7278 } 7279 } 7280 7281 mOpenGlTraceApp = processName; 7282 } 7283 } 7284 7285 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7286 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7287 synchronized (this) { 7288 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7289 if (!isDebuggable) { 7290 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7291 throw new SecurityException("Process not debuggable: " + app.packageName); 7292 } 7293 } 7294 mProfileApp = processName; 7295 mProfileFile = profileFile; 7296 if (mProfileFd != null) { 7297 try { 7298 mProfileFd.close(); 7299 } catch (IOException e) { 7300 } 7301 mProfileFd = null; 7302 } 7303 mProfileFd = profileFd; 7304 mProfileType = 0; 7305 mAutoStopProfiler = autoStopProfiler; 7306 } 7307 } 7308 7309 public void setAlwaysFinish(boolean enabled) { 7310 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7311 "setAlwaysFinish()"); 7312 7313 Settings.System.putInt( 7314 mContext.getContentResolver(), 7315 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7316 7317 synchronized (this) { 7318 mAlwaysFinishActivities = enabled; 7319 } 7320 } 7321 7322 public void setActivityController(IActivityController controller) { 7323 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7324 "setActivityController()"); 7325 synchronized (this) { 7326 mController = controller; 7327 } 7328 } 7329 7330 public boolean isUserAMonkey() { 7331 // For now the fact that there is a controller implies 7332 // we have a monkey. 7333 synchronized (this) { 7334 return mController != null; 7335 } 7336 } 7337 7338 public void requestBugReport() { 7339 // No permission check because this can't do anything harmful -- 7340 // it will just eventually cause the user to be presented with 7341 // a UI to select where the bug report goes. 7342 SystemProperties.set("ctl.start", "bugreport"); 7343 } 7344 7345 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) { 7346 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7347 != PackageManager.PERMISSION_GRANTED) { 7348 throw new SecurityException("Requires permission " 7349 + android.Manifest.permission.FILTER_EVENTS); 7350 } 7351 7352 ProcessRecord proc; 7353 7354 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut(). 7355 synchronized (this) { 7356 synchronized (mPidsSelfLocked) { 7357 proc = mPidsSelfLocked.get(pid); 7358 } 7359 if (proc != null) { 7360 if (proc.debugging) { 7361 return -1; 7362 } 7363 7364 if (mDidDexOpt) { 7365 // Give more time since we were dexopting. 7366 mDidDexOpt = false; 7367 return -1; 7368 } 7369 7370 if (proc.instrumentationClass != null) { 7371 Bundle info = new Bundle(); 7372 info.putString("shortMsg", "keyDispatchingTimedOut"); 7373 info.putString("longMsg", "Timed out while dispatching key event"); 7374 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 7375 proc = null; 7376 } 7377 } 7378 } 7379 7380 if (proc != null) { 7381 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut"); 7382 if (proc.instrumentationClass != null || proc.usingWrapper) { 7383 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 7384 } 7385 } 7386 7387 return KEY_DISPATCHING_TIMEOUT; 7388 } 7389 7390 public void registerProcessObserver(IProcessObserver observer) { 7391 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7392 "registerProcessObserver()"); 7393 synchronized (this) { 7394 mProcessObservers.register(observer); 7395 } 7396 } 7397 7398 public void unregisterProcessObserver(IProcessObserver observer) { 7399 synchronized (this) { 7400 mProcessObservers.unregister(observer); 7401 } 7402 } 7403 7404 public void setImmersive(IBinder token, boolean immersive) { 7405 synchronized(this) { 7406 ActivityRecord r = mMainStack.isInStackLocked(token); 7407 if (r == null) { 7408 throw new IllegalArgumentException(); 7409 } 7410 r.immersive = immersive; 7411 } 7412 } 7413 7414 public boolean isImmersive(IBinder token) { 7415 synchronized (this) { 7416 ActivityRecord r = mMainStack.isInStackLocked(token); 7417 if (r == null) { 7418 throw new IllegalArgumentException(); 7419 } 7420 return r.immersive; 7421 } 7422 } 7423 7424 public boolean isTopActivityImmersive() { 7425 enforceNotIsolatedCaller("startActivity"); 7426 synchronized (this) { 7427 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7428 return (r != null) ? r.immersive : false; 7429 } 7430 } 7431 7432 public final void enterSafeMode() { 7433 synchronized(this) { 7434 // It only makes sense to do this before the system is ready 7435 // and started launching other packages. 7436 if (!mSystemReady) { 7437 try { 7438 AppGlobals.getPackageManager().enterSafeMode(); 7439 } catch (RemoteException e) { 7440 } 7441 } 7442 } 7443 } 7444 7445 public final void showSafeModeOverlay() { 7446 View v = LayoutInflater.from(mContext).inflate( 7447 com.android.internal.R.layout.safe_mode, null); 7448 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7449 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7450 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7451 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7452 lp.gravity = Gravity.BOTTOM | Gravity.START; 7453 lp.format = v.getBackground().getOpacity(); 7454 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7455 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7456 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 7457 ((WindowManager)mContext.getSystemService( 7458 Context.WINDOW_SERVICE)).addView(v, lp); 7459 } 7460 7461 public void noteWakeupAlarm(IIntentSender sender) { 7462 if (!(sender instanceof PendingIntentRecord)) { 7463 return; 7464 } 7465 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7466 synchronized (stats) { 7467 if (mBatteryStatsService.isOnBattery()) { 7468 mBatteryStatsService.enforceCallingPermission(); 7469 PendingIntentRecord rec = (PendingIntentRecord)sender; 7470 int MY_UID = Binder.getCallingUid(); 7471 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7472 BatteryStatsImpl.Uid.Pkg pkg = 7473 stats.getPackageStatsLocked(uid, rec.key.packageName); 7474 pkg.incWakeupsLocked(); 7475 } 7476 } 7477 } 7478 7479 public boolean killPids(int[] pids, String pReason, boolean secure) { 7480 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7481 throw new SecurityException("killPids only available to the system"); 7482 } 7483 String reason = (pReason == null) ? "Unknown" : pReason; 7484 // XXX Note: don't acquire main activity lock here, because the window 7485 // manager calls in with its locks held. 7486 7487 boolean killed = false; 7488 synchronized (mPidsSelfLocked) { 7489 int[] types = new int[pids.length]; 7490 int worstType = 0; 7491 for (int i=0; i<pids.length; i++) { 7492 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7493 if (proc != null) { 7494 int type = proc.setAdj; 7495 types[i] = type; 7496 if (type > worstType) { 7497 worstType = type; 7498 } 7499 } 7500 } 7501 7502 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7503 // then constrain it so we will kill all hidden procs. 7504 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7505 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7506 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7507 } 7508 7509 // If this is not a secure call, don't let it kill processes that 7510 // are important. 7511 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7512 worstType = ProcessList.SERVICE_ADJ; 7513 } 7514 7515 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7516 for (int i=0; i<pids.length; i++) { 7517 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7518 if (proc == null) { 7519 continue; 7520 } 7521 int adj = proc.setAdj; 7522 if (adj >= worstType && !proc.killedBackground) { 7523 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7524 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7525 proc.processName, adj, reason); 7526 killed = true; 7527 proc.killedBackground = true; 7528 Process.killProcessQuiet(pids[i]); 7529 } 7530 } 7531 } 7532 return killed; 7533 } 7534 7535 @Override 7536 public boolean killProcessesBelowForeground(String reason) { 7537 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7538 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7539 } 7540 7541 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7542 } 7543 7544 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7545 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7546 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7547 } 7548 7549 boolean killed = false; 7550 synchronized (mPidsSelfLocked) { 7551 final int size = mPidsSelfLocked.size(); 7552 for (int i = 0; i < size; i++) { 7553 final int pid = mPidsSelfLocked.keyAt(i); 7554 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7555 if (proc == null) continue; 7556 7557 final int adj = proc.setAdj; 7558 if (adj > belowAdj && !proc.killedBackground) { 7559 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7560 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7561 proc.pid, proc.processName, adj, reason); 7562 killed = true; 7563 proc.killedBackground = true; 7564 Process.killProcessQuiet(pid); 7565 } 7566 } 7567 } 7568 return killed; 7569 } 7570 7571 public final void startRunning(String pkg, String cls, String action, 7572 String data) { 7573 synchronized(this) { 7574 if (mStartRunning) { 7575 return; 7576 } 7577 mStartRunning = true; 7578 mTopComponent = pkg != null && cls != null 7579 ? new ComponentName(pkg, cls) : null; 7580 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7581 mTopData = data; 7582 if (!mSystemReady) { 7583 return; 7584 } 7585 } 7586 7587 systemReady(null); 7588 } 7589 7590 private void retrieveSettings() { 7591 final ContentResolver resolver = mContext.getContentResolver(); 7592 String debugApp = Settings.System.getString( 7593 resolver, Settings.System.DEBUG_APP); 7594 boolean waitForDebugger = Settings.System.getInt( 7595 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7596 boolean alwaysFinishActivities = Settings.System.getInt( 7597 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7598 7599 Configuration configuration = new Configuration(); 7600 Settings.System.getConfiguration(resolver, configuration); 7601 7602 synchronized (this) { 7603 mDebugApp = mOrigDebugApp = debugApp; 7604 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7605 mAlwaysFinishActivities = alwaysFinishActivities; 7606 // This happens before any activities are started, so we can 7607 // change mConfiguration in-place. 7608 updateConfigurationLocked(configuration, null, false, true); 7609 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7610 } 7611 } 7612 7613 public boolean testIsSystemReady() { 7614 // no need to synchronize(this) just to read & return the value 7615 return mSystemReady; 7616 } 7617 7618 private static File getCalledPreBootReceiversFile() { 7619 File dataDir = Environment.getDataDirectory(); 7620 File systemDir = new File(dataDir, "system"); 7621 File fname = new File(systemDir, "called_pre_boots.dat"); 7622 return fname; 7623 } 7624 7625 static final int LAST_DONE_VERSION = 10000; 7626 7627 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7628 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7629 File file = getCalledPreBootReceiversFile(); 7630 FileInputStream fis = null; 7631 try { 7632 fis = new FileInputStream(file); 7633 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7634 int fvers = dis.readInt(); 7635 if (fvers == LAST_DONE_VERSION) { 7636 String vers = dis.readUTF(); 7637 String codename = dis.readUTF(); 7638 String build = dis.readUTF(); 7639 if (android.os.Build.VERSION.RELEASE.equals(vers) 7640 && android.os.Build.VERSION.CODENAME.equals(codename) 7641 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7642 int num = dis.readInt(); 7643 while (num > 0) { 7644 num--; 7645 String pkg = dis.readUTF(); 7646 String cls = dis.readUTF(); 7647 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7648 } 7649 } 7650 } 7651 } catch (FileNotFoundException e) { 7652 } catch (IOException e) { 7653 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7654 } finally { 7655 if (fis != null) { 7656 try { 7657 fis.close(); 7658 } catch (IOException e) { 7659 } 7660 } 7661 } 7662 return lastDoneReceivers; 7663 } 7664 7665 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7666 File file = getCalledPreBootReceiversFile(); 7667 FileOutputStream fos = null; 7668 DataOutputStream dos = null; 7669 try { 7670 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7671 fos = new FileOutputStream(file); 7672 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7673 dos.writeInt(LAST_DONE_VERSION); 7674 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7675 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7676 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7677 dos.writeInt(list.size()); 7678 for (int i=0; i<list.size(); i++) { 7679 dos.writeUTF(list.get(i).getPackageName()); 7680 dos.writeUTF(list.get(i).getClassName()); 7681 } 7682 } catch (IOException e) { 7683 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7684 file.delete(); 7685 } finally { 7686 FileUtils.sync(fos); 7687 if (dos != null) { 7688 try { 7689 dos.close(); 7690 } catch (IOException e) { 7691 // TODO Auto-generated catch block 7692 e.printStackTrace(); 7693 } 7694 } 7695 } 7696 } 7697 7698 public void systemReady(final Runnable goingCallback) { 7699 synchronized(this) { 7700 if (mSystemReady) { 7701 if (goingCallback != null) goingCallback.run(); 7702 return; 7703 } 7704 7705 // Check to see if there are any update receivers to run. 7706 if (!mDidUpdate) { 7707 if (mWaitingUpdate) { 7708 return; 7709 } 7710 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7711 List<ResolveInfo> ris = null; 7712 try { 7713 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7714 intent, null, 0, 0); 7715 } catch (RemoteException e) { 7716 } 7717 if (ris != null) { 7718 for (int i=ris.size()-1; i>=0; i--) { 7719 if ((ris.get(i).activityInfo.applicationInfo.flags 7720 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7721 ris.remove(i); 7722 } 7723 } 7724 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7725 7726 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7727 7728 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7729 for (int i=0; i<ris.size(); i++) { 7730 ActivityInfo ai = ris.get(i).activityInfo; 7731 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7732 if (lastDoneReceivers.contains(comp)) { 7733 ris.remove(i); 7734 i--; 7735 } 7736 } 7737 7738 final int[] users = getUsersLocked(); 7739 for (int i=0; i<ris.size(); i++) { 7740 ActivityInfo ai = ris.get(i).activityInfo; 7741 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7742 doneReceivers.add(comp); 7743 intent.setComponent(comp); 7744 for (int j=0; j<users.length; j++) { 7745 IIntentReceiver finisher = null; 7746 if (i == ris.size()-1 && j == users.length-1) { 7747 finisher = new IIntentReceiver.Stub() { 7748 public void performReceive(Intent intent, int resultCode, 7749 String data, Bundle extras, boolean ordered, 7750 boolean sticky, int sendingUser) { 7751 // The raw IIntentReceiver interface is called 7752 // with the AM lock held, so redispatch to 7753 // execute our code without the lock. 7754 mHandler.post(new Runnable() { 7755 public void run() { 7756 synchronized (ActivityManagerService.this) { 7757 mDidUpdate = true; 7758 } 7759 writeLastDonePreBootReceivers(doneReceivers); 7760 showBootMessage(mContext.getText( 7761 R.string.android_upgrading_complete), 7762 false); 7763 systemReady(goingCallback); 7764 } 7765 }); 7766 } 7767 }; 7768 } 7769 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7770 + " for user " + users[j]); 7771 broadcastIntentLocked(null, null, intent, null, finisher, 7772 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7773 users[j]); 7774 if (finisher != null) { 7775 mWaitingUpdate = true; 7776 } 7777 } 7778 } 7779 } 7780 if (mWaitingUpdate) { 7781 return; 7782 } 7783 mDidUpdate = true; 7784 } 7785 7786 mSystemReady = true; 7787 if (!mStartRunning) { 7788 return; 7789 } 7790 } 7791 7792 ArrayList<ProcessRecord> procsToKill = null; 7793 synchronized(mPidsSelfLocked) { 7794 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7795 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7796 if (!isAllowedWhileBooting(proc.info)){ 7797 if (procsToKill == null) { 7798 procsToKill = new ArrayList<ProcessRecord>(); 7799 } 7800 procsToKill.add(proc); 7801 } 7802 } 7803 } 7804 7805 synchronized(this) { 7806 if (procsToKill != null) { 7807 for (int i=procsToKill.size()-1; i>=0; i--) { 7808 ProcessRecord proc = procsToKill.get(i); 7809 Slog.i(TAG, "Removing system update proc: " + proc); 7810 removeProcessLocked(proc, true, false, "system update done"); 7811 } 7812 } 7813 7814 // Now that we have cleaned up any update processes, we 7815 // are ready to start launching real processes and know that 7816 // we won't trample on them any more. 7817 mProcessesReady = true; 7818 } 7819 7820 Slog.i(TAG, "System now ready"); 7821 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7822 SystemClock.uptimeMillis()); 7823 7824 synchronized(this) { 7825 // Make sure we have no pre-ready processes sitting around. 7826 7827 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7828 ResolveInfo ri = mContext.getPackageManager() 7829 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7830 STOCK_PM_FLAGS); 7831 CharSequence errorMsg = null; 7832 if (ri != null) { 7833 ActivityInfo ai = ri.activityInfo; 7834 ApplicationInfo app = ai.applicationInfo; 7835 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7836 mTopAction = Intent.ACTION_FACTORY_TEST; 7837 mTopData = null; 7838 mTopComponent = new ComponentName(app.packageName, 7839 ai.name); 7840 } else { 7841 errorMsg = mContext.getResources().getText( 7842 com.android.internal.R.string.factorytest_not_system); 7843 } 7844 } else { 7845 errorMsg = mContext.getResources().getText( 7846 com.android.internal.R.string.factorytest_no_action); 7847 } 7848 if (errorMsg != null) { 7849 mTopAction = null; 7850 mTopData = null; 7851 mTopComponent = null; 7852 Message msg = Message.obtain(); 7853 msg.what = SHOW_FACTORY_ERROR_MSG; 7854 msg.getData().putCharSequence("msg", errorMsg); 7855 mHandler.sendMessage(msg); 7856 } 7857 } 7858 } 7859 7860 retrieveSettings(); 7861 7862 if (goingCallback != null) goingCallback.run(); 7863 7864 synchronized (this) { 7865 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7866 try { 7867 List apps = AppGlobals.getPackageManager(). 7868 getPersistentApplications(STOCK_PM_FLAGS); 7869 if (apps != null) { 7870 int N = apps.size(); 7871 int i; 7872 for (i=0; i<N; i++) { 7873 ApplicationInfo info 7874 = (ApplicationInfo)apps.get(i); 7875 if (info != null && 7876 !info.packageName.equals("android")) { 7877 addAppLocked(info, false); 7878 } 7879 } 7880 } 7881 } catch (RemoteException ex) { 7882 // pm is in same process, this will never happen. 7883 } 7884 } 7885 7886 // Start up initial activity. 7887 mBooting = true; 7888 7889 try { 7890 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7891 Message msg = Message.obtain(); 7892 msg.what = SHOW_UID_ERROR_MSG; 7893 mHandler.sendMessage(msg); 7894 } 7895 } catch (RemoteException e) { 7896 } 7897 7898 long ident = Binder.clearCallingIdentity(); 7899 try { 7900 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7901 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 7902 | Intent.FLAG_RECEIVER_FOREGROUND); 7903 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7904 broadcastIntentLocked(null, null, intent, 7905 null, null, 0, null, null, null, 7906 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7907 } finally { 7908 Binder.restoreCallingIdentity(ident); 7909 } 7910 mMainStack.resumeTopActivityLocked(null); 7911 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7912 } 7913 } 7914 7915 private boolean makeAppCrashingLocked(ProcessRecord app, 7916 String shortMsg, String longMsg, String stackTrace) { 7917 app.crashing = true; 7918 app.crashingReport = generateProcessError(app, 7919 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7920 startAppProblemLocked(app); 7921 app.stopFreezingAllLocked(); 7922 return handleAppCrashLocked(app); 7923 } 7924 7925 private void makeAppNotRespondingLocked(ProcessRecord app, 7926 String activity, String shortMsg, String longMsg) { 7927 app.notResponding = true; 7928 app.notRespondingReport = generateProcessError(app, 7929 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7930 activity, shortMsg, longMsg, null); 7931 startAppProblemLocked(app); 7932 app.stopFreezingAllLocked(); 7933 } 7934 7935 /** 7936 * Generate a process error record, suitable for attachment to a ProcessRecord. 7937 * 7938 * @param app The ProcessRecord in which the error occurred. 7939 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7940 * ActivityManager.AppErrorStateInfo 7941 * @param activity The activity associated with the crash, if known. 7942 * @param shortMsg Short message describing the crash. 7943 * @param longMsg Long message describing the crash. 7944 * @param stackTrace Full crash stack trace, may be null. 7945 * 7946 * @return Returns a fully-formed AppErrorStateInfo record. 7947 */ 7948 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7949 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7950 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7951 7952 report.condition = condition; 7953 report.processName = app.processName; 7954 report.pid = app.pid; 7955 report.uid = app.info.uid; 7956 report.tag = activity; 7957 report.shortMsg = shortMsg; 7958 report.longMsg = longMsg; 7959 report.stackTrace = stackTrace; 7960 7961 return report; 7962 } 7963 7964 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7965 synchronized (this) { 7966 app.crashing = false; 7967 app.crashingReport = null; 7968 app.notResponding = false; 7969 app.notRespondingReport = null; 7970 if (app.anrDialog == fromDialog) { 7971 app.anrDialog = null; 7972 } 7973 if (app.waitDialog == fromDialog) { 7974 app.waitDialog = null; 7975 } 7976 if (app.pid > 0 && app.pid != MY_PID) { 7977 handleAppCrashLocked(app); 7978 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7979 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 7980 app.processName, app.setAdj, "user's request after error"); 7981 Process.killProcessQuiet(app.pid); 7982 } 7983 } 7984 } 7985 7986 private boolean handleAppCrashLocked(ProcessRecord app) { 7987 if (mHeadless) { 7988 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7989 return false; 7990 } 7991 long now = SystemClock.uptimeMillis(); 7992 7993 Long crashTime; 7994 if (!app.isolated) { 7995 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7996 } else { 7997 crashTime = null; 7998 } 7999 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 8000 // This process loses! 8001 Slog.w(TAG, "Process " + app.info.processName 8002 + " has crashed too many times: killing!"); 8003 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8004 app.userId, app.info.processName, app.uid); 8005 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8006 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8007 if (r.app == app) { 8008 Slog.w(TAG, " Force finishing activity " 8009 + r.intent.getComponent().flattenToShortString()); 8010 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8011 null, "crashed", false); 8012 } 8013 } 8014 if (!app.persistent) { 8015 // We don't want to start this process again until the user 8016 // explicitly does so... but for persistent process, we really 8017 // need to keep it running. If a persistent process is actually 8018 // repeatedly crashing, then badness for everyone. 8019 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 8020 app.info.processName); 8021 if (!app.isolated) { 8022 // XXX We don't have a way to mark isolated processes 8023 // as bad, since they don't have a peristent identity. 8024 mBadProcesses.put(app.info.processName, app.uid, now); 8025 mProcessCrashTimes.remove(app.info.processName, app.uid); 8026 } 8027 app.bad = true; 8028 app.removed = true; 8029 // Don't let services in this process be restarted and potentially 8030 // annoy the user repeatedly. Unless it is persistent, since those 8031 // processes run critical code. 8032 removeProcessLocked(app, false, false, "crash"); 8033 mMainStack.resumeTopActivityLocked(null); 8034 return false; 8035 } 8036 mMainStack.resumeTopActivityLocked(null); 8037 } else { 8038 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8039 if (r != null && r.app == app) { 8040 // If the top running activity is from this crashing 8041 // process, then terminate it to avoid getting in a loop. 8042 Slog.w(TAG, " Force finishing activity " 8043 + r.intent.getComponent().flattenToShortString()); 8044 int index = mMainStack.indexOfActivityLocked(r); 8045 r.stack.finishActivityLocked(r, index, 8046 Activity.RESULT_CANCELED, null, "crashed", false); 8047 // Also terminate any activities below it that aren't yet 8048 // stopped, to avoid a situation where one will get 8049 // re-start our crashing activity once it gets resumed again. 8050 index--; 8051 if (index >= 0) { 8052 r = (ActivityRecord)mMainStack.mHistory.get(index); 8053 if (r.state == ActivityState.RESUMED 8054 || r.state == ActivityState.PAUSING 8055 || r.state == ActivityState.PAUSED) { 8056 if (!r.isHomeActivity || mHomeProcess != r.app) { 8057 Slog.w(TAG, " Force finishing activity " 8058 + r.intent.getComponent().flattenToShortString()); 8059 r.stack.finishActivityLocked(r, index, 8060 Activity.RESULT_CANCELED, null, "crashed", false); 8061 } 8062 } 8063 } 8064 } 8065 } 8066 8067 // Bump up the crash count of any services currently running in the proc. 8068 if (app.services.size() != 0) { 8069 // Any services running in the application need to be placed 8070 // back in the pending list. 8071 Iterator<ServiceRecord> it = app.services.iterator(); 8072 while (it.hasNext()) { 8073 ServiceRecord sr = it.next(); 8074 sr.crashCount++; 8075 } 8076 } 8077 8078 // If the crashing process is what we consider to be the "home process" and it has been 8079 // replaced by a third-party app, clear the package preferred activities from packages 8080 // with a home activity running in the process to prevent a repeatedly crashing app 8081 // from blocking the user to manually clear the list. 8082 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8083 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8084 Iterator it = mHomeProcess.activities.iterator(); 8085 while (it.hasNext()) { 8086 ActivityRecord r = (ActivityRecord)it.next(); 8087 if (r.isHomeActivity) { 8088 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8089 try { 8090 ActivityThread.getPackageManager() 8091 .clearPackagePreferredActivities(r.packageName); 8092 } catch (RemoteException c) { 8093 // pm is in same process, this will never happen. 8094 } 8095 } 8096 } 8097 } 8098 8099 if (!app.isolated) { 8100 // XXX Can't keep track of crash times for isolated processes, 8101 // because they don't have a perisistent identity. 8102 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8103 } 8104 8105 return true; 8106 } 8107 8108 void startAppProblemLocked(ProcessRecord app) { 8109 if (app.userId == mCurrentUserId) { 8110 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8111 mContext, app.info.packageName, app.info.flags); 8112 } else { 8113 // If this app is not running under the current user, then we 8114 // can't give it a report button because that would require 8115 // launching the report UI under a different user. 8116 app.errorReportReceiver = null; 8117 } 8118 skipCurrentReceiverLocked(app); 8119 } 8120 8121 void skipCurrentReceiverLocked(ProcessRecord app) { 8122 for (BroadcastQueue queue : mBroadcastQueues) { 8123 queue.skipCurrentReceiverLocked(app); 8124 } 8125 } 8126 8127 /** 8128 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8129 * The application process will exit immediately after this call returns. 8130 * @param app object of the crashing app, null for the system server 8131 * @param crashInfo describing the exception 8132 */ 8133 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8134 ProcessRecord r = findAppProcess(app, "Crash"); 8135 final String processName = app == null ? "system_server" 8136 : (r == null ? "unknown" : r.processName); 8137 8138 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8139 UserHandle.getUserId(Binder.getCallingUid()), processName, 8140 r == null ? -1 : r.info.flags, 8141 crashInfo.exceptionClassName, 8142 crashInfo.exceptionMessage, 8143 crashInfo.throwFileName, 8144 crashInfo.throwLineNumber); 8145 8146 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8147 8148 crashApplication(r, crashInfo); 8149 } 8150 8151 public void handleApplicationStrictModeViolation( 8152 IBinder app, 8153 int violationMask, 8154 StrictMode.ViolationInfo info) { 8155 ProcessRecord r = findAppProcess(app, "StrictMode"); 8156 if (r == null) { 8157 return; 8158 } 8159 8160 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8161 Integer stackFingerprint = info.hashCode(); 8162 boolean logIt = true; 8163 synchronized (mAlreadyLoggedViolatedStacks) { 8164 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8165 logIt = false; 8166 // TODO: sub-sample into EventLog for these, with 8167 // the info.durationMillis? Then we'd get 8168 // the relative pain numbers, without logging all 8169 // the stack traces repeatedly. We'd want to do 8170 // likewise in the client code, which also does 8171 // dup suppression, before the Binder call. 8172 } else { 8173 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8174 mAlreadyLoggedViolatedStacks.clear(); 8175 } 8176 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8177 } 8178 } 8179 if (logIt) { 8180 logStrictModeViolationToDropBox(r, info); 8181 } 8182 } 8183 8184 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8185 AppErrorResult result = new AppErrorResult(); 8186 synchronized (this) { 8187 final long origId = Binder.clearCallingIdentity(); 8188 8189 Message msg = Message.obtain(); 8190 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8191 HashMap<String, Object> data = new HashMap<String, Object>(); 8192 data.put("result", result); 8193 data.put("app", r); 8194 data.put("violationMask", violationMask); 8195 data.put("info", info); 8196 msg.obj = data; 8197 mHandler.sendMessage(msg); 8198 8199 Binder.restoreCallingIdentity(origId); 8200 } 8201 int res = result.get(); 8202 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8203 } 8204 } 8205 8206 // Depending on the policy in effect, there could be a bunch of 8207 // these in quick succession so we try to batch these together to 8208 // minimize disk writes, number of dropbox entries, and maximize 8209 // compression, by having more fewer, larger records. 8210 private void logStrictModeViolationToDropBox( 8211 ProcessRecord process, 8212 StrictMode.ViolationInfo info) { 8213 if (info == null) { 8214 return; 8215 } 8216 final boolean isSystemApp = process == null || 8217 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8218 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8219 final String processName = process == null ? "unknown" : process.processName; 8220 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8221 final DropBoxManager dbox = (DropBoxManager) 8222 mContext.getSystemService(Context.DROPBOX_SERVICE); 8223 8224 // Exit early if the dropbox isn't configured to accept this report type. 8225 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8226 8227 boolean bufferWasEmpty; 8228 boolean needsFlush; 8229 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8230 synchronized (sb) { 8231 bufferWasEmpty = sb.length() == 0; 8232 appendDropBoxProcessHeaders(process, processName, sb); 8233 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8234 sb.append("System-App: ").append(isSystemApp).append("\n"); 8235 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8236 if (info.violationNumThisLoop != 0) { 8237 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8238 } 8239 if (info.numAnimationsRunning != 0) { 8240 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8241 } 8242 if (info.broadcastIntentAction != null) { 8243 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8244 } 8245 if (info.durationMillis != -1) { 8246 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8247 } 8248 if (info.numInstances != -1) { 8249 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8250 } 8251 if (info.tags != null) { 8252 for (String tag : info.tags) { 8253 sb.append("Span-Tag: ").append(tag).append("\n"); 8254 } 8255 } 8256 sb.append("\n"); 8257 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8258 sb.append(info.crashInfo.stackTrace); 8259 } 8260 sb.append("\n"); 8261 8262 // Only buffer up to ~64k. Various logging bits truncate 8263 // things at 128k. 8264 needsFlush = (sb.length() > 64 * 1024); 8265 } 8266 8267 // Flush immediately if the buffer's grown too large, or this 8268 // is a non-system app. Non-system apps are isolated with a 8269 // different tag & policy and not batched. 8270 // 8271 // Batching is useful during internal testing with 8272 // StrictMode settings turned up high. Without batching, 8273 // thousands of separate files could be created on boot. 8274 if (!isSystemApp || needsFlush) { 8275 new Thread("Error dump: " + dropboxTag) { 8276 @Override 8277 public void run() { 8278 String report; 8279 synchronized (sb) { 8280 report = sb.toString(); 8281 sb.delete(0, sb.length()); 8282 sb.trimToSize(); 8283 } 8284 if (report.length() != 0) { 8285 dbox.addText(dropboxTag, report); 8286 } 8287 } 8288 }.start(); 8289 return; 8290 } 8291 8292 // System app batching: 8293 if (!bufferWasEmpty) { 8294 // An existing dropbox-writing thread is outstanding, so 8295 // we don't need to start it up. The existing thread will 8296 // catch the buffer appends we just did. 8297 return; 8298 } 8299 8300 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8301 // (After this point, we shouldn't access AMS internal data structures.) 8302 new Thread("Error dump: " + dropboxTag) { 8303 @Override 8304 public void run() { 8305 // 5 second sleep to let stacks arrive and be batched together 8306 try { 8307 Thread.sleep(5000); // 5 seconds 8308 } catch (InterruptedException e) {} 8309 8310 String errorReport; 8311 synchronized (mStrictModeBuffer) { 8312 errorReport = mStrictModeBuffer.toString(); 8313 if (errorReport.length() == 0) { 8314 return; 8315 } 8316 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8317 mStrictModeBuffer.trimToSize(); 8318 } 8319 dbox.addText(dropboxTag, errorReport); 8320 } 8321 }.start(); 8322 } 8323 8324 /** 8325 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8326 * @param app object of the crashing app, null for the system server 8327 * @param tag reported by the caller 8328 * @param crashInfo describing the context of the error 8329 * @return true if the process should exit immediately (WTF is fatal) 8330 */ 8331 public boolean handleApplicationWtf(IBinder app, String tag, 8332 ApplicationErrorReport.CrashInfo crashInfo) { 8333 ProcessRecord r = findAppProcess(app, "WTF"); 8334 final String processName = app == null ? "system_server" 8335 : (r == null ? "unknown" : r.processName); 8336 8337 EventLog.writeEvent(EventLogTags.AM_WTF, 8338 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8339 processName, 8340 r == null ? -1 : r.info.flags, 8341 tag, crashInfo.exceptionMessage); 8342 8343 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8344 8345 if (r != null && r.pid != Process.myPid() && 8346 Settings.Global.getInt(mContext.getContentResolver(), 8347 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8348 crashApplication(r, crashInfo); 8349 return true; 8350 } else { 8351 return false; 8352 } 8353 } 8354 8355 /** 8356 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8357 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8358 */ 8359 private ProcessRecord findAppProcess(IBinder app, String reason) { 8360 if (app == null) { 8361 return null; 8362 } 8363 8364 synchronized (this) { 8365 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8366 final int NA = apps.size(); 8367 for (int ia=0; ia<NA; ia++) { 8368 ProcessRecord p = apps.valueAt(ia); 8369 if (p.thread != null && p.thread.asBinder() == app) { 8370 return p; 8371 } 8372 } 8373 } 8374 8375 Slog.w(TAG, "Can't find mystery application for " + reason 8376 + " from pid=" + Binder.getCallingPid() 8377 + " uid=" + Binder.getCallingUid() + ": " + app); 8378 return null; 8379 } 8380 } 8381 8382 /** 8383 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8384 * to append various headers to the dropbox log text. 8385 */ 8386 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8387 StringBuilder sb) { 8388 // Watchdog thread ends up invoking this function (with 8389 // a null ProcessRecord) to add the stack file to dropbox. 8390 // Do not acquire a lock on this (am) in such cases, as it 8391 // could cause a potential deadlock, if and when watchdog 8392 // is invoked due to unavailability of lock on am and it 8393 // would prevent watchdog from killing system_server. 8394 if (process == null) { 8395 sb.append("Process: ").append(processName).append("\n"); 8396 return; 8397 } 8398 // Note: ProcessRecord 'process' is guarded by the service 8399 // instance. (notably process.pkgList, which could otherwise change 8400 // concurrently during execution of this method) 8401 synchronized (this) { 8402 sb.append("Process: ").append(processName).append("\n"); 8403 int flags = process.info.flags; 8404 IPackageManager pm = AppGlobals.getPackageManager(); 8405 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8406 for (String pkg : process.pkgList) { 8407 sb.append("Package: ").append(pkg); 8408 try { 8409 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8410 if (pi != null) { 8411 sb.append(" v").append(pi.versionCode); 8412 if (pi.versionName != null) { 8413 sb.append(" (").append(pi.versionName).append(")"); 8414 } 8415 } 8416 } catch (RemoteException e) { 8417 Slog.e(TAG, "Error getting package info: " + pkg, e); 8418 } 8419 sb.append("\n"); 8420 } 8421 } 8422 } 8423 8424 private static String processClass(ProcessRecord process) { 8425 if (process == null || process.pid == MY_PID) { 8426 return "system_server"; 8427 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8428 return "system_app"; 8429 } else { 8430 return "data_app"; 8431 } 8432 } 8433 8434 /** 8435 * Write a description of an error (crash, WTF, ANR) to the drop box. 8436 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8437 * @param process which caused the error, null means the system server 8438 * @param activity which triggered the error, null if unknown 8439 * @param parent activity related to the error, null if unknown 8440 * @param subject line related to the error, null if absent 8441 * @param report in long form describing the error, null if absent 8442 * @param logFile to include in the report, null if none 8443 * @param crashInfo giving an application stack trace, null if absent 8444 */ 8445 public void addErrorToDropBox(String eventType, 8446 ProcessRecord process, String processName, ActivityRecord activity, 8447 ActivityRecord parent, String subject, 8448 final String report, final File logFile, 8449 final ApplicationErrorReport.CrashInfo crashInfo) { 8450 // NOTE -- this must never acquire the ActivityManagerService lock, 8451 // otherwise the watchdog may be prevented from resetting the system. 8452 8453 final String dropboxTag = processClass(process) + "_" + eventType; 8454 final DropBoxManager dbox = (DropBoxManager) 8455 mContext.getSystemService(Context.DROPBOX_SERVICE); 8456 8457 // Exit early if the dropbox isn't configured to accept this report type. 8458 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8459 8460 final StringBuilder sb = new StringBuilder(1024); 8461 appendDropBoxProcessHeaders(process, processName, sb); 8462 if (activity != null) { 8463 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8464 } 8465 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8466 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8467 } 8468 if (parent != null && parent != activity) { 8469 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8470 } 8471 if (subject != null) { 8472 sb.append("Subject: ").append(subject).append("\n"); 8473 } 8474 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8475 if (Debug.isDebuggerConnected()) { 8476 sb.append("Debugger: Connected\n"); 8477 } 8478 sb.append("\n"); 8479 8480 // Do the rest in a worker thread to avoid blocking the caller on I/O 8481 // (After this point, we shouldn't access AMS internal data structures.) 8482 Thread worker = new Thread("Error dump: " + dropboxTag) { 8483 @Override 8484 public void run() { 8485 if (report != null) { 8486 sb.append(report); 8487 } 8488 if (logFile != null) { 8489 try { 8490 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8491 } catch (IOException e) { 8492 Slog.e(TAG, "Error reading " + logFile, e); 8493 } 8494 } 8495 if (crashInfo != null && crashInfo.stackTrace != null) { 8496 sb.append(crashInfo.stackTrace); 8497 } 8498 8499 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8500 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8501 if (lines > 0) { 8502 sb.append("\n"); 8503 8504 // Merge several logcat streams, and take the last N lines 8505 InputStreamReader input = null; 8506 try { 8507 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8508 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8509 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8510 8511 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8512 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8513 input = new InputStreamReader(logcat.getInputStream()); 8514 8515 int num; 8516 char[] buf = new char[8192]; 8517 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8518 } catch (IOException e) { 8519 Slog.e(TAG, "Error running logcat", e); 8520 } finally { 8521 if (input != null) try { input.close(); } catch (IOException e) {} 8522 } 8523 } 8524 8525 dbox.addText(dropboxTag, sb.toString()); 8526 } 8527 }; 8528 8529 if (process == null) { 8530 // If process is null, we are being called from some internal code 8531 // and may be about to die -- run this synchronously. 8532 worker.run(); 8533 } else { 8534 worker.start(); 8535 } 8536 } 8537 8538 /** 8539 * Bring up the "unexpected error" dialog box for a crashing app. 8540 * Deal with edge cases (intercepts from instrumented applications, 8541 * ActivityController, error intent receivers, that sort of thing). 8542 * @param r the application crashing 8543 * @param crashInfo describing the failure 8544 */ 8545 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8546 long timeMillis = System.currentTimeMillis(); 8547 String shortMsg = crashInfo.exceptionClassName; 8548 String longMsg = crashInfo.exceptionMessage; 8549 String stackTrace = crashInfo.stackTrace; 8550 if (shortMsg != null && longMsg != null) { 8551 longMsg = shortMsg + ": " + longMsg; 8552 } else if (shortMsg != null) { 8553 longMsg = shortMsg; 8554 } 8555 8556 AppErrorResult result = new AppErrorResult(); 8557 synchronized (this) { 8558 if (mController != null) { 8559 try { 8560 String name = r != null ? r.processName : null; 8561 int pid = r != null ? r.pid : Binder.getCallingPid(); 8562 if (!mController.appCrashed(name, pid, 8563 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8564 Slog.w(TAG, "Force-killing crashed app " + name 8565 + " at watcher's request"); 8566 Process.killProcess(pid); 8567 return; 8568 } 8569 } catch (RemoteException e) { 8570 mController = null; 8571 } 8572 } 8573 8574 final long origId = Binder.clearCallingIdentity(); 8575 8576 // If this process is running instrumentation, finish it. 8577 if (r != null && r.instrumentationClass != null) { 8578 Slog.w(TAG, "Error in app " + r.processName 8579 + " running instrumentation " + r.instrumentationClass + ":"); 8580 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8581 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8582 Bundle info = new Bundle(); 8583 info.putString("shortMsg", shortMsg); 8584 info.putString("longMsg", longMsg); 8585 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8586 Binder.restoreCallingIdentity(origId); 8587 return; 8588 } 8589 8590 // If we can't identify the process or it's already exceeded its crash quota, 8591 // quit right away without showing a crash dialog. 8592 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8593 Binder.restoreCallingIdentity(origId); 8594 return; 8595 } 8596 8597 Message msg = Message.obtain(); 8598 msg.what = SHOW_ERROR_MSG; 8599 HashMap data = new HashMap(); 8600 data.put("result", result); 8601 data.put("app", r); 8602 msg.obj = data; 8603 mHandler.sendMessage(msg); 8604 8605 Binder.restoreCallingIdentity(origId); 8606 } 8607 8608 int res = result.get(); 8609 8610 Intent appErrorIntent = null; 8611 synchronized (this) { 8612 if (r != null && !r.isolated) { 8613 // XXX Can't keep track of crash time for isolated processes, 8614 // since they don't have a persistent identity. 8615 mProcessCrashTimes.put(r.info.processName, r.uid, 8616 SystemClock.uptimeMillis()); 8617 } 8618 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8619 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8620 } 8621 } 8622 8623 if (appErrorIntent != null) { 8624 try { 8625 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8626 } catch (ActivityNotFoundException e) { 8627 Slog.w(TAG, "bug report receiver dissappeared", e); 8628 } 8629 } 8630 } 8631 8632 Intent createAppErrorIntentLocked(ProcessRecord r, 8633 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8634 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8635 if (report == null) { 8636 return null; 8637 } 8638 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8639 result.setComponent(r.errorReportReceiver); 8640 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8641 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8642 return result; 8643 } 8644 8645 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8646 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8647 if (r.errorReportReceiver == null) { 8648 return null; 8649 } 8650 8651 if (!r.crashing && !r.notResponding) { 8652 return null; 8653 } 8654 8655 ApplicationErrorReport report = new ApplicationErrorReport(); 8656 report.packageName = r.info.packageName; 8657 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8658 report.processName = r.processName; 8659 report.time = timeMillis; 8660 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8661 8662 if (r.crashing) { 8663 report.type = ApplicationErrorReport.TYPE_CRASH; 8664 report.crashInfo = crashInfo; 8665 } else if (r.notResponding) { 8666 report.type = ApplicationErrorReport.TYPE_ANR; 8667 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8668 8669 report.anrInfo.activity = r.notRespondingReport.tag; 8670 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8671 report.anrInfo.info = r.notRespondingReport.longMsg; 8672 } 8673 8674 return report; 8675 } 8676 8677 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8678 enforceNotIsolatedCaller("getProcessesInErrorState"); 8679 // assume our apps are happy - lazy create the list 8680 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8681 8682 final boolean allUsers = ActivityManager.checkUidPermission( 8683 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8684 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8685 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8686 8687 synchronized (this) { 8688 8689 // iterate across all processes 8690 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8691 ProcessRecord app = mLruProcesses.get(i); 8692 if (!allUsers && app.userId != userId) { 8693 continue; 8694 } 8695 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8696 // This one's in trouble, so we'll generate a report for it 8697 // crashes are higher priority (in case there's a crash *and* an anr) 8698 ActivityManager.ProcessErrorStateInfo report = null; 8699 if (app.crashing) { 8700 report = app.crashingReport; 8701 } else if (app.notResponding) { 8702 report = app.notRespondingReport; 8703 } 8704 8705 if (report != null) { 8706 if (errList == null) { 8707 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8708 } 8709 errList.add(report); 8710 } else { 8711 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8712 " crashing = " + app.crashing + 8713 " notResponding = " + app.notResponding); 8714 } 8715 } 8716 } 8717 } 8718 8719 return errList; 8720 } 8721 8722 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8723 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8724 if (currApp != null) { 8725 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8726 } 8727 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8728 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8729 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8730 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8731 if (currApp != null) { 8732 currApp.lru = 0; 8733 } 8734 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8735 } else if (adj >= ProcessList.SERVICE_ADJ) { 8736 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8737 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8738 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8739 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8740 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8741 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8742 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8743 } else { 8744 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8745 } 8746 } 8747 8748 private void fillInProcMemInfo(ProcessRecord app, 8749 ActivityManager.RunningAppProcessInfo outInfo) { 8750 outInfo.pid = app.pid; 8751 outInfo.uid = app.info.uid; 8752 if (mHeavyWeightProcess == app) { 8753 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8754 } 8755 if (app.persistent) { 8756 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8757 } 8758 if (app.hasActivities) { 8759 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8760 } 8761 outInfo.lastTrimLevel = app.trimMemoryLevel; 8762 int adj = app.curAdj; 8763 outInfo.importance = oomAdjToImportance(adj, outInfo); 8764 outInfo.importanceReasonCode = app.adjTypeCode; 8765 } 8766 8767 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8768 enforceNotIsolatedCaller("getRunningAppProcesses"); 8769 // Lazy instantiation of list 8770 List<ActivityManager.RunningAppProcessInfo> runList = null; 8771 final boolean allUsers = ActivityManager.checkUidPermission( 8772 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8773 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8774 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8775 synchronized (this) { 8776 // Iterate across all processes 8777 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8778 ProcessRecord app = mLruProcesses.get(i); 8779 if (!allUsers && app.userId != userId) { 8780 continue; 8781 } 8782 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8783 // Generate process state info for running application 8784 ActivityManager.RunningAppProcessInfo currApp = 8785 new ActivityManager.RunningAppProcessInfo(app.processName, 8786 app.pid, app.getPackageList()); 8787 fillInProcMemInfo(app, currApp); 8788 if (app.adjSource instanceof ProcessRecord) { 8789 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8790 currApp.importanceReasonImportance = oomAdjToImportance( 8791 app.adjSourceOom, null); 8792 } else if (app.adjSource instanceof ActivityRecord) { 8793 ActivityRecord r = (ActivityRecord)app.adjSource; 8794 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8795 } 8796 if (app.adjTarget instanceof ComponentName) { 8797 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8798 } 8799 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8800 // + " lru=" + currApp.lru); 8801 if (runList == null) { 8802 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8803 } 8804 runList.add(currApp); 8805 } 8806 } 8807 } 8808 return runList; 8809 } 8810 8811 public List<ApplicationInfo> getRunningExternalApplications() { 8812 enforceNotIsolatedCaller("getRunningExternalApplications"); 8813 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8814 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8815 if (runningApps != null && runningApps.size() > 0) { 8816 Set<String> extList = new HashSet<String>(); 8817 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8818 if (app.pkgList != null) { 8819 for (String pkg : app.pkgList) { 8820 extList.add(pkg); 8821 } 8822 } 8823 } 8824 IPackageManager pm = AppGlobals.getPackageManager(); 8825 for (String pkg : extList) { 8826 try { 8827 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8828 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8829 retList.add(info); 8830 } 8831 } catch (RemoteException e) { 8832 } 8833 } 8834 } 8835 return retList; 8836 } 8837 8838 @Override 8839 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8840 enforceNotIsolatedCaller("getMyMemoryState"); 8841 synchronized (this) { 8842 ProcessRecord proc; 8843 synchronized (mPidsSelfLocked) { 8844 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8845 } 8846 fillInProcMemInfo(proc, outInfo); 8847 } 8848 } 8849 8850 @Override 8851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8852 if (checkCallingPermission(android.Manifest.permission.DUMP) 8853 != PackageManager.PERMISSION_GRANTED) { 8854 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8855 + Binder.getCallingPid() 8856 + ", uid=" + Binder.getCallingUid() 8857 + " without permission " 8858 + android.Manifest.permission.DUMP); 8859 return; 8860 } 8861 8862 boolean dumpAll = false; 8863 boolean dumpClient = false; 8864 String dumpPackage = null; 8865 8866 int opti = 0; 8867 while (opti < args.length) { 8868 String opt = args[opti]; 8869 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8870 break; 8871 } 8872 opti++; 8873 if ("-a".equals(opt)) { 8874 dumpAll = true; 8875 } else if ("-c".equals(opt)) { 8876 dumpClient = true; 8877 } else if ("-h".equals(opt)) { 8878 pw.println("Activity manager dump options:"); 8879 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8880 pw.println(" cmd may be one of:"); 8881 pw.println(" a[ctivities]: activity stack state"); 8882 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8883 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8884 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8885 pw.println(" o[om]: out of memory management"); 8886 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8887 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8888 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8889 pw.println(" service [COMP_SPEC]: service client-side state"); 8890 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8891 pw.println(" all: dump all activities"); 8892 pw.println(" top: dump the top activity"); 8893 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8894 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8895 pw.println(" a partial substring in a component name, a"); 8896 pw.println(" hex object identifier."); 8897 pw.println(" -a: include all available server state."); 8898 pw.println(" -c: include client state."); 8899 return; 8900 } else { 8901 pw.println("Unknown argument: " + opt + "; use -h for help"); 8902 } 8903 } 8904 8905 long origId = Binder.clearCallingIdentity(); 8906 boolean more = false; 8907 // Is the caller requesting to dump a particular piece of data? 8908 if (opti < args.length) { 8909 String cmd = args[opti]; 8910 opti++; 8911 if ("activities".equals(cmd) || "a".equals(cmd)) { 8912 synchronized (this) { 8913 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8914 } 8915 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8916 String[] newArgs; 8917 String name; 8918 if (opti >= args.length) { 8919 name = null; 8920 newArgs = EMPTY_STRING_ARRAY; 8921 } else { 8922 name = args[opti]; 8923 opti++; 8924 newArgs = new String[args.length - opti]; 8925 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8926 args.length - opti); 8927 } 8928 synchronized (this) { 8929 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8930 } 8931 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8932 String[] newArgs; 8933 String name; 8934 if (opti >= args.length) { 8935 name = null; 8936 newArgs = EMPTY_STRING_ARRAY; 8937 } else { 8938 name = args[opti]; 8939 opti++; 8940 newArgs = new String[args.length - opti]; 8941 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8942 args.length - opti); 8943 } 8944 synchronized (this) { 8945 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8946 } 8947 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8948 String[] newArgs; 8949 String name; 8950 if (opti >= args.length) { 8951 name = null; 8952 newArgs = EMPTY_STRING_ARRAY; 8953 } else { 8954 name = args[opti]; 8955 opti++; 8956 newArgs = new String[args.length - opti]; 8957 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8958 args.length - opti); 8959 } 8960 synchronized (this) { 8961 dumpProcessesLocked(fd, pw, args, opti, true, name); 8962 } 8963 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8964 synchronized (this) { 8965 dumpOomLocked(fd, pw, args, opti, true); 8966 } 8967 } else if ("provider".equals(cmd)) { 8968 String[] newArgs; 8969 String name; 8970 if (opti >= args.length) { 8971 name = null; 8972 newArgs = EMPTY_STRING_ARRAY; 8973 } else { 8974 name = args[opti]; 8975 opti++; 8976 newArgs = new String[args.length - opti]; 8977 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8978 } 8979 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8980 pw.println("No providers match: " + name); 8981 pw.println("Use -h for help."); 8982 } 8983 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8984 synchronized (this) { 8985 dumpProvidersLocked(fd, pw, args, opti, true, null); 8986 } 8987 } else if ("service".equals(cmd)) { 8988 String[] newArgs; 8989 String name; 8990 if (opti >= args.length) { 8991 name = null; 8992 newArgs = EMPTY_STRING_ARRAY; 8993 } else { 8994 name = args[opti]; 8995 opti++; 8996 newArgs = new String[args.length - opti]; 8997 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8998 args.length - opti); 8999 } 9000 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 9001 pw.println("No services match: " + name); 9002 pw.println("Use -h for help."); 9003 } 9004 } else if ("package".equals(cmd)) { 9005 String[] newArgs; 9006 if (opti >= args.length) { 9007 pw.println("package: no package name specified"); 9008 pw.println("Use -h for help."); 9009 } else { 9010 dumpPackage = args[opti]; 9011 opti++; 9012 newArgs = new String[args.length - opti]; 9013 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9014 args.length - opti); 9015 args = newArgs; 9016 opti = 0; 9017 more = true; 9018 } 9019 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9020 synchronized (this) { 9021 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9022 } 9023 } else { 9024 // Dumping a single activity? 9025 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9026 pw.println("Bad activity command, or no activities match: " + cmd); 9027 pw.println("Use -h for help."); 9028 } 9029 } 9030 if (!more) { 9031 Binder.restoreCallingIdentity(origId); 9032 return; 9033 } 9034 } 9035 9036 // No piece of data specified, dump everything. 9037 synchronized (this) { 9038 boolean needSep; 9039 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9040 if (needSep) { 9041 pw.println(" "); 9042 } 9043 if (dumpAll) { 9044 pw.println("-------------------------------------------------------------------------------"); 9045 } 9046 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9047 if (needSep) { 9048 pw.println(" "); 9049 } 9050 if (dumpAll) { 9051 pw.println("-------------------------------------------------------------------------------"); 9052 } 9053 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9054 if (needSep) { 9055 pw.println(" "); 9056 } 9057 if (dumpAll) { 9058 pw.println("-------------------------------------------------------------------------------"); 9059 } 9060 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9061 if (needSep) { 9062 pw.println(" "); 9063 } 9064 if (dumpAll) { 9065 pw.println("-------------------------------------------------------------------------------"); 9066 } 9067 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9068 if (needSep) { 9069 pw.println(" "); 9070 } 9071 if (dumpAll) { 9072 pw.println("-------------------------------------------------------------------------------"); 9073 } 9074 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9075 } 9076 Binder.restoreCallingIdentity(origId); 9077 } 9078 9079 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9080 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9081 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9082 pw.println(" Main stack:"); 9083 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9084 dumpPackage); 9085 pw.println(" "); 9086 pw.println(" Running activities (most recent first):"); 9087 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9088 dumpPackage); 9089 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9090 pw.println(" "); 9091 pw.println(" Activities waiting for another to become visible:"); 9092 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9093 !dumpAll, false, dumpPackage); 9094 } 9095 if (mMainStack.mStoppingActivities.size() > 0) { 9096 pw.println(" "); 9097 pw.println(" Activities waiting to stop:"); 9098 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9099 !dumpAll, false, dumpPackage); 9100 } 9101 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9102 pw.println(" "); 9103 pw.println(" Activities waiting to sleep:"); 9104 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9105 !dumpAll, false, dumpPackage); 9106 } 9107 if (mMainStack.mFinishingActivities.size() > 0) { 9108 pw.println(" "); 9109 pw.println(" Activities waiting to finish:"); 9110 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9111 !dumpAll, false, dumpPackage); 9112 } 9113 9114 pw.println(" "); 9115 if (mMainStack.mPausingActivity != null) { 9116 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9117 } 9118 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9119 pw.println(" mFocusedActivity: " + mFocusedActivity); 9120 if (dumpAll) { 9121 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9122 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9123 pw.println(" mDismissKeyguardOnNextActivity: " 9124 + mMainStack.mDismissKeyguardOnNextActivity); 9125 } 9126 9127 if (mRecentTasks.size() > 0) { 9128 pw.println(); 9129 pw.println(" Recent tasks:"); 9130 9131 final int N = mRecentTasks.size(); 9132 for (int i=0; i<N; i++) { 9133 TaskRecord tr = mRecentTasks.get(i); 9134 if (dumpPackage != null) { 9135 if (tr.realActivity == null || 9136 !dumpPackage.equals(tr.realActivity)) { 9137 continue; 9138 } 9139 } 9140 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9141 pw.println(tr); 9142 if (dumpAll) { 9143 mRecentTasks.get(i).dump(pw, " "); 9144 } 9145 } 9146 } 9147 9148 if (dumpAll) { 9149 pw.println(" "); 9150 pw.println(" mCurTask: " + mCurTask); 9151 } 9152 9153 return true; 9154 } 9155 9156 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9157 int opti, boolean dumpAll, String dumpPackage) { 9158 boolean needSep = false; 9159 int numPers = 0; 9160 9161 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9162 9163 if (dumpAll) { 9164 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9165 final int NA = procs.size(); 9166 for (int ia=0; ia<NA; ia++) { 9167 ProcessRecord r = procs.valueAt(ia); 9168 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9169 continue; 9170 } 9171 if (!needSep) { 9172 pw.println(" All known processes:"); 9173 needSep = true; 9174 } 9175 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9176 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9177 pw.print(" "); pw.println(r); 9178 r.dump(pw, " "); 9179 if (r.persistent) { 9180 numPers++; 9181 } 9182 } 9183 } 9184 } 9185 9186 if (mIsolatedProcesses.size() > 0) { 9187 if (needSep) pw.println(" "); 9188 needSep = true; 9189 pw.println(" Isolated process list (sorted by uid):"); 9190 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9191 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9192 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9193 continue; 9194 } 9195 pw.println(String.format("%sIsolated #%2d: %s", 9196 " ", i, r.toString())); 9197 } 9198 } 9199 9200 if (mLruProcesses.size() > 0) { 9201 if (needSep) pw.println(" "); 9202 needSep = true; 9203 pw.println(" Process LRU list (sorted by oom_adj):"); 9204 dumpProcessOomList(pw, this, mLruProcesses, " ", 9205 "Proc", "PERS", false, dumpPackage); 9206 needSep = true; 9207 } 9208 9209 if (dumpAll) { 9210 synchronized (mPidsSelfLocked) { 9211 boolean printed = false; 9212 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9213 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9214 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9215 continue; 9216 } 9217 if (!printed) { 9218 if (needSep) pw.println(" "); 9219 needSep = true; 9220 pw.println(" PID mappings:"); 9221 printed = true; 9222 } 9223 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9224 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9225 } 9226 } 9227 } 9228 9229 if (mForegroundProcesses.size() > 0) { 9230 synchronized (mPidsSelfLocked) { 9231 boolean printed = false; 9232 for (int i=0; i<mForegroundProcesses.size(); i++) { 9233 ProcessRecord r = mPidsSelfLocked.get( 9234 mForegroundProcesses.valueAt(i).pid); 9235 if (dumpPackage != null && (r == null 9236 || !dumpPackage.equals(r.info.packageName))) { 9237 continue; 9238 } 9239 if (!printed) { 9240 if (needSep) pw.println(" "); 9241 needSep = true; 9242 pw.println(" Foreground Processes:"); 9243 printed = true; 9244 } 9245 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9246 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9247 } 9248 } 9249 } 9250 9251 if (mPersistentStartingProcesses.size() > 0) { 9252 if (needSep) pw.println(" "); 9253 needSep = true; 9254 pw.println(" Persisent processes that are starting:"); 9255 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9256 "Starting Norm", "Restarting PERS", dumpPackage); 9257 } 9258 9259 if (mRemovedProcesses.size() > 0) { 9260 if (needSep) pw.println(" "); 9261 needSep = true; 9262 pw.println(" Processes that are being removed:"); 9263 dumpProcessList(pw, this, mRemovedProcesses, " ", 9264 "Removed Norm", "Removed PERS", dumpPackage); 9265 } 9266 9267 if (mProcessesOnHold.size() > 0) { 9268 if (needSep) pw.println(" "); 9269 needSep = true; 9270 pw.println(" Processes that are on old until the system is ready:"); 9271 dumpProcessList(pw, this, mProcessesOnHold, " ", 9272 "OnHold Norm", "OnHold PERS", dumpPackage); 9273 } 9274 9275 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9276 9277 if (mProcessCrashTimes.getMap().size() > 0) { 9278 boolean printed = false; 9279 long now = SystemClock.uptimeMillis(); 9280 for (Map.Entry<String, SparseArray<Long>> procs 9281 : mProcessCrashTimes.getMap().entrySet()) { 9282 String pname = procs.getKey(); 9283 SparseArray<Long> uids = procs.getValue(); 9284 final int N = uids.size(); 9285 for (int i=0; i<N; i++) { 9286 int puid = uids.keyAt(i); 9287 ProcessRecord r = mProcessNames.get(pname, puid); 9288 if (dumpPackage != null && (r == null 9289 || !dumpPackage.equals(r.info.packageName))) { 9290 continue; 9291 } 9292 if (!printed) { 9293 if (needSep) pw.println(" "); 9294 needSep = true; 9295 pw.println(" Time since processes crashed:"); 9296 printed = true; 9297 } 9298 pw.print(" Process "); pw.print(pname); 9299 pw.print(" uid "); pw.print(puid); 9300 pw.print(": last crashed "); 9301 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9302 pw.println(" ago"); 9303 } 9304 } 9305 } 9306 9307 if (mBadProcesses.getMap().size() > 0) { 9308 boolean printed = false; 9309 for (Map.Entry<String, SparseArray<Long>> procs 9310 : mBadProcesses.getMap().entrySet()) { 9311 String pname = procs.getKey(); 9312 SparseArray<Long> uids = procs.getValue(); 9313 final int N = uids.size(); 9314 for (int i=0; i<N; i++) { 9315 int puid = uids.keyAt(i); 9316 ProcessRecord r = mProcessNames.get(pname, puid); 9317 if (dumpPackage != null && (r == null 9318 || !dumpPackage.equals(r.info.packageName))) { 9319 continue; 9320 } 9321 if (!printed) { 9322 if (needSep) pw.println(" "); 9323 needSep = true; 9324 pw.println(" Bad processes:"); 9325 } 9326 pw.print(" Bad process "); pw.print(pname); 9327 pw.print(" uid "); pw.print(puid); 9328 pw.print(": crashed at time "); 9329 pw.println(uids.valueAt(i)); 9330 } 9331 } 9332 } 9333 9334 pw.println(); 9335 pw.println(" mStartedUsers:"); 9336 for (int i=0; i<mStartedUsers.size(); i++) { 9337 UserStartedState uss = mStartedUsers.valueAt(i); 9338 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9339 pw.print(": "); uss.dump("", pw); 9340 } 9341 pw.print(" mUserLru: ["); 9342 for (int i=0; i<mUserLru.size(); i++) { 9343 if (i > 0) pw.print(", "); 9344 pw.print(mUserLru.get(i)); 9345 } 9346 pw.println("]"); 9347 if (dumpAll) { 9348 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9349 } 9350 pw.println(" mHomeProcess: " + mHomeProcess); 9351 pw.println(" mPreviousProcess: " + mPreviousProcess); 9352 if (dumpAll) { 9353 StringBuilder sb = new StringBuilder(128); 9354 sb.append(" mPreviousProcessVisibleTime: "); 9355 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9356 pw.println(sb); 9357 } 9358 if (mHeavyWeightProcess != null) { 9359 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9360 } 9361 pw.println(" mConfiguration: " + mConfiguration); 9362 if (dumpAll) { 9363 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9364 if (mCompatModePackages.getPackages().size() > 0) { 9365 boolean printed = false; 9366 for (Map.Entry<String, Integer> entry 9367 : mCompatModePackages.getPackages().entrySet()) { 9368 String pkg = entry.getKey(); 9369 int mode = entry.getValue(); 9370 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9371 continue; 9372 } 9373 if (!printed) { 9374 pw.println(" mScreenCompatPackages:"); 9375 printed = true; 9376 } 9377 pw.print(" "); pw.print(pkg); pw.print(": "); 9378 pw.print(mode); pw.println(); 9379 } 9380 } 9381 } 9382 if (mSleeping || mWentToSleep || mLockScreenShown) { 9383 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9384 + " mLockScreenShown " + mLockScreenShown); 9385 } 9386 if (mShuttingDown) { 9387 pw.println(" mShuttingDown=" + mShuttingDown); 9388 } 9389 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9390 || mOrigWaitForDebugger) { 9391 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9392 + " mDebugTransient=" + mDebugTransient 9393 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9394 } 9395 if (mOpenGlTraceApp != null) { 9396 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9397 } 9398 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9399 || mProfileFd != null) { 9400 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9401 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9402 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9403 + mAutoStopProfiler); 9404 } 9405 if (mAlwaysFinishActivities || mController != null) { 9406 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9407 + " mController=" + mController); 9408 } 9409 if (dumpAll) { 9410 pw.println(" Total persistent processes: " + numPers); 9411 pw.println(" mStartRunning=" + mStartRunning 9412 + " mProcessesReady=" + mProcessesReady 9413 + " mSystemReady=" + mSystemReady); 9414 pw.println(" mBooting=" + mBooting 9415 + " mBooted=" + mBooted 9416 + " mFactoryTest=" + mFactoryTest); 9417 pw.print(" mLastPowerCheckRealtime="); 9418 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9419 pw.println(""); 9420 pw.print(" mLastPowerCheckUptime="); 9421 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9422 pw.println(""); 9423 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9424 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9425 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9426 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9427 + " mNumHiddenProcs=" + mNumHiddenProcs 9428 + " mNumServiceProcs=" + mNumServiceProcs 9429 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9430 } 9431 9432 return true; 9433 } 9434 9435 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9436 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9437 if (mProcessesToGc.size() > 0) { 9438 boolean printed = false; 9439 long now = SystemClock.uptimeMillis(); 9440 for (int i=0; i<mProcessesToGc.size(); i++) { 9441 ProcessRecord proc = mProcessesToGc.get(i); 9442 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9443 continue; 9444 } 9445 if (!printed) { 9446 if (needSep) pw.println(" "); 9447 needSep = true; 9448 pw.println(" Processes that are waiting to GC:"); 9449 printed = true; 9450 } 9451 pw.print(" Process "); pw.println(proc); 9452 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9453 pw.print(", last gced="); 9454 pw.print(now-proc.lastRequestedGc); 9455 pw.print(" ms ago, last lowMem="); 9456 pw.print(now-proc.lastLowMemory); 9457 pw.println(" ms ago"); 9458 9459 } 9460 } 9461 return needSep; 9462 } 9463 9464 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9465 int opti, boolean dumpAll) { 9466 boolean needSep = false; 9467 9468 if (mLruProcesses.size() > 0) { 9469 if (needSep) pw.println(" "); 9470 needSep = true; 9471 pw.println(" OOM levels:"); 9472 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9473 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9474 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9475 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9476 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9477 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9478 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9479 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9480 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9481 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9482 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9483 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9484 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9485 9486 if (needSep) pw.println(" "); 9487 needSep = true; 9488 pw.println(" Process OOM control:"); 9489 dumpProcessOomList(pw, this, mLruProcesses, " ", 9490 "Proc", "PERS", true, null); 9491 needSep = true; 9492 } 9493 9494 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9495 9496 pw.println(); 9497 pw.println(" mHomeProcess: " + mHomeProcess); 9498 pw.println(" mPreviousProcess: " + mPreviousProcess); 9499 if (mHeavyWeightProcess != null) { 9500 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9501 } 9502 9503 return true; 9504 } 9505 9506 /** 9507 * There are three ways to call this: 9508 * - no provider specified: dump all the providers 9509 * - a flattened component name that matched an existing provider was specified as the 9510 * first arg: dump that one provider 9511 * - the first arg isn't the flattened component name of an existing provider: 9512 * dump all providers whose component contains the first arg as a substring 9513 */ 9514 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9515 int opti, boolean dumpAll) { 9516 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9517 } 9518 9519 static class ItemMatcher { 9520 ArrayList<ComponentName> components; 9521 ArrayList<String> strings; 9522 ArrayList<Integer> objects; 9523 boolean all; 9524 9525 ItemMatcher() { 9526 all = true; 9527 } 9528 9529 void build(String name) { 9530 ComponentName componentName = ComponentName.unflattenFromString(name); 9531 if (componentName != null) { 9532 if (components == null) { 9533 components = new ArrayList<ComponentName>(); 9534 } 9535 components.add(componentName); 9536 all = false; 9537 } else { 9538 int objectId = 0; 9539 // Not a '/' separated full component name; maybe an object ID? 9540 try { 9541 objectId = Integer.parseInt(name, 16); 9542 if (objects == null) { 9543 objects = new ArrayList<Integer>(); 9544 } 9545 objects.add(objectId); 9546 all = false; 9547 } catch (RuntimeException e) { 9548 // Not an integer; just do string match. 9549 if (strings == null) { 9550 strings = new ArrayList<String>(); 9551 } 9552 strings.add(name); 9553 all = false; 9554 } 9555 } 9556 } 9557 9558 int build(String[] args, int opti) { 9559 for (; opti<args.length; opti++) { 9560 String name = args[opti]; 9561 if ("--".equals(name)) { 9562 return opti+1; 9563 } 9564 build(name); 9565 } 9566 return opti; 9567 } 9568 9569 boolean match(Object object, ComponentName comp) { 9570 if (all) { 9571 return true; 9572 } 9573 if (components != null) { 9574 for (int i=0; i<components.size(); i++) { 9575 if (components.get(i).equals(comp)) { 9576 return true; 9577 } 9578 } 9579 } 9580 if (objects != null) { 9581 for (int i=0; i<objects.size(); i++) { 9582 if (System.identityHashCode(object) == objects.get(i)) { 9583 return true; 9584 } 9585 } 9586 } 9587 if (strings != null) { 9588 String flat = comp.flattenToString(); 9589 for (int i=0; i<strings.size(); i++) { 9590 if (flat.contains(strings.get(i))) { 9591 return true; 9592 } 9593 } 9594 } 9595 return false; 9596 } 9597 } 9598 9599 /** 9600 * There are three things that cmd can be: 9601 * - a flattened component name that matches an existing activity 9602 * - the cmd arg isn't the flattened component name of an existing activity: 9603 * dump all activity whose component contains the cmd as a substring 9604 * - A hex number of the ActivityRecord object instance. 9605 */ 9606 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9607 int opti, boolean dumpAll) { 9608 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9609 9610 if ("all".equals(name)) { 9611 synchronized (this) { 9612 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9613 activities.add(r1); 9614 } 9615 } 9616 } else if ("top".equals(name)) { 9617 synchronized (this) { 9618 final int N = mMainStack.mHistory.size(); 9619 if (N > 0) { 9620 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9621 } 9622 } 9623 } else { 9624 ItemMatcher matcher = new ItemMatcher(); 9625 matcher.build(name); 9626 9627 synchronized (this) { 9628 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9629 if (matcher.match(r1, r1.intent.getComponent())) { 9630 activities.add(r1); 9631 } 9632 } 9633 } 9634 } 9635 9636 if (activities.size() <= 0) { 9637 return false; 9638 } 9639 9640 String[] newArgs = new String[args.length - opti]; 9641 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9642 9643 TaskRecord lastTask = null; 9644 boolean needSep = false; 9645 for (int i=activities.size()-1; i>=0; i--) { 9646 ActivityRecord r = (ActivityRecord)activities.get(i); 9647 if (needSep) { 9648 pw.println(); 9649 } 9650 needSep = true; 9651 synchronized (this) { 9652 if (lastTask != r.task) { 9653 lastTask = r.task; 9654 pw.print("TASK "); pw.print(lastTask.affinity); 9655 pw.print(" id="); pw.println(lastTask.taskId); 9656 if (dumpAll) { 9657 lastTask.dump(pw, " "); 9658 } 9659 } 9660 } 9661 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9662 } 9663 return true; 9664 } 9665 9666 /** 9667 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9668 * there is a thread associated with the activity. 9669 */ 9670 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9671 final ActivityRecord r, String[] args, boolean dumpAll) { 9672 String innerPrefix = prefix + " "; 9673 synchronized (this) { 9674 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9675 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9676 pw.print(" pid="); 9677 if (r.app != null) pw.println(r.app.pid); 9678 else pw.println("(not running)"); 9679 if (dumpAll) { 9680 r.dump(pw, innerPrefix); 9681 } 9682 } 9683 if (r.app != null && r.app.thread != null) { 9684 // flush anything that is already in the PrintWriter since the thread is going 9685 // to write to the file descriptor directly 9686 pw.flush(); 9687 try { 9688 TransferPipe tp = new TransferPipe(); 9689 try { 9690 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9691 r.appToken, innerPrefix, args); 9692 tp.go(fd); 9693 } finally { 9694 tp.kill(); 9695 } 9696 } catch (IOException e) { 9697 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9698 } catch (RemoteException e) { 9699 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9700 } 9701 } 9702 } 9703 9704 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9705 int opti, boolean dumpAll, String dumpPackage) { 9706 boolean needSep = false; 9707 boolean onlyHistory = false; 9708 9709 if ("history".equals(dumpPackage)) { 9710 onlyHistory = true; 9711 dumpPackage = null; 9712 } 9713 9714 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9715 if (!onlyHistory && dumpAll) { 9716 if (mRegisteredReceivers.size() > 0) { 9717 boolean printed = false; 9718 Iterator it = mRegisteredReceivers.values().iterator(); 9719 while (it.hasNext()) { 9720 ReceiverList r = (ReceiverList)it.next(); 9721 if (dumpPackage != null && (r.app == null || 9722 !dumpPackage.equals(r.app.info.packageName))) { 9723 continue; 9724 } 9725 if (!printed) { 9726 pw.println(" Registered Receivers:"); 9727 needSep = true; 9728 printed = true; 9729 } 9730 pw.print(" * "); pw.println(r); 9731 r.dump(pw, " "); 9732 } 9733 } 9734 9735 if (mReceiverResolver.dump(pw, needSep ? 9736 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9737 " ", dumpPackage, false)) { 9738 needSep = true; 9739 } 9740 } 9741 9742 for (BroadcastQueue q : mBroadcastQueues) { 9743 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9744 } 9745 9746 needSep = true; 9747 9748 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9749 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9750 if (needSep) { 9751 pw.println(); 9752 } 9753 needSep = true; 9754 pw.print(" Sticky broadcasts for user "); 9755 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9756 StringBuilder sb = new StringBuilder(128); 9757 for (Map.Entry<String, ArrayList<Intent>> ent 9758 : mStickyBroadcasts.valueAt(user).entrySet()) { 9759 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9760 if (dumpAll) { 9761 pw.println(":"); 9762 ArrayList<Intent> intents = ent.getValue(); 9763 final int N = intents.size(); 9764 for (int i=0; i<N; i++) { 9765 sb.setLength(0); 9766 sb.append(" Intent: "); 9767 intents.get(i).toShortString(sb, false, true, false, false); 9768 pw.println(sb.toString()); 9769 Bundle bundle = intents.get(i).getExtras(); 9770 if (bundle != null) { 9771 pw.print(" "); 9772 pw.println(bundle.toString()); 9773 } 9774 } 9775 } else { 9776 pw.println(""); 9777 } 9778 } 9779 } 9780 } 9781 9782 if (!onlyHistory && dumpAll) { 9783 pw.println(); 9784 for (BroadcastQueue queue : mBroadcastQueues) { 9785 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9786 + queue.mBroadcastsScheduled); 9787 } 9788 pw.println(" mHandler:"); 9789 mHandler.dump(new PrintWriterPrinter(pw), " "); 9790 needSep = true; 9791 } 9792 9793 return needSep; 9794 } 9795 9796 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9797 int opti, boolean dumpAll, String dumpPackage) { 9798 boolean needSep = true; 9799 9800 ItemMatcher matcher = new ItemMatcher(); 9801 matcher.build(args, opti); 9802 9803 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9804 9805 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9806 9807 if (mLaunchingProviders.size() > 0) { 9808 boolean printed = false; 9809 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9810 ContentProviderRecord r = mLaunchingProviders.get(i); 9811 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9812 continue; 9813 } 9814 if (!printed) { 9815 if (needSep) pw.println(" "); 9816 needSep = true; 9817 pw.println(" Launching content providers:"); 9818 printed = true; 9819 } 9820 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9821 pw.println(r); 9822 } 9823 } 9824 9825 if (mGrantedUriPermissions.size() > 0) { 9826 if (needSep) pw.println(); 9827 needSep = true; 9828 pw.println("Granted Uri Permissions:"); 9829 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9830 int uid = mGrantedUriPermissions.keyAt(i); 9831 HashMap<Uri, UriPermission> perms 9832 = mGrantedUriPermissions.valueAt(i); 9833 pw.print(" * UID "); pw.print(uid); 9834 pw.println(" holds:"); 9835 for (UriPermission perm : perms.values()) { 9836 pw.print(" "); pw.println(perm); 9837 if (dumpAll) { 9838 perm.dump(pw, " "); 9839 } 9840 } 9841 } 9842 needSep = true; 9843 } 9844 9845 return needSep; 9846 } 9847 9848 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9849 int opti, boolean dumpAll, String dumpPackage) { 9850 boolean needSep = false; 9851 9852 if (mIntentSenderRecords.size() > 0) { 9853 boolean printed = false; 9854 Iterator<WeakReference<PendingIntentRecord>> it 9855 = mIntentSenderRecords.values().iterator(); 9856 while (it.hasNext()) { 9857 WeakReference<PendingIntentRecord> ref = it.next(); 9858 PendingIntentRecord rec = ref != null ? ref.get(): null; 9859 if (dumpPackage != null && (rec == null 9860 || !dumpPackage.equals(rec.key.packageName))) { 9861 continue; 9862 } 9863 if (!printed) { 9864 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9865 printed = true; 9866 } 9867 needSep = true; 9868 if (rec != null) { 9869 pw.print(" * "); pw.println(rec); 9870 if (dumpAll) { 9871 rec.dump(pw, " "); 9872 } 9873 } else { 9874 pw.print(" * "); pw.println(ref); 9875 } 9876 } 9877 } 9878 9879 return needSep; 9880 } 9881 9882 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9883 String prefix, String label, boolean complete, boolean brief, boolean client, 9884 String dumpPackage) { 9885 TaskRecord lastTask = null; 9886 boolean needNL = false; 9887 final String innerPrefix = prefix + " "; 9888 final String[] args = new String[0]; 9889 for (int i=list.size()-1; i>=0; i--) { 9890 final ActivityRecord r = (ActivityRecord)list.get(i); 9891 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9892 continue; 9893 } 9894 final boolean full = !brief && (complete || !r.isInHistory()); 9895 if (needNL) { 9896 pw.println(" "); 9897 needNL = false; 9898 } 9899 if (lastTask != r.task) { 9900 lastTask = r.task; 9901 pw.print(prefix); 9902 pw.print(full ? "* " : " "); 9903 pw.println(lastTask); 9904 if (full) { 9905 lastTask.dump(pw, prefix + " "); 9906 } else if (complete) { 9907 // Complete + brief == give a summary. Isn't that obvious?!? 9908 if (lastTask.intent != null) { 9909 pw.print(prefix); pw.print(" "); 9910 pw.println(lastTask.intent.toInsecureStringWithClip()); 9911 } 9912 } 9913 } 9914 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9915 pw.print(" #"); pw.print(i); pw.print(": "); 9916 pw.println(r); 9917 if (full) { 9918 r.dump(pw, innerPrefix); 9919 } else if (complete) { 9920 // Complete + brief == give a summary. Isn't that obvious?!? 9921 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9922 if (r.app != null) { 9923 pw.print(innerPrefix); pw.println(r.app); 9924 } 9925 } 9926 if (client && r.app != null && r.app.thread != null) { 9927 // flush anything that is already in the PrintWriter since the thread is going 9928 // to write to the file descriptor directly 9929 pw.flush(); 9930 try { 9931 TransferPipe tp = new TransferPipe(); 9932 try { 9933 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9934 r.appToken, innerPrefix, args); 9935 // Short timeout, since blocking here can 9936 // deadlock with the application. 9937 tp.go(fd, 2000); 9938 } finally { 9939 tp.kill(); 9940 } 9941 } catch (IOException e) { 9942 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9943 } catch (RemoteException e) { 9944 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9945 } 9946 needNL = true; 9947 } 9948 } 9949 } 9950 9951 private static String buildOomTag(String prefix, String space, int val, int base) { 9952 if (val == base) { 9953 if (space == null) return prefix; 9954 return prefix + " "; 9955 } 9956 return prefix + "+" + Integer.toString(val-base); 9957 } 9958 9959 private static final int dumpProcessList(PrintWriter pw, 9960 ActivityManagerService service, List list, 9961 String prefix, String normalLabel, String persistentLabel, 9962 String dumpPackage) { 9963 int numPers = 0; 9964 final int N = list.size()-1; 9965 for (int i=N; i>=0; i--) { 9966 ProcessRecord r = (ProcessRecord)list.get(i); 9967 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9968 continue; 9969 } 9970 pw.println(String.format("%s%s #%2d: %s", 9971 prefix, (r.persistent ? persistentLabel : normalLabel), 9972 i, r.toString())); 9973 if (r.persistent) { 9974 numPers++; 9975 } 9976 } 9977 return numPers; 9978 } 9979 9980 private static final boolean dumpProcessOomList(PrintWriter pw, 9981 ActivityManagerService service, List<ProcessRecord> origList, 9982 String prefix, String normalLabel, String persistentLabel, 9983 boolean inclDetails, String dumpPackage) { 9984 9985 ArrayList<Pair<ProcessRecord, Integer>> list 9986 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9987 for (int i=0; i<origList.size(); i++) { 9988 ProcessRecord r = origList.get(i); 9989 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9990 continue; 9991 } 9992 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9993 } 9994 9995 if (list.size() <= 0) { 9996 return false; 9997 } 9998 9999 Comparator<Pair<ProcessRecord, Integer>> comparator 10000 = new Comparator<Pair<ProcessRecord, Integer>>() { 10001 @Override 10002 public int compare(Pair<ProcessRecord, Integer> object1, 10003 Pair<ProcessRecord, Integer> object2) { 10004 if (object1.first.setAdj != object2.first.setAdj) { 10005 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10006 } 10007 if (object1.second.intValue() != object2.second.intValue()) { 10008 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10009 } 10010 return 0; 10011 } 10012 }; 10013 10014 Collections.sort(list, comparator); 10015 10016 final long curRealtime = SystemClock.elapsedRealtime(); 10017 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10018 final long curUptime = SystemClock.uptimeMillis(); 10019 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10020 10021 for (int i=list.size()-1; i>=0; i--) { 10022 ProcessRecord r = list.get(i).first; 10023 String oomAdj; 10024 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10025 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10026 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10027 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10028 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10029 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10030 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10031 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10032 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10033 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10034 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10035 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10036 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10037 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10038 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10039 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10040 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10041 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10042 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10043 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10044 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10045 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10046 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10047 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10048 } else { 10049 oomAdj = Integer.toString(r.setAdj); 10050 } 10051 String schedGroup; 10052 switch (r.setSchedGroup) { 10053 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10054 schedGroup = "B"; 10055 break; 10056 case Process.THREAD_GROUP_DEFAULT: 10057 schedGroup = "F"; 10058 break; 10059 default: 10060 schedGroup = Integer.toString(r.setSchedGroup); 10061 break; 10062 } 10063 String foreground; 10064 if (r.foregroundActivities) { 10065 foreground = "A"; 10066 } else if (r.foregroundServices) { 10067 foreground = "S"; 10068 } else { 10069 foreground = " "; 10070 } 10071 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10072 prefix, (r.persistent ? persistentLabel : normalLabel), 10073 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10074 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10075 if (r.adjSource != null || r.adjTarget != null) { 10076 pw.print(prefix); 10077 pw.print(" "); 10078 if (r.adjTarget instanceof ComponentName) { 10079 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10080 } else if (r.adjTarget != null) { 10081 pw.print(r.adjTarget.toString()); 10082 } else { 10083 pw.print("{null}"); 10084 } 10085 pw.print("<="); 10086 if (r.adjSource instanceof ProcessRecord) { 10087 pw.print("Proc{"); 10088 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10089 pw.println("}"); 10090 } else if (r.adjSource != null) { 10091 pw.println(r.adjSource.toString()); 10092 } else { 10093 pw.println("{null}"); 10094 } 10095 } 10096 if (inclDetails) { 10097 pw.print(prefix); 10098 pw.print(" "); 10099 pw.print("oom: max="); pw.print(r.maxAdj); 10100 pw.print(" hidden="); pw.print(r.hiddenAdj); 10101 pw.print(" client="); pw.print(r.clientHiddenAdj); 10102 pw.print(" empty="); pw.print(r.emptyAdj); 10103 pw.print(" curRaw="); pw.print(r.curRawAdj); 10104 pw.print(" setRaw="); pw.print(r.setRawAdj); 10105 pw.print(" cur="); pw.print(r.curAdj); 10106 pw.print(" set="); pw.println(r.setAdj); 10107 pw.print(prefix); 10108 pw.print(" "); 10109 pw.print("keeping="); pw.print(r.keeping); 10110 pw.print(" hidden="); pw.print(r.hidden); 10111 pw.print(" empty="); pw.print(r.empty); 10112 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10113 10114 if (!r.keeping) { 10115 if (r.lastWakeTime != 0) { 10116 long wtime; 10117 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10118 synchronized (stats) { 10119 wtime = stats.getProcessWakeTime(r.info.uid, 10120 r.pid, curRealtime); 10121 } 10122 long timeUsed = wtime - r.lastWakeTime; 10123 pw.print(prefix); 10124 pw.print(" "); 10125 pw.print("keep awake over "); 10126 TimeUtils.formatDuration(realtimeSince, pw); 10127 pw.print(" used "); 10128 TimeUtils.formatDuration(timeUsed, pw); 10129 pw.print(" ("); 10130 pw.print((timeUsed*100)/realtimeSince); 10131 pw.println("%)"); 10132 } 10133 if (r.lastCpuTime != 0) { 10134 long timeUsed = r.curCpuTime - r.lastCpuTime; 10135 pw.print(prefix); 10136 pw.print(" "); 10137 pw.print("run cpu over "); 10138 TimeUtils.formatDuration(uptimeSince, pw); 10139 pw.print(" used "); 10140 TimeUtils.formatDuration(timeUsed, pw); 10141 pw.print(" ("); 10142 pw.print((timeUsed*100)/uptimeSince); 10143 pw.println("%)"); 10144 } 10145 } 10146 } 10147 } 10148 return true; 10149 } 10150 10151 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10152 ArrayList<ProcessRecord> procs; 10153 synchronized (this) { 10154 if (args != null && args.length > start 10155 && args[start].charAt(0) != '-') { 10156 procs = new ArrayList<ProcessRecord>(); 10157 int pid = -1; 10158 try { 10159 pid = Integer.parseInt(args[start]); 10160 } catch (NumberFormatException e) { 10161 10162 } 10163 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10164 ProcessRecord proc = mLruProcesses.get(i); 10165 if (proc.pid == pid) { 10166 procs.add(proc); 10167 } else if (proc.processName.equals(args[start])) { 10168 procs.add(proc); 10169 } 10170 } 10171 if (procs.size() <= 0) { 10172 pw.println("No process found for: " + args[start]); 10173 return null; 10174 } 10175 } else { 10176 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10177 } 10178 } 10179 return procs; 10180 } 10181 10182 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10183 PrintWriter pw, String[] args) { 10184 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10185 if (procs == null) { 10186 return; 10187 } 10188 10189 long uptime = SystemClock.uptimeMillis(); 10190 long realtime = SystemClock.elapsedRealtime(); 10191 pw.println("Applications Graphics Acceleration Info:"); 10192 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10193 10194 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10195 ProcessRecord r = procs.get(i); 10196 if (r.thread != null) { 10197 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10198 pw.flush(); 10199 try { 10200 TransferPipe tp = new TransferPipe(); 10201 try { 10202 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10203 tp.go(fd); 10204 } finally { 10205 tp.kill(); 10206 } 10207 } catch (IOException e) { 10208 pw.println("Failure while dumping the app: " + r); 10209 pw.flush(); 10210 } catch (RemoteException e) { 10211 pw.println("Got a RemoteException while dumping the app " + r); 10212 pw.flush(); 10213 } 10214 } 10215 } 10216 } 10217 10218 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10219 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10220 if (procs == null) { 10221 return; 10222 } 10223 10224 pw.println("Applications Database Info:"); 10225 10226 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10227 ProcessRecord r = procs.get(i); 10228 if (r.thread != null) { 10229 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10230 pw.flush(); 10231 try { 10232 TransferPipe tp = new TransferPipe(); 10233 try { 10234 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10235 tp.go(fd); 10236 } finally { 10237 tp.kill(); 10238 } 10239 } catch (IOException e) { 10240 pw.println("Failure while dumping the app: " + r); 10241 pw.flush(); 10242 } catch (RemoteException e) { 10243 pw.println("Got a RemoteException while dumping the app " + r); 10244 pw.flush(); 10245 } 10246 } 10247 } 10248 } 10249 10250 final static class MemItem { 10251 final String label; 10252 final String shortLabel; 10253 final long pss; 10254 final int id; 10255 ArrayList<MemItem> subitems; 10256 10257 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10258 label = _label; 10259 shortLabel = _shortLabel; 10260 pss = _pss; 10261 id = _id; 10262 } 10263 } 10264 10265 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10266 boolean sort) { 10267 if (sort) { 10268 Collections.sort(items, new Comparator<MemItem>() { 10269 @Override 10270 public int compare(MemItem lhs, MemItem rhs) { 10271 if (lhs.pss < rhs.pss) { 10272 return 1; 10273 } else if (lhs.pss > rhs.pss) { 10274 return -1; 10275 } 10276 return 0; 10277 } 10278 }); 10279 } 10280 10281 for (int i=0; i<items.size(); i++) { 10282 MemItem mi = items.get(i); 10283 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10284 if (mi.subitems != null) { 10285 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10286 } 10287 } 10288 } 10289 10290 // These are in KB. 10291 static final long[] DUMP_MEM_BUCKETS = new long[] { 10292 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10293 120*1024, 160*1024, 200*1024, 10294 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10295 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10296 }; 10297 10298 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10299 boolean stackLike) { 10300 int start = label.lastIndexOf('.'); 10301 if (start >= 0) start++; 10302 else start = 0; 10303 int end = label.length(); 10304 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10305 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10306 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10307 out.append(bucket); 10308 out.append(stackLike ? "MB." : "MB "); 10309 out.append(label, start, end); 10310 return; 10311 } 10312 } 10313 out.append(memKB/1024); 10314 out.append(stackLike ? "MB." : "MB "); 10315 out.append(label, start, end); 10316 } 10317 10318 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10319 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10320 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10321 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10322 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10323 }; 10324 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10325 "System", "Persistent", "Foreground", 10326 "Visible", "Perceptible", "Heavy Weight", 10327 "Backup", "A Services", "Home", "Previous", 10328 "B Services", "Background" 10329 }; 10330 10331 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10332 PrintWriter pw, String prefix, String[] args, boolean brief, 10333 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10334 boolean dumpAll = false; 10335 boolean oomOnly = false; 10336 10337 int opti = 0; 10338 while (opti < args.length) { 10339 String opt = args[opti]; 10340 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10341 break; 10342 } 10343 opti++; 10344 if ("-a".equals(opt)) { 10345 dumpAll = true; 10346 } else if ("--oom".equals(opt)) { 10347 oomOnly = true; 10348 } else if ("-h".equals(opt)) { 10349 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10350 pw.println(" -a: include all available information for each process."); 10351 pw.println(" --oom: only show processes organized by oom adj."); 10352 pw.println("If [process] is specified it can be the name or "); 10353 pw.println("pid of a specific process to dump."); 10354 return; 10355 } else { 10356 pw.println("Unknown argument: " + opt + "; use -h for help"); 10357 } 10358 } 10359 10360 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10361 if (procs == null) { 10362 return; 10363 } 10364 10365 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10366 long uptime = SystemClock.uptimeMillis(); 10367 long realtime = SystemClock.elapsedRealtime(); 10368 10369 if (procs.size() == 1 || isCheckinRequest) { 10370 dumpAll = true; 10371 } 10372 10373 if (isCheckinRequest) { 10374 // short checkin version 10375 pw.println(uptime + "," + realtime); 10376 pw.flush(); 10377 } else { 10378 pw.println("Applications Memory Usage (kB):"); 10379 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10380 } 10381 10382 String[] innerArgs = new String[args.length-opti]; 10383 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10384 10385 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10386 long nativePss=0, dalvikPss=0, otherPss=0; 10387 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10388 10389 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10390 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10391 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10392 10393 long totalPss = 0; 10394 10395 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10396 ProcessRecord r = procs.get(i); 10397 if (r.thread != null) { 10398 if (!isCheckinRequest && dumpAll) { 10399 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10400 pw.flush(); 10401 } 10402 Debug.MemoryInfo mi = null; 10403 if (dumpAll) { 10404 try { 10405 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10406 } catch (RemoteException e) { 10407 if (!isCheckinRequest) { 10408 pw.println("Got RemoteException!"); 10409 pw.flush(); 10410 } 10411 } 10412 } else { 10413 mi = new Debug.MemoryInfo(); 10414 Debug.getMemoryInfo(r.pid, mi); 10415 } 10416 10417 if (!isCheckinRequest && mi != null) { 10418 long myTotalPss = mi.getTotalPss(); 10419 totalPss += myTotalPss; 10420 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10421 r.processName, myTotalPss, 0); 10422 procMems.add(pssItem); 10423 10424 nativePss += mi.nativePss; 10425 dalvikPss += mi.dalvikPss; 10426 otherPss += mi.otherPss; 10427 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10428 long mem = mi.getOtherPss(j); 10429 miscPss[j] += mem; 10430 otherPss -= mem; 10431 } 10432 10433 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10434 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10435 || oomIndex == (oomPss.length-1)) { 10436 oomPss[oomIndex] += myTotalPss; 10437 if (oomProcs[oomIndex] == null) { 10438 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10439 } 10440 oomProcs[oomIndex].add(pssItem); 10441 break; 10442 } 10443 } 10444 } 10445 } 10446 } 10447 10448 if (!isCheckinRequest && procs.size() > 1) { 10449 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10450 10451 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10452 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10453 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10454 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10455 String label = Debug.MemoryInfo.getOtherLabel(j); 10456 catMems.add(new MemItem(label, label, miscPss[j], j)); 10457 } 10458 10459 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10460 for (int j=0; j<oomPss.length; j++) { 10461 if (oomPss[j] != 0) { 10462 String label = DUMP_MEM_OOM_LABEL[j]; 10463 MemItem item = new MemItem(label, label, oomPss[j], 10464 DUMP_MEM_OOM_ADJ[j]); 10465 item.subitems = oomProcs[j]; 10466 oomMems.add(item); 10467 } 10468 } 10469 10470 if (outTag != null || outStack != null) { 10471 if (outTag != null) { 10472 appendMemBucket(outTag, totalPss, "total", false); 10473 } 10474 if (outStack != null) { 10475 appendMemBucket(outStack, totalPss, "total", true); 10476 } 10477 boolean firstLine = true; 10478 for (int i=0; i<oomMems.size(); i++) { 10479 MemItem miCat = oomMems.get(i); 10480 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10481 continue; 10482 } 10483 if (miCat.id < ProcessList.SERVICE_ADJ 10484 || miCat.id == ProcessList.HOME_APP_ADJ 10485 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10486 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10487 outTag.append(" / "); 10488 } 10489 if (outStack != null) { 10490 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10491 if (firstLine) { 10492 outStack.append(":"); 10493 firstLine = false; 10494 } 10495 outStack.append("\n\t at "); 10496 } else { 10497 outStack.append("$"); 10498 } 10499 } 10500 for (int j=0; j<miCat.subitems.size(); j++) { 10501 MemItem mi = miCat.subitems.get(j); 10502 if (j > 0) { 10503 if (outTag != null) { 10504 outTag.append(" "); 10505 } 10506 if (outStack != null) { 10507 outStack.append("$"); 10508 } 10509 } 10510 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10511 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10512 } 10513 if (outStack != null) { 10514 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10515 } 10516 } 10517 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10518 outStack.append("("); 10519 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10520 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10521 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10522 outStack.append(":"); 10523 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10524 } 10525 } 10526 outStack.append(")"); 10527 } 10528 } 10529 } 10530 } 10531 10532 if (!brief && !oomOnly) { 10533 pw.println(); 10534 pw.println("Total PSS by process:"); 10535 dumpMemItems(pw, " ", procMems, true); 10536 pw.println(); 10537 } 10538 pw.println("Total PSS by OOM adjustment:"); 10539 dumpMemItems(pw, " ", oomMems, false); 10540 if (!oomOnly) { 10541 PrintWriter out = categoryPw != null ? categoryPw : pw; 10542 out.println(); 10543 out.println("Total PSS by category:"); 10544 dumpMemItems(out, " ", catMems, true); 10545 } 10546 pw.println(); 10547 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10548 final int[] SINGLE_LONG_FORMAT = new int[] { 10549 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10550 }; 10551 long[] longOut = new long[1]; 10552 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10553 SINGLE_LONG_FORMAT, null, longOut, null); 10554 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10555 longOut[0] = 0; 10556 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10557 SINGLE_LONG_FORMAT, null, longOut, null); 10558 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10559 longOut[0] = 0; 10560 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10561 SINGLE_LONG_FORMAT, null, longOut, null); 10562 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10563 longOut[0] = 0; 10564 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10565 SINGLE_LONG_FORMAT, null, longOut, null); 10566 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10567 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10568 pw.print(shared); pw.println(" kB"); 10569 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10570 pw.print(voltile); pw.println(" kB volatile"); 10571 } 10572 } 10573 10574 /** 10575 * Searches array of arguments for the specified string 10576 * @param args array of argument strings 10577 * @param value value to search for 10578 * @return true if the value is contained in the array 10579 */ 10580 private static boolean scanArgs(String[] args, String value) { 10581 if (args != null) { 10582 for (String arg : args) { 10583 if (value.equals(arg)) { 10584 return true; 10585 } 10586 } 10587 } 10588 return false; 10589 } 10590 10591 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10592 ContentProviderRecord cpr, boolean always) { 10593 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10594 10595 if (!inLaunching || always) { 10596 synchronized (cpr) { 10597 cpr.launchingApp = null; 10598 cpr.notifyAll(); 10599 } 10600 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10601 String names[] = cpr.info.authority.split(";"); 10602 for (int j = 0; j < names.length; j++) { 10603 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10604 } 10605 } 10606 10607 for (int i=0; i<cpr.connections.size(); i++) { 10608 ContentProviderConnection conn = cpr.connections.get(i); 10609 if (conn.waiting) { 10610 // If this connection is waiting for the provider, then we don't 10611 // need to mess with its process unless we are always removing 10612 // or for some reason the provider is not currently launching. 10613 if (inLaunching && !always) { 10614 continue; 10615 } 10616 } 10617 ProcessRecord capp = conn.client; 10618 conn.dead = true; 10619 if (conn.stableCount > 0) { 10620 if (!capp.persistent && capp.thread != null 10621 && capp.pid != 0 10622 && capp.pid != MY_PID) { 10623 Slog.i(TAG, "Kill " + capp.processName 10624 + " (pid " + capp.pid + "): provider " + cpr.info.name 10625 + " in dying process " + (proc != null ? proc.processName : "??")); 10626 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10627 capp.processName, capp.setAdj, "dying provider " 10628 + cpr.name.toShortString()); 10629 Process.killProcessQuiet(capp.pid); 10630 } 10631 } else if (capp.thread != null && conn.provider.provider != null) { 10632 try { 10633 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10634 } catch (RemoteException e) { 10635 } 10636 // In the protocol here, we don't expect the client to correctly 10637 // clean up this connection, we'll just remove it. 10638 cpr.connections.remove(i); 10639 conn.client.conProviders.remove(conn); 10640 } 10641 } 10642 10643 if (inLaunching && always) { 10644 mLaunchingProviders.remove(cpr); 10645 } 10646 return inLaunching; 10647 } 10648 10649 /** 10650 * Main code for cleaning up a process when it has gone away. This is 10651 * called both as a result of the process dying, or directly when stopping 10652 * a process when running in single process mode. 10653 */ 10654 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10655 boolean restarting, boolean allowRestart, int index) { 10656 if (index >= 0) { 10657 mLruProcesses.remove(index); 10658 } 10659 10660 mProcessesToGc.remove(app); 10661 10662 // Dismiss any open dialogs. 10663 if (app.crashDialog != null) { 10664 app.crashDialog.dismiss(); 10665 app.crashDialog = null; 10666 } 10667 if (app.anrDialog != null) { 10668 app.anrDialog.dismiss(); 10669 app.anrDialog = null; 10670 } 10671 if (app.waitDialog != null) { 10672 app.waitDialog.dismiss(); 10673 app.waitDialog = null; 10674 } 10675 10676 app.crashing = false; 10677 app.notResponding = false; 10678 10679 app.resetPackageList(); 10680 app.unlinkDeathRecipient(); 10681 app.thread = null; 10682 app.forcingToForeground = null; 10683 app.foregroundServices = false; 10684 app.foregroundActivities = false; 10685 app.hasShownUi = false; 10686 app.hasAboveClient = false; 10687 10688 mServices.killServicesLocked(app, allowRestart); 10689 10690 boolean restart = false; 10691 10692 // Remove published content providers. 10693 if (!app.pubProviders.isEmpty()) { 10694 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10695 while (it.hasNext()) { 10696 ContentProviderRecord cpr = it.next(); 10697 10698 final boolean always = app.bad || !allowRestart; 10699 if (removeDyingProviderLocked(app, cpr, always) || always) { 10700 // We left the provider in the launching list, need to 10701 // restart it. 10702 restart = true; 10703 } 10704 10705 cpr.provider = null; 10706 cpr.proc = null; 10707 } 10708 app.pubProviders.clear(); 10709 } 10710 10711 // Take care of any launching providers waiting for this process. 10712 if (checkAppInLaunchingProvidersLocked(app, false)) { 10713 restart = true; 10714 } 10715 10716 // Unregister from connected content providers. 10717 if (!app.conProviders.isEmpty()) { 10718 for (int i=0; i<app.conProviders.size(); i++) { 10719 ContentProviderConnection conn = app.conProviders.get(i); 10720 conn.provider.connections.remove(conn); 10721 } 10722 app.conProviders.clear(); 10723 } 10724 10725 // At this point there may be remaining entries in mLaunchingProviders 10726 // where we were the only one waiting, so they are no longer of use. 10727 // Look for these and clean up if found. 10728 // XXX Commented out for now. Trying to figure out a way to reproduce 10729 // the actual situation to identify what is actually going on. 10730 if (false) { 10731 for (int i=0; i<mLaunchingProviders.size(); i++) { 10732 ContentProviderRecord cpr = (ContentProviderRecord) 10733 mLaunchingProviders.get(i); 10734 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10735 synchronized (cpr) { 10736 cpr.launchingApp = null; 10737 cpr.notifyAll(); 10738 } 10739 } 10740 } 10741 } 10742 10743 skipCurrentReceiverLocked(app); 10744 10745 // Unregister any receivers. 10746 if (app.receivers.size() > 0) { 10747 Iterator<ReceiverList> it = app.receivers.iterator(); 10748 while (it.hasNext()) { 10749 removeReceiverLocked(it.next()); 10750 } 10751 app.receivers.clear(); 10752 } 10753 10754 // If the app is undergoing backup, tell the backup manager about it 10755 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10756 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10757 + mBackupTarget.appInfo + " died during backup"); 10758 try { 10759 IBackupManager bm = IBackupManager.Stub.asInterface( 10760 ServiceManager.getService(Context.BACKUP_SERVICE)); 10761 bm.agentDisconnected(app.info.packageName); 10762 } catch (RemoteException e) { 10763 // can't happen; backup manager is local 10764 } 10765 } 10766 10767 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10768 ProcessChangeItem item = mPendingProcessChanges.get(i); 10769 if (item.pid == app.pid) { 10770 mPendingProcessChanges.remove(i); 10771 mAvailProcessChanges.add(item); 10772 } 10773 } 10774 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10775 10776 // If the caller is restarting this app, then leave it in its 10777 // current lists and let the caller take care of it. 10778 if (restarting) { 10779 return; 10780 } 10781 10782 if (!app.persistent || app.isolated) { 10783 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10784 "Removing non-persistent process during cleanup: " + app); 10785 mProcessNames.remove(app.processName, app.uid); 10786 mIsolatedProcesses.remove(app.uid); 10787 if (mHeavyWeightProcess == app) { 10788 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10789 mHeavyWeightProcess.userId, 0)); 10790 mHeavyWeightProcess = null; 10791 } 10792 } else if (!app.removed) { 10793 // This app is persistent, so we need to keep its record around. 10794 // If it is not already on the pending app list, add it there 10795 // and start a new process for it. 10796 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10797 mPersistentStartingProcesses.add(app); 10798 restart = true; 10799 } 10800 } 10801 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10802 "Clean-up removing on hold: " + app); 10803 mProcessesOnHold.remove(app); 10804 10805 if (app == mHomeProcess) { 10806 mHomeProcess = null; 10807 } 10808 if (app == mPreviousProcess) { 10809 mPreviousProcess = null; 10810 } 10811 10812 if (restart && !app.isolated) { 10813 // We have components that still need to be running in the 10814 // process, so re-launch it. 10815 mProcessNames.put(app.processName, app.uid, app); 10816 startProcessLocked(app, "restart", app.processName); 10817 } else if (app.pid > 0 && app.pid != MY_PID) { 10818 // Goodbye! 10819 synchronized (mPidsSelfLocked) { 10820 mPidsSelfLocked.remove(app.pid); 10821 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10822 } 10823 app.setPid(0); 10824 } 10825 } 10826 10827 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10828 // Look through the content providers we are waiting to have launched, 10829 // and if any run in this process then either schedule a restart of 10830 // the process or kill the client waiting for it if this process has 10831 // gone bad. 10832 int NL = mLaunchingProviders.size(); 10833 boolean restart = false; 10834 for (int i=0; i<NL; i++) { 10835 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10836 if (cpr.launchingApp == app) { 10837 if (!alwaysBad && !app.bad) { 10838 restart = true; 10839 } else { 10840 removeDyingProviderLocked(app, cpr, true); 10841 // cpr should have been removed from mLaunchingProviders 10842 NL = mLaunchingProviders.size(); 10843 i--; 10844 } 10845 } 10846 } 10847 return restart; 10848 } 10849 10850 // ========================================================= 10851 // SERVICES 10852 // ========================================================= 10853 10854 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10855 int flags) { 10856 enforceNotIsolatedCaller("getServices"); 10857 synchronized (this) { 10858 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10859 } 10860 } 10861 10862 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10863 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10864 synchronized (this) { 10865 return mServices.getRunningServiceControlPanelLocked(name); 10866 } 10867 } 10868 10869 public ComponentName startService(IApplicationThread caller, Intent service, 10870 String resolvedType, int userId) { 10871 enforceNotIsolatedCaller("startService"); 10872 // Refuse possible leaked file descriptors 10873 if (service != null && service.hasFileDescriptors() == true) { 10874 throw new IllegalArgumentException("File descriptors passed in Intent"); 10875 } 10876 10877 if (DEBUG_SERVICE) 10878 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10879 synchronized(this) { 10880 final int callingPid = Binder.getCallingPid(); 10881 final int callingUid = Binder.getCallingUid(); 10882 checkValidCaller(callingUid, userId); 10883 final long origId = Binder.clearCallingIdentity(); 10884 ComponentName res = mServices.startServiceLocked(caller, service, 10885 resolvedType, callingPid, callingUid, userId); 10886 Binder.restoreCallingIdentity(origId); 10887 return res; 10888 } 10889 } 10890 10891 ComponentName startServiceInPackage(int uid, 10892 Intent service, String resolvedType, int userId) { 10893 synchronized(this) { 10894 if (DEBUG_SERVICE) 10895 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10896 final long origId = Binder.clearCallingIdentity(); 10897 ComponentName res = mServices.startServiceLocked(null, service, 10898 resolvedType, -1, uid, userId); 10899 Binder.restoreCallingIdentity(origId); 10900 return res; 10901 } 10902 } 10903 10904 public int stopService(IApplicationThread caller, Intent service, 10905 String resolvedType, int userId) { 10906 enforceNotIsolatedCaller("stopService"); 10907 // Refuse possible leaked file descriptors 10908 if (service != null && service.hasFileDescriptors() == true) { 10909 throw new IllegalArgumentException("File descriptors passed in Intent"); 10910 } 10911 10912 checkValidCaller(Binder.getCallingUid(), userId); 10913 10914 synchronized(this) { 10915 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10916 } 10917 } 10918 10919 public IBinder peekService(Intent service, String resolvedType) { 10920 enforceNotIsolatedCaller("peekService"); 10921 // Refuse possible leaked file descriptors 10922 if (service != null && service.hasFileDescriptors() == true) { 10923 throw new IllegalArgumentException("File descriptors passed in Intent"); 10924 } 10925 synchronized(this) { 10926 return mServices.peekServiceLocked(service, resolvedType); 10927 } 10928 } 10929 10930 public boolean stopServiceToken(ComponentName className, IBinder token, 10931 int startId) { 10932 synchronized(this) { 10933 return mServices.stopServiceTokenLocked(className, token, startId); 10934 } 10935 } 10936 10937 public void setServiceForeground(ComponentName className, IBinder token, 10938 int id, Notification notification, boolean removeNotification) { 10939 synchronized(this) { 10940 mServices.setServiceForegroundLocked(className, token, id, notification, 10941 removeNotification); 10942 } 10943 } 10944 10945 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10946 boolean requireFull, String name, String callerPackage) { 10947 final int callingUserId = UserHandle.getUserId(callingUid); 10948 if (callingUserId != userId) { 10949 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10950 if ((requireFull || checkComponentPermission( 10951 android.Manifest.permission.INTERACT_ACROSS_USERS, 10952 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10953 && checkComponentPermission( 10954 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10955 callingPid, callingUid, -1, true) 10956 != PackageManager.PERMISSION_GRANTED) { 10957 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10958 // In this case, they would like to just execute as their 10959 // owner user instead of failing. 10960 userId = callingUserId; 10961 } else { 10962 StringBuilder builder = new StringBuilder(128); 10963 builder.append("Permission Denial: "); 10964 builder.append(name); 10965 if (callerPackage != null) { 10966 builder.append(" from "); 10967 builder.append(callerPackage); 10968 } 10969 builder.append(" asks to run as user "); 10970 builder.append(userId); 10971 builder.append(" but is calling from user "); 10972 builder.append(UserHandle.getUserId(callingUid)); 10973 builder.append("; this requires "); 10974 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10975 if (!requireFull) { 10976 builder.append(" or "); 10977 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10978 } 10979 String msg = builder.toString(); 10980 Slog.w(TAG, msg); 10981 throw new SecurityException(msg); 10982 } 10983 } 10984 } 10985 if (userId == UserHandle.USER_CURRENT 10986 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10987 // Note that we may be accessing this outside of a lock... 10988 // shouldn't be a big deal, if this is being called outside 10989 // of a locked context there is intrinsically a race with 10990 // the value the caller will receive and someone else changing it. 10991 userId = mCurrentUserId; 10992 } 10993 if (!allowAll && userId < 0) { 10994 throw new IllegalArgumentException( 10995 "Call does not support special user #" + userId); 10996 } 10997 } 10998 return userId; 10999 } 11000 11001 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11002 String className, int flags) { 11003 boolean result = false; 11004 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11005 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11006 if (ActivityManager.checkUidPermission( 11007 android.Manifest.permission.INTERACT_ACROSS_USERS, 11008 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11009 ComponentName comp = new ComponentName(aInfo.packageName, className); 11010 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11011 + " requests FLAG_SINGLE_USER, but app does not hold " 11012 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11013 Slog.w(TAG, msg); 11014 throw new SecurityException(msg); 11015 } 11016 result = true; 11017 } 11018 } else if (componentProcessName == aInfo.packageName) { 11019 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11020 } else if ("system".equals(componentProcessName)) { 11021 result = true; 11022 } 11023 if (DEBUG_MU) { 11024 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11025 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11026 } 11027 return result; 11028 } 11029 11030 public int bindService(IApplicationThread caller, IBinder token, 11031 Intent service, String resolvedType, 11032 IServiceConnection connection, int flags, int userId) { 11033 enforceNotIsolatedCaller("bindService"); 11034 // Refuse possible leaked file descriptors 11035 if (service != null && service.hasFileDescriptors() == true) { 11036 throw new IllegalArgumentException("File descriptors passed in Intent"); 11037 } 11038 11039 synchronized(this) { 11040 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11041 connection, flags, userId); 11042 } 11043 } 11044 11045 public boolean unbindService(IServiceConnection connection) { 11046 synchronized (this) { 11047 return mServices.unbindServiceLocked(connection); 11048 } 11049 } 11050 11051 public void publishService(IBinder token, Intent intent, IBinder service) { 11052 // Refuse possible leaked file descriptors 11053 if (intent != null && intent.hasFileDescriptors() == true) { 11054 throw new IllegalArgumentException("File descriptors passed in Intent"); 11055 } 11056 11057 synchronized(this) { 11058 if (!(token instanceof ServiceRecord)) { 11059 throw new IllegalArgumentException("Invalid service token"); 11060 } 11061 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11062 } 11063 } 11064 11065 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11066 // Refuse possible leaked file descriptors 11067 if (intent != null && intent.hasFileDescriptors() == true) { 11068 throw new IllegalArgumentException("File descriptors passed in Intent"); 11069 } 11070 11071 synchronized(this) { 11072 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11073 } 11074 } 11075 11076 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11077 synchronized(this) { 11078 if (!(token instanceof ServiceRecord)) { 11079 throw new IllegalArgumentException("Invalid service token"); 11080 } 11081 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11082 } 11083 } 11084 11085 // ========================================================= 11086 // BACKUP AND RESTORE 11087 // ========================================================= 11088 11089 // Cause the target app to be launched if necessary and its backup agent 11090 // instantiated. The backup agent will invoke backupAgentCreated() on the 11091 // activity manager to announce its creation. 11092 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11093 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11094 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11095 11096 synchronized(this) { 11097 // !!! TODO: currently no check here that we're already bound 11098 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11099 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11100 synchronized (stats) { 11101 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11102 } 11103 11104 // Backup agent is now in use, its package can't be stopped. 11105 try { 11106 AppGlobals.getPackageManager().setPackageStoppedState( 11107 app.packageName, false, UserHandle.getUserId(app.uid)); 11108 } catch (RemoteException e) { 11109 } catch (IllegalArgumentException e) { 11110 Slog.w(TAG, "Failed trying to unstop package " 11111 + app.packageName + ": " + e); 11112 } 11113 11114 BackupRecord r = new BackupRecord(ss, app, backupMode); 11115 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11116 ? new ComponentName(app.packageName, app.backupAgentName) 11117 : new ComponentName("android", "FullBackupAgent"); 11118 // startProcessLocked() returns existing proc's record if it's already running 11119 ProcessRecord proc = startProcessLocked(app.processName, app, 11120 false, 0, "backup", hostingName, false, false); 11121 if (proc == null) { 11122 Slog.e(TAG, "Unable to start backup agent process " + r); 11123 return false; 11124 } 11125 11126 r.app = proc; 11127 mBackupTarget = r; 11128 mBackupAppName = app.packageName; 11129 11130 // Try not to kill the process during backup 11131 updateOomAdjLocked(proc); 11132 11133 // If the process is already attached, schedule the creation of the backup agent now. 11134 // If it is not yet live, this will be done when it attaches to the framework. 11135 if (proc.thread != null) { 11136 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11137 try { 11138 proc.thread.scheduleCreateBackupAgent(app, 11139 compatibilityInfoForPackageLocked(app), backupMode); 11140 } catch (RemoteException e) { 11141 // Will time out on the backup manager side 11142 } 11143 } else { 11144 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11145 } 11146 // Invariants: at this point, the target app process exists and the application 11147 // is either already running or in the process of coming up. mBackupTarget and 11148 // mBackupAppName describe the app, so that when it binds back to the AM we 11149 // know that it's scheduled for a backup-agent operation. 11150 } 11151 11152 return true; 11153 } 11154 11155 // A backup agent has just come up 11156 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11157 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11158 + " = " + agent); 11159 11160 synchronized(this) { 11161 if (!agentPackageName.equals(mBackupAppName)) { 11162 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11163 return; 11164 } 11165 } 11166 11167 long oldIdent = Binder.clearCallingIdentity(); 11168 try { 11169 IBackupManager bm = IBackupManager.Stub.asInterface( 11170 ServiceManager.getService(Context.BACKUP_SERVICE)); 11171 bm.agentConnected(agentPackageName, agent); 11172 } catch (RemoteException e) { 11173 // can't happen; the backup manager service is local 11174 } catch (Exception e) { 11175 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11176 e.printStackTrace(); 11177 } finally { 11178 Binder.restoreCallingIdentity(oldIdent); 11179 } 11180 } 11181 11182 // done with this agent 11183 public void unbindBackupAgent(ApplicationInfo appInfo) { 11184 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11185 if (appInfo == null) { 11186 Slog.w(TAG, "unbind backup agent for null app"); 11187 return; 11188 } 11189 11190 synchronized(this) { 11191 if (mBackupAppName == null) { 11192 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11193 return; 11194 } 11195 11196 if (!mBackupAppName.equals(appInfo.packageName)) { 11197 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11198 return; 11199 } 11200 11201 ProcessRecord proc = mBackupTarget.app; 11202 mBackupTarget = null; 11203 mBackupAppName = null; 11204 11205 // Not backing this app up any more; reset its OOM adjustment 11206 updateOomAdjLocked(proc); 11207 11208 // If the app crashed during backup, 'thread' will be null here 11209 if (proc.thread != null) { 11210 try { 11211 proc.thread.scheduleDestroyBackupAgent(appInfo, 11212 compatibilityInfoForPackageLocked(appInfo)); 11213 } catch (Exception e) { 11214 Slog.e(TAG, "Exception when unbinding backup agent:"); 11215 e.printStackTrace(); 11216 } 11217 } 11218 } 11219 } 11220 // ========================================================= 11221 // BROADCASTS 11222 // ========================================================= 11223 11224 private final List getStickiesLocked(String action, IntentFilter filter, 11225 List cur, int userId) { 11226 final ContentResolver resolver = mContext.getContentResolver(); 11227 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11228 if (stickies == null) { 11229 return cur; 11230 } 11231 final ArrayList<Intent> list = stickies.get(action); 11232 if (list == null) { 11233 return cur; 11234 } 11235 int N = list.size(); 11236 for (int i=0; i<N; i++) { 11237 Intent intent = list.get(i); 11238 if (filter.match(resolver, intent, true, TAG) >= 0) { 11239 if (cur == null) { 11240 cur = new ArrayList<Intent>(); 11241 } 11242 cur.add(intent); 11243 } 11244 } 11245 return cur; 11246 } 11247 11248 boolean isPendingBroadcastProcessLocked(int pid) { 11249 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11250 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11251 } 11252 11253 void skipPendingBroadcastLocked(int pid) { 11254 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11255 for (BroadcastQueue queue : mBroadcastQueues) { 11256 queue.skipPendingBroadcastLocked(pid); 11257 } 11258 } 11259 11260 // The app just attached; send any pending broadcasts that it should receive 11261 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11262 boolean didSomething = false; 11263 for (BroadcastQueue queue : mBroadcastQueues) { 11264 didSomething |= queue.sendPendingBroadcastsLocked(app); 11265 } 11266 return didSomething; 11267 } 11268 11269 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11270 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11271 enforceNotIsolatedCaller("registerReceiver"); 11272 int callingUid; 11273 int callingPid; 11274 synchronized(this) { 11275 ProcessRecord callerApp = null; 11276 if (caller != null) { 11277 callerApp = getRecordForAppLocked(caller); 11278 if (callerApp == null) { 11279 throw new SecurityException( 11280 "Unable to find app for caller " + caller 11281 + " (pid=" + Binder.getCallingPid() 11282 + ") when registering receiver " + receiver); 11283 } 11284 if (callerApp.info.uid != Process.SYSTEM_UID && 11285 !callerApp.pkgList.contains(callerPackage)) { 11286 throw new SecurityException("Given caller package " + callerPackage 11287 + " is not running in process " + callerApp); 11288 } 11289 callingUid = callerApp.info.uid; 11290 callingPid = callerApp.pid; 11291 } else { 11292 callerPackage = null; 11293 callingUid = Binder.getCallingUid(); 11294 callingPid = Binder.getCallingPid(); 11295 } 11296 11297 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11298 true, true, "registerReceiver", callerPackage); 11299 11300 List allSticky = null; 11301 11302 // Look for any matching sticky broadcasts... 11303 Iterator actions = filter.actionsIterator(); 11304 if (actions != null) { 11305 while (actions.hasNext()) { 11306 String action = (String)actions.next(); 11307 allSticky = getStickiesLocked(action, filter, allSticky, 11308 UserHandle.USER_ALL); 11309 allSticky = getStickiesLocked(action, filter, allSticky, 11310 UserHandle.getUserId(callingUid)); 11311 } 11312 } else { 11313 allSticky = getStickiesLocked(null, filter, allSticky, 11314 UserHandle.USER_ALL); 11315 allSticky = getStickiesLocked(null, filter, allSticky, 11316 UserHandle.getUserId(callingUid)); 11317 } 11318 11319 // The first sticky in the list is returned directly back to 11320 // the client. 11321 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11322 11323 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11324 + ": " + sticky); 11325 11326 if (receiver == null) { 11327 return sticky; 11328 } 11329 11330 ReceiverList rl 11331 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11332 if (rl == null) { 11333 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11334 userId, receiver); 11335 if (rl.app != null) { 11336 rl.app.receivers.add(rl); 11337 } else { 11338 try { 11339 receiver.asBinder().linkToDeath(rl, 0); 11340 } catch (RemoteException e) { 11341 return sticky; 11342 } 11343 rl.linkedToDeath = true; 11344 } 11345 mRegisteredReceivers.put(receiver.asBinder(), rl); 11346 } else if (rl.uid != callingUid) { 11347 throw new IllegalArgumentException( 11348 "Receiver requested to register for uid " + callingUid 11349 + " was previously registered for uid " + rl.uid); 11350 } else if (rl.pid != callingPid) { 11351 throw new IllegalArgumentException( 11352 "Receiver requested to register for pid " + callingPid 11353 + " was previously registered for pid " + rl.pid); 11354 } else if (rl.userId != userId) { 11355 throw new IllegalArgumentException( 11356 "Receiver requested to register for user " + userId 11357 + " was previously registered for user " + rl.userId); 11358 } 11359 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11360 permission, callingUid, userId); 11361 rl.add(bf); 11362 if (!bf.debugCheck()) { 11363 Slog.w(TAG, "==> For Dynamic broadast"); 11364 } 11365 mReceiverResolver.addFilter(bf); 11366 11367 // Enqueue broadcasts for all existing stickies that match 11368 // this filter. 11369 if (allSticky != null) { 11370 ArrayList receivers = new ArrayList(); 11371 receivers.add(bf); 11372 11373 int N = allSticky.size(); 11374 for (int i=0; i<N; i++) { 11375 Intent intent = (Intent)allSticky.get(i); 11376 BroadcastQueue queue = broadcastQueueForIntent(intent); 11377 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11378 null, -1, -1, null, receivers, null, 0, null, null, 11379 false, true, true, -1); 11380 queue.enqueueParallelBroadcastLocked(r); 11381 queue.scheduleBroadcastsLocked(); 11382 } 11383 } 11384 11385 return sticky; 11386 } 11387 } 11388 11389 public void unregisterReceiver(IIntentReceiver receiver) { 11390 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11391 11392 final long origId = Binder.clearCallingIdentity(); 11393 try { 11394 boolean doTrim = false; 11395 11396 synchronized(this) { 11397 ReceiverList rl 11398 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11399 if (rl != null) { 11400 if (rl.curBroadcast != null) { 11401 BroadcastRecord r = rl.curBroadcast; 11402 final boolean doNext = finishReceiverLocked( 11403 receiver.asBinder(), r.resultCode, r.resultData, 11404 r.resultExtras, r.resultAbort, true); 11405 if (doNext) { 11406 doTrim = true; 11407 r.queue.processNextBroadcast(false); 11408 } 11409 } 11410 11411 if (rl.app != null) { 11412 rl.app.receivers.remove(rl); 11413 } 11414 removeReceiverLocked(rl); 11415 if (rl.linkedToDeath) { 11416 rl.linkedToDeath = false; 11417 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11418 } 11419 } 11420 } 11421 11422 // If we actually concluded any broadcasts, we might now be able 11423 // to trim the recipients' apps from our working set 11424 if (doTrim) { 11425 trimApplications(); 11426 return; 11427 } 11428 11429 } finally { 11430 Binder.restoreCallingIdentity(origId); 11431 } 11432 } 11433 11434 void removeReceiverLocked(ReceiverList rl) { 11435 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11436 int N = rl.size(); 11437 for (int i=0; i<N; i++) { 11438 mReceiverResolver.removeFilter(rl.get(i)); 11439 } 11440 } 11441 11442 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11443 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11444 ProcessRecord r = mLruProcesses.get(i); 11445 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11446 try { 11447 r.thread.dispatchPackageBroadcast(cmd, packages); 11448 } catch (RemoteException ex) { 11449 } 11450 } 11451 } 11452 } 11453 11454 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11455 int[] users) { 11456 List<ResolveInfo> receivers = null; 11457 try { 11458 HashSet<ComponentName> singleUserReceivers = null; 11459 boolean scannedFirstReceivers = false; 11460 for (int user : users) { 11461 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11462 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11463 if (user != 0 && newReceivers != null) { 11464 // If this is not the primary user, we need to check for 11465 // any receivers that should be filtered out. 11466 for (int i=0; i<newReceivers.size(); i++) { 11467 ResolveInfo ri = newReceivers.get(i); 11468 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11469 newReceivers.remove(i); 11470 i--; 11471 } 11472 } 11473 } 11474 if (newReceivers != null && newReceivers.size() == 0) { 11475 newReceivers = null; 11476 } 11477 if (receivers == null) { 11478 receivers = newReceivers; 11479 } else if (newReceivers != null) { 11480 // We need to concatenate the additional receivers 11481 // found with what we have do far. This would be easy, 11482 // but we also need to de-dup any receivers that are 11483 // singleUser. 11484 if (!scannedFirstReceivers) { 11485 // Collect any single user receivers we had already retrieved. 11486 scannedFirstReceivers = true; 11487 for (int i=0; i<receivers.size(); i++) { 11488 ResolveInfo ri = receivers.get(i); 11489 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11490 ComponentName cn = new ComponentName( 11491 ri.activityInfo.packageName, ri.activityInfo.name); 11492 if (singleUserReceivers == null) { 11493 singleUserReceivers = new HashSet<ComponentName>(); 11494 } 11495 singleUserReceivers.add(cn); 11496 } 11497 } 11498 } 11499 // Add the new results to the existing results, tracking 11500 // and de-dupping single user receivers. 11501 for (int i=0; i<newReceivers.size(); i++) { 11502 ResolveInfo ri = newReceivers.get(i); 11503 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11504 ComponentName cn = new ComponentName( 11505 ri.activityInfo.packageName, ri.activityInfo.name); 11506 if (singleUserReceivers == null) { 11507 singleUserReceivers = new HashSet<ComponentName>(); 11508 } 11509 if (!singleUserReceivers.contains(cn)) { 11510 singleUserReceivers.add(cn); 11511 receivers.add(ri); 11512 } 11513 } else { 11514 receivers.add(ri); 11515 } 11516 } 11517 } 11518 } 11519 } catch (RemoteException ex) { 11520 // pm is in same process, this will never happen. 11521 } 11522 return receivers; 11523 } 11524 11525 private final int broadcastIntentLocked(ProcessRecord callerApp, 11526 String callerPackage, Intent intent, String resolvedType, 11527 IIntentReceiver resultTo, int resultCode, String resultData, 11528 Bundle map, String requiredPermission, 11529 boolean ordered, boolean sticky, int callingPid, int callingUid, 11530 int userId) { 11531 intent = new Intent(intent); 11532 11533 // By default broadcasts do not go to stopped apps. 11534 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11535 11536 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11537 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11538 + " ordered=" + ordered + " userid=" + userId); 11539 if ((resultTo != null) && !ordered) { 11540 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11541 } 11542 11543 userId = handleIncomingUser(callingPid, callingUid, userId, 11544 true, false, "broadcast", callerPackage); 11545 11546 // Make sure that the user who is receiving this broadcast is started. 11547 // If not, we will just skip it. 11548 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11549 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11550 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11551 Slog.w(TAG, "Skipping broadcast of " + intent 11552 + ": user " + userId + " is stopped"); 11553 return ActivityManager.BROADCAST_SUCCESS; 11554 } 11555 } 11556 11557 /* 11558 * Prevent non-system code (defined here to be non-persistent 11559 * processes) from sending protected broadcasts. 11560 */ 11561 int callingAppId = UserHandle.getAppId(callingUid); 11562 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11563 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11564 callingUid == 0) { 11565 // Always okay. 11566 } else if (callerApp == null || !callerApp.persistent) { 11567 try { 11568 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11569 intent.getAction())) { 11570 String msg = "Permission Denial: not allowed to send broadcast " 11571 + intent.getAction() + " from pid=" 11572 + callingPid + ", uid=" + callingUid; 11573 Slog.w(TAG, msg); 11574 throw new SecurityException(msg); 11575 } 11576 } catch (RemoteException e) { 11577 Slog.w(TAG, "Remote exception", e); 11578 return ActivityManager.BROADCAST_SUCCESS; 11579 } 11580 } 11581 11582 // Handle special intents: if this broadcast is from the package 11583 // manager about a package being removed, we need to remove all of 11584 // its activities from the history stack. 11585 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11586 intent.getAction()); 11587 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11588 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11589 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11590 || uidRemoved) { 11591 if (checkComponentPermission( 11592 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11593 callingPid, callingUid, -1, true) 11594 == PackageManager.PERMISSION_GRANTED) { 11595 if (uidRemoved) { 11596 final Bundle intentExtras = intent.getExtras(); 11597 final int uid = intentExtras != null 11598 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11599 if (uid >= 0) { 11600 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11601 synchronized (bs) { 11602 bs.removeUidStatsLocked(uid); 11603 } 11604 } 11605 } else { 11606 // If resources are unavailable just force stop all 11607 // those packages and flush the attribute cache as well. 11608 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11609 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11610 if (list != null && (list.length > 0)) { 11611 for (String pkg : list) { 11612 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11613 } 11614 sendPackageBroadcastLocked( 11615 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11616 } 11617 } else { 11618 Uri data = intent.getData(); 11619 String ssp; 11620 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11621 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11622 forceStopPackageLocked(ssp, 11623 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11624 false, userId); 11625 } 11626 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11627 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11628 new String[] {ssp}, userId); 11629 } 11630 } 11631 } 11632 } 11633 } else { 11634 String msg = "Permission Denial: " + intent.getAction() 11635 + " broadcast from " + callerPackage + " (pid=" + callingPid 11636 + ", uid=" + callingUid + ")" 11637 + " requires " 11638 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11639 Slog.w(TAG, msg); 11640 throw new SecurityException(msg); 11641 } 11642 11643 // Special case for adding a package: by default turn on compatibility 11644 // mode. 11645 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11646 Uri data = intent.getData(); 11647 String ssp; 11648 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11649 mCompatModePackages.handlePackageAddedLocked(ssp, 11650 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11651 } 11652 } 11653 11654 /* 11655 * If this is the time zone changed action, queue up a message that will reset the timezone 11656 * of all currently running processes. This message will get queued up before the broadcast 11657 * happens. 11658 */ 11659 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11660 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11661 } 11662 11663 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11664 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11665 } 11666 11667 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11668 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11669 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11670 } 11671 11672 // Add to the sticky list if requested. 11673 if (sticky) { 11674 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11675 callingPid, callingUid) 11676 != PackageManager.PERMISSION_GRANTED) { 11677 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11678 + callingPid + ", uid=" + callingUid 11679 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11680 Slog.w(TAG, msg); 11681 throw new SecurityException(msg); 11682 } 11683 if (requiredPermission != null) { 11684 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11685 + " and enforce permission " + requiredPermission); 11686 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11687 } 11688 if (intent.getComponent() != null) { 11689 throw new SecurityException( 11690 "Sticky broadcasts can't target a specific component"); 11691 } 11692 // We use userId directly here, since the "all" target is maintained 11693 // as a separate set of sticky broadcasts. 11694 if (userId != UserHandle.USER_ALL) { 11695 // But first, if this is not a broadcast to all users, then 11696 // make sure it doesn't conflict with an existing broadcast to 11697 // all users. 11698 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11699 UserHandle.USER_ALL); 11700 if (stickies != null) { 11701 ArrayList<Intent> list = stickies.get(intent.getAction()); 11702 if (list != null) { 11703 int N = list.size(); 11704 int i; 11705 for (i=0; i<N; i++) { 11706 if (intent.filterEquals(list.get(i))) { 11707 throw new IllegalArgumentException( 11708 "Sticky broadcast " + intent + " for user " 11709 + userId + " conflicts with existing global broadcast"); 11710 } 11711 } 11712 } 11713 } 11714 } 11715 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11716 if (stickies == null) { 11717 stickies = new HashMap<String, ArrayList<Intent>>(); 11718 mStickyBroadcasts.put(userId, stickies); 11719 } 11720 ArrayList<Intent> list = stickies.get(intent.getAction()); 11721 if (list == null) { 11722 list = new ArrayList<Intent>(); 11723 stickies.put(intent.getAction(), list); 11724 } 11725 int N = list.size(); 11726 int i; 11727 for (i=0; i<N; i++) { 11728 if (intent.filterEquals(list.get(i))) { 11729 // This sticky already exists, replace it. 11730 list.set(i, new Intent(intent)); 11731 break; 11732 } 11733 } 11734 if (i >= N) { 11735 list.add(new Intent(intent)); 11736 } 11737 } 11738 11739 int[] users; 11740 if (userId == UserHandle.USER_ALL) { 11741 // Caller wants broadcast to go to all started users. 11742 users = mStartedUserArray; 11743 } else { 11744 // Caller wants broadcast to go to one specific user. 11745 users = new int[] {userId}; 11746 } 11747 11748 // Figure out who all will receive this broadcast. 11749 List receivers = null; 11750 List<BroadcastFilter> registeredReceivers = null; 11751 // Need to resolve the intent to interested receivers... 11752 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11753 == 0) { 11754 receivers = collectReceiverComponents(intent, resolvedType, users); 11755 } 11756 if (intent.getComponent() == null) { 11757 registeredReceivers = mReceiverResolver.queryIntent(intent, 11758 resolvedType, false, userId); 11759 } 11760 11761 final boolean replacePending = 11762 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11763 11764 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11765 + " replacePending=" + replacePending); 11766 11767 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11768 if (!ordered && NR > 0) { 11769 // If we are not serializing this broadcast, then send the 11770 // registered receivers separately so they don't wait for the 11771 // components to be launched. 11772 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11773 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11774 callerPackage, callingPid, callingUid, requiredPermission, 11775 registeredReceivers, resultTo, resultCode, resultData, map, 11776 ordered, sticky, false, userId); 11777 if (DEBUG_BROADCAST) Slog.v( 11778 TAG, "Enqueueing parallel broadcast " + r); 11779 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11780 if (!replaced) { 11781 queue.enqueueParallelBroadcastLocked(r); 11782 queue.scheduleBroadcastsLocked(); 11783 } 11784 registeredReceivers = null; 11785 NR = 0; 11786 } 11787 11788 // Merge into one list. 11789 int ir = 0; 11790 if (receivers != null) { 11791 // A special case for PACKAGE_ADDED: do not allow the package 11792 // being added to see this broadcast. This prevents them from 11793 // using this as a back door to get run as soon as they are 11794 // installed. Maybe in the future we want to have a special install 11795 // broadcast or such for apps, but we'd like to deliberately make 11796 // this decision. 11797 String skipPackages[] = null; 11798 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11799 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11800 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11801 Uri data = intent.getData(); 11802 if (data != null) { 11803 String pkgName = data.getSchemeSpecificPart(); 11804 if (pkgName != null) { 11805 skipPackages = new String[] { pkgName }; 11806 } 11807 } 11808 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11809 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11810 } 11811 if (skipPackages != null && (skipPackages.length > 0)) { 11812 for (String skipPackage : skipPackages) { 11813 if (skipPackage != null) { 11814 int NT = receivers.size(); 11815 for (int it=0; it<NT; it++) { 11816 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11817 if (curt.activityInfo.packageName.equals(skipPackage)) { 11818 receivers.remove(it); 11819 it--; 11820 NT--; 11821 } 11822 } 11823 } 11824 } 11825 } 11826 11827 int NT = receivers != null ? receivers.size() : 0; 11828 int it = 0; 11829 ResolveInfo curt = null; 11830 BroadcastFilter curr = null; 11831 while (it < NT && ir < NR) { 11832 if (curt == null) { 11833 curt = (ResolveInfo)receivers.get(it); 11834 } 11835 if (curr == null) { 11836 curr = registeredReceivers.get(ir); 11837 } 11838 if (curr.getPriority() >= curt.priority) { 11839 // Insert this broadcast record into the final list. 11840 receivers.add(it, curr); 11841 ir++; 11842 curr = null; 11843 it++; 11844 NT++; 11845 } else { 11846 // Skip to the next ResolveInfo in the final list. 11847 it++; 11848 curt = null; 11849 } 11850 } 11851 } 11852 while (ir < NR) { 11853 if (receivers == null) { 11854 receivers = new ArrayList(); 11855 } 11856 receivers.add(registeredReceivers.get(ir)); 11857 ir++; 11858 } 11859 11860 if ((receivers != null && receivers.size() > 0) 11861 || resultTo != null) { 11862 BroadcastQueue queue = broadcastQueueForIntent(intent); 11863 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11864 callerPackage, callingPid, callingUid, requiredPermission, 11865 receivers, resultTo, resultCode, resultData, map, ordered, 11866 sticky, false, userId); 11867 if (DEBUG_BROADCAST) Slog.v( 11868 TAG, "Enqueueing ordered broadcast " + r 11869 + ": prev had " + queue.mOrderedBroadcasts.size()); 11870 if (DEBUG_BROADCAST) { 11871 int seq = r.intent.getIntExtra("seq", -1); 11872 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11873 } 11874 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11875 if (!replaced) { 11876 queue.enqueueOrderedBroadcastLocked(r); 11877 queue.scheduleBroadcastsLocked(); 11878 } 11879 } 11880 11881 return ActivityManager.BROADCAST_SUCCESS; 11882 } 11883 11884 final Intent verifyBroadcastLocked(Intent intent) { 11885 // Refuse possible leaked file descriptors 11886 if (intent != null && intent.hasFileDescriptors() == true) { 11887 throw new IllegalArgumentException("File descriptors passed in Intent"); 11888 } 11889 11890 int flags = intent.getFlags(); 11891 11892 if (!mProcessesReady) { 11893 // if the caller really truly claims to know what they're doing, go 11894 // ahead and allow the broadcast without launching any receivers 11895 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11896 intent = new Intent(intent); 11897 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11898 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11899 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11900 + " before boot completion"); 11901 throw new IllegalStateException("Cannot broadcast before boot completed"); 11902 } 11903 } 11904 11905 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11906 throw new IllegalArgumentException( 11907 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11908 } 11909 11910 return intent; 11911 } 11912 11913 public final int broadcastIntent(IApplicationThread caller, 11914 Intent intent, String resolvedType, IIntentReceiver resultTo, 11915 int resultCode, String resultData, Bundle map, 11916 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11917 enforceNotIsolatedCaller("broadcastIntent"); 11918 synchronized(this) { 11919 intent = verifyBroadcastLocked(intent); 11920 11921 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11922 final int callingPid = Binder.getCallingPid(); 11923 final int callingUid = Binder.getCallingUid(); 11924 final long origId = Binder.clearCallingIdentity(); 11925 int res = broadcastIntentLocked(callerApp, 11926 callerApp != null ? callerApp.info.packageName : null, 11927 intent, resolvedType, resultTo, 11928 resultCode, resultData, map, requiredPermission, serialized, sticky, 11929 callingPid, callingUid, userId); 11930 Binder.restoreCallingIdentity(origId); 11931 return res; 11932 } 11933 } 11934 11935 int broadcastIntentInPackage(String packageName, int uid, 11936 Intent intent, String resolvedType, IIntentReceiver resultTo, 11937 int resultCode, String resultData, Bundle map, 11938 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11939 synchronized(this) { 11940 intent = verifyBroadcastLocked(intent); 11941 11942 final long origId = Binder.clearCallingIdentity(); 11943 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11944 resultTo, resultCode, resultData, map, requiredPermission, 11945 serialized, sticky, -1, uid, userId); 11946 Binder.restoreCallingIdentity(origId); 11947 return res; 11948 } 11949 } 11950 11951 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11952 // Refuse possible leaked file descriptors 11953 if (intent != null && intent.hasFileDescriptors() == true) { 11954 throw new IllegalArgumentException("File descriptors passed in Intent"); 11955 } 11956 11957 userId = handleIncomingUser(Binder.getCallingPid(), 11958 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11959 11960 synchronized(this) { 11961 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11962 != PackageManager.PERMISSION_GRANTED) { 11963 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11964 + Binder.getCallingPid() 11965 + ", uid=" + Binder.getCallingUid() 11966 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11967 Slog.w(TAG, msg); 11968 throw new SecurityException(msg); 11969 } 11970 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11971 if (stickies != null) { 11972 ArrayList<Intent> list = stickies.get(intent.getAction()); 11973 if (list != null) { 11974 int N = list.size(); 11975 int i; 11976 for (i=0; i<N; i++) { 11977 if (intent.filterEquals(list.get(i))) { 11978 list.remove(i); 11979 break; 11980 } 11981 } 11982 if (list.size() <= 0) { 11983 stickies.remove(intent.getAction()); 11984 } 11985 } 11986 if (stickies.size() <= 0) { 11987 mStickyBroadcasts.remove(userId); 11988 } 11989 } 11990 } 11991 } 11992 11993 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11994 String resultData, Bundle resultExtras, boolean resultAbort, 11995 boolean explicit) { 11996 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11997 if (r == null) { 11998 Slog.w(TAG, "finishReceiver called but not found on queue"); 11999 return false; 12000 } 12001 12002 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12003 explicit); 12004 } 12005 12006 public void finishReceiver(IBinder who, int resultCode, String resultData, 12007 Bundle resultExtras, boolean resultAbort) { 12008 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12009 12010 // Refuse possible leaked file descriptors 12011 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12012 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12013 } 12014 12015 final long origId = Binder.clearCallingIdentity(); 12016 try { 12017 boolean doNext = false; 12018 BroadcastRecord r = null; 12019 12020 synchronized(this) { 12021 r = broadcastRecordForReceiverLocked(who); 12022 if (r != null) { 12023 doNext = r.queue.finishReceiverLocked(r, resultCode, 12024 resultData, resultExtras, resultAbort, true); 12025 } 12026 } 12027 12028 if (doNext) { 12029 r.queue.processNextBroadcast(false); 12030 } 12031 trimApplications(); 12032 } finally { 12033 Binder.restoreCallingIdentity(origId); 12034 } 12035 } 12036 12037 // ========================================================= 12038 // INSTRUMENTATION 12039 // ========================================================= 12040 12041 public boolean startInstrumentation(ComponentName className, 12042 String profileFile, int flags, Bundle arguments, 12043 IInstrumentationWatcher watcher, int userId) { 12044 enforceNotIsolatedCaller("startInstrumentation"); 12045 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12046 userId, false, true, "startInstrumentation", null); 12047 // Refuse possible leaked file descriptors 12048 if (arguments != null && arguments.hasFileDescriptors()) { 12049 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12050 } 12051 12052 synchronized(this) { 12053 InstrumentationInfo ii = null; 12054 ApplicationInfo ai = null; 12055 try { 12056 ii = mContext.getPackageManager().getInstrumentationInfo( 12057 className, STOCK_PM_FLAGS); 12058 ai = AppGlobals.getPackageManager().getApplicationInfo( 12059 ii.targetPackage, STOCK_PM_FLAGS, userId); 12060 } catch (PackageManager.NameNotFoundException e) { 12061 } catch (RemoteException e) { 12062 } 12063 if (ii == null) { 12064 reportStartInstrumentationFailure(watcher, className, 12065 "Unable to find instrumentation info for: " + className); 12066 return false; 12067 } 12068 if (ai == null) { 12069 reportStartInstrumentationFailure(watcher, className, 12070 "Unable to find instrumentation target package: " + ii.targetPackage); 12071 return false; 12072 } 12073 12074 int match = mContext.getPackageManager().checkSignatures( 12075 ii.targetPackage, ii.packageName); 12076 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12077 String msg = "Permission Denial: starting instrumentation " 12078 + className + " from pid=" 12079 + Binder.getCallingPid() 12080 + ", uid=" + Binder.getCallingPid() 12081 + " not allowed because package " + ii.packageName 12082 + " does not have a signature matching the target " 12083 + ii.targetPackage; 12084 reportStartInstrumentationFailure(watcher, className, msg); 12085 throw new SecurityException(msg); 12086 } 12087 12088 final long origId = Binder.clearCallingIdentity(); 12089 // Instrumentation can kill and relaunch even persistent processes 12090 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12091 ProcessRecord app = addAppLocked(ai, false); 12092 app.instrumentationClass = className; 12093 app.instrumentationInfo = ai; 12094 app.instrumentationProfileFile = profileFile; 12095 app.instrumentationArguments = arguments; 12096 app.instrumentationWatcher = watcher; 12097 app.instrumentationResultClass = className; 12098 Binder.restoreCallingIdentity(origId); 12099 } 12100 12101 return true; 12102 } 12103 12104 /** 12105 * Report errors that occur while attempting to start Instrumentation. Always writes the 12106 * error to the logs, but if somebody is watching, send the report there too. This enables 12107 * the "am" command to report errors with more information. 12108 * 12109 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12110 * @param cn The component name of the instrumentation. 12111 * @param report The error report. 12112 */ 12113 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12114 ComponentName cn, String report) { 12115 Slog.w(TAG, report); 12116 try { 12117 if (watcher != null) { 12118 Bundle results = new Bundle(); 12119 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12120 results.putString("Error", report); 12121 watcher.instrumentationStatus(cn, -1, results); 12122 } 12123 } catch (RemoteException e) { 12124 Slog.w(TAG, e); 12125 } 12126 } 12127 12128 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12129 if (app.instrumentationWatcher != null) { 12130 try { 12131 // NOTE: IInstrumentationWatcher *must* be oneway here 12132 app.instrumentationWatcher.instrumentationFinished( 12133 app.instrumentationClass, 12134 resultCode, 12135 results); 12136 } catch (RemoteException e) { 12137 } 12138 } 12139 app.instrumentationWatcher = null; 12140 app.instrumentationClass = null; 12141 app.instrumentationInfo = null; 12142 app.instrumentationProfileFile = null; 12143 app.instrumentationArguments = null; 12144 12145 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12146 } 12147 12148 public void finishInstrumentation(IApplicationThread target, 12149 int resultCode, Bundle results) { 12150 int userId = UserHandle.getCallingUserId(); 12151 // Refuse possible leaked file descriptors 12152 if (results != null && results.hasFileDescriptors()) { 12153 throw new IllegalArgumentException("File descriptors passed in Intent"); 12154 } 12155 12156 synchronized(this) { 12157 ProcessRecord app = getRecordForAppLocked(target); 12158 if (app == null) { 12159 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12160 return; 12161 } 12162 final long origId = Binder.clearCallingIdentity(); 12163 finishInstrumentationLocked(app, resultCode, results); 12164 Binder.restoreCallingIdentity(origId); 12165 } 12166 } 12167 12168 // ========================================================= 12169 // CONFIGURATION 12170 // ========================================================= 12171 12172 public ConfigurationInfo getDeviceConfigurationInfo() { 12173 ConfigurationInfo config = new ConfigurationInfo(); 12174 synchronized (this) { 12175 config.reqTouchScreen = mConfiguration.touchscreen; 12176 config.reqKeyboardType = mConfiguration.keyboard; 12177 config.reqNavigation = mConfiguration.navigation; 12178 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12179 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12180 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12181 } 12182 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12183 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12184 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12185 } 12186 config.reqGlEsVersion = GL_ES_VERSION; 12187 } 12188 return config; 12189 } 12190 12191 public Configuration getConfiguration() { 12192 Configuration ci; 12193 synchronized(this) { 12194 ci = new Configuration(mConfiguration); 12195 } 12196 return ci; 12197 } 12198 12199 public void updatePersistentConfiguration(Configuration values) { 12200 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12201 "updateConfiguration()"); 12202 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12203 "updateConfiguration()"); 12204 if (values == null) { 12205 throw new NullPointerException("Configuration must not be null"); 12206 } 12207 12208 synchronized(this) { 12209 final long origId = Binder.clearCallingIdentity(); 12210 updateConfigurationLocked(values, null, true, false); 12211 Binder.restoreCallingIdentity(origId); 12212 } 12213 } 12214 12215 public void updateConfiguration(Configuration values) { 12216 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12217 "updateConfiguration()"); 12218 12219 synchronized(this) { 12220 if (values == null && mWindowManager != null) { 12221 // sentinel: fetch the current configuration from the window manager 12222 values = mWindowManager.computeNewConfiguration(); 12223 } 12224 12225 if (mWindowManager != null) { 12226 mProcessList.applyDisplaySize(mWindowManager); 12227 } 12228 12229 final long origId = Binder.clearCallingIdentity(); 12230 if (values != null) { 12231 Settings.System.clearConfiguration(values); 12232 } 12233 updateConfigurationLocked(values, null, false, false); 12234 Binder.restoreCallingIdentity(origId); 12235 } 12236 } 12237 12238 /** 12239 * Do either or both things: (1) change the current configuration, and (2) 12240 * make sure the given activity is running with the (now) current 12241 * configuration. Returns true if the activity has been left running, or 12242 * false if <var>starting</var> is being destroyed to match the new 12243 * configuration. 12244 * @param persistent TODO 12245 */ 12246 boolean updateConfigurationLocked(Configuration values, 12247 ActivityRecord starting, boolean persistent, boolean initLocale) { 12248 // do nothing if we are headless 12249 if (mHeadless) return true; 12250 12251 int changes = 0; 12252 12253 boolean kept = true; 12254 12255 if (values != null) { 12256 Configuration newConfig = new Configuration(mConfiguration); 12257 changes = newConfig.updateFrom(values); 12258 if (changes != 0) { 12259 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12260 Slog.i(TAG, "Updating configuration to: " + values); 12261 } 12262 12263 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12264 12265 if (values.locale != null && !initLocale) { 12266 saveLocaleLocked(values.locale, 12267 !values.locale.equals(mConfiguration.locale), 12268 values.userSetLocale); 12269 } 12270 12271 mConfigurationSeq++; 12272 if (mConfigurationSeq <= 0) { 12273 mConfigurationSeq = 1; 12274 } 12275 newConfig.seq = mConfigurationSeq; 12276 mConfiguration = newConfig; 12277 Slog.i(TAG, "Config changed: " + newConfig); 12278 12279 final Configuration configCopy = new Configuration(mConfiguration); 12280 12281 // TODO: If our config changes, should we auto dismiss any currently 12282 // showing dialogs? 12283 mShowDialogs = shouldShowDialogs(newConfig); 12284 12285 AttributeCache ac = AttributeCache.instance(); 12286 if (ac != null) { 12287 ac.updateConfiguration(configCopy); 12288 } 12289 12290 // Make sure all resources in our process are updated 12291 // right now, so that anyone who is going to retrieve 12292 // resource values after we return will be sure to get 12293 // the new ones. This is especially important during 12294 // boot, where the first config change needs to guarantee 12295 // all resources have that config before following boot 12296 // code is executed. 12297 mSystemThread.applyConfigurationToResources(configCopy); 12298 12299 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12300 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12301 msg.obj = new Configuration(configCopy); 12302 mHandler.sendMessage(msg); 12303 } 12304 12305 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12306 ProcessRecord app = mLruProcesses.get(i); 12307 try { 12308 if (app.thread != null) { 12309 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12310 + app.processName + " new config " + mConfiguration); 12311 app.thread.scheduleConfigurationChanged(configCopy); 12312 } 12313 } catch (Exception e) { 12314 } 12315 } 12316 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12317 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12318 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12319 | Intent.FLAG_RECEIVER_FOREGROUND); 12320 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12321 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12322 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12323 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12324 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12325 broadcastIntentLocked(null, null, intent, 12326 null, null, 0, null, null, 12327 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12328 } 12329 } 12330 } 12331 12332 if (changes != 0 && starting == null) { 12333 // If the configuration changed, and the caller is not already 12334 // in the process of starting an activity, then find the top 12335 // activity to check if its configuration needs to change. 12336 starting = mMainStack.topRunningActivityLocked(null); 12337 } 12338 12339 if (starting != null) { 12340 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12341 // And we need to make sure at this point that all other activities 12342 // are made visible with the correct configuration. 12343 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12344 } 12345 12346 if (values != null && mWindowManager != null) { 12347 mWindowManager.setNewConfiguration(mConfiguration); 12348 } 12349 12350 return kept; 12351 } 12352 12353 /** 12354 * Decide based on the configuration whether we should shouw the ANR, 12355 * crash, etc dialogs. The idea is that if there is no affordnace to 12356 * press the on-screen buttons, we shouldn't show the dialog. 12357 * 12358 * A thought: SystemUI might also want to get told about this, the Power 12359 * dialog / global actions also might want different behaviors. 12360 */ 12361 private static final boolean shouldShowDialogs(Configuration config) { 12362 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12363 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12364 } 12365 12366 /** 12367 * Save the locale. You must be inside a synchronized (this) block. 12368 */ 12369 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12370 if(isDiff) { 12371 SystemProperties.set("user.language", l.getLanguage()); 12372 SystemProperties.set("user.region", l.getCountry()); 12373 } 12374 12375 if(isPersist) { 12376 SystemProperties.set("persist.sys.language", l.getLanguage()); 12377 SystemProperties.set("persist.sys.country", l.getCountry()); 12378 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12379 } 12380 } 12381 12382 @Override 12383 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12384 ActivityRecord srec = ActivityRecord.forToken(token); 12385 return srec != null && srec.task.affinity != null && 12386 srec.task.affinity.equals(destAffinity); 12387 } 12388 12389 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12390 Intent resultData) { 12391 ComponentName dest = destIntent.getComponent(); 12392 12393 synchronized (this) { 12394 ActivityRecord srec = ActivityRecord.forToken(token); 12395 if (srec == null) { 12396 return false; 12397 } 12398 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12399 final int start = history.indexOf(srec); 12400 if (start < 0) { 12401 // Current activity is not in history stack; do nothing. 12402 return false; 12403 } 12404 int finishTo = start - 1; 12405 ActivityRecord parent = null; 12406 boolean foundParentInTask = false; 12407 if (dest != null) { 12408 TaskRecord tr = srec.task; 12409 for (int i = start - 1; i >= 0; i--) { 12410 ActivityRecord r = history.get(i); 12411 if (tr != r.task) { 12412 // Couldn't find parent in the same task; stop at the one above this. 12413 // (Root of current task; in-app "home" behavior) 12414 // Always at least finish the current activity. 12415 finishTo = Math.min(start - 1, i + 1); 12416 parent = history.get(finishTo); 12417 break; 12418 } else if (r.info.packageName.equals(dest.getPackageName()) && 12419 r.info.name.equals(dest.getClassName())) { 12420 finishTo = i; 12421 parent = r; 12422 foundParentInTask = true; 12423 break; 12424 } 12425 } 12426 } 12427 12428 if (mController != null) { 12429 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12430 if (next != null) { 12431 // ask watcher if this is allowed 12432 boolean resumeOK = true; 12433 try { 12434 resumeOK = mController.activityResuming(next.packageName); 12435 } catch (RemoteException e) { 12436 mController = null; 12437 } 12438 12439 if (!resumeOK) { 12440 return false; 12441 } 12442 } 12443 } 12444 final long origId = Binder.clearCallingIdentity(); 12445 for (int i = start; i > finishTo; i--) { 12446 ActivityRecord r = history.get(i); 12447 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12448 "navigate-up", true); 12449 // Only return the supplied result for the first activity finished 12450 resultCode = Activity.RESULT_CANCELED; 12451 resultData = null; 12452 } 12453 12454 if (parent != null && foundParentInTask) { 12455 final int parentLaunchMode = parent.info.launchMode; 12456 final int destIntentFlags = destIntent.getFlags(); 12457 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12458 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12459 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12460 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12461 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12462 } else { 12463 try { 12464 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12465 destIntent.getComponent(), 0, srec.userId); 12466 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12467 null, aInfo, parent.appToken, null, 12468 0, -1, parent.launchedFromUid, 0, null, true, null); 12469 foundParentInTask = res == ActivityManager.START_SUCCESS; 12470 } catch (RemoteException e) { 12471 foundParentInTask = false; 12472 } 12473 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12474 resultData, "navigate-up", true); 12475 } 12476 } 12477 Binder.restoreCallingIdentity(origId); 12478 return foundParentInTask; 12479 } 12480 } 12481 12482 public int getLaunchedFromUid(IBinder activityToken) { 12483 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12484 if (srec == null) { 12485 return -1; 12486 } 12487 return srec.launchedFromUid; 12488 } 12489 12490 // ========================================================= 12491 // LIFETIME MANAGEMENT 12492 // ========================================================= 12493 12494 // Returns which broadcast queue the app is the current [or imminent] receiver 12495 // on, or 'null' if the app is not an active broadcast recipient. 12496 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12497 BroadcastRecord r = app.curReceiver; 12498 if (r != null) { 12499 return r.queue; 12500 } 12501 12502 // It's not the current receiver, but it might be starting up to become one 12503 synchronized (this) { 12504 for (BroadcastQueue queue : mBroadcastQueues) { 12505 r = queue.mPendingBroadcast; 12506 if (r != null && r.curApp == app) { 12507 // found it; report which queue it's in 12508 return queue; 12509 } 12510 } 12511 } 12512 12513 return null; 12514 } 12515 12516 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12517 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12518 if (mAdjSeq == app.adjSeq) { 12519 // This adjustment has already been computed. If we are calling 12520 // from the top, we may have already computed our adjustment with 12521 // an earlier hidden adjustment that isn't really for us... if 12522 // so, use the new hidden adjustment. 12523 if (!recursed && app.hidden) { 12524 if (app.hasActivities) { 12525 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12526 } else if (app.hasClientActivities) { 12527 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12528 } else { 12529 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12530 } 12531 } 12532 return app.curRawAdj; 12533 } 12534 12535 if (app.thread == null) { 12536 app.adjSeq = mAdjSeq; 12537 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12538 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12539 } 12540 12541 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12542 app.adjSource = null; 12543 app.adjTarget = null; 12544 app.empty = false; 12545 app.hidden = false; 12546 app.hasClientActivities = false; 12547 12548 final int activitiesSize = app.activities.size(); 12549 12550 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12551 // The max adjustment doesn't allow this app to be anything 12552 // below foreground, so it is not worth doing work for it. 12553 app.adjType = "fixed"; 12554 app.adjSeq = mAdjSeq; 12555 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12556 app.hasActivities = false; 12557 app.foregroundActivities = false; 12558 app.keeping = true; 12559 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12560 // System process can do UI, and when they do we want to have 12561 // them trim their memory after the user leaves the UI. To 12562 // facilitate this, here we need to determine whether or not it 12563 // is currently showing UI. 12564 app.systemNoUi = true; 12565 if (app == TOP_APP) { 12566 app.systemNoUi = false; 12567 app.hasActivities = true; 12568 } else if (activitiesSize > 0) { 12569 for (int j = 0; j < activitiesSize; j++) { 12570 final ActivityRecord r = app.activities.get(j); 12571 if (r.visible) { 12572 app.systemNoUi = false; 12573 } 12574 if (r.app == app) { 12575 app.hasActivities = true; 12576 } 12577 } 12578 } 12579 return (app.curAdj=app.maxAdj); 12580 } 12581 12582 app.keeping = false; 12583 app.systemNoUi = false; 12584 app.hasActivities = false; 12585 12586 // Determine the importance of the process, starting with most 12587 // important to least, and assign an appropriate OOM adjustment. 12588 int adj; 12589 int schedGroup; 12590 boolean foregroundActivities = false; 12591 boolean interesting = false; 12592 BroadcastQueue queue; 12593 if (app == TOP_APP) { 12594 // The last app on the list is the foreground app. 12595 adj = ProcessList.FOREGROUND_APP_ADJ; 12596 schedGroup = Process.THREAD_GROUP_DEFAULT; 12597 app.adjType = "top-activity"; 12598 foregroundActivities = true; 12599 interesting = true; 12600 app.hasActivities = true; 12601 } else if (app.instrumentationClass != null) { 12602 // Don't want to kill running instrumentation. 12603 adj = ProcessList.FOREGROUND_APP_ADJ; 12604 schedGroup = Process.THREAD_GROUP_DEFAULT; 12605 app.adjType = "instrumentation"; 12606 interesting = true; 12607 } else if ((queue = isReceivingBroadcast(app)) != null) { 12608 // An app that is currently receiving a broadcast also 12609 // counts as being in the foreground for OOM killer purposes. 12610 // It's placed in a sched group based on the nature of the 12611 // broadcast as reflected by which queue it's active in. 12612 adj = ProcessList.FOREGROUND_APP_ADJ; 12613 schedGroup = (queue == mFgBroadcastQueue) 12614 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12615 app.adjType = "broadcast"; 12616 } else if (app.executingServices.size() > 0) { 12617 // An app that is currently executing a service callback also 12618 // counts as being in the foreground. 12619 adj = ProcessList.FOREGROUND_APP_ADJ; 12620 schedGroup = Process.THREAD_GROUP_DEFAULT; 12621 app.adjType = "exec-service"; 12622 } else { 12623 // Assume process is hidden (has activities); we will correct 12624 // later if this is not the case. 12625 adj = hiddenAdj; 12626 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12627 app.hidden = true; 12628 app.adjType = "bg-act"; 12629 } 12630 12631 boolean hasStoppingActivities = false; 12632 12633 // Examine all activities if not already foreground. 12634 if (!foregroundActivities && activitiesSize > 0) { 12635 for (int j = 0; j < activitiesSize; j++) { 12636 final ActivityRecord r = app.activities.get(j); 12637 if (r.visible) { 12638 // App has a visible activity; only upgrade adjustment. 12639 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12640 adj = ProcessList.VISIBLE_APP_ADJ; 12641 app.adjType = "visible"; 12642 } 12643 schedGroup = Process.THREAD_GROUP_DEFAULT; 12644 app.hidden = false; 12645 app.hasActivities = true; 12646 foregroundActivities = true; 12647 break; 12648 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12649 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12650 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12651 app.adjType = "pausing"; 12652 } 12653 app.hidden = false; 12654 foregroundActivities = true; 12655 } else if (r.state == ActivityState.STOPPING) { 12656 // We will apply the actual adjustment later, because 12657 // we want to allow this process to immediately go through 12658 // any memory trimming that is in effect. 12659 app.hidden = false; 12660 foregroundActivities = true; 12661 hasStoppingActivities = true; 12662 } 12663 if (r.app == app) { 12664 app.hasActivities = true; 12665 } 12666 } 12667 } 12668 12669 if (adj == hiddenAdj && !app.hasActivities) { 12670 if (app.hasClientActivities) { 12671 adj = clientHiddenAdj; 12672 app.adjType = "bg-client-act"; 12673 } else { 12674 // Whoops, this process is completely empty as far as we know 12675 // at this point. 12676 adj = emptyAdj; 12677 app.empty = true; 12678 app.adjType = "bg-empty"; 12679 } 12680 } 12681 12682 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12683 if (app.foregroundServices) { 12684 // The user is aware of this app, so make it visible. 12685 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12686 app.hidden = false; 12687 app.adjType = "fg-service"; 12688 schedGroup = Process.THREAD_GROUP_DEFAULT; 12689 } else if (app.forcingToForeground != null) { 12690 // The user is aware of this app, so make it visible. 12691 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12692 app.hidden = false; 12693 app.adjType = "force-fg"; 12694 app.adjSource = app.forcingToForeground; 12695 schedGroup = Process.THREAD_GROUP_DEFAULT; 12696 } 12697 } 12698 12699 if (app.foregroundServices) { 12700 interesting = true; 12701 } 12702 12703 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12704 // We don't want to kill the current heavy-weight process. 12705 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12706 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12707 app.hidden = false; 12708 app.adjType = "heavy"; 12709 } 12710 12711 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12712 // This process is hosting what we currently consider to be the 12713 // home app, so we don't want to let it go into the background. 12714 adj = ProcessList.HOME_APP_ADJ; 12715 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12716 app.hidden = false; 12717 app.adjType = "home"; 12718 } 12719 12720 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12721 && app.activities.size() > 0) { 12722 // This was the previous process that showed UI to the user. 12723 // We want to try to keep it around more aggressively, to give 12724 // a good experience around switching between two apps. 12725 adj = ProcessList.PREVIOUS_APP_ADJ; 12726 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12727 app.hidden = false; 12728 app.adjType = "previous"; 12729 } 12730 12731 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12732 + " reason=" + app.adjType); 12733 12734 // By default, we use the computed adjustment. It may be changed if 12735 // there are applications dependent on our services or providers, but 12736 // this gives us a baseline and makes sure we don't get into an 12737 // infinite recursion. 12738 app.adjSeq = mAdjSeq; 12739 app.curRawAdj = app.nonStoppingAdj = adj; 12740 12741 if (mBackupTarget != null && app == mBackupTarget.app) { 12742 // If possible we want to avoid killing apps while they're being backed up 12743 if (adj > ProcessList.BACKUP_APP_ADJ) { 12744 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12745 adj = ProcessList.BACKUP_APP_ADJ; 12746 app.adjType = "backup"; 12747 app.hidden = false; 12748 } 12749 } 12750 12751 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12752 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12753 final long now = SystemClock.uptimeMillis(); 12754 // This process is more important if the top activity is 12755 // bound to the service. 12756 Iterator<ServiceRecord> jt = app.services.iterator(); 12757 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12758 ServiceRecord s = jt.next(); 12759 if (s.startRequested) { 12760 if (app.hasShownUi && app != mHomeProcess) { 12761 // If this process has shown some UI, let it immediately 12762 // go to the LRU list because it may be pretty heavy with 12763 // UI stuff. We'll tag it with a label just to help 12764 // debug and understand what is going on. 12765 if (adj > ProcessList.SERVICE_ADJ) { 12766 app.adjType = "started-bg-ui-services"; 12767 } 12768 } else { 12769 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12770 // This service has seen some activity within 12771 // recent memory, so we will keep its process ahead 12772 // of the background processes. 12773 if (adj > ProcessList.SERVICE_ADJ) { 12774 adj = ProcessList.SERVICE_ADJ; 12775 app.adjType = "started-services"; 12776 app.hidden = false; 12777 } 12778 } 12779 // If we have let the service slide into the background 12780 // state, still have some text describing what it is doing 12781 // even though the service no longer has an impact. 12782 if (adj > ProcessList.SERVICE_ADJ) { 12783 app.adjType = "started-bg-services"; 12784 } 12785 } 12786 // Don't kill this process because it is doing work; it 12787 // has said it is doing work. 12788 app.keeping = true; 12789 } 12790 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12791 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12792 Iterator<ArrayList<ConnectionRecord>> kt 12793 = s.connections.values().iterator(); 12794 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12795 ArrayList<ConnectionRecord> clist = kt.next(); 12796 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12797 // XXX should compute this based on the max of 12798 // all connected clients. 12799 ConnectionRecord cr = clist.get(i); 12800 if (cr.binding.client == app) { 12801 // Binding to ourself is not interesting. 12802 continue; 12803 } 12804 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12805 ProcessRecord client = cr.binding.client; 12806 int clientAdj = adj; 12807 int myHiddenAdj = hiddenAdj; 12808 if (myHiddenAdj > client.hiddenAdj) { 12809 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12810 myHiddenAdj = client.hiddenAdj; 12811 } else { 12812 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12813 } 12814 } 12815 int myClientHiddenAdj = clientHiddenAdj; 12816 if (myClientHiddenAdj > client.clientHiddenAdj) { 12817 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12818 myClientHiddenAdj = client.clientHiddenAdj; 12819 } else { 12820 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12821 } 12822 } 12823 int myEmptyAdj = emptyAdj; 12824 if (myEmptyAdj > client.emptyAdj) { 12825 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12826 myEmptyAdj = client.emptyAdj; 12827 } else { 12828 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12829 } 12830 } 12831 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12832 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12833 String adjType = null; 12834 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12835 // Not doing bind OOM management, so treat 12836 // this guy more like a started service. 12837 if (app.hasShownUi && app != mHomeProcess) { 12838 // If this process has shown some UI, let it immediately 12839 // go to the LRU list because it may be pretty heavy with 12840 // UI stuff. We'll tag it with a label just to help 12841 // debug and understand what is going on. 12842 if (adj > clientAdj) { 12843 adjType = "bound-bg-ui-services"; 12844 } 12845 app.hidden = false; 12846 clientAdj = adj; 12847 } else { 12848 if (now >= (s.lastActivity 12849 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12850 // This service has not seen activity within 12851 // recent memory, so allow it to drop to the 12852 // LRU list if there is no other reason to keep 12853 // it around. We'll also tag it with a label just 12854 // to help debug and undertand what is going on. 12855 if (adj > clientAdj) { 12856 adjType = "bound-bg-services"; 12857 } 12858 clientAdj = adj; 12859 } 12860 } 12861 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12862 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12863 // If this connection is keeping the service 12864 // created, then we want to try to better follow 12865 // its memory management semantics for activities. 12866 // That is, if it is sitting in the background 12867 // LRU list as a hidden process (with activities), 12868 // we don't want the service it is connected to 12869 // to go into the empty LRU and quickly get killed, 12870 // because I'll we'll do is just end up restarting 12871 // the service. 12872 app.hasClientActivities |= client.hasActivities; 12873 } 12874 } 12875 if (adj > clientAdj) { 12876 // If this process has recently shown UI, and 12877 // the process that is binding to it is less 12878 // important than being visible, then we don't 12879 // care about the binding as much as we care 12880 // about letting this process get into the LRU 12881 // list to be killed and restarted if needed for 12882 // memory. 12883 if (app.hasShownUi && app != mHomeProcess 12884 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12885 adjType = "bound-bg-ui-services"; 12886 } else { 12887 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12888 |Context.BIND_IMPORTANT)) != 0) { 12889 adj = clientAdj; 12890 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12891 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12892 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12893 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12894 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12895 adj = clientAdj; 12896 } else { 12897 app.pendingUiClean = true; 12898 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12899 adj = ProcessList.VISIBLE_APP_ADJ; 12900 } 12901 } 12902 if (!client.hidden) { 12903 app.hidden = false; 12904 } 12905 if (client.keeping) { 12906 app.keeping = true; 12907 } 12908 adjType = "service"; 12909 } 12910 } 12911 if (adjType != null) { 12912 app.adjType = adjType; 12913 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12914 .REASON_SERVICE_IN_USE; 12915 app.adjSource = cr.binding.client; 12916 app.adjSourceOom = clientAdj; 12917 app.adjTarget = s.name; 12918 } 12919 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12920 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12921 schedGroup = Process.THREAD_GROUP_DEFAULT; 12922 } 12923 } 12924 } 12925 final ActivityRecord a = cr.activity; 12926 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12927 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12928 (a.visible || a.state == ActivityState.RESUMED 12929 || a.state == ActivityState.PAUSING)) { 12930 adj = ProcessList.FOREGROUND_APP_ADJ; 12931 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12932 schedGroup = Process.THREAD_GROUP_DEFAULT; 12933 } 12934 app.hidden = false; 12935 app.adjType = "service"; 12936 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12937 .REASON_SERVICE_IN_USE; 12938 app.adjSource = a; 12939 app.adjSourceOom = adj; 12940 app.adjTarget = s.name; 12941 } 12942 } 12943 } 12944 } 12945 } 12946 } 12947 12948 // Finally, if this process has active services running in it, we 12949 // would like to avoid killing it unless it would prevent the current 12950 // application from running. By default we put the process in 12951 // with the rest of the background processes; as we scan through 12952 // its services we may bump it up from there. 12953 if (adj > hiddenAdj) { 12954 adj = hiddenAdj; 12955 app.hidden = false; 12956 app.adjType = "bg-services"; 12957 } 12958 } 12959 12960 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12961 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12962 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12963 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12964 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12965 ContentProviderRecord cpr = jt.next(); 12966 for (int i = cpr.connections.size()-1; 12967 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12968 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12969 i--) { 12970 ContentProviderConnection conn = cpr.connections.get(i); 12971 ProcessRecord client = conn.client; 12972 if (client == app) { 12973 // Being our own client is not interesting. 12974 continue; 12975 } 12976 int myHiddenAdj = hiddenAdj; 12977 if (myHiddenAdj > client.hiddenAdj) { 12978 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12979 myHiddenAdj = client.hiddenAdj; 12980 } else { 12981 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12982 } 12983 } 12984 int myClientHiddenAdj = clientHiddenAdj; 12985 if (myClientHiddenAdj > client.clientHiddenAdj) { 12986 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 12987 myClientHiddenAdj = client.clientHiddenAdj; 12988 } else { 12989 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12990 } 12991 } 12992 int myEmptyAdj = emptyAdj; 12993 if (myEmptyAdj > client.emptyAdj) { 12994 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12995 myEmptyAdj = client.emptyAdj; 12996 } else { 12997 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12998 } 12999 } 13000 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13001 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13002 if (adj > clientAdj) { 13003 if (app.hasShownUi && app != mHomeProcess 13004 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13005 app.adjType = "bg-ui-provider"; 13006 } else { 13007 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13008 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13009 app.adjType = "provider"; 13010 } 13011 if (!client.hidden) { 13012 app.hidden = false; 13013 } 13014 if (client.keeping) { 13015 app.keeping = true; 13016 } 13017 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13018 .REASON_PROVIDER_IN_USE; 13019 app.adjSource = client; 13020 app.adjSourceOom = clientAdj; 13021 app.adjTarget = cpr.name; 13022 } 13023 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13024 schedGroup = Process.THREAD_GROUP_DEFAULT; 13025 } 13026 } 13027 // If the provider has external (non-framework) process 13028 // dependencies, ensure that its adjustment is at least 13029 // FOREGROUND_APP_ADJ. 13030 if (cpr.hasExternalProcessHandles()) { 13031 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13032 adj = ProcessList.FOREGROUND_APP_ADJ; 13033 schedGroup = Process.THREAD_GROUP_DEFAULT; 13034 app.hidden = false; 13035 app.keeping = true; 13036 app.adjType = "provider"; 13037 app.adjTarget = cpr.name; 13038 } 13039 } 13040 } 13041 } 13042 13043 if (adj == ProcessList.SERVICE_ADJ) { 13044 if (doingAll) { 13045 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13046 mNewNumServiceProcs++; 13047 } 13048 if (app.serviceb) { 13049 adj = ProcessList.SERVICE_B_ADJ; 13050 } 13051 } else { 13052 app.serviceb = false; 13053 } 13054 13055 app.nonStoppingAdj = adj; 13056 13057 if (hasStoppingActivities) { 13058 // Only upgrade adjustment. 13059 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13060 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13061 app.adjType = "stopping"; 13062 } 13063 } 13064 13065 app.curRawAdj = adj; 13066 13067 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13068 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13069 if (adj > app.maxAdj) { 13070 adj = app.maxAdj; 13071 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13072 schedGroup = Process.THREAD_GROUP_DEFAULT; 13073 } 13074 } 13075 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13076 app.keeping = true; 13077 } 13078 13079 if (app.hasAboveClient) { 13080 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13081 // then we need to drop its adjustment to be lower than the service's 13082 // in order to honor the request. We want to drop it by one adjustment 13083 // level... but there is special meaning applied to various levels so 13084 // we will skip some of them. 13085 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13086 // System process will not get dropped, ever 13087 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13088 adj = ProcessList.VISIBLE_APP_ADJ; 13089 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13090 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13091 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13092 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13093 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13094 adj++; 13095 } 13096 } 13097 13098 int importance = app.memImportance; 13099 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13100 app.curAdj = adj; 13101 app.curSchedGroup = schedGroup; 13102 if (!interesting) { 13103 // For this reporting, if there is not something explicitly 13104 // interesting in this process then we will push it to the 13105 // background importance. 13106 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13107 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13108 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13109 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13110 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13111 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13112 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13113 } else if (adj >= ProcessList.SERVICE_ADJ) { 13114 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13115 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13116 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13117 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13118 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13119 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13120 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13121 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13122 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13123 } else { 13124 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13125 } 13126 } 13127 13128 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13129 if (foregroundActivities != app.foregroundActivities) { 13130 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13131 } 13132 if (changes != 0) { 13133 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13134 app.memImportance = importance; 13135 app.foregroundActivities = foregroundActivities; 13136 int i = mPendingProcessChanges.size()-1; 13137 ProcessChangeItem item = null; 13138 while (i >= 0) { 13139 item = mPendingProcessChanges.get(i); 13140 if (item.pid == app.pid) { 13141 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13142 break; 13143 } 13144 i--; 13145 } 13146 if (i < 0) { 13147 // No existing item in pending changes; need a new one. 13148 final int NA = mAvailProcessChanges.size(); 13149 if (NA > 0) { 13150 item = mAvailProcessChanges.remove(NA-1); 13151 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13152 } else { 13153 item = new ProcessChangeItem(); 13154 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13155 } 13156 item.changes = 0; 13157 item.pid = app.pid; 13158 item.uid = app.info.uid; 13159 if (mPendingProcessChanges.size() == 0) { 13160 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13161 "*** Enqueueing dispatch processes changed!"); 13162 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13163 } 13164 mPendingProcessChanges.add(item); 13165 } 13166 item.changes |= changes; 13167 item.importance = importance; 13168 item.foregroundActivities = foregroundActivities; 13169 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13170 + Integer.toHexString(System.identityHashCode(item)) 13171 + " " + app.toShortString() + ": changes=" + item.changes 13172 + " importance=" + item.importance 13173 + " foreground=" + item.foregroundActivities 13174 + " type=" + app.adjType + " source=" + app.adjSource 13175 + " target=" + app.adjTarget); 13176 } 13177 13178 return app.curRawAdj; 13179 } 13180 13181 /** 13182 * Ask a given process to GC right now. 13183 */ 13184 final void performAppGcLocked(ProcessRecord app) { 13185 try { 13186 app.lastRequestedGc = SystemClock.uptimeMillis(); 13187 if (app.thread != null) { 13188 if (app.reportLowMemory) { 13189 app.reportLowMemory = false; 13190 app.thread.scheduleLowMemory(); 13191 } else { 13192 app.thread.processInBackground(); 13193 } 13194 } 13195 } catch (Exception e) { 13196 // whatever. 13197 } 13198 } 13199 13200 /** 13201 * Returns true if things are idle enough to perform GCs. 13202 */ 13203 private final boolean canGcNowLocked() { 13204 boolean processingBroadcasts = false; 13205 for (BroadcastQueue q : mBroadcastQueues) { 13206 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13207 processingBroadcasts = true; 13208 } 13209 } 13210 return !processingBroadcasts 13211 && (mSleeping || (mMainStack.mResumedActivity != null && 13212 mMainStack.mResumedActivity.idle)); 13213 } 13214 13215 /** 13216 * Perform GCs on all processes that are waiting for it, but only 13217 * if things are idle. 13218 */ 13219 final void performAppGcsLocked() { 13220 final int N = mProcessesToGc.size(); 13221 if (N <= 0) { 13222 return; 13223 } 13224 if (canGcNowLocked()) { 13225 while (mProcessesToGc.size() > 0) { 13226 ProcessRecord proc = mProcessesToGc.remove(0); 13227 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13228 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13229 <= SystemClock.uptimeMillis()) { 13230 // To avoid spamming the system, we will GC processes one 13231 // at a time, waiting a few seconds between each. 13232 performAppGcLocked(proc); 13233 scheduleAppGcsLocked(); 13234 return; 13235 } else { 13236 // It hasn't been long enough since we last GCed this 13237 // process... put it in the list to wait for its time. 13238 addProcessToGcListLocked(proc); 13239 break; 13240 } 13241 } 13242 } 13243 13244 scheduleAppGcsLocked(); 13245 } 13246 } 13247 13248 /** 13249 * If all looks good, perform GCs on all processes waiting for them. 13250 */ 13251 final void performAppGcsIfAppropriateLocked() { 13252 if (canGcNowLocked()) { 13253 performAppGcsLocked(); 13254 return; 13255 } 13256 // Still not idle, wait some more. 13257 scheduleAppGcsLocked(); 13258 } 13259 13260 /** 13261 * Schedule the execution of all pending app GCs. 13262 */ 13263 final void scheduleAppGcsLocked() { 13264 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13265 13266 if (mProcessesToGc.size() > 0) { 13267 // Schedule a GC for the time to the next process. 13268 ProcessRecord proc = mProcessesToGc.get(0); 13269 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13270 13271 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13272 long now = SystemClock.uptimeMillis(); 13273 if (when < (now+GC_TIMEOUT)) { 13274 when = now + GC_TIMEOUT; 13275 } 13276 mHandler.sendMessageAtTime(msg, when); 13277 } 13278 } 13279 13280 /** 13281 * Add a process to the array of processes waiting to be GCed. Keeps the 13282 * list in sorted order by the last GC time. The process can't already be 13283 * on the list. 13284 */ 13285 final void addProcessToGcListLocked(ProcessRecord proc) { 13286 boolean added = false; 13287 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13288 if (mProcessesToGc.get(i).lastRequestedGc < 13289 proc.lastRequestedGc) { 13290 added = true; 13291 mProcessesToGc.add(i+1, proc); 13292 break; 13293 } 13294 } 13295 if (!added) { 13296 mProcessesToGc.add(0, proc); 13297 } 13298 } 13299 13300 /** 13301 * Set up to ask a process to GC itself. This will either do it 13302 * immediately, or put it on the list of processes to gc the next 13303 * time things are idle. 13304 */ 13305 final void scheduleAppGcLocked(ProcessRecord app) { 13306 long now = SystemClock.uptimeMillis(); 13307 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13308 return; 13309 } 13310 if (!mProcessesToGc.contains(app)) { 13311 addProcessToGcListLocked(app); 13312 scheduleAppGcsLocked(); 13313 } 13314 } 13315 13316 final void checkExcessivePowerUsageLocked(boolean doKills) { 13317 updateCpuStatsNow(); 13318 13319 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13320 boolean doWakeKills = doKills; 13321 boolean doCpuKills = doKills; 13322 if (mLastPowerCheckRealtime == 0) { 13323 doWakeKills = false; 13324 } 13325 if (mLastPowerCheckUptime == 0) { 13326 doCpuKills = false; 13327 } 13328 if (stats.isScreenOn()) { 13329 doWakeKills = false; 13330 } 13331 final long curRealtime = SystemClock.elapsedRealtime(); 13332 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13333 final long curUptime = SystemClock.uptimeMillis(); 13334 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13335 mLastPowerCheckRealtime = curRealtime; 13336 mLastPowerCheckUptime = curUptime; 13337 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13338 doWakeKills = false; 13339 } 13340 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13341 doCpuKills = false; 13342 } 13343 int i = mLruProcesses.size(); 13344 while (i > 0) { 13345 i--; 13346 ProcessRecord app = mLruProcesses.get(i); 13347 if (!app.keeping) { 13348 long wtime; 13349 synchronized (stats) { 13350 wtime = stats.getProcessWakeTime(app.info.uid, 13351 app.pid, curRealtime); 13352 } 13353 long wtimeUsed = wtime - app.lastWakeTime; 13354 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13355 if (DEBUG_POWER) { 13356 StringBuilder sb = new StringBuilder(128); 13357 sb.append("Wake for "); 13358 app.toShortString(sb); 13359 sb.append(": over "); 13360 TimeUtils.formatDuration(realtimeSince, sb); 13361 sb.append(" used "); 13362 TimeUtils.formatDuration(wtimeUsed, sb); 13363 sb.append(" ("); 13364 sb.append((wtimeUsed*100)/realtimeSince); 13365 sb.append("%)"); 13366 Slog.i(TAG, sb.toString()); 13367 sb.setLength(0); 13368 sb.append("CPU for "); 13369 app.toShortString(sb); 13370 sb.append(": over "); 13371 TimeUtils.formatDuration(uptimeSince, sb); 13372 sb.append(" used "); 13373 TimeUtils.formatDuration(cputimeUsed, sb); 13374 sb.append(" ("); 13375 sb.append((cputimeUsed*100)/uptimeSince); 13376 sb.append("%)"); 13377 Slog.i(TAG, sb.toString()); 13378 } 13379 // If a process has held a wake lock for more 13380 // than 50% of the time during this period, 13381 // that sounds bad. Kill! 13382 if (doWakeKills && realtimeSince > 0 13383 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13384 synchronized (stats) { 13385 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13386 realtimeSince, wtimeUsed); 13387 } 13388 Slog.w(TAG, "Excessive wake lock in " + app.processName 13389 + " (pid " + app.pid + "): held " + wtimeUsed 13390 + " during " + realtimeSince); 13391 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13392 app.processName, app.setAdj, "excessive wake lock"); 13393 Process.killProcessQuiet(app.pid); 13394 } else if (doCpuKills && uptimeSince > 0 13395 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13396 synchronized (stats) { 13397 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13398 uptimeSince, cputimeUsed); 13399 } 13400 Slog.w(TAG, "Excessive CPU in " + app.processName 13401 + " (pid " + app.pid + "): used " + cputimeUsed 13402 + " during " + uptimeSince); 13403 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13404 app.processName, app.setAdj, "excessive cpu"); 13405 Process.killProcessQuiet(app.pid); 13406 } else { 13407 app.lastWakeTime = wtime; 13408 app.lastCpuTime = app.curCpuTime; 13409 } 13410 } 13411 } 13412 } 13413 13414 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13415 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13416 app.hiddenAdj = hiddenAdj; 13417 app.clientHiddenAdj = clientHiddenAdj; 13418 app.emptyAdj = emptyAdj; 13419 13420 if (app.thread == null) { 13421 return false; 13422 } 13423 13424 final boolean wasKeeping = app.keeping; 13425 13426 boolean success = true; 13427 13428 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13429 13430 if (app.curRawAdj != app.setRawAdj) { 13431 if (wasKeeping && !app.keeping) { 13432 // This app is no longer something we want to keep. Note 13433 // its current wake lock time to later know to kill it if 13434 // it is not behaving well. 13435 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13436 synchronized (stats) { 13437 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13438 app.pid, SystemClock.elapsedRealtime()); 13439 } 13440 app.lastCpuTime = app.curCpuTime; 13441 } 13442 13443 app.setRawAdj = app.curRawAdj; 13444 } 13445 13446 if (app.curAdj != app.setAdj) { 13447 if (Process.setOomAdj(app.pid, app.curAdj)) { 13448 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13449 TAG, "Set " + app.pid + " " + app.processName + 13450 " adj " + app.curAdj + ": " + app.adjType); 13451 app.setAdj = app.curAdj; 13452 } else { 13453 success = false; 13454 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13455 } 13456 } 13457 if (app.setSchedGroup != app.curSchedGroup) { 13458 app.setSchedGroup = app.curSchedGroup; 13459 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13460 "Setting process group of " + app.processName 13461 + " to " + app.curSchedGroup); 13462 if (app.waitingToKill != null && 13463 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13464 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13465 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13466 app.processName, app.setAdj, app.waitingToKill); 13467 app.killedBackground = true; 13468 Process.killProcessQuiet(app.pid); 13469 success = false; 13470 } else { 13471 if (true) { 13472 long oldId = Binder.clearCallingIdentity(); 13473 try { 13474 Process.setProcessGroup(app.pid, app.curSchedGroup); 13475 } catch (Exception e) { 13476 Slog.w(TAG, "Failed setting process group of " + app.pid 13477 + " to " + app.curSchedGroup); 13478 e.printStackTrace(); 13479 } finally { 13480 Binder.restoreCallingIdentity(oldId); 13481 } 13482 } else { 13483 if (app.thread != null) { 13484 try { 13485 app.thread.setSchedulingGroup(app.curSchedGroup); 13486 } catch (RemoteException e) { 13487 } 13488 } 13489 } 13490 } 13491 } 13492 return success; 13493 } 13494 13495 private final ActivityRecord resumedAppLocked() { 13496 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13497 if (resumedActivity == null || resumedActivity.app == null) { 13498 resumedActivity = mMainStack.mPausingActivity; 13499 if (resumedActivity == null || resumedActivity.app == null) { 13500 resumedActivity = mMainStack.topRunningActivityLocked(null); 13501 } 13502 } 13503 return resumedActivity; 13504 } 13505 13506 final boolean updateOomAdjLocked(ProcessRecord app) { 13507 final ActivityRecord TOP_ACT = resumedAppLocked(); 13508 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13509 int curAdj = app.curAdj; 13510 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13511 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13512 13513 mAdjSeq++; 13514 13515 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13516 app.emptyAdj, TOP_APP, false); 13517 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13518 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13519 if (nowHidden != wasHidden) { 13520 // Changed to/from hidden state, so apps after it in the LRU 13521 // list may also be changed. 13522 updateOomAdjLocked(); 13523 } 13524 return success; 13525 } 13526 13527 final void updateOomAdjLocked() { 13528 final ActivityRecord TOP_ACT = resumedAppLocked(); 13529 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13530 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13531 13532 if (false) { 13533 RuntimeException e = new RuntimeException(); 13534 e.fillInStackTrace(); 13535 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13536 } 13537 13538 mAdjSeq++; 13539 mNewNumServiceProcs = 0; 13540 13541 final int emptyProcessLimit; 13542 final int hiddenProcessLimit; 13543 if (mProcessLimit <= 0) { 13544 emptyProcessLimit = hiddenProcessLimit = 0; 13545 } else if (mProcessLimit == 1) { 13546 emptyProcessLimit = 1; 13547 hiddenProcessLimit = 0; 13548 } else { 13549 emptyProcessLimit = (mProcessLimit*2)/3; 13550 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13551 } 13552 13553 // Let's determine how many processes we have running vs. 13554 // how many slots we have for background processes; we may want 13555 // to put multiple processes in a slot of there are enough of 13556 // them. 13557 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13558 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13559 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13560 if (numEmptyProcs > hiddenProcessLimit) { 13561 // If there are more empty processes than our limit on hidden 13562 // processes, then use the hidden process limit for the factor. 13563 // This ensures that the really old empty processes get pushed 13564 // down to the bottom, so if we are running low on memory we will 13565 // have a better chance at keeping around more hidden processes 13566 // instead of a gazillion empty processes. 13567 numEmptyProcs = hiddenProcessLimit; 13568 } 13569 int emptyFactor = numEmptyProcs/numSlots; 13570 if (emptyFactor < 1) emptyFactor = 1; 13571 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13572 if (hiddenFactor < 1) hiddenFactor = 1; 13573 int stepHidden = 0; 13574 int stepEmpty = 0; 13575 int numHidden = 0; 13576 int numEmpty = 0; 13577 int numTrimming = 0; 13578 13579 mNumNonHiddenProcs = 0; 13580 mNumHiddenProcs = 0; 13581 13582 // First update the OOM adjustment for each of the 13583 // application processes based on their current state. 13584 int i = mLruProcesses.size(); 13585 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13586 int nextHiddenAdj = curHiddenAdj+1; 13587 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13588 int nextEmptyAdj = curEmptyAdj+2; 13589 int curClientHiddenAdj = curEmptyAdj; 13590 while (i > 0) { 13591 i--; 13592 ProcessRecord app = mLruProcesses.get(i); 13593 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13594 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13595 if (!app.killedBackground) { 13596 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13597 // This process was assigned as a hidden process... step the 13598 // hidden level. 13599 mNumHiddenProcs++; 13600 if (curHiddenAdj != nextHiddenAdj) { 13601 stepHidden++; 13602 if (stepHidden >= hiddenFactor) { 13603 stepHidden = 0; 13604 curHiddenAdj = nextHiddenAdj; 13605 nextHiddenAdj += 2; 13606 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13607 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13608 } 13609 if (curClientHiddenAdj <= curHiddenAdj) { 13610 curClientHiddenAdj = curHiddenAdj + 1; 13611 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13612 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13613 } 13614 } 13615 } 13616 } 13617 numHidden++; 13618 if (numHidden > hiddenProcessLimit) { 13619 Slog.i(TAG, "No longer want " + app.processName 13620 + " (pid " + app.pid + "): hidden #" + numHidden); 13621 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13622 app.processName, app.setAdj, "too many background"); 13623 app.killedBackground = true; 13624 Process.killProcessQuiet(app.pid); 13625 } 13626 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13627 // This process has a client that has activities. We will have 13628 // given it the current hidden adj; here we will just leave it 13629 // without stepping the hidden adj. 13630 curClientHiddenAdj++; 13631 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13632 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13633 } 13634 } else { 13635 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13636 // This process was assigned as an empty process... step the 13637 // empty level. 13638 if (curEmptyAdj != nextEmptyAdj) { 13639 stepEmpty++; 13640 if (stepEmpty >= emptyFactor) { 13641 stepEmpty = 0; 13642 curEmptyAdj = nextEmptyAdj; 13643 nextEmptyAdj += 2; 13644 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13645 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13646 } 13647 } 13648 } 13649 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13650 mNumNonHiddenProcs++; 13651 } 13652 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13653 && !app.hasClientActivities) { 13654 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13655 && app.lastActivityTime < oldTime) { 13656 Slog.i(TAG, "No longer want " + app.processName 13657 + " (pid " + app.pid + "): empty for " 13658 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13659 / 1000) + "s"); 13660 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13661 app.processName, app.setAdj, "old background process"); 13662 app.killedBackground = true; 13663 Process.killProcessQuiet(app.pid); 13664 } else { 13665 numEmpty++; 13666 if (numEmpty > emptyProcessLimit) { 13667 Slog.i(TAG, "No longer want " + app.processName 13668 + " (pid " + app.pid + "): empty #" + numEmpty); 13669 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13670 app.processName, app.setAdj, "too many background"); 13671 app.killedBackground = true; 13672 Process.killProcessQuiet(app.pid); 13673 } 13674 } 13675 } 13676 } 13677 if (app.isolated && app.services.size() <= 0) { 13678 // If this is an isolated process, and there are no 13679 // services running in it, then the process is no longer 13680 // needed. We agressively kill these because we can by 13681 // definition not re-use the same process again, and it is 13682 // good to avoid having whatever code was running in them 13683 // left sitting around after no longer needed. 13684 Slog.i(TAG, "Isolated process " + app.processName 13685 + " (pid " + app.pid + ") no longer needed"); 13686 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13687 app.processName, app.setAdj, "isolated not needed"); 13688 app.killedBackground = true; 13689 Process.killProcessQuiet(app.pid); 13690 } 13691 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13692 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13693 && !app.killedBackground) { 13694 numTrimming++; 13695 } 13696 } 13697 } 13698 13699 mNumServiceProcs = mNewNumServiceProcs; 13700 13701 // Now determine the memory trimming level of background processes. 13702 // Unfortunately we need to start at the back of the list to do this 13703 // properly. We only do this if the number of background apps we 13704 // are managing to keep around is less than half the maximum we desire; 13705 // if we are keeping a good number around, we'll let them use whatever 13706 // memory they want. 13707 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13708 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13709 final int numHiddenAndEmpty = numHidden + numEmpty; 13710 final int N = mLruProcesses.size(); 13711 int factor = numTrimming/3; 13712 int minFactor = 2; 13713 if (mHomeProcess != null) minFactor++; 13714 if (mPreviousProcess != null) minFactor++; 13715 if (factor < minFactor) factor = minFactor; 13716 int step = 0; 13717 int fgTrimLevel; 13718 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13719 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13720 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13721 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13722 } else { 13723 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13724 } 13725 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13726 for (i=0; i<N; i++) { 13727 ProcessRecord app = mLruProcesses.get(i); 13728 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13729 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13730 && !app.killedBackground) { 13731 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13732 try { 13733 app.thread.scheduleTrimMemory(curLevel); 13734 } catch (RemoteException e) { 13735 } 13736 if (false) { 13737 // For now we won't do this; our memory trimming seems 13738 // to be good enough at this point that destroying 13739 // activities causes more harm than good. 13740 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13741 && app != mHomeProcess && app != mPreviousProcess) { 13742 // Need to do this on its own message because the stack may not 13743 // be in a consistent state at this point. 13744 // For these apps we will also finish their activities 13745 // to help them free memory. 13746 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13747 } 13748 } 13749 } 13750 app.trimMemoryLevel = curLevel; 13751 step++; 13752 if (step >= factor) { 13753 step = 0; 13754 switch (curLevel) { 13755 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13756 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13757 break; 13758 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13759 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13760 break; 13761 } 13762 } 13763 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13764 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13765 && app.thread != null) { 13766 try { 13767 app.thread.scheduleTrimMemory( 13768 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13769 } catch (RemoteException e) { 13770 } 13771 } 13772 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13773 } else { 13774 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13775 && app.pendingUiClean) { 13776 // If this application is now in the background and it 13777 // had done UI, then give it the special trim level to 13778 // have it free UI resources. 13779 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13780 if (app.trimMemoryLevel < level && app.thread != null) { 13781 try { 13782 app.thread.scheduleTrimMemory(level); 13783 } catch (RemoteException e) { 13784 } 13785 } 13786 app.pendingUiClean = false; 13787 } 13788 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13789 try { 13790 app.thread.scheduleTrimMemory(fgTrimLevel); 13791 } catch (RemoteException e) { 13792 } 13793 } 13794 app.trimMemoryLevel = fgTrimLevel; 13795 } 13796 } 13797 } else { 13798 final int N = mLruProcesses.size(); 13799 for (i=0; i<N; i++) { 13800 ProcessRecord app = mLruProcesses.get(i); 13801 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13802 && app.pendingUiClean) { 13803 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13804 && app.thread != null) { 13805 try { 13806 app.thread.scheduleTrimMemory( 13807 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13808 } catch (RemoteException e) { 13809 } 13810 } 13811 app.pendingUiClean = false; 13812 } 13813 app.trimMemoryLevel = 0; 13814 } 13815 } 13816 13817 if (mAlwaysFinishActivities) { 13818 // Need to do this on its own message because the stack may not 13819 // be in a consistent state at this point. 13820 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13821 } 13822 } 13823 13824 final void trimApplications() { 13825 synchronized (this) { 13826 int i; 13827 13828 // First remove any unused application processes whose package 13829 // has been removed. 13830 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13831 final ProcessRecord app = mRemovedProcesses.get(i); 13832 if (app.activities.size() == 0 13833 && app.curReceiver == null && app.services.size() == 0) { 13834 Slog.i( 13835 TAG, "Exiting empty application process " 13836 + app.processName + " (" 13837 + (app.thread != null ? app.thread.asBinder() : null) 13838 + ")\n"); 13839 if (app.pid > 0 && app.pid != MY_PID) { 13840 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13841 app.processName, app.setAdj, "empty"); 13842 Process.killProcessQuiet(app.pid); 13843 } else { 13844 try { 13845 app.thread.scheduleExit(); 13846 } catch (Exception e) { 13847 // Ignore exceptions. 13848 } 13849 } 13850 cleanUpApplicationRecordLocked(app, false, true, -1); 13851 mRemovedProcesses.remove(i); 13852 13853 if (app.persistent) { 13854 if (app.persistent) { 13855 addAppLocked(app.info, false); 13856 } 13857 } 13858 } 13859 } 13860 13861 // Now update the oom adj for all processes. 13862 updateOomAdjLocked(); 13863 } 13864 } 13865 13866 /** This method sends the specified signal to each of the persistent apps */ 13867 public void signalPersistentProcesses(int sig) throws RemoteException { 13868 if (sig != Process.SIGNAL_USR1) { 13869 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13870 } 13871 13872 synchronized (this) { 13873 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13874 != PackageManager.PERMISSION_GRANTED) { 13875 throw new SecurityException("Requires permission " 13876 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13877 } 13878 13879 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13880 ProcessRecord r = mLruProcesses.get(i); 13881 if (r.thread != null && r.persistent) { 13882 Process.sendSignal(r.pid, sig); 13883 } 13884 } 13885 } 13886 } 13887 13888 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13889 if (proc == null || proc == mProfileProc) { 13890 proc = mProfileProc; 13891 path = mProfileFile; 13892 profileType = mProfileType; 13893 clearProfilerLocked(); 13894 } 13895 if (proc == null) { 13896 return; 13897 } 13898 try { 13899 proc.thread.profilerControl(false, path, null, profileType); 13900 } catch (RemoteException e) { 13901 throw new IllegalStateException("Process disappeared"); 13902 } 13903 } 13904 13905 private void clearProfilerLocked() { 13906 if (mProfileFd != null) { 13907 try { 13908 mProfileFd.close(); 13909 } catch (IOException e) { 13910 } 13911 } 13912 mProfileApp = null; 13913 mProfileProc = null; 13914 mProfileFile = null; 13915 mProfileType = 0; 13916 mAutoStopProfiler = false; 13917 } 13918 13919 public boolean profileControl(String process, int userId, boolean start, 13920 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13921 13922 try { 13923 synchronized (this) { 13924 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13925 // its own permission. 13926 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13927 != PackageManager.PERMISSION_GRANTED) { 13928 throw new SecurityException("Requires permission " 13929 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13930 } 13931 13932 if (start && fd == null) { 13933 throw new IllegalArgumentException("null fd"); 13934 } 13935 13936 ProcessRecord proc = null; 13937 if (process != null) { 13938 proc = findProcessLocked(process, userId, "profileControl"); 13939 } 13940 13941 if (start && (proc == null || proc.thread == null)) { 13942 throw new IllegalArgumentException("Unknown process: " + process); 13943 } 13944 13945 if (start) { 13946 stopProfilerLocked(null, null, 0); 13947 setProfileApp(proc.info, proc.processName, path, fd, false); 13948 mProfileProc = proc; 13949 mProfileType = profileType; 13950 try { 13951 fd = fd.dup(); 13952 } catch (IOException e) { 13953 fd = null; 13954 } 13955 proc.thread.profilerControl(start, path, fd, profileType); 13956 fd = null; 13957 mProfileFd = null; 13958 } else { 13959 stopProfilerLocked(proc, path, profileType); 13960 if (fd != null) { 13961 try { 13962 fd.close(); 13963 } catch (IOException e) { 13964 } 13965 } 13966 } 13967 13968 return true; 13969 } 13970 } catch (RemoteException e) { 13971 throw new IllegalStateException("Process disappeared"); 13972 } finally { 13973 if (fd != null) { 13974 try { 13975 fd.close(); 13976 } catch (IOException e) { 13977 } 13978 } 13979 } 13980 } 13981 13982 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13983 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13984 userId, true, true, callName, null); 13985 ProcessRecord proc = null; 13986 try { 13987 int pid = Integer.parseInt(process); 13988 synchronized (mPidsSelfLocked) { 13989 proc = mPidsSelfLocked.get(pid); 13990 } 13991 } catch (NumberFormatException e) { 13992 } 13993 13994 if (proc == null) { 13995 HashMap<String, SparseArray<ProcessRecord>> all 13996 = mProcessNames.getMap(); 13997 SparseArray<ProcessRecord> procs = all.get(process); 13998 if (procs != null && procs.size() > 0) { 13999 proc = procs.valueAt(0); 14000 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14001 for (int i=1; i<procs.size(); i++) { 14002 ProcessRecord thisProc = procs.valueAt(i); 14003 if (thisProc.userId == userId) { 14004 proc = thisProc; 14005 break; 14006 } 14007 } 14008 } 14009 } 14010 } 14011 14012 return proc; 14013 } 14014 14015 public boolean dumpHeap(String process, int userId, boolean managed, 14016 String path, ParcelFileDescriptor fd) throws RemoteException { 14017 14018 try { 14019 synchronized (this) { 14020 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14021 // its own permission (same as profileControl). 14022 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14023 != PackageManager.PERMISSION_GRANTED) { 14024 throw new SecurityException("Requires permission " 14025 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14026 } 14027 14028 if (fd == null) { 14029 throw new IllegalArgumentException("null fd"); 14030 } 14031 14032 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14033 if (proc == null || proc.thread == null) { 14034 throw new IllegalArgumentException("Unknown process: " + process); 14035 } 14036 14037 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14038 if (!isDebuggable) { 14039 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14040 throw new SecurityException("Process not debuggable: " + proc); 14041 } 14042 } 14043 14044 proc.thread.dumpHeap(managed, path, fd); 14045 fd = null; 14046 return true; 14047 } 14048 } catch (RemoteException e) { 14049 throw new IllegalStateException("Process disappeared"); 14050 } finally { 14051 if (fd != null) { 14052 try { 14053 fd.close(); 14054 } catch (IOException e) { 14055 } 14056 } 14057 } 14058 } 14059 14060 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14061 public void monitor() { 14062 synchronized (this) { } 14063 } 14064 14065 void onCoreSettingsChange(Bundle settings) { 14066 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14067 ProcessRecord processRecord = mLruProcesses.get(i); 14068 try { 14069 if (processRecord.thread != null) { 14070 processRecord.thread.setCoreSettings(settings); 14071 } 14072 } catch (RemoteException re) { 14073 /* ignore */ 14074 } 14075 } 14076 } 14077 14078 // Multi-user methods 14079 14080 @Override 14081 public boolean switchUser(int userId) { 14082 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14083 != PackageManager.PERMISSION_GRANTED) { 14084 String msg = "Permission Denial: switchUser() from pid=" 14085 + Binder.getCallingPid() 14086 + ", uid=" + Binder.getCallingUid() 14087 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14088 Slog.w(TAG, msg); 14089 throw new SecurityException(msg); 14090 } 14091 14092 final long ident = Binder.clearCallingIdentity(); 14093 try { 14094 synchronized (this) { 14095 final int oldUserId = mCurrentUserId; 14096 if (oldUserId == userId) { 14097 return true; 14098 } 14099 14100 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14101 if (userInfo == null) { 14102 Slog.w(TAG, "No user info for user #" + userId); 14103 return false; 14104 } 14105 14106 mWindowManager.lockNow(); 14107 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14108 R.anim.screen_user_enter); 14109 14110 // If the user we are switching to is not currently started, then 14111 // we need to start it now. 14112 if (mStartedUsers.get(userId) == null) { 14113 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14114 updateStartedUserArrayLocked(); 14115 } 14116 14117 mCurrentUserId = userId; 14118 mCurrentUserArray = new int[] { userId }; 14119 final Integer userIdInt = Integer.valueOf(userId); 14120 mUserLru.remove(userIdInt); 14121 mUserLru.add(userIdInt); 14122 14123 mWindowManager.setCurrentUser(userId); 14124 14125 final UserStartedState uss = mStartedUsers.get(userId); 14126 14127 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14128 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14129 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14130 oldUserId, userId, uss)); 14131 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14132 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14133 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14134 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14135 | Intent.FLAG_RECEIVER_FOREGROUND); 14136 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14137 broadcastIntentLocked(null, null, intent, 14138 null, null, 0, null, null, null, 14139 false, false, MY_PID, Process.SYSTEM_UID, userId); 14140 14141 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14142 if (userId != 0) { 14143 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14144 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14145 broadcastIntentLocked(null, null, intent, null, 14146 new IIntentReceiver.Stub() { 14147 public void performReceive(Intent intent, int resultCode, 14148 String data, Bundle extras, boolean ordered, 14149 boolean sticky, int sendingUser) { 14150 userInitialized(uss); 14151 } 14152 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14153 userId); 14154 uss.initializing = true; 14155 } else { 14156 getUserManagerLocked().makeInitialized(userInfo.id); 14157 } 14158 } 14159 14160 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14161 if (!haveActivities) { 14162 startHomeActivityLocked(userId); 14163 } 14164 14165 getUserManagerLocked().userForeground(userId); 14166 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14167 } 14168 } finally { 14169 Binder.restoreCallingIdentity(ident); 14170 } 14171 14172 return true; 14173 } 14174 14175 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14176 long ident = Binder.clearCallingIdentity(); 14177 try { 14178 Intent intent; 14179 if (oldUserId >= 0) { 14180 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14181 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14182 | Intent.FLAG_RECEIVER_FOREGROUND); 14183 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14184 broadcastIntentLocked(null, null, intent, 14185 null, null, 0, null, null, null, 14186 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14187 } 14188 if (newUserId >= 0) { 14189 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14190 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14191 | Intent.FLAG_RECEIVER_FOREGROUND); 14192 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14193 broadcastIntentLocked(null, null, intent, 14194 null, null, 0, null, null, null, 14195 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14196 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14197 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14198 | Intent.FLAG_RECEIVER_FOREGROUND); 14199 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14200 broadcastIntentLocked(null, null, intent, 14201 null, null, 0, null, null, 14202 android.Manifest.permission.MANAGE_USERS, 14203 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14204 } 14205 } finally { 14206 Binder.restoreCallingIdentity(ident); 14207 } 14208 } 14209 14210 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14211 final int newUserId) { 14212 final int N = mUserSwitchObservers.beginBroadcast(); 14213 if (N > 0) { 14214 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14215 int mCount = 0; 14216 @Override 14217 public void sendResult(Bundle data) throws RemoteException { 14218 synchronized (ActivityManagerService.this) { 14219 if (mCurUserSwitchCallback == this) { 14220 mCount++; 14221 if (mCount == N) { 14222 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14223 } 14224 } 14225 } 14226 } 14227 }; 14228 synchronized (this) { 14229 uss.switching = true; 14230 mCurUserSwitchCallback = callback; 14231 } 14232 for (int i=0; i<N; i++) { 14233 try { 14234 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14235 newUserId, callback); 14236 } catch (RemoteException e) { 14237 } 14238 } 14239 } else { 14240 synchronized (this) { 14241 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14242 } 14243 } 14244 mUserSwitchObservers.finishBroadcast(); 14245 } 14246 14247 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14248 synchronized (this) { 14249 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14250 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14251 } 14252 } 14253 14254 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14255 mCurUserSwitchCallback = null; 14256 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14257 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14258 oldUserId, newUserId, uss)); 14259 } 14260 14261 void userInitialized(UserStartedState uss) { 14262 synchronized (ActivityManagerService.this) { 14263 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14264 uss.initializing = false; 14265 completeSwitchAndInitalizeLocked(uss); 14266 } 14267 } 14268 14269 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14270 final int N = mUserSwitchObservers.beginBroadcast(); 14271 for (int i=0; i<N; i++) { 14272 try { 14273 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14274 } catch (RemoteException e) { 14275 } 14276 } 14277 mUserSwitchObservers.finishBroadcast(); 14278 synchronized (this) { 14279 uss.switching = false; 14280 completeSwitchAndInitalizeLocked(uss); 14281 } 14282 } 14283 14284 void completeSwitchAndInitalizeLocked(UserStartedState uss) { 14285 if (!uss.switching && !uss.initializing) { 14286 mWindowManager.stopFreezingScreen(); 14287 } 14288 } 14289 14290 void finishUserSwitch(UserStartedState uss) { 14291 synchronized (this) { 14292 if (uss.mState == UserStartedState.STATE_BOOTING 14293 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14294 uss.mState = UserStartedState.STATE_RUNNING; 14295 final int userId = uss.mHandle.getIdentifier(); 14296 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14297 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14298 broadcastIntentLocked(null, null, intent, 14299 null, null, 0, null, null, 14300 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14301 false, false, MY_PID, Process.SYSTEM_UID, userId); 14302 } 14303 int num = mUserLru.size(); 14304 int i = 0; 14305 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14306 Integer oldUserId = mUserLru.get(i); 14307 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14308 if (oldUss == null) { 14309 // Shouldn't happen, but be sane if it does. 14310 mUserLru.remove(i); 14311 num--; 14312 continue; 14313 } 14314 if (oldUss.mState == UserStartedState.STATE_STOPPING) { 14315 // This user is already stopping, doesn't count. 14316 num--; 14317 i++; 14318 continue; 14319 } 14320 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14321 // Owner and current can't be stopped, but count as running. 14322 i++; 14323 continue; 14324 } 14325 // This is a user to be stopped. 14326 stopUserLocked(oldUserId, null); 14327 num--; 14328 i++; 14329 } 14330 } 14331 } 14332 14333 @Override 14334 public int stopUser(final int userId, final IStopUserCallback callback) { 14335 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14336 != PackageManager.PERMISSION_GRANTED) { 14337 String msg = "Permission Denial: switchUser() from pid=" 14338 + Binder.getCallingPid() 14339 + ", uid=" + Binder.getCallingUid() 14340 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14341 Slog.w(TAG, msg); 14342 throw new SecurityException(msg); 14343 } 14344 if (userId <= 0) { 14345 throw new IllegalArgumentException("Can't stop primary user " + userId); 14346 } 14347 synchronized (this) { 14348 return stopUserLocked(userId, callback); 14349 } 14350 } 14351 14352 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14353 if (mCurrentUserId == userId) { 14354 return ActivityManager.USER_OP_IS_CURRENT; 14355 } 14356 14357 final UserStartedState uss = mStartedUsers.get(userId); 14358 if (uss == null) { 14359 // User is not started, nothing to do... but we do need to 14360 // callback if requested. 14361 if (callback != null) { 14362 mHandler.post(new Runnable() { 14363 @Override 14364 public void run() { 14365 try { 14366 callback.userStopped(userId); 14367 } catch (RemoteException e) { 14368 } 14369 } 14370 }); 14371 } 14372 return ActivityManager.USER_OP_SUCCESS; 14373 } 14374 14375 if (callback != null) { 14376 uss.mStopCallbacks.add(callback); 14377 } 14378 14379 if (uss.mState != UserStartedState.STATE_STOPPING) { 14380 uss.mState = UserStartedState.STATE_STOPPING; 14381 14382 long ident = Binder.clearCallingIdentity(); 14383 try { 14384 // Inform of user switch 14385 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14386 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14387 @Override 14388 public void performReceive(Intent intent, int resultCode, String data, 14389 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14390 finishUserStop(uss); 14391 } 14392 }; 14393 broadcastIntentLocked(null, null, intent, 14394 null, resultReceiver, 0, null, null, null, 14395 true, false, MY_PID, Process.SYSTEM_UID, userId); 14396 } finally { 14397 Binder.restoreCallingIdentity(ident); 14398 } 14399 } 14400 14401 return ActivityManager.USER_OP_SUCCESS; 14402 } 14403 14404 void finishUserStop(UserStartedState uss) { 14405 final int userId = uss.mHandle.getIdentifier(); 14406 boolean stopped; 14407 ArrayList<IStopUserCallback> callbacks; 14408 synchronized (this) { 14409 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14410 if (uss.mState != UserStartedState.STATE_STOPPING 14411 || mStartedUsers.get(userId) != uss) { 14412 stopped = false; 14413 } else { 14414 stopped = true; 14415 // User can no longer run. 14416 mStartedUsers.remove(userId); 14417 mUserLru.remove(Integer.valueOf(userId)); 14418 updateStartedUserArrayLocked(); 14419 14420 // Clean up all state and processes associated with the user. 14421 // Kill all the processes for the user. 14422 forceStopUserLocked(userId); 14423 } 14424 } 14425 14426 for (int i=0; i<callbacks.size(); i++) { 14427 try { 14428 if (stopped) callbacks.get(i).userStopped(userId); 14429 else callbacks.get(i).userStopAborted(userId); 14430 } catch (RemoteException e) { 14431 } 14432 } 14433 } 14434 14435 @Override 14436 public UserInfo getCurrentUser() { 14437 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14438 != PackageManager.PERMISSION_GRANTED) && ( 14439 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14440 != PackageManager.PERMISSION_GRANTED)) { 14441 String msg = "Permission Denial: getCurrentUser() from pid=" 14442 + Binder.getCallingPid() 14443 + ", uid=" + Binder.getCallingUid() 14444 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14445 Slog.w(TAG, msg); 14446 throw new SecurityException(msg); 14447 } 14448 synchronized (this) { 14449 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14450 } 14451 } 14452 14453 int getCurrentUserIdLocked() { 14454 return mCurrentUserId; 14455 } 14456 14457 @Override 14458 public boolean isUserRunning(int userId) { 14459 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14460 != PackageManager.PERMISSION_GRANTED) { 14461 String msg = "Permission Denial: isUserRunning() from pid=" 14462 + Binder.getCallingPid() 14463 + ", uid=" + Binder.getCallingUid() 14464 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14465 Slog.w(TAG, msg); 14466 throw new SecurityException(msg); 14467 } 14468 synchronized (this) { 14469 return isUserRunningLocked(userId); 14470 } 14471 } 14472 14473 boolean isUserRunningLocked(int userId) { 14474 UserStartedState state = mStartedUsers.get(userId); 14475 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14476 } 14477 14478 @Override 14479 public int[] getRunningUserIds() { 14480 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14481 != PackageManager.PERMISSION_GRANTED) { 14482 String msg = "Permission Denial: isUserRunning() from pid=" 14483 + Binder.getCallingPid() 14484 + ", uid=" + Binder.getCallingUid() 14485 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14486 Slog.w(TAG, msg); 14487 throw new SecurityException(msg); 14488 } 14489 synchronized (this) { 14490 return mStartedUserArray; 14491 } 14492 } 14493 14494 private void updateStartedUserArrayLocked() { 14495 mStartedUserArray = new int[mStartedUsers.size()]; 14496 for (int i=0; i<mStartedUsers.size(); i++) { 14497 mStartedUserArray[i] = mStartedUsers.keyAt(i); 14498 } 14499 } 14500 14501 @Override 14502 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14503 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14504 != PackageManager.PERMISSION_GRANTED) { 14505 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14506 + Binder.getCallingPid() 14507 + ", uid=" + Binder.getCallingUid() 14508 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14509 Slog.w(TAG, msg); 14510 throw new SecurityException(msg); 14511 } 14512 14513 mUserSwitchObservers.register(observer); 14514 } 14515 14516 @Override 14517 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14518 mUserSwitchObservers.unregister(observer); 14519 } 14520 14521 private boolean userExists(int userId) { 14522 if (userId == 0) { 14523 return true; 14524 } 14525 UserManagerService ums = getUserManagerLocked(); 14526 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14527 } 14528 14529 int[] getUsersLocked() { 14530 UserManagerService ums = getUserManagerLocked(); 14531 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14532 } 14533 14534 UserManagerService getUserManagerLocked() { 14535 if (mUserManager == null) { 14536 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14537 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14538 } 14539 return mUserManager; 14540 } 14541 14542 private void checkValidCaller(int uid, int userId) { 14543 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14544 14545 throw new SecurityException("Caller uid=" + uid 14546 + " is not privileged to communicate with user=" + userId); 14547 } 14548 14549 private int applyUserId(int uid, int userId) { 14550 return UserHandle.getUid(userId, uid); 14551 } 14552 14553 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14554 if (info == null) return null; 14555 ApplicationInfo newInfo = new ApplicationInfo(info); 14556 newInfo.uid = applyUserId(info.uid, userId); 14557 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14558 + info.packageName; 14559 return newInfo; 14560 } 14561 14562 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14563 if (aInfo == null 14564 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14565 return aInfo; 14566 } 14567 14568 ActivityInfo info = new ActivityInfo(aInfo); 14569 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14570 return info; 14571 } 14572} 14573