ActivityManagerService.java revision a8a9bd65bf5865d83ef44f54552ca39522bfbcf0
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.internal.widget.LockPatternUtils; 25import com.android.server.AttributeCache; 26import com.android.server.IntentResolver; 27import com.android.server.ProcessMap; 28import com.android.server.SystemServer; 29import com.android.server.Watchdog; 30import com.android.server.am.ActivityStack.ActivityState; 31import com.android.server.pm.UserManagerService; 32import com.android.server.wm.WindowManagerService; 33 34import dalvik.system.Zygote; 35 36import android.app.Activity; 37import android.app.ActivityManager; 38import android.app.ActivityManagerNative; 39import android.app.ActivityOptions; 40import android.app.ActivityThread; 41import android.app.AlertDialog; 42import android.app.AppGlobals; 43import android.app.ApplicationErrorReport; 44import android.app.Dialog; 45import android.app.IActivityController; 46import android.app.IApplicationThread; 47import android.app.IInstrumentationWatcher; 48import android.app.INotificationManager; 49import android.app.IProcessObserver; 50import android.app.IServiceConnection; 51import android.app.IStopUserCallback; 52import android.app.IThumbnailReceiver; 53import android.app.IUserSwitchObserver; 54import android.app.Instrumentation; 55import android.app.Notification; 56import android.app.NotificationManager; 57import android.app.PendingIntent; 58import android.app.backup.IBackupManager; 59import android.content.ActivityNotFoundException; 60import android.content.BroadcastReceiver; 61import android.content.ClipData; 62import android.content.ComponentCallbacks2; 63import android.content.ComponentName; 64import android.content.ContentProvider; 65import android.content.ContentResolver; 66import android.content.Context; 67import android.content.DialogInterface; 68import android.content.IContentProvider; 69import android.content.IIntentReceiver; 70import android.content.IIntentSender; 71import android.content.Intent; 72import android.content.IntentFilter; 73import android.content.IntentSender; 74import android.content.pm.ActivityInfo; 75import android.content.pm.ApplicationInfo; 76import android.content.pm.ConfigurationInfo; 77import android.content.pm.IPackageDataObserver; 78import android.content.pm.IPackageManager; 79import android.content.pm.InstrumentationInfo; 80import android.content.pm.PackageInfo; 81import android.content.pm.PackageManager; 82import android.content.pm.UserInfo; 83import android.content.pm.PackageManager.NameNotFoundException; 84import android.content.pm.PathPermission; 85import android.content.pm.ProviderInfo; 86import android.content.pm.ResolveInfo; 87import android.content.pm.ServiceInfo; 88import android.content.res.CompatibilityInfo; 89import android.content.res.Configuration; 90import android.graphics.Bitmap; 91import android.net.Proxy; 92import android.net.ProxyProperties; 93import android.net.Uri; 94import android.os.Binder; 95import android.os.Build; 96import android.os.Bundle; 97import android.os.Debug; 98import android.os.DropBoxManager; 99import android.os.Environment; 100import android.os.FileObserver; 101import android.os.FileUtils; 102import android.os.Handler; 103import android.os.IBinder; 104import android.os.IPermissionController; 105import android.os.IRemoteCallback; 106import android.os.IUserManager; 107import android.os.Looper; 108import android.os.Message; 109import android.os.Parcel; 110import android.os.ParcelFileDescriptor; 111import android.os.Process; 112import android.os.RemoteCallbackList; 113import android.os.RemoteException; 114import android.os.SELinux; 115import android.os.ServiceManager; 116import android.os.StrictMode; 117import android.os.SystemClock; 118import android.os.SystemProperties; 119import android.os.UserHandle; 120import android.provider.Settings; 121import android.text.format.Time; 122import android.util.EventLog; 123import android.util.Log; 124import android.util.Pair; 125import android.util.PrintWriterPrinter; 126import android.util.Slog; 127import android.util.SparseArray; 128import android.util.TimeUtils; 129import android.view.Gravity; 130import android.view.LayoutInflater; 131import android.view.View; 132import android.view.WindowManager; 133import android.view.WindowManagerPolicy; 134 135import java.io.BufferedInputStream; 136import java.io.BufferedOutputStream; 137import java.io.BufferedReader; 138import java.io.DataInputStream; 139import java.io.DataOutputStream; 140import java.io.File; 141import java.io.FileDescriptor; 142import java.io.FileInputStream; 143import java.io.FileNotFoundException; 144import java.io.FileOutputStream; 145import java.io.IOException; 146import java.io.InputStreamReader; 147import java.io.PrintWriter; 148import java.io.StringWriter; 149import java.lang.ref.WeakReference; 150import java.util.ArrayList; 151import java.util.Arrays; 152import java.util.Collections; 153import java.util.Comparator; 154import java.util.HashMap; 155import java.util.HashSet; 156import java.util.Iterator; 157import java.util.List; 158import java.util.Locale; 159import java.util.Map; 160import java.util.Set; 161import java.util.concurrent.atomic.AtomicBoolean; 162import java.util.concurrent.atomic.AtomicLong; 163 164public final class ActivityManagerService extends ActivityManagerNative 165 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 166 private static final String USER_DATA_DIR = "/data/user/"; 167 static final String TAG = "ActivityManager"; 168 static final String TAG_MU = "ActivityManagerServiceMU"; 169 static final boolean DEBUG = false; 170 static final boolean localLOGV = DEBUG; 171 static final boolean DEBUG_SWITCH = localLOGV || false; 172 static final boolean DEBUG_TASKS = localLOGV || false; 173 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 174 static final boolean DEBUG_PAUSE = localLOGV || false; 175 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 176 static final boolean DEBUG_TRANSITION = localLOGV || false; 177 static final boolean DEBUG_BROADCAST = localLOGV || false; 178 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 180 static final boolean DEBUG_SERVICE = localLOGV || false; 181 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 182 static final boolean DEBUG_VISBILITY = localLOGV || false; 183 static final boolean DEBUG_PROCESSES = localLOGV || false; 184 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 185 static final boolean DEBUG_CLEANUP = localLOGV || false; 186 static final boolean DEBUG_PROVIDER = localLOGV || false; 187 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 188 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 189 static final boolean DEBUG_RESULTS = localLOGV || false; 190 static final boolean DEBUG_BACKUP = localLOGV || false; 191 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 192 static final boolean DEBUG_POWER = localLOGV || false; 193 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 194 static final boolean DEBUG_MU = localLOGV || false; 195 static final boolean VALIDATE_TOKENS = false; 196 static final boolean SHOW_ACTIVITY_START_TIME = true; 197 198 // Control over CPU and battery monitoring. 199 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 200 static final boolean MONITOR_CPU_USAGE = true; 201 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 202 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 203 static final boolean MONITOR_THREAD_CPU_USAGE = false; 204 205 // The flags that are set for all calls we make to the package manager. 206 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 207 208 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 209 210 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 211 212 // Maximum number of recent tasks that we can remember. 213 static final int MAX_RECENT_TASKS = 20; 214 215 // Amount of time after a call to stopAppSwitches() during which we will 216 // prevent further untrusted switches from happening. 217 static final long APP_SWITCH_DELAY_TIME = 5*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real. 221 static final int PROC_START_TIMEOUT = 10*1000; 222 223 // How long we wait for a launched process to attach to the activity manager 224 // before we decide it's never going to come up for real, when the process was 225 // started with a wrapper for instrumentation (such as Valgrind) because it 226 // could take much longer than usual. 227 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 228 229 // How long to wait after going idle before forcing apps to GC. 230 static final int GC_TIMEOUT = 5*1000; 231 232 // The minimum amount of time between successive GC requests for a process. 233 static final int GC_MIN_INTERVAL = 60*1000; 234 235 // The rate at which we check for apps using excessive power -- 15 mins. 236 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on wake locks to start killing things. 240 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // The minimum sample duration we will allow before deciding we have 243 // enough data on CPU usage to start killing things. 244 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 245 246 // How long we allow a receiver to run before giving up on it. 247 static final int BROADCAST_FG_TIMEOUT = 10*1000; 248 static final int BROADCAST_BG_TIMEOUT = 60*1000; 249 250 // How long we wait until we timeout on key dispatching. 251 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 252 253 // How long we wait until we timeout on key dispatching during instrumentation. 254 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 255 256 // Amount of time we wait for observers to handle a user switch before 257 // giving up on them and unfreezing the screen. 258 static final int USER_SWITCH_TIMEOUT = 2*1000; 259 260 // Maximum number of users we allow to be running at a time. 261 static final int MAX_RUNNING_USERS = 3; 262 263 static final int MY_PID = Process.myPid(); 264 265 static final String[] EMPTY_STRING_ARRAY = new String[0]; 266 267 public ActivityStack mMainStack; 268 269 private final boolean mHeadless; 270 271 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 272 // default actuion automatically. Important for devices without direct input 273 // devices. 274 private boolean mShowDialogs = true; 275 276 /** 277 * Description of a request to start a new activity, which has been held 278 * due to app switches being disabled. 279 */ 280 static class PendingActivityLaunch { 281 ActivityRecord r; 282 ActivityRecord sourceRecord; 283 int startFlags; 284 } 285 286 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 287 = new ArrayList<PendingActivityLaunch>(); 288 289 290 BroadcastQueue mFgBroadcastQueue; 291 BroadcastQueue mBgBroadcastQueue; 292 // Convenient for easy iteration over the queues. Foreground is first 293 // so that dispatch of foreground broadcasts gets precedence. 294 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 295 296 BroadcastQueue broadcastQueueForIntent(Intent intent) { 297 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 298 if (DEBUG_BACKGROUND_BROADCAST) { 299 Slog.i(TAG, "Broadcast intent " + intent + " on " 300 + (isFg ? "foreground" : "background") 301 + " queue"); 302 } 303 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 304 } 305 306 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 307 for (BroadcastQueue queue : mBroadcastQueues) { 308 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 309 if (r != null) { 310 return r; 311 } 312 } 313 return null; 314 } 315 316 /** 317 * Activity we have told the window manager to have key focus. 318 */ 319 ActivityRecord mFocusedActivity = null; 320 /** 321 * List of intents that were used to start the most recent tasks. 322 */ 323 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 324 325 /** 326 * Process management. 327 */ 328 final ProcessList mProcessList = new ProcessList(); 329 330 /** 331 * All of the applications we currently have running organized by name. 332 * The keys are strings of the application package name (as 333 * returned by the package manager), and the keys are ApplicationRecord 334 * objects. 335 */ 336 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 337 338 /** 339 * The currently running isolated processes. 340 */ 341 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 342 343 /** 344 * Counter for assigning isolated process uids, to avoid frequently reusing the 345 * same ones. 346 */ 347 int mNextIsolatedProcessUid = 0; 348 349 /** 350 * The currently running heavy-weight process, if any. 351 */ 352 ProcessRecord mHeavyWeightProcess = null; 353 354 /** 355 * The last time that various processes have crashed. 356 */ 357 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 358 359 /** 360 * Set of applications that we consider to be bad, and will reject 361 * incoming broadcasts from (which the user has no control over). 362 * Processes are added to this set when they have crashed twice within 363 * a minimum amount of time; they are removed from it when they are 364 * later restarted (hopefully due to some user action). The value is the 365 * time it was added to the list. 366 */ 367 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 368 369 /** 370 * All of the processes we currently have running organized by pid. 371 * The keys are the pid running the application. 372 * 373 * <p>NOTE: This object is protected by its own lock, NOT the global 374 * activity manager lock! 375 */ 376 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 377 378 /** 379 * All of the processes that have been forced to be foreground. The key 380 * is the pid of the caller who requested it (we hold a death 381 * link on it). 382 */ 383 abstract class ForegroundToken implements IBinder.DeathRecipient { 384 int pid; 385 IBinder token; 386 } 387 final SparseArray<ForegroundToken> mForegroundProcesses 388 = new SparseArray<ForegroundToken>(); 389 390 /** 391 * List of records for processes that someone had tried to start before the 392 * system was ready. We don't start them at that point, but ensure they 393 * are started by the time booting is complete. 394 */ 395 final ArrayList<ProcessRecord> mProcessesOnHold 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of persistent applications that are in the process 400 * of being started. 401 */ 402 final ArrayList<ProcessRecord> mPersistentStartingProcesses 403 = new ArrayList<ProcessRecord>(); 404 405 /** 406 * Processes that are being forcibly torn down. 407 */ 408 final ArrayList<ProcessRecord> mRemovedProcesses 409 = new ArrayList<ProcessRecord>(); 410 411 /** 412 * List of running applications, sorted by recent usage. 413 * The first entry in the list is the least recently used. 414 * It contains ApplicationRecord objects. This list does NOT include 415 * any persistent application records (since we never want to exit them). 416 */ 417 final ArrayList<ProcessRecord> mLruProcesses 418 = new ArrayList<ProcessRecord>(); 419 420 /** 421 * List of processes that should gc as soon as things are idle. 422 */ 423 final ArrayList<ProcessRecord> mProcessesToGc 424 = new ArrayList<ProcessRecord>(); 425 426 /** 427 * This is the process holding what we currently consider to be 428 * the "home" activity. 429 */ 430 ProcessRecord mHomeProcess; 431 432 /** 433 * This is the process holding the activity the user last visited that 434 * is in a different process from the one they are currently in. 435 */ 436 ProcessRecord mPreviousProcess; 437 438 /** 439 * The time at which the previous process was last visible. 440 */ 441 long mPreviousProcessVisibleTime; 442 443 /** 444 * Which uses have been started, so are allowed to run code. 445 */ 446 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 447 448 /** 449 * LRU list of history of current users. Most recently current is at the end. 450 */ 451 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 452 453 /** 454 * Constant array of the users that are currently started. 455 */ 456 int[] mStartedUserArray = new int[] { 0 }; 457 458 /** 459 * Registered observers of the user switching mechanics. 460 */ 461 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 462 = new RemoteCallbackList<IUserSwitchObserver>(); 463 464 /** 465 * Currently active user switch. 466 */ 467 Object mCurUserSwitchCallback; 468 469 /** 470 * Packages that the user has asked to have run in screen size 471 * compatibility mode instead of filling the screen. 472 */ 473 final CompatModePackages mCompatModePackages; 474 475 /** 476 * Set of PendingResultRecord objects that are currently active. 477 */ 478 final HashSet mPendingResultRecords = new HashSet(); 479 480 /** 481 * Set of IntentSenderRecord objects that are currently active. 482 */ 483 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 484 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 485 486 /** 487 * Fingerprints (hashCode()) of stack traces that we've 488 * already logged DropBox entries for. Guarded by itself. If 489 * something (rogue user app) forces this over 490 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 491 */ 492 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 493 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 494 495 /** 496 * Strict Mode background batched logging state. 497 * 498 * The string buffer is guarded by itself, and its lock is also 499 * used to determine if another batched write is already 500 * in-flight. 501 */ 502 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 503 504 /** 505 * Keeps track of all IIntentReceivers that have been registered for 506 * broadcasts. Hash keys are the receiver IBinder, hash value is 507 * a ReceiverList. 508 */ 509 final HashMap mRegisteredReceivers = new HashMap(); 510 511 /** 512 * Resolver for broadcast intents to registered receivers. 513 * Holds BroadcastFilter (subclass of IntentFilter). 514 */ 515 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 516 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 517 @Override 518 protected boolean allowFilterResult( 519 BroadcastFilter filter, List<BroadcastFilter> dest) { 520 IBinder target = filter.receiverList.receiver.asBinder(); 521 for (int i=dest.size()-1; i>=0; i--) { 522 if (dest.get(i).receiverList.receiver.asBinder() == target) { 523 return false; 524 } 525 } 526 return true; 527 } 528 529 @Override 530 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 531 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 532 || userId == filter.owningUserId) { 533 return super.newResult(filter, match, userId); 534 } 535 return null; 536 } 537 538 @Override 539 protected BroadcastFilter[] newArray(int size) { 540 return new BroadcastFilter[size]; 541 } 542 543 @Override 544 protected String packageForFilter(BroadcastFilter filter) { 545 return filter.packageName; 546 } 547 }; 548 549 /** 550 * State of all active sticky broadcasts per user. Keys are the action of the 551 * sticky Intent, values are an ArrayList of all broadcasted intents with 552 * that action (which should usually be one). The SparseArray is keyed 553 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 554 * for stickies that are sent to all users. 555 */ 556 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 557 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 558 559 final ActiveServices mServices; 560 561 /** 562 * Backup/restore process management 563 */ 564 String mBackupAppName = null; 565 BackupRecord mBackupTarget = null; 566 567 /** 568 * List of PendingThumbnailsRecord objects of clients who are still 569 * waiting to receive all of the thumbnails for a task. 570 */ 571 final ArrayList mPendingThumbnails = new ArrayList(); 572 573 /** 574 * List of HistoryRecord objects that have been finished and must 575 * still report back to a pending thumbnail receiver. 576 */ 577 final ArrayList mCancelledThumbnails = new ArrayList(); 578 579 final ProviderMap mProviderMap; 580 581 /** 582 * List of content providers who have clients waiting for them. The 583 * application is currently being launched and the provider will be 584 * removed from this list once it is published. 585 */ 586 final ArrayList<ContentProviderRecord> mLaunchingProviders 587 = new ArrayList<ContentProviderRecord>(); 588 589 /** 590 * Global set of specific Uri permissions that have been granted. 591 */ 592 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 593 = new SparseArray<HashMap<Uri, UriPermission>>(); 594 595 CoreSettingsObserver mCoreSettingsObserver; 596 597 /** 598 * Thread-local storage used to carry caller permissions over through 599 * indirect content-provider access. 600 * @see #ActivityManagerService.openContentUri() 601 */ 602 private class Identity { 603 public int pid; 604 public int uid; 605 606 Identity(int _pid, int _uid) { 607 pid = _pid; 608 uid = _uid; 609 } 610 } 611 612 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 613 614 /** 615 * All information we have collected about the runtime performance of 616 * any user id that can impact battery performance. 617 */ 618 final BatteryStatsService mBatteryStatsService; 619 620 /** 621 * information about component usage 622 */ 623 final UsageStatsService mUsageStatsService; 624 625 /** 626 * Current configuration information. HistoryRecord objects are given 627 * a reference to this object to indicate which configuration they are 628 * currently running in, so this object must be kept immutable. 629 */ 630 Configuration mConfiguration = new Configuration(); 631 632 /** 633 * Current sequencing integer of the configuration, for skipping old 634 * configurations. 635 */ 636 int mConfigurationSeq = 0; 637 638 /** 639 * Hardware-reported OpenGLES version. 640 */ 641 final int GL_ES_VERSION; 642 643 /** 644 * List of initialization arguments to pass to all processes when binding applications to them. 645 * For example, references to the commonly used services. 646 */ 647 HashMap<String, IBinder> mAppBindArgs; 648 649 /** 650 * Temporary to avoid allocations. Protected by main lock. 651 */ 652 final StringBuilder mStringBuilder = new StringBuilder(256); 653 654 /** 655 * Used to control how we initialize the service. 656 */ 657 boolean mStartRunning = false; 658 ComponentName mTopComponent; 659 String mTopAction; 660 String mTopData; 661 boolean mProcessesReady = false; 662 boolean mSystemReady = false; 663 boolean mBooting = false; 664 boolean mWaitingUpdate = false; 665 boolean mDidUpdate = false; 666 boolean mOnBattery = false; 667 boolean mLaunchWarningShown = false; 668 669 Context mContext; 670 671 int mFactoryTest; 672 673 boolean mCheckedForSetup; 674 675 /** 676 * The time at which we will allow normal application switches again, 677 * after a call to {@link #stopAppSwitches()}. 678 */ 679 long mAppSwitchesAllowedTime; 680 681 /** 682 * This is set to true after the first switch after mAppSwitchesAllowedTime 683 * is set; any switches after that will clear the time. 684 */ 685 boolean mDidAppSwitch; 686 687 /** 688 * Last time (in realtime) at which we checked for power usage. 689 */ 690 long mLastPowerCheckRealtime; 691 692 /** 693 * Last time (in uptime) at which we checked for power usage. 694 */ 695 long mLastPowerCheckUptime; 696 697 /** 698 * Set while we are wanting to sleep, to prevent any 699 * activities from being started/resumed. 700 */ 701 boolean mSleeping = false; 702 703 /** 704 * State of external calls telling us if the device is asleep. 705 */ 706 boolean mWentToSleep = false; 707 708 /** 709 * State of external call telling us if the lock screen is shown. 710 */ 711 boolean mLockScreenShown = false; 712 713 /** 714 * Set if we are shutting down the system, similar to sleeping. 715 */ 716 boolean mShuttingDown = false; 717 718 /** 719 * Task identifier that activities are currently being started 720 * in. Incremented each time a new task is created. 721 * todo: Replace this with a TokenSpace class that generates non-repeating 722 * integers that won't wrap. 723 */ 724 int mCurTask = 1; 725 726 /** 727 * Current sequence id for oom_adj computation traversal. 728 */ 729 int mAdjSeq = 0; 730 731 /** 732 * Current sequence id for process LRU updating. 733 */ 734 int mLruSeq = 0; 735 736 /** 737 * Keep track of the non-hidden/empty process we last found, to help 738 * determine how to distribute hidden/empty processes next time. 739 */ 740 int mNumNonHiddenProcs = 0; 741 742 /** 743 * Keep track of the number of hidden procs, to balance oom adj 744 * distribution between those and empty procs. 745 */ 746 int mNumHiddenProcs = 0; 747 748 /** 749 * Keep track of the number of service processes we last found, to 750 * determine on the next iteration which should be B services. 751 */ 752 int mNumServiceProcs = 0; 753 int mNewNumServiceProcs = 0; 754 755 /** 756 * System monitoring: number of processes that died since the last 757 * N procs were started. 758 */ 759 int[] mProcDeaths = new int[20]; 760 761 /** 762 * This is set if we had to do a delayed dexopt of an app before launching 763 * it, to increasing the ANR timeouts in that case. 764 */ 765 boolean mDidDexOpt; 766 767 String mDebugApp = null; 768 boolean mWaitForDebugger = false; 769 boolean mDebugTransient = false; 770 String mOrigDebugApp = null; 771 boolean mOrigWaitForDebugger = false; 772 boolean mAlwaysFinishActivities = false; 773 IActivityController mController = null; 774 String mProfileApp = null; 775 ProcessRecord mProfileProc = null; 776 String mProfileFile; 777 ParcelFileDescriptor mProfileFd; 778 int mProfileType = 0; 779 boolean mAutoStopProfiler = false; 780 String mOpenGlTraceApp = null; 781 782 static class ProcessChangeItem { 783 static final int CHANGE_ACTIVITIES = 1<<0; 784 static final int CHANGE_IMPORTANCE= 1<<1; 785 int changes; 786 int uid; 787 int pid; 788 int importance; 789 boolean foregroundActivities; 790 } 791 792 final RemoteCallbackList<IProcessObserver> mProcessObservers 793 = new RemoteCallbackList<IProcessObserver>(); 794 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 795 796 final ArrayList<ProcessChangeItem> mPendingProcessChanges 797 = new ArrayList<ProcessChangeItem>(); 798 final ArrayList<ProcessChangeItem> mAvailProcessChanges 799 = new ArrayList<ProcessChangeItem>(); 800 801 /** 802 * Callback of last caller to {@link #requestPss}. 803 */ 804 Runnable mRequestPssCallback; 805 806 /** 807 * Remaining processes for which we are waiting results from the last 808 * call to {@link #requestPss}. 809 */ 810 final ArrayList<ProcessRecord> mRequestPssList 811 = new ArrayList<ProcessRecord>(); 812 813 /** 814 * Runtime statistics collection thread. This object's lock is used to 815 * protect all related state. 816 */ 817 final Thread mProcessStatsThread; 818 819 /** 820 * Used to collect process stats when showing not responding dialog. 821 * Protected by mProcessStatsThread. 822 */ 823 final ProcessStats mProcessStats = new ProcessStats( 824 MONITOR_THREAD_CPU_USAGE); 825 final AtomicLong mLastCpuTime = new AtomicLong(0); 826 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 827 828 long mLastWriteTime = 0; 829 830 /** 831 * Set to true after the system has finished booting. 832 */ 833 boolean mBooted = false; 834 835 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 836 int mProcessLimitOverride = -1; 837 838 WindowManagerService mWindowManager; 839 840 static ActivityManagerService mSelf; 841 static ActivityThread mSystemThread; 842 843 private int mCurrentUserId = 0; 844 private int[] mCurrentUserArray = new int[] { 0 }; 845 private UserManagerService mUserManager; 846 847 private final class AppDeathRecipient implements IBinder.DeathRecipient { 848 final ProcessRecord mApp; 849 final int mPid; 850 final IApplicationThread mAppThread; 851 852 AppDeathRecipient(ProcessRecord app, int pid, 853 IApplicationThread thread) { 854 if (localLOGV) Slog.v( 855 TAG, "New death recipient " + this 856 + " for thread " + thread.asBinder()); 857 mApp = app; 858 mPid = pid; 859 mAppThread = thread; 860 } 861 862 public void binderDied() { 863 if (localLOGV) Slog.v( 864 TAG, "Death received in " + this 865 + " for thread " + mAppThread.asBinder()); 866 synchronized(ActivityManagerService.this) { 867 appDiedLocked(mApp, mPid, mAppThread); 868 } 869 } 870 } 871 872 static final int SHOW_ERROR_MSG = 1; 873 static final int SHOW_NOT_RESPONDING_MSG = 2; 874 static final int SHOW_FACTORY_ERROR_MSG = 3; 875 static final int UPDATE_CONFIGURATION_MSG = 4; 876 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 877 static final int WAIT_FOR_DEBUGGER_MSG = 6; 878 static final int SERVICE_TIMEOUT_MSG = 12; 879 static final int UPDATE_TIME_ZONE = 13; 880 static final int SHOW_UID_ERROR_MSG = 14; 881 static final int IM_FEELING_LUCKY_MSG = 15; 882 static final int PROC_START_TIMEOUT_MSG = 20; 883 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 884 static final int KILL_APPLICATION_MSG = 22; 885 static final int FINALIZE_PENDING_INTENT_MSG = 23; 886 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 887 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 888 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 889 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 890 static final int CLEAR_DNS_CACHE = 28; 891 static final int UPDATE_HTTP_PROXY = 29; 892 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 893 static final int DISPATCH_PROCESSES_CHANGED = 31; 894 static final int DISPATCH_PROCESS_DIED = 32; 895 static final int REPORT_MEM_USAGE = 33; 896 static final int REPORT_USER_SWITCH_MSG = 34; 897 static final int CONTINUE_USER_SWITCH_MSG = 35; 898 static final int USER_SWITCH_TIMEOUT_MSG = 36; 899 900 static final int FIRST_ACTIVITY_STACK_MSG = 100; 901 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 902 static final int FIRST_COMPAT_MODE_MSG = 300; 903 904 AlertDialog mUidAlert; 905 CompatModeDialog mCompatModeDialog; 906 long mLastMemUsageReportTime = 0; 907 908 final Handler mHandler = new Handler() { 909 //public Handler() { 910 // if (localLOGV) Slog.v(TAG, "Handler started!"); 911 //} 912 913 public void handleMessage(Message msg) { 914 switch (msg.what) { 915 case SHOW_ERROR_MSG: { 916 HashMap data = (HashMap) msg.obj; 917 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 918 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 919 synchronized (ActivityManagerService.this) { 920 ProcessRecord proc = (ProcessRecord)data.get("app"); 921 AppErrorResult res = (AppErrorResult) data.get("result"); 922 if (proc != null && proc.crashDialog != null) { 923 Slog.e(TAG, "App already has crash dialog: " + proc); 924 if (res != null) { 925 res.set(0); 926 } 927 return; 928 } 929 if (!showBackground && UserHandle.getAppId(proc.uid) 930 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 931 && proc.pid != MY_PID) { 932 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 933 if (res != null) { 934 res.set(0); 935 } 936 return; 937 } 938 if (mShowDialogs && !mSleeping && !mShuttingDown) { 939 Dialog d = new AppErrorDialog(mContext, 940 ActivityManagerService.this, res, proc); 941 d.show(); 942 proc.crashDialog = d; 943 } else { 944 // The device is asleep, so just pretend that the user 945 // saw a crash dialog and hit "force quit". 946 if (res != null) { 947 res.set(0); 948 } 949 } 950 } 951 952 ensureBootCompleted(); 953 } break; 954 case SHOW_NOT_RESPONDING_MSG: { 955 synchronized (ActivityManagerService.this) { 956 HashMap data = (HashMap) msg.obj; 957 ProcessRecord proc = (ProcessRecord)data.get("app"); 958 if (proc != null && proc.anrDialog != null) { 959 Slog.e(TAG, "App already has anr dialog: " + proc); 960 return; 961 } 962 963 Intent intent = new Intent("android.intent.action.ANR"); 964 if (!mProcessesReady) { 965 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 966 | Intent.FLAG_RECEIVER_FOREGROUND); 967 } 968 broadcastIntentLocked(null, null, intent, 969 null, null, 0, null, null, null, 970 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 971 972 if (mShowDialogs) { 973 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 974 mContext, proc, (ActivityRecord)data.get("activity"), 975 msg.arg1 != 0); 976 d.show(); 977 proc.anrDialog = d; 978 } else { 979 // Just kill the app if there is no dialog to be shown. 980 killAppAtUsersRequest(proc, null); 981 } 982 } 983 984 ensureBootCompleted(); 985 } break; 986 case SHOW_STRICT_MODE_VIOLATION_MSG: { 987 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 988 synchronized (ActivityManagerService.this) { 989 ProcessRecord proc = (ProcessRecord) data.get("app"); 990 if (proc == null) { 991 Slog.e(TAG, "App not found when showing strict mode dialog."); 992 break; 993 } 994 if (proc.crashDialog != null) { 995 Slog.e(TAG, "App already has strict mode dialog: " + proc); 996 return; 997 } 998 AppErrorResult res = (AppErrorResult) data.get("result"); 999 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1000 Dialog d = new StrictModeViolationDialog(mContext, 1001 ActivityManagerService.this, res, proc); 1002 d.show(); 1003 proc.crashDialog = d; 1004 } else { 1005 // The device is asleep, so just pretend that the user 1006 // saw a crash dialog and hit "force quit". 1007 res.set(0); 1008 } 1009 } 1010 ensureBootCompleted(); 1011 } break; 1012 case SHOW_FACTORY_ERROR_MSG: { 1013 Dialog d = new FactoryErrorDialog( 1014 mContext, msg.getData().getCharSequence("msg")); 1015 d.show(); 1016 ensureBootCompleted(); 1017 } break; 1018 case UPDATE_CONFIGURATION_MSG: { 1019 final ContentResolver resolver = mContext.getContentResolver(); 1020 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1021 } break; 1022 case GC_BACKGROUND_PROCESSES_MSG: { 1023 synchronized (ActivityManagerService.this) { 1024 performAppGcsIfAppropriateLocked(); 1025 } 1026 } break; 1027 case WAIT_FOR_DEBUGGER_MSG: { 1028 synchronized (ActivityManagerService.this) { 1029 ProcessRecord app = (ProcessRecord)msg.obj; 1030 if (msg.arg1 != 0) { 1031 if (!app.waitedForDebugger) { 1032 Dialog d = new AppWaitingForDebuggerDialog( 1033 ActivityManagerService.this, 1034 mContext, app); 1035 app.waitDialog = d; 1036 app.waitedForDebugger = true; 1037 d.show(); 1038 } 1039 } else { 1040 if (app.waitDialog != null) { 1041 app.waitDialog.dismiss(); 1042 app.waitDialog = null; 1043 } 1044 } 1045 } 1046 } break; 1047 case SERVICE_TIMEOUT_MSG: { 1048 if (mDidDexOpt) { 1049 mDidDexOpt = false; 1050 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1051 nmsg.obj = msg.obj; 1052 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1053 return; 1054 } 1055 mServices.serviceTimeout((ProcessRecord)msg.obj); 1056 } break; 1057 case UPDATE_TIME_ZONE: { 1058 synchronized (ActivityManagerService.this) { 1059 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1060 ProcessRecord r = mLruProcesses.get(i); 1061 if (r.thread != null) { 1062 try { 1063 r.thread.updateTimeZone(); 1064 } catch (RemoteException ex) { 1065 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1066 } 1067 } 1068 } 1069 } 1070 } break; 1071 case CLEAR_DNS_CACHE: { 1072 synchronized (ActivityManagerService.this) { 1073 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1074 ProcessRecord r = mLruProcesses.get(i); 1075 if (r.thread != null) { 1076 try { 1077 r.thread.clearDnsCache(); 1078 } catch (RemoteException ex) { 1079 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1080 } 1081 } 1082 } 1083 } 1084 } break; 1085 case UPDATE_HTTP_PROXY: { 1086 ProxyProperties proxy = (ProxyProperties)msg.obj; 1087 String host = ""; 1088 String port = ""; 1089 String exclList = ""; 1090 if (proxy != null) { 1091 host = proxy.getHost(); 1092 port = Integer.toString(proxy.getPort()); 1093 exclList = proxy.getExclusionList(); 1094 } 1095 synchronized (ActivityManagerService.this) { 1096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1097 ProcessRecord r = mLruProcesses.get(i); 1098 if (r.thread != null) { 1099 try { 1100 r.thread.setHttpProxy(host, port, exclList); 1101 } catch (RemoteException ex) { 1102 Slog.w(TAG, "Failed to update http proxy for: " + 1103 r.info.processName); 1104 } 1105 } 1106 } 1107 } 1108 } break; 1109 case SHOW_UID_ERROR_MSG: { 1110 String title = "System UIDs Inconsistent"; 1111 String text = "UIDs on the system are inconsistent, you need to wipe your" 1112 + " data partition or your device will be unstable."; 1113 Log.e(TAG, title + ": " + text); 1114 if (mShowDialogs) { 1115 // XXX This is a temporary dialog, no need to localize. 1116 AlertDialog d = new BaseErrorDialog(mContext); 1117 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1118 d.setCancelable(false); 1119 d.setTitle(title); 1120 d.setMessage(text); 1121 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1122 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1123 mUidAlert = d; 1124 d.show(); 1125 } 1126 } break; 1127 case IM_FEELING_LUCKY_MSG: { 1128 if (mUidAlert != null) { 1129 mUidAlert.dismiss(); 1130 mUidAlert = null; 1131 } 1132 } break; 1133 case PROC_START_TIMEOUT_MSG: { 1134 if (mDidDexOpt) { 1135 mDidDexOpt = false; 1136 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1137 nmsg.obj = msg.obj; 1138 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1139 return; 1140 } 1141 ProcessRecord app = (ProcessRecord)msg.obj; 1142 synchronized (ActivityManagerService.this) { 1143 processStartTimedOutLocked(app); 1144 } 1145 } break; 1146 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1147 synchronized (ActivityManagerService.this) { 1148 doPendingActivityLaunchesLocked(true); 1149 } 1150 } break; 1151 case KILL_APPLICATION_MSG: { 1152 synchronized (ActivityManagerService.this) { 1153 int appid = msg.arg1; 1154 boolean restart = (msg.arg2 == 1); 1155 String pkg = (String) msg.obj; 1156 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1157 UserHandle.USER_ALL); 1158 } 1159 } break; 1160 case FINALIZE_PENDING_INTENT_MSG: { 1161 ((PendingIntentRecord)msg.obj).completeFinalize(); 1162 } break; 1163 case POST_HEAVY_NOTIFICATION_MSG: { 1164 INotificationManager inm = NotificationManager.getService(); 1165 if (inm == null) { 1166 return; 1167 } 1168 1169 ActivityRecord root = (ActivityRecord)msg.obj; 1170 ProcessRecord process = root.app; 1171 if (process == null) { 1172 return; 1173 } 1174 1175 try { 1176 Context context = mContext.createPackageContext(process.info.packageName, 0); 1177 String text = mContext.getString(R.string.heavy_weight_notification, 1178 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1179 Notification notification = new Notification(); 1180 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1181 notification.when = 0; 1182 notification.flags = Notification.FLAG_ONGOING_EVENT; 1183 notification.tickerText = text; 1184 notification.defaults = 0; // please be quiet 1185 notification.sound = null; 1186 notification.vibrate = null; 1187 notification.setLatestEventInfo(context, text, 1188 mContext.getText(R.string.heavy_weight_notification_detail), 1189 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1190 PendingIntent.FLAG_CANCEL_CURRENT, null, 1191 new UserHandle(root.userId))); 1192 1193 try { 1194 int[] outId = new int[1]; 1195 inm.enqueueNotificationWithTag("android", null, 1196 R.string.heavy_weight_notification, 1197 notification, outId, root.userId); 1198 } catch (RuntimeException e) { 1199 Slog.w(ActivityManagerService.TAG, 1200 "Error showing notification for heavy-weight app", e); 1201 } catch (RemoteException e) { 1202 } 1203 } catch (NameNotFoundException e) { 1204 Slog.w(TAG, "Unable to create context for heavy notification", e); 1205 } 1206 } break; 1207 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1208 INotificationManager inm = NotificationManager.getService(); 1209 if (inm == null) { 1210 return; 1211 } 1212 try { 1213 inm.cancelNotificationWithTag("android", null, 1214 R.string.heavy_weight_notification, msg.arg1); 1215 } catch (RuntimeException e) { 1216 Slog.w(ActivityManagerService.TAG, 1217 "Error canceling notification for service", e); 1218 } catch (RemoteException e) { 1219 } 1220 } break; 1221 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1222 synchronized (ActivityManagerService.this) { 1223 checkExcessivePowerUsageLocked(true); 1224 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1225 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1226 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1227 } 1228 } break; 1229 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1230 synchronized (ActivityManagerService.this) { 1231 ActivityRecord ar = (ActivityRecord)msg.obj; 1232 if (mCompatModeDialog != null) { 1233 if (mCompatModeDialog.mAppInfo.packageName.equals( 1234 ar.info.applicationInfo.packageName)) { 1235 return; 1236 } 1237 mCompatModeDialog.dismiss(); 1238 mCompatModeDialog = null; 1239 } 1240 if (ar != null && false) { 1241 if (mCompatModePackages.getPackageAskCompatModeLocked( 1242 ar.packageName)) { 1243 int mode = mCompatModePackages.computeCompatModeLocked( 1244 ar.info.applicationInfo); 1245 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1246 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1247 mCompatModeDialog = new CompatModeDialog( 1248 ActivityManagerService.this, mContext, 1249 ar.info.applicationInfo); 1250 mCompatModeDialog.show(); 1251 } 1252 } 1253 } 1254 } 1255 break; 1256 } 1257 case DISPATCH_PROCESSES_CHANGED: { 1258 dispatchProcessesChanged(); 1259 break; 1260 } 1261 case DISPATCH_PROCESS_DIED: { 1262 final int pid = msg.arg1; 1263 final int uid = msg.arg2; 1264 dispatchProcessDied(pid, uid); 1265 break; 1266 } 1267 case REPORT_MEM_USAGE: { 1268 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1269 if (!isDebuggable) { 1270 return; 1271 } 1272 synchronized (ActivityManagerService.this) { 1273 long now = SystemClock.uptimeMillis(); 1274 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1275 // Don't report more than every 5 minutes to somewhat 1276 // avoid spamming. 1277 return; 1278 } 1279 mLastMemUsageReportTime = now; 1280 } 1281 Thread thread = new Thread() { 1282 @Override public void run() { 1283 StringBuilder dropBuilder = new StringBuilder(1024); 1284 StringBuilder logBuilder = new StringBuilder(1024); 1285 StringWriter oomSw = new StringWriter(); 1286 PrintWriter oomPw = new PrintWriter(oomSw); 1287 StringWriter catSw = new StringWriter(); 1288 PrintWriter catPw = new PrintWriter(catSw); 1289 String[] emptyArgs = new String[] { }; 1290 StringBuilder tag = new StringBuilder(128); 1291 StringBuilder stack = new StringBuilder(128); 1292 tag.append("Low on memory -- "); 1293 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1294 tag, stack); 1295 dropBuilder.append(stack); 1296 dropBuilder.append('\n'); 1297 dropBuilder.append('\n'); 1298 String oomString = oomSw.toString(); 1299 dropBuilder.append(oomString); 1300 dropBuilder.append('\n'); 1301 logBuilder.append(oomString); 1302 try { 1303 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1304 "procrank", }); 1305 final InputStreamReader converter = new InputStreamReader( 1306 proc.getInputStream()); 1307 BufferedReader in = new BufferedReader(converter); 1308 String line; 1309 while (true) { 1310 line = in.readLine(); 1311 if (line == null) { 1312 break; 1313 } 1314 if (line.length() > 0) { 1315 logBuilder.append(line); 1316 logBuilder.append('\n'); 1317 } 1318 dropBuilder.append(line); 1319 dropBuilder.append('\n'); 1320 } 1321 converter.close(); 1322 } catch (IOException e) { 1323 } 1324 synchronized (ActivityManagerService.this) { 1325 catPw.println(); 1326 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1327 catPw.println(); 1328 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1329 false, false, null); 1330 catPw.println(); 1331 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1332 } 1333 dropBuilder.append(catSw.toString()); 1334 addErrorToDropBox("lowmem", null, "system_server", null, 1335 null, tag.toString(), dropBuilder.toString(), null, null); 1336 Slog.i(TAG, logBuilder.toString()); 1337 synchronized (ActivityManagerService.this) { 1338 long now = SystemClock.uptimeMillis(); 1339 if (mLastMemUsageReportTime < now) { 1340 mLastMemUsageReportTime = now; 1341 } 1342 } 1343 } 1344 }; 1345 thread.start(); 1346 break; 1347 } 1348 case REPORT_USER_SWITCH_MSG: { 1349 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1350 break; 1351 } 1352 case CONTINUE_USER_SWITCH_MSG: { 1353 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1354 break; 1355 } 1356 case USER_SWITCH_TIMEOUT_MSG: { 1357 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1358 break; 1359 } 1360 } 1361 } 1362 }; 1363 1364 public static void setSystemProcess() { 1365 try { 1366 ActivityManagerService m = mSelf; 1367 1368 ServiceManager.addService("activity", m, true); 1369 ServiceManager.addService("meminfo", new MemBinder(m)); 1370 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1371 ServiceManager.addService("dbinfo", new DbBinder(m)); 1372 if (MONITOR_CPU_USAGE) { 1373 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1374 } 1375 ServiceManager.addService("permission", new PermissionController(m)); 1376 1377 ApplicationInfo info = 1378 mSelf.mContext.getPackageManager().getApplicationInfo( 1379 "android", STOCK_PM_FLAGS); 1380 mSystemThread.installSystemApplicationInfo(info); 1381 1382 synchronized (mSelf) { 1383 ProcessRecord app = mSelf.newProcessRecordLocked( 1384 mSystemThread.getApplicationThread(), info, 1385 info.processName, false); 1386 app.persistent = true; 1387 app.pid = MY_PID; 1388 app.maxAdj = ProcessList.SYSTEM_ADJ; 1389 mSelf.mProcessNames.put(app.processName, app.uid, app); 1390 synchronized (mSelf.mPidsSelfLocked) { 1391 mSelf.mPidsSelfLocked.put(app.pid, app); 1392 } 1393 mSelf.updateLruProcessLocked(app, true); 1394 } 1395 } catch (PackageManager.NameNotFoundException e) { 1396 throw new RuntimeException( 1397 "Unable to find android system package", e); 1398 } 1399 } 1400 1401 public void setWindowManager(WindowManagerService wm) { 1402 mWindowManager = wm; 1403 } 1404 1405 public static final Context main(int factoryTest) { 1406 AThread thr = new AThread(); 1407 thr.start(); 1408 1409 synchronized (thr) { 1410 while (thr.mService == null) { 1411 try { 1412 thr.wait(); 1413 } catch (InterruptedException e) { 1414 } 1415 } 1416 } 1417 1418 ActivityManagerService m = thr.mService; 1419 mSelf = m; 1420 ActivityThread at = ActivityThread.systemMain(); 1421 mSystemThread = at; 1422 Context context = at.getSystemContext(); 1423 context.setTheme(android.R.style.Theme_Holo); 1424 m.mContext = context; 1425 m.mFactoryTest = factoryTest; 1426 m.mMainStack = new ActivityStack(m, context, true); 1427 1428 m.mBatteryStatsService.publish(context); 1429 m.mUsageStatsService.publish(context); 1430 1431 synchronized (thr) { 1432 thr.mReady = true; 1433 thr.notifyAll(); 1434 } 1435 1436 m.startRunning(null, null, null, null); 1437 1438 return context; 1439 } 1440 1441 public static ActivityManagerService self() { 1442 return mSelf; 1443 } 1444 1445 static class AThread extends Thread { 1446 ActivityManagerService mService; 1447 boolean mReady = false; 1448 1449 public AThread() { 1450 super("ActivityManager"); 1451 } 1452 1453 public void run() { 1454 Looper.prepare(); 1455 1456 android.os.Process.setThreadPriority( 1457 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1458 android.os.Process.setCanSelfBackground(false); 1459 1460 ActivityManagerService m = new ActivityManagerService(); 1461 1462 synchronized (this) { 1463 mService = m; 1464 notifyAll(); 1465 } 1466 1467 synchronized (this) { 1468 while (!mReady) { 1469 try { 1470 wait(); 1471 } catch (InterruptedException e) { 1472 } 1473 } 1474 } 1475 1476 // For debug builds, log event loop stalls to dropbox for analysis. 1477 if (StrictMode.conditionallyEnableDebugLogging()) { 1478 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1479 } 1480 1481 Looper.loop(); 1482 } 1483 } 1484 1485 static class MemBinder extends Binder { 1486 ActivityManagerService mActivityManagerService; 1487 MemBinder(ActivityManagerService activityManagerService) { 1488 mActivityManagerService = activityManagerService; 1489 } 1490 1491 @Override 1492 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1493 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1494 != PackageManager.PERMISSION_GRANTED) { 1495 pw.println("Permission Denial: can't dump meminfo from from pid=" 1496 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1497 + " without permission " + android.Manifest.permission.DUMP); 1498 return; 1499 } 1500 1501 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1502 false, null, null, null); 1503 } 1504 } 1505 1506 static class GraphicsBinder extends Binder { 1507 ActivityManagerService mActivityManagerService; 1508 GraphicsBinder(ActivityManagerService activityManagerService) { 1509 mActivityManagerService = activityManagerService; 1510 } 1511 1512 @Override 1513 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1514 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1515 != PackageManager.PERMISSION_GRANTED) { 1516 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1517 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1518 + " without permission " + android.Manifest.permission.DUMP); 1519 return; 1520 } 1521 1522 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1523 } 1524 } 1525 1526 static class DbBinder extends Binder { 1527 ActivityManagerService mActivityManagerService; 1528 DbBinder(ActivityManagerService activityManagerService) { 1529 mActivityManagerService = activityManagerService; 1530 } 1531 1532 @Override 1533 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1534 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1535 != PackageManager.PERMISSION_GRANTED) { 1536 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1537 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1538 + " without permission " + android.Manifest.permission.DUMP); 1539 return; 1540 } 1541 1542 mActivityManagerService.dumpDbInfo(fd, pw, args); 1543 } 1544 } 1545 1546 static class CpuBinder extends Binder { 1547 ActivityManagerService mActivityManagerService; 1548 CpuBinder(ActivityManagerService activityManagerService) { 1549 mActivityManagerService = activityManagerService; 1550 } 1551 1552 @Override 1553 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1554 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1555 != PackageManager.PERMISSION_GRANTED) { 1556 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1557 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1558 + " without permission " + android.Manifest.permission.DUMP); 1559 return; 1560 } 1561 1562 synchronized (mActivityManagerService.mProcessStatsThread) { 1563 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1564 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1565 SystemClock.uptimeMillis())); 1566 } 1567 } 1568 } 1569 1570 private ActivityManagerService() { 1571 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1572 1573 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1574 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1575 mBroadcastQueues[0] = mFgBroadcastQueue; 1576 mBroadcastQueues[1] = mBgBroadcastQueue; 1577 1578 mServices = new ActiveServices(this); 1579 mProviderMap = new ProviderMap(this); 1580 1581 File dataDir = Environment.getDataDirectory(); 1582 File systemDir = new File(dataDir, "system"); 1583 systemDir.mkdirs(); 1584 mBatteryStatsService = new BatteryStatsService(new File( 1585 systemDir, "batterystats.bin").toString()); 1586 mBatteryStatsService.getActiveStatistics().readLocked(); 1587 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1588 mOnBattery = DEBUG_POWER ? true 1589 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1590 mBatteryStatsService.getActiveStatistics().setCallback(this); 1591 1592 mUsageStatsService = new UsageStatsService(new File( 1593 systemDir, "usagestats").toString()); 1594 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1595 1596 // User 0 is the first and only user that runs at boot. 1597 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1598 mUserLru.add(Integer.valueOf(0)); 1599 updateStartedUserArrayLocked(); 1600 1601 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1602 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1603 1604 mConfiguration.setToDefaults(); 1605 mConfiguration.setLocale(Locale.getDefault()); 1606 1607 mConfigurationSeq = mConfiguration.seq = 1; 1608 mProcessStats.init(); 1609 1610 mCompatModePackages = new CompatModePackages(this, systemDir); 1611 1612 // Add ourself to the Watchdog monitors. 1613 Watchdog.getInstance().addMonitor(this); 1614 1615 mProcessStatsThread = new Thread("ProcessStats") { 1616 public void run() { 1617 while (true) { 1618 try { 1619 try { 1620 synchronized(this) { 1621 final long now = SystemClock.uptimeMillis(); 1622 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1623 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1624 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1625 // + ", write delay=" + nextWriteDelay); 1626 if (nextWriteDelay < nextCpuDelay) { 1627 nextCpuDelay = nextWriteDelay; 1628 } 1629 if (nextCpuDelay > 0) { 1630 mProcessStatsMutexFree.set(true); 1631 this.wait(nextCpuDelay); 1632 } 1633 } 1634 } catch (InterruptedException e) { 1635 } 1636 updateCpuStatsNow(); 1637 } catch (Exception e) { 1638 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1639 } 1640 } 1641 } 1642 }; 1643 mProcessStatsThread.start(); 1644 } 1645 1646 @Override 1647 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1648 throws RemoteException { 1649 if (code == SYSPROPS_TRANSACTION) { 1650 // We need to tell all apps about the system property change. 1651 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1652 synchronized(this) { 1653 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1654 final int NA = apps.size(); 1655 for (int ia=0; ia<NA; ia++) { 1656 ProcessRecord app = apps.valueAt(ia); 1657 if (app.thread != null) { 1658 procs.add(app.thread.asBinder()); 1659 } 1660 } 1661 } 1662 } 1663 1664 int N = procs.size(); 1665 for (int i=0; i<N; i++) { 1666 Parcel data2 = Parcel.obtain(); 1667 try { 1668 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1669 } catch (RemoteException e) { 1670 } 1671 data2.recycle(); 1672 } 1673 } 1674 try { 1675 return super.onTransact(code, data, reply, flags); 1676 } catch (RuntimeException e) { 1677 // The activity manager only throws security exceptions, so let's 1678 // log all others. 1679 if (!(e instanceof SecurityException)) { 1680 Slog.e(TAG, "Activity Manager Crash", e); 1681 } 1682 throw e; 1683 } 1684 } 1685 1686 void updateCpuStats() { 1687 final long now = SystemClock.uptimeMillis(); 1688 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1689 return; 1690 } 1691 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1692 synchronized (mProcessStatsThread) { 1693 mProcessStatsThread.notify(); 1694 } 1695 } 1696 } 1697 1698 void updateCpuStatsNow() { 1699 synchronized (mProcessStatsThread) { 1700 mProcessStatsMutexFree.set(false); 1701 final long now = SystemClock.uptimeMillis(); 1702 boolean haveNewCpuStats = false; 1703 1704 if (MONITOR_CPU_USAGE && 1705 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1706 mLastCpuTime.set(now); 1707 haveNewCpuStats = true; 1708 mProcessStats.update(); 1709 //Slog.i(TAG, mProcessStats.printCurrentState()); 1710 //Slog.i(TAG, "Total CPU usage: " 1711 // + mProcessStats.getTotalCpuPercent() + "%"); 1712 1713 // Slog the cpu usage if the property is set. 1714 if ("true".equals(SystemProperties.get("events.cpu"))) { 1715 int user = mProcessStats.getLastUserTime(); 1716 int system = mProcessStats.getLastSystemTime(); 1717 int iowait = mProcessStats.getLastIoWaitTime(); 1718 int irq = mProcessStats.getLastIrqTime(); 1719 int softIrq = mProcessStats.getLastSoftIrqTime(); 1720 int idle = mProcessStats.getLastIdleTime(); 1721 1722 int total = user + system + iowait + irq + softIrq + idle; 1723 if (total == 0) total = 1; 1724 1725 EventLog.writeEvent(EventLogTags.CPU, 1726 ((user+system+iowait+irq+softIrq) * 100) / total, 1727 (user * 100) / total, 1728 (system * 100) / total, 1729 (iowait * 100) / total, 1730 (irq * 100) / total, 1731 (softIrq * 100) / total); 1732 } 1733 } 1734 1735 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1736 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1737 synchronized(bstats) { 1738 synchronized(mPidsSelfLocked) { 1739 if (haveNewCpuStats) { 1740 if (mOnBattery) { 1741 int perc = bstats.startAddingCpuLocked(); 1742 int totalUTime = 0; 1743 int totalSTime = 0; 1744 final int N = mProcessStats.countStats(); 1745 for (int i=0; i<N; i++) { 1746 ProcessStats.Stats st = mProcessStats.getStats(i); 1747 if (!st.working) { 1748 continue; 1749 } 1750 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1751 int otherUTime = (st.rel_utime*perc)/100; 1752 int otherSTime = (st.rel_stime*perc)/100; 1753 totalUTime += otherUTime; 1754 totalSTime += otherSTime; 1755 if (pr != null) { 1756 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1757 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1758 st.rel_stime-otherSTime); 1759 ps.addSpeedStepTimes(cpuSpeedTimes); 1760 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1761 } else { 1762 BatteryStatsImpl.Uid.Proc ps = 1763 bstats.getProcessStatsLocked(st.name, st.pid); 1764 if (ps != null) { 1765 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1766 st.rel_stime-otherSTime); 1767 ps.addSpeedStepTimes(cpuSpeedTimes); 1768 } 1769 } 1770 } 1771 bstats.finishAddingCpuLocked(perc, totalUTime, 1772 totalSTime, cpuSpeedTimes); 1773 } 1774 } 1775 } 1776 1777 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1778 mLastWriteTime = now; 1779 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1780 } 1781 } 1782 } 1783 } 1784 1785 @Override 1786 public void batteryNeedsCpuUpdate() { 1787 updateCpuStatsNow(); 1788 } 1789 1790 @Override 1791 public void batteryPowerChanged(boolean onBattery) { 1792 // When plugging in, update the CPU stats first before changing 1793 // the plug state. 1794 updateCpuStatsNow(); 1795 synchronized (this) { 1796 synchronized(mPidsSelfLocked) { 1797 mOnBattery = DEBUG_POWER ? true : onBattery; 1798 } 1799 } 1800 } 1801 1802 /** 1803 * Initialize the application bind args. These are passed to each 1804 * process when the bindApplication() IPC is sent to the process. They're 1805 * lazily setup to make sure the services are running when they're asked for. 1806 */ 1807 private HashMap<String, IBinder> getCommonServicesLocked() { 1808 if (mAppBindArgs == null) { 1809 mAppBindArgs = new HashMap<String, IBinder>(); 1810 1811 // Setup the application init args 1812 mAppBindArgs.put("package", ServiceManager.getService("package")); 1813 mAppBindArgs.put("window", ServiceManager.getService("window")); 1814 mAppBindArgs.put(Context.ALARM_SERVICE, 1815 ServiceManager.getService(Context.ALARM_SERVICE)); 1816 } 1817 return mAppBindArgs; 1818 } 1819 1820 final void setFocusedActivityLocked(ActivityRecord r) { 1821 if (mFocusedActivity != r) { 1822 mFocusedActivity = r; 1823 if (r != null) { 1824 mWindowManager.setFocusedApp(r.appToken, true); 1825 } 1826 } 1827 } 1828 1829 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1830 // put it on the LRU to keep track of when it should be exited. 1831 int lrui = mLruProcesses.indexOf(app); 1832 if (lrui >= 0) mLruProcesses.remove(lrui); 1833 1834 int i = mLruProcesses.size()-1; 1835 int skipTop = 0; 1836 1837 app.lruSeq = mLruSeq; 1838 1839 // compute the new weight for this process. 1840 app.lastActivityTime = SystemClock.uptimeMillis(); 1841 if (app.activities.size() > 0) { 1842 // If this process has activities, we more strongly want to keep 1843 // it around. 1844 app.lruWeight = app.lastActivityTime; 1845 } else if (app.pubProviders.size() > 0) { 1846 // If this process contains content providers, we want to keep 1847 // it a little more strongly. 1848 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1849 // Also don't let it kick out the first few "real" hidden processes. 1850 skipTop = ProcessList.MIN_HIDDEN_APPS; 1851 } else { 1852 // If this process doesn't have activities, we less strongly 1853 // want to keep it around, and generally want to avoid getting 1854 // in front of any very recently used activities. 1855 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1856 // Also don't let it kick out the first few "real" hidden processes. 1857 skipTop = ProcessList.MIN_HIDDEN_APPS; 1858 } 1859 1860 while (i >= 0) { 1861 ProcessRecord p = mLruProcesses.get(i); 1862 // If this app shouldn't be in front of the first N background 1863 // apps, then skip over that many that are currently hidden. 1864 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1865 skipTop--; 1866 } 1867 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1868 mLruProcesses.add(i+1, app); 1869 break; 1870 } 1871 i--; 1872 } 1873 if (i < 0) { 1874 mLruProcesses.add(0, app); 1875 } 1876 1877 // If the app is currently using a content provider or service, 1878 // bump those processes as well. 1879 if (app.connections.size() > 0) { 1880 for (ConnectionRecord cr : app.connections) { 1881 if (cr.binding != null && cr.binding.service != null 1882 && cr.binding.service.app != null 1883 && cr.binding.service.app.lruSeq != mLruSeq) { 1884 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1885 } 1886 } 1887 } 1888 for (int j=app.conProviders.size()-1; j>=0; j--) { 1889 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1890 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1891 updateLruProcessInternalLocked(cpr.proc, i+1); 1892 } 1893 } 1894 } 1895 1896 final void updateLruProcessLocked(ProcessRecord app, 1897 boolean oomAdj) { 1898 mLruSeq++; 1899 updateLruProcessInternalLocked(app, 0); 1900 1901 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1902 if (oomAdj) { 1903 updateOomAdjLocked(); 1904 } 1905 } 1906 1907 final ProcessRecord getProcessRecordLocked( 1908 String processName, int uid) { 1909 if (uid == Process.SYSTEM_UID) { 1910 // The system gets to run in any process. If there are multiple 1911 // processes with the same uid, just pick the first (this 1912 // should never happen). 1913 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1914 processName); 1915 if (procs == null) return null; 1916 final int N = procs.size(); 1917 for (int i = 0; i < N; i++) { 1918 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1919 } 1920 } 1921 ProcessRecord proc = mProcessNames.get(processName, uid); 1922 return proc; 1923 } 1924 1925 void ensurePackageDexOpt(String packageName) { 1926 IPackageManager pm = AppGlobals.getPackageManager(); 1927 try { 1928 if (pm.performDexOpt(packageName)) { 1929 mDidDexOpt = true; 1930 } 1931 } catch (RemoteException e) { 1932 } 1933 } 1934 1935 boolean isNextTransitionForward() { 1936 int transit = mWindowManager.getPendingAppTransition(); 1937 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1938 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1939 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1940 } 1941 1942 final ProcessRecord startProcessLocked(String processName, 1943 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1944 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1945 boolean isolated) { 1946 ProcessRecord app; 1947 if (!isolated) { 1948 app = getProcessRecordLocked(processName, info.uid); 1949 } else { 1950 // If this is an isolated process, it can't re-use an existing process. 1951 app = null; 1952 } 1953 // We don't have to do anything more if: 1954 // (1) There is an existing application record; and 1955 // (2) The caller doesn't think it is dead, OR there is no thread 1956 // object attached to it so we know it couldn't have crashed; and 1957 // (3) There is a pid assigned to it, so it is either starting or 1958 // already running. 1959 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1960 + " app=" + app + " knownToBeDead=" + knownToBeDead 1961 + " thread=" + (app != null ? app.thread : null) 1962 + " pid=" + (app != null ? app.pid : -1)); 1963 if (app != null && app.pid > 0) { 1964 if (!knownToBeDead || app.thread == null) { 1965 // We already have the app running, or are waiting for it to 1966 // come up (we have a pid but not yet its thread), so keep it. 1967 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1968 // If this is a new package in the process, add the package to the list 1969 app.addPackage(info.packageName); 1970 return app; 1971 } else { 1972 // An application record is attached to a previous process, 1973 // clean it up now. 1974 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 1975 handleAppDiedLocked(app, true, true); 1976 } 1977 } 1978 1979 String hostingNameStr = hostingName != null 1980 ? hostingName.flattenToShortString() : null; 1981 1982 if (!isolated) { 1983 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1984 // If we are in the background, then check to see if this process 1985 // is bad. If so, we will just silently fail. 1986 if (mBadProcesses.get(info.processName, info.uid) != null) { 1987 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1988 + "/" + info.processName); 1989 return null; 1990 } 1991 } else { 1992 // When the user is explicitly starting a process, then clear its 1993 // crash count so that we won't make it bad until they see at 1994 // least one crash dialog again, and make the process good again 1995 // if it had been bad. 1996 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1997 + "/" + info.processName); 1998 mProcessCrashTimes.remove(info.processName, info.uid); 1999 if (mBadProcesses.get(info.processName, info.uid) != null) { 2000 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2001 UserHandle.getUserId(info.uid), info.uid, 2002 info.processName); 2003 mBadProcesses.remove(info.processName, info.uid); 2004 if (app != null) { 2005 app.bad = false; 2006 } 2007 } 2008 } 2009 } 2010 2011 if (app == null) { 2012 app = newProcessRecordLocked(null, info, processName, isolated); 2013 if (app == null) { 2014 Slog.w(TAG, "Failed making new process record for " 2015 + processName + "/" + info.uid + " isolated=" + isolated); 2016 return null; 2017 } 2018 mProcessNames.put(processName, app.uid, app); 2019 if (isolated) { 2020 mIsolatedProcesses.put(app.uid, app); 2021 } 2022 } else { 2023 // If this is a new package in the process, add the package to the list 2024 app.addPackage(info.packageName); 2025 } 2026 2027 // If the system is not ready yet, then hold off on starting this 2028 // process until it is. 2029 if (!mProcessesReady 2030 && !isAllowedWhileBooting(info) 2031 && !allowWhileBooting) { 2032 if (!mProcessesOnHold.contains(app)) { 2033 mProcessesOnHold.add(app); 2034 } 2035 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2036 return app; 2037 } 2038 2039 startProcessLocked(app, hostingType, hostingNameStr); 2040 return (app.pid != 0) ? app : null; 2041 } 2042 2043 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2044 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2045 } 2046 2047 private final void startProcessLocked(ProcessRecord app, 2048 String hostingType, String hostingNameStr) { 2049 if (app.pid > 0 && app.pid != MY_PID) { 2050 synchronized (mPidsSelfLocked) { 2051 mPidsSelfLocked.remove(app.pid); 2052 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2053 } 2054 app.setPid(0); 2055 } 2056 2057 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2058 "startProcessLocked removing on hold: " + app); 2059 mProcessesOnHold.remove(app); 2060 2061 updateCpuStats(); 2062 2063 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2064 mProcDeaths[0] = 0; 2065 2066 try { 2067 int uid = app.uid; 2068 2069 int[] gids = null; 2070 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2071 if (!app.isolated) { 2072 int[] permGids = null; 2073 try { 2074 final PackageManager pm = mContext.getPackageManager(); 2075 permGids = pm.getPackageGids(app.info.packageName); 2076 2077 if (Environment.isExternalStorageEmulated()) { 2078 if (pm.checkPermission( 2079 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2080 app.info.packageName) == PERMISSION_GRANTED) { 2081 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2082 } else { 2083 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2084 } 2085 } 2086 } catch (PackageManager.NameNotFoundException e) { 2087 Slog.w(TAG, "Unable to retrieve gids", e); 2088 } 2089 2090 /* 2091 * Add shared application GID so applications can share some 2092 * resources like shared libraries 2093 */ 2094 if (permGids == null) { 2095 gids = new int[1]; 2096 } else { 2097 gids = new int[permGids.length + 1]; 2098 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2099 } 2100 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2101 } 2102 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2103 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2104 && mTopComponent != null 2105 && app.processName.equals(mTopComponent.getPackageName())) { 2106 uid = 0; 2107 } 2108 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2109 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2110 uid = 0; 2111 } 2112 } 2113 int debugFlags = 0; 2114 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2115 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2116 // Also turn on CheckJNI for debuggable apps. It's quite 2117 // awkward to turn on otherwise. 2118 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2119 } 2120 // Run the app in safe mode if its manifest requests so or the 2121 // system is booted in safe mode. 2122 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2123 Zygote.systemInSafeMode == true) { 2124 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2125 } 2126 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2127 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2128 } 2129 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2130 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2131 } 2132 if ("1".equals(SystemProperties.get("debug.assert"))) { 2133 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2134 } 2135 2136 // Start the process. It will either succeed and return a result containing 2137 // the PID of the new process, or else throw a RuntimeException. 2138 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2139 app.processName, uid, uid, gids, debugFlags, mountExternal, 2140 app.info.targetSdkVersion, null, null); 2141 2142 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2143 synchronized (bs) { 2144 if (bs.isOnBattery()) { 2145 app.batteryStats.incStartsLocked(); 2146 } 2147 } 2148 2149 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2150 UserHandle.getUserId(uid), startResult.pid, uid, 2151 app.processName, hostingType, 2152 hostingNameStr != null ? hostingNameStr : ""); 2153 2154 if (app.persistent) { 2155 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2156 } 2157 2158 StringBuilder buf = mStringBuilder; 2159 buf.setLength(0); 2160 buf.append("Start proc "); 2161 buf.append(app.processName); 2162 buf.append(" for "); 2163 buf.append(hostingType); 2164 if (hostingNameStr != null) { 2165 buf.append(" "); 2166 buf.append(hostingNameStr); 2167 } 2168 buf.append(": pid="); 2169 buf.append(startResult.pid); 2170 buf.append(" uid="); 2171 buf.append(uid); 2172 buf.append(" gids={"); 2173 if (gids != null) { 2174 for (int gi=0; gi<gids.length; gi++) { 2175 if (gi != 0) buf.append(", "); 2176 buf.append(gids[gi]); 2177 2178 } 2179 } 2180 buf.append("}"); 2181 Slog.i(TAG, buf.toString()); 2182 app.setPid(startResult.pid); 2183 app.usingWrapper = startResult.usingWrapper; 2184 app.removed = false; 2185 synchronized (mPidsSelfLocked) { 2186 this.mPidsSelfLocked.put(startResult.pid, app); 2187 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2188 msg.obj = app; 2189 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2190 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2191 } 2192 } catch (RuntimeException e) { 2193 // XXX do better error recovery. 2194 app.setPid(0); 2195 Slog.e(TAG, "Failure starting process " + app.processName, e); 2196 } 2197 } 2198 2199 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2200 if (resumed) { 2201 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2202 } else { 2203 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2204 } 2205 } 2206 2207 boolean startHomeActivityLocked(int userId) { 2208 if (mHeadless) { 2209 // Added because none of the other calls to ensureBootCompleted seem to fire 2210 // when running headless. 2211 ensureBootCompleted(); 2212 return false; 2213 } 2214 2215 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2216 && mTopAction == null) { 2217 // We are running in factory test mode, but unable to find 2218 // the factory test app, so just sit around displaying the 2219 // error message and don't try to start anything. 2220 return false; 2221 } 2222 Intent intent = new Intent( 2223 mTopAction, 2224 mTopData != null ? Uri.parse(mTopData) : null); 2225 intent.setComponent(mTopComponent); 2226 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2227 intent.addCategory(Intent.CATEGORY_HOME); 2228 } 2229 ActivityInfo aInfo = 2230 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2231 if (aInfo != null) { 2232 intent.setComponent(new ComponentName( 2233 aInfo.applicationInfo.packageName, aInfo.name)); 2234 // Don't do this if the home app is currently being 2235 // instrumented. 2236 aInfo = new ActivityInfo(aInfo); 2237 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2238 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2239 aInfo.applicationInfo.uid); 2240 if (app == null || app.instrumentationClass == null) { 2241 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2242 mMainStack.startActivityLocked(null, intent, null, aInfo, 2243 null, null, 0, 0, 0, 0, null, false, null); 2244 } 2245 } 2246 2247 return true; 2248 } 2249 2250 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2251 ActivityInfo ai = null; 2252 ComponentName comp = intent.getComponent(); 2253 try { 2254 if (comp != null) { 2255 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2256 } else { 2257 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2258 intent, 2259 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2260 flags, userId); 2261 2262 if (info != null) { 2263 ai = info.activityInfo; 2264 } 2265 } 2266 } catch (RemoteException e) { 2267 // ignore 2268 } 2269 2270 return ai; 2271 } 2272 2273 /** 2274 * Starts the "new version setup screen" if appropriate. 2275 */ 2276 void startSetupActivityLocked() { 2277 // Only do this once per boot. 2278 if (mCheckedForSetup) { 2279 return; 2280 } 2281 2282 // We will show this screen if the current one is a different 2283 // version than the last one shown, and we are not running in 2284 // low-level factory test mode. 2285 final ContentResolver resolver = mContext.getContentResolver(); 2286 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2287 Settings.Global.getInt(resolver, 2288 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2289 mCheckedForSetup = true; 2290 2291 // See if we should be showing the platform update setup UI. 2292 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2293 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2294 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2295 2296 // We don't allow third party apps to replace this. 2297 ResolveInfo ri = null; 2298 for (int i=0; ris != null && i<ris.size(); i++) { 2299 if ((ris.get(i).activityInfo.applicationInfo.flags 2300 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2301 ri = ris.get(i); 2302 break; 2303 } 2304 } 2305 2306 if (ri != null) { 2307 String vers = ri.activityInfo.metaData != null 2308 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2309 : null; 2310 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2311 vers = ri.activityInfo.applicationInfo.metaData.getString( 2312 Intent.METADATA_SETUP_VERSION); 2313 } 2314 String lastVers = Settings.Secure.getString( 2315 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2316 if (vers != null && !vers.equals(lastVers)) { 2317 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2318 intent.setComponent(new ComponentName( 2319 ri.activityInfo.packageName, ri.activityInfo.name)); 2320 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2321 null, null, 0, 0, 0, 0, null, false, null); 2322 } 2323 } 2324 } 2325 } 2326 2327 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2328 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2329 } 2330 2331 void enforceNotIsolatedCaller(String caller) { 2332 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2333 throw new SecurityException("Isolated process not allowed to call " + caller); 2334 } 2335 } 2336 2337 public int getFrontActivityScreenCompatMode() { 2338 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2339 synchronized (this) { 2340 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2341 } 2342 } 2343 2344 public void setFrontActivityScreenCompatMode(int mode) { 2345 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2346 "setFrontActivityScreenCompatMode"); 2347 synchronized (this) { 2348 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2349 } 2350 } 2351 2352 public int getPackageScreenCompatMode(String packageName) { 2353 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2354 synchronized (this) { 2355 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2356 } 2357 } 2358 2359 public void setPackageScreenCompatMode(String packageName, int mode) { 2360 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2361 "setPackageScreenCompatMode"); 2362 synchronized (this) { 2363 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2364 } 2365 } 2366 2367 public boolean getPackageAskScreenCompat(String packageName) { 2368 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2369 synchronized (this) { 2370 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2371 } 2372 } 2373 2374 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2375 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2376 "setPackageAskScreenCompat"); 2377 synchronized (this) { 2378 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2379 } 2380 } 2381 2382 void reportResumedActivityLocked(ActivityRecord r) { 2383 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2384 updateUsageStats(r, true); 2385 } 2386 2387 private void dispatchProcessesChanged() { 2388 int N; 2389 synchronized (this) { 2390 N = mPendingProcessChanges.size(); 2391 if (mActiveProcessChanges.length < N) { 2392 mActiveProcessChanges = new ProcessChangeItem[N]; 2393 } 2394 mPendingProcessChanges.toArray(mActiveProcessChanges); 2395 mAvailProcessChanges.addAll(mPendingProcessChanges); 2396 mPendingProcessChanges.clear(); 2397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2398 } 2399 int i = mProcessObservers.beginBroadcast(); 2400 while (i > 0) { 2401 i--; 2402 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2403 if (observer != null) { 2404 try { 2405 for (int j=0; j<N; j++) { 2406 ProcessChangeItem item = mActiveProcessChanges[j]; 2407 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2408 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2409 + item.pid + " uid=" + item.uid + ": " 2410 + item.foregroundActivities); 2411 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2412 item.foregroundActivities); 2413 } 2414 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2415 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2416 + item.pid + " uid=" + item.uid + ": " + item.importance); 2417 observer.onImportanceChanged(item.pid, item.uid, 2418 item.importance); 2419 } 2420 } 2421 } catch (RemoteException e) { 2422 } 2423 } 2424 } 2425 mProcessObservers.finishBroadcast(); 2426 } 2427 2428 private void dispatchProcessDied(int pid, int uid) { 2429 int i = mProcessObservers.beginBroadcast(); 2430 while (i > 0) { 2431 i--; 2432 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2433 if (observer != null) { 2434 try { 2435 observer.onProcessDied(pid, uid); 2436 } catch (RemoteException e) { 2437 } 2438 } 2439 } 2440 mProcessObservers.finishBroadcast(); 2441 } 2442 2443 final void doPendingActivityLaunchesLocked(boolean doResume) { 2444 final int N = mPendingActivityLaunches.size(); 2445 if (N <= 0) { 2446 return; 2447 } 2448 for (int i=0; i<N; i++) { 2449 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2450 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2451 pal.startFlags, doResume && i == (N-1), null); 2452 } 2453 mPendingActivityLaunches.clear(); 2454 } 2455 2456 public final int startActivity(IApplicationThread caller, 2457 Intent intent, String resolvedType, IBinder resultTo, 2458 String resultWho, int requestCode, int startFlags, 2459 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2460 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2461 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2462 } 2463 2464 public final int startActivityAsUser(IApplicationThread caller, 2465 Intent intent, String resolvedType, IBinder resultTo, 2466 String resultWho, int requestCode, int startFlags, 2467 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2468 enforceNotIsolatedCaller("startActivity"); 2469 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2470 false, true, "startActivity", null); 2471 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2472 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2473 null, null, options, userId); 2474 } 2475 2476 public final WaitResult startActivityAndWait(IApplicationThread caller, 2477 Intent intent, String resolvedType, IBinder resultTo, 2478 String resultWho, int requestCode, int startFlags, String profileFile, 2479 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2480 enforceNotIsolatedCaller("startActivityAndWait"); 2481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2482 false, true, "startActivityAndWait", null); 2483 WaitResult res = new WaitResult(); 2484 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2485 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2486 res, null, options, UserHandle.getCallingUserId()); 2487 return res; 2488 } 2489 2490 public final int startActivityWithConfig(IApplicationThread caller, 2491 Intent intent, String resolvedType, IBinder resultTo, 2492 String resultWho, int requestCode, int startFlags, Configuration config, 2493 Bundle options, int userId) { 2494 enforceNotIsolatedCaller("startActivityWithConfig"); 2495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2496 false, true, "startActivityWithConfig", null); 2497 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2498 resultTo, resultWho, requestCode, startFlags, 2499 null, null, null, config, options, userId); 2500 return ret; 2501 } 2502 2503 public int startActivityIntentSender(IApplicationThread caller, 2504 IntentSender intent, Intent fillInIntent, String resolvedType, 2505 IBinder resultTo, String resultWho, int requestCode, 2506 int flagsMask, int flagsValues, Bundle options) { 2507 enforceNotIsolatedCaller("startActivityIntentSender"); 2508 // Refuse possible leaked file descriptors 2509 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2510 throw new IllegalArgumentException("File descriptors passed in Intent"); 2511 } 2512 2513 IIntentSender sender = intent.getTarget(); 2514 if (!(sender instanceof PendingIntentRecord)) { 2515 throw new IllegalArgumentException("Bad PendingIntent object"); 2516 } 2517 2518 PendingIntentRecord pir = (PendingIntentRecord)sender; 2519 2520 synchronized (this) { 2521 // If this is coming from the currently resumed activity, it is 2522 // effectively saying that app switches are allowed at this point. 2523 if (mMainStack.mResumedActivity != null 2524 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2525 Binder.getCallingUid()) { 2526 mAppSwitchesAllowedTime = 0; 2527 } 2528 } 2529 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2530 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2531 return ret; 2532 } 2533 2534 public boolean startNextMatchingActivity(IBinder callingActivity, 2535 Intent intent, Bundle options) { 2536 // Refuse possible leaked file descriptors 2537 if (intent != null && intent.hasFileDescriptors() == true) { 2538 throw new IllegalArgumentException("File descriptors passed in Intent"); 2539 } 2540 2541 synchronized (this) { 2542 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2543 if (r == null) { 2544 ActivityOptions.abort(options); 2545 return false; 2546 } 2547 if (r.app == null || r.app.thread == null) { 2548 // The caller is not running... d'oh! 2549 ActivityOptions.abort(options); 2550 return false; 2551 } 2552 intent = new Intent(intent); 2553 // The caller is not allowed to change the data. 2554 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2555 // And we are resetting to find the next component... 2556 intent.setComponent(null); 2557 2558 ActivityInfo aInfo = null; 2559 try { 2560 List<ResolveInfo> resolves = 2561 AppGlobals.getPackageManager().queryIntentActivities( 2562 intent, r.resolvedType, 2563 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2564 UserHandle.getCallingUserId()); 2565 2566 // Look for the original activity in the list... 2567 final int N = resolves != null ? resolves.size() : 0; 2568 for (int i=0; i<N; i++) { 2569 ResolveInfo rInfo = resolves.get(i); 2570 if (rInfo.activityInfo.packageName.equals(r.packageName) 2571 && rInfo.activityInfo.name.equals(r.info.name)) { 2572 // We found the current one... the next matching is 2573 // after it. 2574 i++; 2575 if (i<N) { 2576 aInfo = resolves.get(i).activityInfo; 2577 } 2578 break; 2579 } 2580 } 2581 } catch (RemoteException e) { 2582 } 2583 2584 if (aInfo == null) { 2585 // Nobody who is next! 2586 ActivityOptions.abort(options); 2587 return false; 2588 } 2589 2590 intent.setComponent(new ComponentName( 2591 aInfo.applicationInfo.packageName, aInfo.name)); 2592 intent.setFlags(intent.getFlags()&~( 2593 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2594 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2595 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2596 Intent.FLAG_ACTIVITY_NEW_TASK)); 2597 2598 // Okay now we need to start the new activity, replacing the 2599 // currently running activity. This is a little tricky because 2600 // we want to start the new one as if the current one is finished, 2601 // but not finish the current one first so that there is no flicker. 2602 // And thus... 2603 final boolean wasFinishing = r.finishing; 2604 r.finishing = true; 2605 2606 // Propagate reply information over to the new activity. 2607 final ActivityRecord resultTo = r.resultTo; 2608 final String resultWho = r.resultWho; 2609 final int requestCode = r.requestCode; 2610 r.resultTo = null; 2611 if (resultTo != null) { 2612 resultTo.removeResultsLocked(r, resultWho, requestCode); 2613 } 2614 2615 final long origId = Binder.clearCallingIdentity(); 2616 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2617 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2618 resultWho, requestCode, -1, r.launchedFromUid, 0, 2619 options, false, null); 2620 Binder.restoreCallingIdentity(origId); 2621 2622 r.finishing = wasFinishing; 2623 if (res != ActivityManager.START_SUCCESS) { 2624 return false; 2625 } 2626 return true; 2627 } 2628 } 2629 2630 final int startActivityInPackage(int uid, 2631 Intent intent, String resolvedType, IBinder resultTo, 2632 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2633 2634 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2635 false, true, "startActivityInPackage", null); 2636 2637 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2638 resultTo, resultWho, requestCode, startFlags, 2639 null, null, null, null, options, userId); 2640 return ret; 2641 } 2642 2643 public final int startActivities(IApplicationThread caller, 2644 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2645 int userId) { 2646 enforceNotIsolatedCaller("startActivities"); 2647 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2648 false, true, "startActivity", null); 2649 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2650 options, userId); 2651 return ret; 2652 } 2653 2654 final int startActivitiesInPackage(int uid, 2655 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2656 Bundle options, int userId) { 2657 2658 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2659 false, true, "startActivityInPackage", null); 2660 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2661 options, userId); 2662 return ret; 2663 } 2664 2665 final void addRecentTaskLocked(TaskRecord task) { 2666 int N = mRecentTasks.size(); 2667 // Quick case: check if the top-most recent task is the same. 2668 if (N > 0 && mRecentTasks.get(0) == task) { 2669 return; 2670 } 2671 // Remove any existing entries that are the same kind of task. 2672 for (int i=0; i<N; i++) { 2673 TaskRecord tr = mRecentTasks.get(i); 2674 if (task.userId == tr.userId 2675 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2676 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2677 mRecentTasks.remove(i); 2678 i--; 2679 N--; 2680 if (task.intent == null) { 2681 // If the new recent task we are adding is not fully 2682 // specified, then replace it with the existing recent task. 2683 task = tr; 2684 } 2685 } 2686 } 2687 if (N >= MAX_RECENT_TASKS) { 2688 mRecentTasks.remove(N-1); 2689 } 2690 mRecentTasks.add(0, task); 2691 } 2692 2693 public void setRequestedOrientation(IBinder token, 2694 int requestedOrientation) { 2695 synchronized (this) { 2696 ActivityRecord r = mMainStack.isInStackLocked(token); 2697 if (r == null) { 2698 return; 2699 } 2700 final long origId = Binder.clearCallingIdentity(); 2701 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2702 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2703 mConfiguration, 2704 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2705 if (config != null) { 2706 r.frozenBeforeDestroy = true; 2707 if (!updateConfigurationLocked(config, r, false, false)) { 2708 mMainStack.resumeTopActivityLocked(null); 2709 } 2710 } 2711 Binder.restoreCallingIdentity(origId); 2712 } 2713 } 2714 2715 public int getRequestedOrientation(IBinder token) { 2716 synchronized (this) { 2717 ActivityRecord r = mMainStack.isInStackLocked(token); 2718 if (r == null) { 2719 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2720 } 2721 return mWindowManager.getAppOrientation(r.appToken); 2722 } 2723 } 2724 2725 /** 2726 * This is the internal entry point for handling Activity.finish(). 2727 * 2728 * @param token The Binder token referencing the Activity we want to finish. 2729 * @param resultCode Result code, if any, from this Activity. 2730 * @param resultData Result data (Intent), if any, from this Activity. 2731 * 2732 * @return Returns true if the activity successfully finished, or false if it is still running. 2733 */ 2734 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2735 // Refuse possible leaked file descriptors 2736 if (resultData != null && resultData.hasFileDescriptors() == true) { 2737 throw new IllegalArgumentException("File descriptors passed in Intent"); 2738 } 2739 2740 synchronized(this) { 2741 if (mController != null) { 2742 // Find the first activity that is not finishing. 2743 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2744 if (next != null) { 2745 // ask watcher if this is allowed 2746 boolean resumeOK = true; 2747 try { 2748 resumeOK = mController.activityResuming(next.packageName); 2749 } catch (RemoteException e) { 2750 mController = null; 2751 } 2752 2753 if (!resumeOK) { 2754 return false; 2755 } 2756 } 2757 } 2758 final long origId = Binder.clearCallingIdentity(); 2759 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2760 resultData, "app-request", true); 2761 Binder.restoreCallingIdentity(origId); 2762 return res; 2763 } 2764 } 2765 2766 public final void finishHeavyWeightApp() { 2767 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2768 != PackageManager.PERMISSION_GRANTED) { 2769 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2770 + Binder.getCallingPid() 2771 + ", uid=" + Binder.getCallingUid() 2772 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2773 Slog.w(TAG, msg); 2774 throw new SecurityException(msg); 2775 } 2776 2777 synchronized(this) { 2778 if (mHeavyWeightProcess == null) { 2779 return; 2780 } 2781 2782 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2783 mHeavyWeightProcess.activities); 2784 for (int i=0; i<activities.size(); i++) { 2785 ActivityRecord r = activities.get(i); 2786 if (!r.finishing) { 2787 int index = mMainStack.indexOfTokenLocked(r.appToken); 2788 if (index >= 0) { 2789 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2790 null, "finish-heavy", true); 2791 } 2792 } 2793 } 2794 2795 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2796 mHeavyWeightProcess.userId, 0)); 2797 mHeavyWeightProcess = null; 2798 } 2799 } 2800 2801 public void crashApplication(int uid, int initialPid, String packageName, 2802 String message) { 2803 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2804 != PackageManager.PERMISSION_GRANTED) { 2805 String msg = "Permission Denial: crashApplication() from pid=" 2806 + Binder.getCallingPid() 2807 + ", uid=" + Binder.getCallingUid() 2808 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2809 Slog.w(TAG, msg); 2810 throw new SecurityException(msg); 2811 } 2812 2813 synchronized(this) { 2814 ProcessRecord proc = null; 2815 2816 // Figure out which process to kill. We don't trust that initialPid 2817 // still has any relation to current pids, so must scan through the 2818 // list. 2819 synchronized (mPidsSelfLocked) { 2820 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2821 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2822 if (p.uid != uid) { 2823 continue; 2824 } 2825 if (p.pid == initialPid) { 2826 proc = p; 2827 break; 2828 } 2829 for (String str : p.pkgList) { 2830 if (str.equals(packageName)) { 2831 proc = p; 2832 } 2833 } 2834 } 2835 } 2836 2837 if (proc == null) { 2838 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2839 + " initialPid=" + initialPid 2840 + " packageName=" + packageName); 2841 return; 2842 } 2843 2844 if (proc.thread != null) { 2845 if (proc.pid == Process.myPid()) { 2846 Log.w(TAG, "crashApplication: trying to crash self!"); 2847 return; 2848 } 2849 long ident = Binder.clearCallingIdentity(); 2850 try { 2851 proc.thread.scheduleCrash(message); 2852 } catch (RemoteException e) { 2853 } 2854 Binder.restoreCallingIdentity(ident); 2855 } 2856 } 2857 } 2858 2859 public final void finishSubActivity(IBinder token, String resultWho, 2860 int requestCode) { 2861 synchronized(this) { 2862 final long origId = Binder.clearCallingIdentity(); 2863 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2864 Binder.restoreCallingIdentity(origId); 2865 } 2866 } 2867 2868 public boolean finishActivityAffinity(IBinder token) { 2869 synchronized(this) { 2870 final long origId = Binder.clearCallingIdentity(); 2871 boolean res = mMainStack.finishActivityAffinityLocked(token); 2872 Binder.restoreCallingIdentity(origId); 2873 return res; 2874 } 2875 } 2876 2877 public boolean willActivityBeVisible(IBinder token) { 2878 synchronized(this) { 2879 int i; 2880 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2881 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2882 if (r.appToken == token) { 2883 return true; 2884 } 2885 if (r.fullscreen && !r.finishing) { 2886 return false; 2887 } 2888 } 2889 return true; 2890 } 2891 } 2892 2893 public void overridePendingTransition(IBinder token, String packageName, 2894 int enterAnim, int exitAnim) { 2895 synchronized(this) { 2896 ActivityRecord self = mMainStack.isInStackLocked(token); 2897 if (self == null) { 2898 return; 2899 } 2900 2901 final long origId = Binder.clearCallingIdentity(); 2902 2903 if (self.state == ActivityState.RESUMED 2904 || self.state == ActivityState.PAUSING) { 2905 mWindowManager.overridePendingAppTransition(packageName, 2906 enterAnim, exitAnim, null); 2907 } 2908 2909 Binder.restoreCallingIdentity(origId); 2910 } 2911 } 2912 2913 /** 2914 * Main function for removing an existing process from the activity manager 2915 * as a result of that process going away. Clears out all connections 2916 * to the process. 2917 */ 2918 private final void handleAppDiedLocked(ProcessRecord app, 2919 boolean restarting, boolean allowRestart) { 2920 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2921 if (!restarting) { 2922 mLruProcesses.remove(app); 2923 } 2924 2925 if (mProfileProc == app) { 2926 clearProfilerLocked(); 2927 } 2928 2929 // Just in case... 2930 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2931 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 2932 "App died while pausing: " + mMainStack.mPausingActivity); 2933 mMainStack.mPausingActivity = null; 2934 } 2935 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2936 mMainStack.mLastPausedActivity = null; 2937 } 2938 2939 // Remove this application's activities from active lists. 2940 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 2941 2942 app.activities.clear(); 2943 2944 if (app.instrumentationClass != null) { 2945 Slog.w(TAG, "Crash of app " + app.processName 2946 + " running instrumentation " + app.instrumentationClass); 2947 Bundle info = new Bundle(); 2948 info.putString("shortMsg", "Process crashed."); 2949 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2950 } 2951 2952 if (!restarting) { 2953 if (!mMainStack.resumeTopActivityLocked(null)) { 2954 // If there was nothing to resume, and we are not already 2955 // restarting this process, but there is a visible activity that 2956 // is hosted by the process... then make sure all visible 2957 // activities are running, taking care of restarting this 2958 // process. 2959 if (hasVisibleActivities) { 2960 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2961 } 2962 } 2963 } 2964 } 2965 2966 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2967 IBinder threadBinder = thread.asBinder(); 2968 // Find the application record. 2969 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2970 ProcessRecord rec = mLruProcesses.get(i); 2971 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2972 return i; 2973 } 2974 } 2975 return -1; 2976 } 2977 2978 final ProcessRecord getRecordForAppLocked( 2979 IApplicationThread thread) { 2980 if (thread == null) { 2981 return null; 2982 } 2983 2984 int appIndex = getLRURecordIndexForAppLocked(thread); 2985 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2986 } 2987 2988 final void appDiedLocked(ProcessRecord app, int pid, 2989 IApplicationThread thread) { 2990 2991 mProcDeaths[0]++; 2992 2993 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2994 synchronized (stats) { 2995 stats.noteProcessDiedLocked(app.info.uid, pid); 2996 } 2997 2998 // Clean up already done if the process has been re-started. 2999 if (app.pid == pid && app.thread != null && 3000 app.thread.asBinder() == thread.asBinder()) { 3001 if (!app.killedBackground) { 3002 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3003 + ") has died."); 3004 } 3005 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3006 if (DEBUG_CLEANUP) Slog.v( 3007 TAG, "Dying app: " + app + ", pid: " + pid 3008 + ", thread: " + thread.asBinder()); 3009 boolean doLowMem = app.instrumentationClass == null; 3010 handleAppDiedLocked(app, false, true); 3011 3012 if (doLowMem) { 3013 // If there are no longer any background processes running, 3014 // and the app that died was not running instrumentation, 3015 // then tell everyone we are now low on memory. 3016 boolean haveBg = false; 3017 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3018 ProcessRecord rec = mLruProcesses.get(i); 3019 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3020 haveBg = true; 3021 break; 3022 } 3023 } 3024 3025 if (!haveBg) { 3026 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3027 long now = SystemClock.uptimeMillis(); 3028 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3029 ProcessRecord rec = mLruProcesses.get(i); 3030 if (rec != app && rec.thread != null && 3031 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3032 // The low memory report is overriding any current 3033 // state for a GC request. Make sure to do 3034 // heavy/important/visible/foreground processes first. 3035 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3036 rec.lastRequestedGc = 0; 3037 } else { 3038 rec.lastRequestedGc = rec.lastLowMemory; 3039 } 3040 rec.reportLowMemory = true; 3041 rec.lastLowMemory = now; 3042 mProcessesToGc.remove(rec); 3043 addProcessToGcListLocked(rec); 3044 } 3045 } 3046 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3047 scheduleAppGcsLocked(); 3048 } 3049 } 3050 } else if (app.pid != pid) { 3051 // A new process has already been started. 3052 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3053 + ") has died and restarted (pid " + app.pid + ")."); 3054 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3055 } else if (DEBUG_PROCESSES) { 3056 Slog.d(TAG, "Received spurious death notification for thread " 3057 + thread.asBinder()); 3058 } 3059 } 3060 3061 /** 3062 * If a stack trace dump file is configured, dump process stack traces. 3063 * @param clearTraces causes the dump file to be erased prior to the new 3064 * traces being written, if true; when false, the new traces will be 3065 * appended to any existing file content. 3066 * @param firstPids of dalvik VM processes to dump stack traces for first 3067 * @param lastPids of dalvik VM processes to dump stack traces for last 3068 * @param nativeProcs optional list of native process names to dump stack crawls 3069 * @return file containing stack traces, or null if no dump file is configured 3070 */ 3071 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3072 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3073 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3074 if (tracesPath == null || tracesPath.length() == 0) { 3075 return null; 3076 } 3077 3078 File tracesFile = new File(tracesPath); 3079 try { 3080 File tracesDir = tracesFile.getParentFile(); 3081 if (!tracesDir.exists()) { 3082 tracesFile.mkdirs(); 3083 if (!SELinux.restorecon(tracesDir)) { 3084 return null; 3085 } 3086 } 3087 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3088 3089 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3090 tracesFile.createNewFile(); 3091 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3092 } catch (IOException e) { 3093 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3094 return null; 3095 } 3096 3097 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3098 return tracesFile; 3099 } 3100 3101 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3102 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3103 // Use a FileObserver to detect when traces finish writing. 3104 // The order of traces is considered important to maintain for legibility. 3105 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3106 public synchronized void onEvent(int event, String path) { notify(); } 3107 }; 3108 3109 try { 3110 observer.startWatching(); 3111 3112 // First collect all of the stacks of the most important pids. 3113 if (firstPids != null) { 3114 try { 3115 int num = firstPids.size(); 3116 for (int i = 0; i < num; i++) { 3117 synchronized (observer) { 3118 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3119 observer.wait(200); // Wait for write-close, give up after 200msec 3120 } 3121 } 3122 } catch (InterruptedException e) { 3123 Log.wtf(TAG, e); 3124 } 3125 } 3126 3127 // Next measure CPU usage. 3128 if (processStats != null) { 3129 processStats.init(); 3130 System.gc(); 3131 processStats.update(); 3132 try { 3133 synchronized (processStats) { 3134 processStats.wait(500); // measure over 1/2 second. 3135 } 3136 } catch (InterruptedException e) { 3137 } 3138 processStats.update(); 3139 3140 // We'll take the stack crawls of just the top apps using CPU. 3141 final int N = processStats.countWorkingStats(); 3142 int numProcs = 0; 3143 for (int i=0; i<N && numProcs<5; i++) { 3144 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3145 if (lastPids.indexOfKey(stats.pid) >= 0) { 3146 numProcs++; 3147 try { 3148 synchronized (observer) { 3149 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3150 observer.wait(200); // Wait for write-close, give up after 200msec 3151 } 3152 } catch (InterruptedException e) { 3153 Log.wtf(TAG, e); 3154 } 3155 3156 } 3157 } 3158 } 3159 3160 } finally { 3161 observer.stopWatching(); 3162 } 3163 3164 if (nativeProcs != null) { 3165 int[] pids = Process.getPidsForCommands(nativeProcs); 3166 if (pids != null) { 3167 for (int pid : pids) { 3168 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3169 } 3170 } 3171 } 3172 } 3173 3174 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3175 if (true || IS_USER_BUILD) { 3176 return; 3177 } 3178 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3179 if (tracesPath == null || tracesPath.length() == 0) { 3180 return; 3181 } 3182 3183 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3184 StrictMode.allowThreadDiskWrites(); 3185 try { 3186 final File tracesFile = new File(tracesPath); 3187 final File tracesDir = tracesFile.getParentFile(); 3188 final File tracesTmp = new File(tracesDir, "__tmp__"); 3189 try { 3190 if (!tracesDir.exists()) { 3191 tracesFile.mkdirs(); 3192 if (!SELinux.restorecon(tracesDir.getPath())) { 3193 return; 3194 } 3195 } 3196 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3197 3198 if (tracesFile.exists()) { 3199 tracesTmp.delete(); 3200 tracesFile.renameTo(tracesTmp); 3201 } 3202 StringBuilder sb = new StringBuilder(); 3203 Time tobj = new Time(); 3204 tobj.set(System.currentTimeMillis()); 3205 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3206 sb.append(": "); 3207 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3208 sb.append(" since "); 3209 sb.append(msg); 3210 FileOutputStream fos = new FileOutputStream(tracesFile); 3211 fos.write(sb.toString().getBytes()); 3212 if (app == null) { 3213 fos.write("\n*** No application process!".getBytes()); 3214 } 3215 fos.close(); 3216 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3217 } catch (IOException e) { 3218 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3219 return; 3220 } 3221 3222 if (app != null) { 3223 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3224 firstPids.add(app.pid); 3225 dumpStackTraces(tracesPath, firstPids, null, null, null); 3226 } 3227 3228 File lastTracesFile = null; 3229 File curTracesFile = null; 3230 for (int i=9; i>=0; i--) { 3231 String name = String.format("slow%02d.txt", i); 3232 curTracesFile = new File(tracesDir, name); 3233 if (curTracesFile.exists()) { 3234 if (lastTracesFile != null) { 3235 curTracesFile.renameTo(lastTracesFile); 3236 } else { 3237 curTracesFile.delete(); 3238 } 3239 } 3240 lastTracesFile = curTracesFile; 3241 } 3242 tracesFile.renameTo(curTracesFile); 3243 if (tracesTmp.exists()) { 3244 tracesTmp.renameTo(tracesFile); 3245 } 3246 } finally { 3247 StrictMode.setThreadPolicy(oldPolicy); 3248 } 3249 } 3250 3251 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3252 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3253 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3254 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3255 3256 if (mController != null) { 3257 try { 3258 // 0 == continue, -1 = kill process immediately 3259 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3260 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3261 } catch (RemoteException e) { 3262 mController = null; 3263 } 3264 } 3265 3266 long anrTime = SystemClock.uptimeMillis(); 3267 if (MONITOR_CPU_USAGE) { 3268 updateCpuStatsNow(); 3269 } 3270 3271 synchronized (this) { 3272 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3273 if (mShuttingDown) { 3274 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3275 return; 3276 } else if (app.notResponding) { 3277 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3278 return; 3279 } else if (app.crashing) { 3280 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3281 return; 3282 } 3283 3284 // In case we come through here for the same app before completing 3285 // this one, mark as anring now so we will bail out. 3286 app.notResponding = true; 3287 3288 // Log the ANR to the event log. 3289 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3290 app.processName, app.info.flags, annotation); 3291 3292 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3293 firstPids.add(app.pid); 3294 3295 int parentPid = app.pid; 3296 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3297 if (parentPid != app.pid) firstPids.add(parentPid); 3298 3299 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3300 3301 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3302 ProcessRecord r = mLruProcesses.get(i); 3303 if (r != null && r.thread != null) { 3304 int pid = r.pid; 3305 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3306 if (r.persistent) { 3307 firstPids.add(pid); 3308 } else { 3309 lastPids.put(pid, Boolean.TRUE); 3310 } 3311 } 3312 } 3313 } 3314 } 3315 3316 // Log the ANR to the main log. 3317 StringBuilder info = new StringBuilder(); 3318 info.setLength(0); 3319 info.append("ANR in ").append(app.processName); 3320 if (activity != null && activity.shortComponentName != null) { 3321 info.append(" (").append(activity.shortComponentName).append(")"); 3322 } 3323 info.append("\n"); 3324 if (annotation != null) { 3325 info.append("Reason: ").append(annotation).append("\n"); 3326 } 3327 if (parent != null && parent != activity) { 3328 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3329 } 3330 3331 final ProcessStats processStats = new ProcessStats(true); 3332 3333 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3334 3335 String cpuInfo = null; 3336 if (MONITOR_CPU_USAGE) { 3337 updateCpuStatsNow(); 3338 synchronized (mProcessStatsThread) { 3339 cpuInfo = mProcessStats.printCurrentState(anrTime); 3340 } 3341 info.append(processStats.printCurrentLoad()); 3342 info.append(cpuInfo); 3343 } 3344 3345 info.append(processStats.printCurrentState(anrTime)); 3346 3347 Slog.e(TAG, info.toString()); 3348 if (tracesFile == null) { 3349 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3350 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3351 } 3352 3353 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3354 cpuInfo, tracesFile, null); 3355 3356 if (mController != null) { 3357 try { 3358 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3359 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3360 if (res != 0) { 3361 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3362 return; 3363 } 3364 } catch (RemoteException e) { 3365 mController = null; 3366 } 3367 } 3368 3369 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3370 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3371 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3372 3373 synchronized (this) { 3374 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3375 Slog.w(TAG, "Killing " + app + ": background ANR"); 3376 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3377 app.processName, app.setAdj, "background ANR"); 3378 Process.killProcessQuiet(app.pid); 3379 return; 3380 } 3381 3382 // Set the app's notResponding state, and look up the errorReportReceiver 3383 makeAppNotRespondingLocked(app, 3384 activity != null ? activity.shortComponentName : null, 3385 annotation != null ? "ANR " + annotation : "ANR", 3386 info.toString()); 3387 3388 // Bring up the infamous App Not Responding dialog 3389 Message msg = Message.obtain(); 3390 HashMap map = new HashMap(); 3391 msg.what = SHOW_NOT_RESPONDING_MSG; 3392 msg.obj = map; 3393 msg.arg1 = aboveSystem ? 1 : 0; 3394 map.put("app", app); 3395 if (activity != null) { 3396 map.put("activity", activity); 3397 } 3398 3399 mHandler.sendMessage(msg); 3400 } 3401 } 3402 3403 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3404 if (!mLaunchWarningShown) { 3405 mLaunchWarningShown = true; 3406 mHandler.post(new Runnable() { 3407 @Override 3408 public void run() { 3409 synchronized (ActivityManagerService.this) { 3410 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3411 d.show(); 3412 mHandler.postDelayed(new Runnable() { 3413 @Override 3414 public void run() { 3415 synchronized (ActivityManagerService.this) { 3416 d.dismiss(); 3417 mLaunchWarningShown = false; 3418 } 3419 } 3420 }, 4000); 3421 } 3422 } 3423 }); 3424 } 3425 } 3426 3427 public boolean clearApplicationUserData(final String packageName, 3428 final IPackageDataObserver observer, int userId) { 3429 enforceNotIsolatedCaller("clearApplicationUserData"); 3430 int uid = Binder.getCallingUid(); 3431 int pid = Binder.getCallingPid(); 3432 userId = handleIncomingUser(pid, uid, 3433 userId, false, true, "clearApplicationUserData", null); 3434 long callingId = Binder.clearCallingIdentity(); 3435 try { 3436 IPackageManager pm = AppGlobals.getPackageManager(); 3437 int pkgUid = -1; 3438 synchronized(this) { 3439 try { 3440 pkgUid = pm.getPackageUid(packageName, userId); 3441 } catch (RemoteException e) { 3442 } 3443 if (pkgUid == -1) { 3444 Slog.w(TAG, "Invalid packageName:" + packageName); 3445 return false; 3446 } 3447 if (uid == pkgUid || checkComponentPermission( 3448 android.Manifest.permission.CLEAR_APP_USER_DATA, 3449 pid, uid, -1, true) 3450 == PackageManager.PERMISSION_GRANTED) { 3451 forceStopPackageLocked(packageName, pkgUid); 3452 } else { 3453 throw new SecurityException(pid+" does not have permission:"+ 3454 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3455 "for process:"+packageName); 3456 } 3457 } 3458 3459 try { 3460 //clear application user data 3461 pm.clearApplicationUserData(packageName, observer, userId); 3462 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3463 Uri.fromParts("package", packageName, null)); 3464 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3465 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3466 null, null, 0, null, null, null, false, false, userId); 3467 } catch (RemoteException e) { 3468 } 3469 } finally { 3470 Binder.restoreCallingIdentity(callingId); 3471 } 3472 return true; 3473 } 3474 3475 public void killBackgroundProcesses(final String packageName, int userId) { 3476 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3477 != PackageManager.PERMISSION_GRANTED && 3478 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3479 != PackageManager.PERMISSION_GRANTED) { 3480 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3481 + Binder.getCallingPid() 3482 + ", uid=" + Binder.getCallingUid() 3483 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3484 Slog.w(TAG, msg); 3485 throw new SecurityException(msg); 3486 } 3487 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3489 userId, true, true, "killBackgroundProcesses", null); 3490 long callingId = Binder.clearCallingIdentity(); 3491 try { 3492 IPackageManager pm = AppGlobals.getPackageManager(); 3493 synchronized(this) { 3494 int appId = -1; 3495 try { 3496 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3497 } catch (RemoteException e) { 3498 } 3499 if (appId == -1) { 3500 Slog.w(TAG, "Invalid packageName: " + packageName); 3501 return; 3502 } 3503 killPackageProcessesLocked(packageName, appId, userId, 3504 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3505 } 3506 } finally { 3507 Binder.restoreCallingIdentity(callingId); 3508 } 3509 } 3510 3511 public void killAllBackgroundProcesses() { 3512 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3513 != PackageManager.PERMISSION_GRANTED) { 3514 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3515 + Binder.getCallingPid() 3516 + ", uid=" + Binder.getCallingUid() 3517 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3518 Slog.w(TAG, msg); 3519 throw new SecurityException(msg); 3520 } 3521 3522 long callingId = Binder.clearCallingIdentity(); 3523 try { 3524 synchronized(this) { 3525 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3526 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3527 final int NA = apps.size(); 3528 for (int ia=0; ia<NA; ia++) { 3529 ProcessRecord app = apps.valueAt(ia); 3530 if (app.persistent) { 3531 // we don't kill persistent processes 3532 continue; 3533 } 3534 if (app.removed) { 3535 procs.add(app); 3536 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3537 app.removed = true; 3538 procs.add(app); 3539 } 3540 } 3541 } 3542 3543 int N = procs.size(); 3544 for (int i=0; i<N; i++) { 3545 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3546 } 3547 } 3548 } finally { 3549 Binder.restoreCallingIdentity(callingId); 3550 } 3551 } 3552 3553 public void forceStopPackage(final String packageName, int userId) { 3554 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3555 != PackageManager.PERMISSION_GRANTED) { 3556 String msg = "Permission Denial: forceStopPackage() from pid=" 3557 + Binder.getCallingPid() 3558 + ", uid=" + Binder.getCallingUid() 3559 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3560 Slog.w(TAG, msg); 3561 throw new SecurityException(msg); 3562 } 3563 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3564 userId, true, true, "forceStopPackage", null); 3565 long callingId = Binder.clearCallingIdentity(); 3566 try { 3567 IPackageManager pm = AppGlobals.getPackageManager(); 3568 synchronized(this) { 3569 int[] users = userId == UserHandle.USER_ALL 3570 ? getUsersLocked() : new int[] { userId }; 3571 for (int user : users) { 3572 int pkgUid = -1; 3573 try { 3574 pkgUid = pm.getPackageUid(packageName, user); 3575 } catch (RemoteException e) { 3576 } 3577 if (pkgUid == -1) { 3578 Slog.w(TAG, "Invalid packageName: " + packageName); 3579 continue; 3580 } 3581 try { 3582 pm.setPackageStoppedState(packageName, true, user); 3583 } catch (RemoteException e) { 3584 } catch (IllegalArgumentException e) { 3585 Slog.w(TAG, "Failed trying to unstop package " 3586 + packageName + ": " + e); 3587 } 3588 if (isUserRunningLocked(user, false)) { 3589 forceStopPackageLocked(packageName, pkgUid); 3590 } 3591 } 3592 } 3593 } finally { 3594 Binder.restoreCallingIdentity(callingId); 3595 } 3596 } 3597 3598 /* 3599 * The pkg name and app id have to be specified. 3600 */ 3601 public void killApplicationWithAppId(String pkg, int appid) { 3602 if (pkg == null) { 3603 return; 3604 } 3605 // Make sure the uid is valid. 3606 if (appid < 0) { 3607 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3608 return; 3609 } 3610 int callerUid = Binder.getCallingUid(); 3611 // Only the system server can kill an application 3612 if (callerUid == Process.SYSTEM_UID) { 3613 // Post an aysnc message to kill the application 3614 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3615 msg.arg1 = appid; 3616 msg.arg2 = 0; 3617 msg.obj = pkg; 3618 mHandler.sendMessage(msg); 3619 } else { 3620 throw new SecurityException(callerUid + " cannot kill pkg: " + 3621 pkg); 3622 } 3623 } 3624 3625 public void closeSystemDialogs(String reason) { 3626 enforceNotIsolatedCaller("closeSystemDialogs"); 3627 3628 final int pid = Binder.getCallingPid(); 3629 final int uid = Binder.getCallingUid(); 3630 final long origId = Binder.clearCallingIdentity(); 3631 try { 3632 synchronized (this) { 3633 // Only allow this from foreground processes, so that background 3634 // applications can't abuse it to prevent system UI from being shown. 3635 if (uid >= Process.FIRST_APPLICATION_UID) { 3636 ProcessRecord proc; 3637 synchronized (mPidsSelfLocked) { 3638 proc = mPidsSelfLocked.get(pid); 3639 } 3640 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3641 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3642 + " from background process " + proc); 3643 return; 3644 } 3645 } 3646 closeSystemDialogsLocked(reason); 3647 } 3648 } finally { 3649 Binder.restoreCallingIdentity(origId); 3650 } 3651 } 3652 3653 void closeSystemDialogsLocked(String reason) { 3654 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3655 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3656 | Intent.FLAG_RECEIVER_FOREGROUND); 3657 if (reason != null) { 3658 intent.putExtra("reason", reason); 3659 } 3660 mWindowManager.closeSystemDialogs(reason); 3661 3662 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3663 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3664 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3665 r.stack.finishActivityLocked(r, i, 3666 Activity.RESULT_CANCELED, null, "close-sys", true); 3667 } 3668 } 3669 3670 broadcastIntentLocked(null, null, intent, null, 3671 null, 0, null, null, null, false, false, -1, 3672 Process.SYSTEM_UID, UserHandle.USER_ALL); 3673 } 3674 3675 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3676 throws RemoteException { 3677 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3678 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3679 for (int i=pids.length-1; i>=0; i--) { 3680 infos[i] = new Debug.MemoryInfo(); 3681 Debug.getMemoryInfo(pids[i], infos[i]); 3682 } 3683 return infos; 3684 } 3685 3686 public long[] getProcessPss(int[] pids) throws RemoteException { 3687 enforceNotIsolatedCaller("getProcessPss"); 3688 long[] pss = new long[pids.length]; 3689 for (int i=pids.length-1; i>=0; i--) { 3690 pss[i] = Debug.getPss(pids[i]); 3691 } 3692 return pss; 3693 } 3694 3695 public void killApplicationProcess(String processName, int uid) { 3696 if (processName == null) { 3697 return; 3698 } 3699 3700 int callerUid = Binder.getCallingUid(); 3701 // Only the system server can kill an application 3702 if (callerUid == Process.SYSTEM_UID) { 3703 synchronized (this) { 3704 ProcessRecord app = getProcessRecordLocked(processName, uid); 3705 if (app != null && app.thread != null) { 3706 try { 3707 app.thread.scheduleSuicide(); 3708 } catch (RemoteException e) { 3709 // If the other end already died, then our work here is done. 3710 } 3711 } else { 3712 Slog.w(TAG, "Process/uid not found attempting kill of " 3713 + processName + " / " + uid); 3714 } 3715 } 3716 } else { 3717 throw new SecurityException(callerUid + " cannot kill app process: " + 3718 processName); 3719 } 3720 } 3721 3722 private void forceStopPackageLocked(final String packageName, int uid) { 3723 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3724 false, true, false, UserHandle.getUserId(uid)); 3725 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3726 Uri.fromParts("package", packageName, null)); 3727 if (!mProcessesReady) { 3728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3729 | Intent.FLAG_RECEIVER_FOREGROUND); 3730 } 3731 intent.putExtra(Intent.EXTRA_UID, uid); 3732 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3733 broadcastIntentLocked(null, null, intent, 3734 null, null, 0, null, null, null, 3735 false, false, 3736 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3737 } 3738 3739 private void forceStopUserLocked(int userId) { 3740 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3741 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 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(" mStartedUserArray: ["); 9342 for (int i=0; i<mStartedUserArray.length; i++) { 9343 if (i > 0) pw.print(", "); 9344 pw.print(mStartedUserArray[i]); 9345 } 9346 pw.println("]"); 9347 pw.print(" mUserLru: ["); 9348 for (int i=0; i<mUserLru.size(); i++) { 9349 if (i > 0) pw.print(", "); 9350 pw.print(mUserLru.get(i)); 9351 } 9352 pw.println("]"); 9353 if (dumpAll) { 9354 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9355 } 9356 pw.println(" mHomeProcess: " + mHomeProcess); 9357 pw.println(" mPreviousProcess: " + mPreviousProcess); 9358 if (dumpAll) { 9359 StringBuilder sb = new StringBuilder(128); 9360 sb.append(" mPreviousProcessVisibleTime: "); 9361 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9362 pw.println(sb); 9363 } 9364 if (mHeavyWeightProcess != null) { 9365 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9366 } 9367 pw.println(" mConfiguration: " + mConfiguration); 9368 if (dumpAll) { 9369 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9370 if (mCompatModePackages.getPackages().size() > 0) { 9371 boolean printed = false; 9372 for (Map.Entry<String, Integer> entry 9373 : mCompatModePackages.getPackages().entrySet()) { 9374 String pkg = entry.getKey(); 9375 int mode = entry.getValue(); 9376 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9377 continue; 9378 } 9379 if (!printed) { 9380 pw.println(" mScreenCompatPackages:"); 9381 printed = true; 9382 } 9383 pw.print(" "); pw.print(pkg); pw.print(": "); 9384 pw.print(mode); pw.println(); 9385 } 9386 } 9387 } 9388 if (mSleeping || mWentToSleep || mLockScreenShown) { 9389 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9390 + " mLockScreenShown " + mLockScreenShown); 9391 } 9392 if (mShuttingDown) { 9393 pw.println(" mShuttingDown=" + mShuttingDown); 9394 } 9395 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9396 || mOrigWaitForDebugger) { 9397 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9398 + " mDebugTransient=" + mDebugTransient 9399 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9400 } 9401 if (mOpenGlTraceApp != null) { 9402 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9403 } 9404 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9405 || mProfileFd != null) { 9406 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9407 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9408 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9409 + mAutoStopProfiler); 9410 } 9411 if (mAlwaysFinishActivities || mController != null) { 9412 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9413 + " mController=" + mController); 9414 } 9415 if (dumpAll) { 9416 pw.println(" Total persistent processes: " + numPers); 9417 pw.println(" mStartRunning=" + mStartRunning 9418 + " mProcessesReady=" + mProcessesReady 9419 + " mSystemReady=" + mSystemReady); 9420 pw.println(" mBooting=" + mBooting 9421 + " mBooted=" + mBooted 9422 + " mFactoryTest=" + mFactoryTest); 9423 pw.print(" mLastPowerCheckRealtime="); 9424 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9425 pw.println(""); 9426 pw.print(" mLastPowerCheckUptime="); 9427 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9428 pw.println(""); 9429 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9430 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9431 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9432 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9433 + " mNumHiddenProcs=" + mNumHiddenProcs 9434 + " mNumServiceProcs=" + mNumServiceProcs 9435 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9436 } 9437 9438 return true; 9439 } 9440 9441 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9442 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9443 if (mProcessesToGc.size() > 0) { 9444 boolean printed = false; 9445 long now = SystemClock.uptimeMillis(); 9446 for (int i=0; i<mProcessesToGc.size(); i++) { 9447 ProcessRecord proc = mProcessesToGc.get(i); 9448 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9449 continue; 9450 } 9451 if (!printed) { 9452 if (needSep) pw.println(" "); 9453 needSep = true; 9454 pw.println(" Processes that are waiting to GC:"); 9455 printed = true; 9456 } 9457 pw.print(" Process "); pw.println(proc); 9458 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9459 pw.print(", last gced="); 9460 pw.print(now-proc.lastRequestedGc); 9461 pw.print(" ms ago, last lowMem="); 9462 pw.print(now-proc.lastLowMemory); 9463 pw.println(" ms ago"); 9464 9465 } 9466 } 9467 return needSep; 9468 } 9469 9470 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9471 int opti, boolean dumpAll) { 9472 boolean needSep = false; 9473 9474 if (mLruProcesses.size() > 0) { 9475 if (needSep) pw.println(" "); 9476 needSep = true; 9477 pw.println(" OOM levels:"); 9478 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9479 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9480 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9481 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9482 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9483 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9484 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9485 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9486 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9487 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9488 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9489 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9490 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9491 9492 if (needSep) pw.println(" "); 9493 needSep = true; 9494 pw.println(" Process OOM control:"); 9495 dumpProcessOomList(pw, this, mLruProcesses, " ", 9496 "Proc", "PERS", true, null); 9497 needSep = true; 9498 } 9499 9500 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9501 9502 pw.println(); 9503 pw.println(" mHomeProcess: " + mHomeProcess); 9504 pw.println(" mPreviousProcess: " + mPreviousProcess); 9505 if (mHeavyWeightProcess != null) { 9506 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9507 } 9508 9509 return true; 9510 } 9511 9512 /** 9513 * There are three ways to call this: 9514 * - no provider specified: dump all the providers 9515 * - a flattened component name that matched an existing provider was specified as the 9516 * first arg: dump that one provider 9517 * - the first arg isn't the flattened component name of an existing provider: 9518 * dump all providers whose component contains the first arg as a substring 9519 */ 9520 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9521 int opti, boolean dumpAll) { 9522 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9523 } 9524 9525 static class ItemMatcher { 9526 ArrayList<ComponentName> components; 9527 ArrayList<String> strings; 9528 ArrayList<Integer> objects; 9529 boolean all; 9530 9531 ItemMatcher() { 9532 all = true; 9533 } 9534 9535 void build(String name) { 9536 ComponentName componentName = ComponentName.unflattenFromString(name); 9537 if (componentName != null) { 9538 if (components == null) { 9539 components = new ArrayList<ComponentName>(); 9540 } 9541 components.add(componentName); 9542 all = false; 9543 } else { 9544 int objectId = 0; 9545 // Not a '/' separated full component name; maybe an object ID? 9546 try { 9547 objectId = Integer.parseInt(name, 16); 9548 if (objects == null) { 9549 objects = new ArrayList<Integer>(); 9550 } 9551 objects.add(objectId); 9552 all = false; 9553 } catch (RuntimeException e) { 9554 // Not an integer; just do string match. 9555 if (strings == null) { 9556 strings = new ArrayList<String>(); 9557 } 9558 strings.add(name); 9559 all = false; 9560 } 9561 } 9562 } 9563 9564 int build(String[] args, int opti) { 9565 for (; opti<args.length; opti++) { 9566 String name = args[opti]; 9567 if ("--".equals(name)) { 9568 return opti+1; 9569 } 9570 build(name); 9571 } 9572 return opti; 9573 } 9574 9575 boolean match(Object object, ComponentName comp) { 9576 if (all) { 9577 return true; 9578 } 9579 if (components != null) { 9580 for (int i=0; i<components.size(); i++) { 9581 if (components.get(i).equals(comp)) { 9582 return true; 9583 } 9584 } 9585 } 9586 if (objects != null) { 9587 for (int i=0; i<objects.size(); i++) { 9588 if (System.identityHashCode(object) == objects.get(i)) { 9589 return true; 9590 } 9591 } 9592 } 9593 if (strings != null) { 9594 String flat = comp.flattenToString(); 9595 for (int i=0; i<strings.size(); i++) { 9596 if (flat.contains(strings.get(i))) { 9597 return true; 9598 } 9599 } 9600 } 9601 return false; 9602 } 9603 } 9604 9605 /** 9606 * There are three things that cmd can be: 9607 * - a flattened component name that matches an existing activity 9608 * - the cmd arg isn't the flattened component name of an existing activity: 9609 * dump all activity whose component contains the cmd as a substring 9610 * - A hex number of the ActivityRecord object instance. 9611 */ 9612 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9613 int opti, boolean dumpAll) { 9614 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9615 9616 if ("all".equals(name)) { 9617 synchronized (this) { 9618 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9619 activities.add(r1); 9620 } 9621 } 9622 } else if ("top".equals(name)) { 9623 synchronized (this) { 9624 final int N = mMainStack.mHistory.size(); 9625 if (N > 0) { 9626 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9627 } 9628 } 9629 } else { 9630 ItemMatcher matcher = new ItemMatcher(); 9631 matcher.build(name); 9632 9633 synchronized (this) { 9634 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9635 if (matcher.match(r1, r1.intent.getComponent())) { 9636 activities.add(r1); 9637 } 9638 } 9639 } 9640 } 9641 9642 if (activities.size() <= 0) { 9643 return false; 9644 } 9645 9646 String[] newArgs = new String[args.length - opti]; 9647 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9648 9649 TaskRecord lastTask = null; 9650 boolean needSep = false; 9651 for (int i=activities.size()-1; i>=0; i--) { 9652 ActivityRecord r = (ActivityRecord)activities.get(i); 9653 if (needSep) { 9654 pw.println(); 9655 } 9656 needSep = true; 9657 synchronized (this) { 9658 if (lastTask != r.task) { 9659 lastTask = r.task; 9660 pw.print("TASK "); pw.print(lastTask.affinity); 9661 pw.print(" id="); pw.println(lastTask.taskId); 9662 if (dumpAll) { 9663 lastTask.dump(pw, " "); 9664 } 9665 } 9666 } 9667 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9668 } 9669 return true; 9670 } 9671 9672 /** 9673 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9674 * there is a thread associated with the activity. 9675 */ 9676 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9677 final ActivityRecord r, String[] args, boolean dumpAll) { 9678 String innerPrefix = prefix + " "; 9679 synchronized (this) { 9680 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9681 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9682 pw.print(" pid="); 9683 if (r.app != null) pw.println(r.app.pid); 9684 else pw.println("(not running)"); 9685 if (dumpAll) { 9686 r.dump(pw, innerPrefix); 9687 } 9688 } 9689 if (r.app != null && r.app.thread != null) { 9690 // flush anything that is already in the PrintWriter since the thread is going 9691 // to write to the file descriptor directly 9692 pw.flush(); 9693 try { 9694 TransferPipe tp = new TransferPipe(); 9695 try { 9696 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9697 r.appToken, innerPrefix, args); 9698 tp.go(fd); 9699 } finally { 9700 tp.kill(); 9701 } 9702 } catch (IOException e) { 9703 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9704 } catch (RemoteException e) { 9705 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9706 } 9707 } 9708 } 9709 9710 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9711 int opti, boolean dumpAll, String dumpPackage) { 9712 boolean needSep = false; 9713 boolean onlyHistory = false; 9714 9715 if ("history".equals(dumpPackage)) { 9716 onlyHistory = true; 9717 dumpPackage = null; 9718 } 9719 9720 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9721 if (!onlyHistory && dumpAll) { 9722 if (mRegisteredReceivers.size() > 0) { 9723 boolean printed = false; 9724 Iterator it = mRegisteredReceivers.values().iterator(); 9725 while (it.hasNext()) { 9726 ReceiverList r = (ReceiverList)it.next(); 9727 if (dumpPackage != null && (r.app == null || 9728 !dumpPackage.equals(r.app.info.packageName))) { 9729 continue; 9730 } 9731 if (!printed) { 9732 pw.println(" Registered Receivers:"); 9733 needSep = true; 9734 printed = true; 9735 } 9736 pw.print(" * "); pw.println(r); 9737 r.dump(pw, " "); 9738 } 9739 } 9740 9741 if (mReceiverResolver.dump(pw, needSep ? 9742 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9743 " ", dumpPackage, false)) { 9744 needSep = true; 9745 } 9746 } 9747 9748 for (BroadcastQueue q : mBroadcastQueues) { 9749 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9750 } 9751 9752 needSep = true; 9753 9754 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9755 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9756 if (needSep) { 9757 pw.println(); 9758 } 9759 needSep = true; 9760 pw.print(" Sticky broadcasts for user "); 9761 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9762 StringBuilder sb = new StringBuilder(128); 9763 for (Map.Entry<String, ArrayList<Intent>> ent 9764 : mStickyBroadcasts.valueAt(user).entrySet()) { 9765 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9766 if (dumpAll) { 9767 pw.println(":"); 9768 ArrayList<Intent> intents = ent.getValue(); 9769 final int N = intents.size(); 9770 for (int i=0; i<N; i++) { 9771 sb.setLength(0); 9772 sb.append(" Intent: "); 9773 intents.get(i).toShortString(sb, false, true, false, false); 9774 pw.println(sb.toString()); 9775 Bundle bundle = intents.get(i).getExtras(); 9776 if (bundle != null) { 9777 pw.print(" "); 9778 pw.println(bundle.toString()); 9779 } 9780 } 9781 } else { 9782 pw.println(""); 9783 } 9784 } 9785 } 9786 } 9787 9788 if (!onlyHistory && dumpAll) { 9789 pw.println(); 9790 for (BroadcastQueue queue : mBroadcastQueues) { 9791 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9792 + queue.mBroadcastsScheduled); 9793 } 9794 pw.println(" mHandler:"); 9795 mHandler.dump(new PrintWriterPrinter(pw), " "); 9796 needSep = true; 9797 } 9798 9799 return needSep; 9800 } 9801 9802 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9803 int opti, boolean dumpAll, String dumpPackage) { 9804 boolean needSep = true; 9805 9806 ItemMatcher matcher = new ItemMatcher(); 9807 matcher.build(args, opti); 9808 9809 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9810 9811 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9812 9813 if (mLaunchingProviders.size() > 0) { 9814 boolean printed = false; 9815 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9816 ContentProviderRecord r = mLaunchingProviders.get(i); 9817 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9818 continue; 9819 } 9820 if (!printed) { 9821 if (needSep) pw.println(" "); 9822 needSep = true; 9823 pw.println(" Launching content providers:"); 9824 printed = true; 9825 } 9826 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9827 pw.println(r); 9828 } 9829 } 9830 9831 if (mGrantedUriPermissions.size() > 0) { 9832 if (needSep) pw.println(); 9833 needSep = true; 9834 pw.println("Granted Uri Permissions:"); 9835 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9836 int uid = mGrantedUriPermissions.keyAt(i); 9837 HashMap<Uri, UriPermission> perms 9838 = mGrantedUriPermissions.valueAt(i); 9839 pw.print(" * UID "); pw.print(uid); 9840 pw.println(" holds:"); 9841 for (UriPermission perm : perms.values()) { 9842 pw.print(" "); pw.println(perm); 9843 if (dumpAll) { 9844 perm.dump(pw, " "); 9845 } 9846 } 9847 } 9848 needSep = true; 9849 } 9850 9851 return needSep; 9852 } 9853 9854 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9855 int opti, boolean dumpAll, String dumpPackage) { 9856 boolean needSep = false; 9857 9858 if (mIntentSenderRecords.size() > 0) { 9859 boolean printed = false; 9860 Iterator<WeakReference<PendingIntentRecord>> it 9861 = mIntentSenderRecords.values().iterator(); 9862 while (it.hasNext()) { 9863 WeakReference<PendingIntentRecord> ref = it.next(); 9864 PendingIntentRecord rec = ref != null ? ref.get(): null; 9865 if (dumpPackage != null && (rec == null 9866 || !dumpPackage.equals(rec.key.packageName))) { 9867 continue; 9868 } 9869 if (!printed) { 9870 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9871 printed = true; 9872 } 9873 needSep = true; 9874 if (rec != null) { 9875 pw.print(" * "); pw.println(rec); 9876 if (dumpAll) { 9877 rec.dump(pw, " "); 9878 } 9879 } else { 9880 pw.print(" * "); pw.println(ref); 9881 } 9882 } 9883 } 9884 9885 return needSep; 9886 } 9887 9888 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9889 String prefix, String label, boolean complete, boolean brief, boolean client, 9890 String dumpPackage) { 9891 TaskRecord lastTask = null; 9892 boolean needNL = false; 9893 final String innerPrefix = prefix + " "; 9894 final String[] args = new String[0]; 9895 for (int i=list.size()-1; i>=0; i--) { 9896 final ActivityRecord r = (ActivityRecord)list.get(i); 9897 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9898 continue; 9899 } 9900 final boolean full = !brief && (complete || !r.isInHistory()); 9901 if (needNL) { 9902 pw.println(" "); 9903 needNL = false; 9904 } 9905 if (lastTask != r.task) { 9906 lastTask = r.task; 9907 pw.print(prefix); 9908 pw.print(full ? "* " : " "); 9909 pw.println(lastTask); 9910 if (full) { 9911 lastTask.dump(pw, prefix + " "); 9912 } else if (complete) { 9913 // Complete + brief == give a summary. Isn't that obvious?!? 9914 if (lastTask.intent != null) { 9915 pw.print(prefix); pw.print(" "); 9916 pw.println(lastTask.intent.toInsecureStringWithClip()); 9917 } 9918 } 9919 } 9920 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9921 pw.print(" #"); pw.print(i); pw.print(": "); 9922 pw.println(r); 9923 if (full) { 9924 r.dump(pw, innerPrefix); 9925 } else if (complete) { 9926 // Complete + brief == give a summary. Isn't that obvious?!? 9927 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9928 if (r.app != null) { 9929 pw.print(innerPrefix); pw.println(r.app); 9930 } 9931 } 9932 if (client && r.app != null && r.app.thread != null) { 9933 // flush anything that is already in the PrintWriter since the thread is going 9934 // to write to the file descriptor directly 9935 pw.flush(); 9936 try { 9937 TransferPipe tp = new TransferPipe(); 9938 try { 9939 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9940 r.appToken, innerPrefix, args); 9941 // Short timeout, since blocking here can 9942 // deadlock with the application. 9943 tp.go(fd, 2000); 9944 } finally { 9945 tp.kill(); 9946 } 9947 } catch (IOException e) { 9948 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9949 } catch (RemoteException e) { 9950 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9951 } 9952 needNL = true; 9953 } 9954 } 9955 } 9956 9957 private static String buildOomTag(String prefix, String space, int val, int base) { 9958 if (val == base) { 9959 if (space == null) return prefix; 9960 return prefix + " "; 9961 } 9962 return prefix + "+" + Integer.toString(val-base); 9963 } 9964 9965 private static final int dumpProcessList(PrintWriter pw, 9966 ActivityManagerService service, List list, 9967 String prefix, String normalLabel, String persistentLabel, 9968 String dumpPackage) { 9969 int numPers = 0; 9970 final int N = list.size()-1; 9971 for (int i=N; i>=0; i--) { 9972 ProcessRecord r = (ProcessRecord)list.get(i); 9973 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9974 continue; 9975 } 9976 pw.println(String.format("%s%s #%2d: %s", 9977 prefix, (r.persistent ? persistentLabel : normalLabel), 9978 i, r.toString())); 9979 if (r.persistent) { 9980 numPers++; 9981 } 9982 } 9983 return numPers; 9984 } 9985 9986 private static final boolean dumpProcessOomList(PrintWriter pw, 9987 ActivityManagerService service, List<ProcessRecord> origList, 9988 String prefix, String normalLabel, String persistentLabel, 9989 boolean inclDetails, String dumpPackage) { 9990 9991 ArrayList<Pair<ProcessRecord, Integer>> list 9992 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9993 for (int i=0; i<origList.size(); i++) { 9994 ProcessRecord r = origList.get(i); 9995 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9996 continue; 9997 } 9998 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9999 } 10000 10001 if (list.size() <= 0) { 10002 return false; 10003 } 10004 10005 Comparator<Pair<ProcessRecord, Integer>> comparator 10006 = new Comparator<Pair<ProcessRecord, Integer>>() { 10007 @Override 10008 public int compare(Pair<ProcessRecord, Integer> object1, 10009 Pair<ProcessRecord, Integer> object2) { 10010 if (object1.first.setAdj != object2.first.setAdj) { 10011 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10012 } 10013 if (object1.second.intValue() != object2.second.intValue()) { 10014 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10015 } 10016 return 0; 10017 } 10018 }; 10019 10020 Collections.sort(list, comparator); 10021 10022 final long curRealtime = SystemClock.elapsedRealtime(); 10023 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10024 final long curUptime = SystemClock.uptimeMillis(); 10025 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10026 10027 for (int i=list.size()-1; i>=0; i--) { 10028 ProcessRecord r = list.get(i).first; 10029 String oomAdj; 10030 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10031 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10032 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10033 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10034 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10035 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10036 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10037 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10038 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10039 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10040 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10041 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10042 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10043 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10044 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10045 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10046 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10047 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10048 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10049 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10050 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10051 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10052 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10053 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10054 } else { 10055 oomAdj = Integer.toString(r.setAdj); 10056 } 10057 String schedGroup; 10058 switch (r.setSchedGroup) { 10059 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10060 schedGroup = "B"; 10061 break; 10062 case Process.THREAD_GROUP_DEFAULT: 10063 schedGroup = "F"; 10064 break; 10065 default: 10066 schedGroup = Integer.toString(r.setSchedGroup); 10067 break; 10068 } 10069 String foreground; 10070 if (r.foregroundActivities) { 10071 foreground = "A"; 10072 } else if (r.foregroundServices) { 10073 foreground = "S"; 10074 } else { 10075 foreground = " "; 10076 } 10077 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10078 prefix, (r.persistent ? persistentLabel : normalLabel), 10079 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10080 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10081 if (r.adjSource != null || r.adjTarget != null) { 10082 pw.print(prefix); 10083 pw.print(" "); 10084 if (r.adjTarget instanceof ComponentName) { 10085 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10086 } else if (r.adjTarget != null) { 10087 pw.print(r.adjTarget.toString()); 10088 } else { 10089 pw.print("{null}"); 10090 } 10091 pw.print("<="); 10092 if (r.adjSource instanceof ProcessRecord) { 10093 pw.print("Proc{"); 10094 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10095 pw.println("}"); 10096 } else if (r.adjSource != null) { 10097 pw.println(r.adjSource.toString()); 10098 } else { 10099 pw.println("{null}"); 10100 } 10101 } 10102 if (inclDetails) { 10103 pw.print(prefix); 10104 pw.print(" "); 10105 pw.print("oom: max="); pw.print(r.maxAdj); 10106 pw.print(" hidden="); pw.print(r.hiddenAdj); 10107 pw.print(" client="); pw.print(r.clientHiddenAdj); 10108 pw.print(" empty="); pw.print(r.emptyAdj); 10109 pw.print(" curRaw="); pw.print(r.curRawAdj); 10110 pw.print(" setRaw="); pw.print(r.setRawAdj); 10111 pw.print(" cur="); pw.print(r.curAdj); 10112 pw.print(" set="); pw.println(r.setAdj); 10113 pw.print(prefix); 10114 pw.print(" "); 10115 pw.print("keeping="); pw.print(r.keeping); 10116 pw.print(" hidden="); pw.print(r.hidden); 10117 pw.print(" empty="); pw.print(r.empty); 10118 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10119 10120 if (!r.keeping) { 10121 if (r.lastWakeTime != 0) { 10122 long wtime; 10123 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10124 synchronized (stats) { 10125 wtime = stats.getProcessWakeTime(r.info.uid, 10126 r.pid, curRealtime); 10127 } 10128 long timeUsed = wtime - r.lastWakeTime; 10129 pw.print(prefix); 10130 pw.print(" "); 10131 pw.print("keep awake over "); 10132 TimeUtils.formatDuration(realtimeSince, pw); 10133 pw.print(" used "); 10134 TimeUtils.formatDuration(timeUsed, pw); 10135 pw.print(" ("); 10136 pw.print((timeUsed*100)/realtimeSince); 10137 pw.println("%)"); 10138 } 10139 if (r.lastCpuTime != 0) { 10140 long timeUsed = r.curCpuTime - r.lastCpuTime; 10141 pw.print(prefix); 10142 pw.print(" "); 10143 pw.print("run cpu over "); 10144 TimeUtils.formatDuration(uptimeSince, pw); 10145 pw.print(" used "); 10146 TimeUtils.formatDuration(timeUsed, pw); 10147 pw.print(" ("); 10148 pw.print((timeUsed*100)/uptimeSince); 10149 pw.println("%)"); 10150 } 10151 } 10152 } 10153 } 10154 return true; 10155 } 10156 10157 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10158 ArrayList<ProcessRecord> procs; 10159 synchronized (this) { 10160 if (args != null && args.length > start 10161 && args[start].charAt(0) != '-') { 10162 procs = new ArrayList<ProcessRecord>(); 10163 int pid = -1; 10164 try { 10165 pid = Integer.parseInt(args[start]); 10166 } catch (NumberFormatException e) { 10167 10168 } 10169 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10170 ProcessRecord proc = mLruProcesses.get(i); 10171 if (proc.pid == pid) { 10172 procs.add(proc); 10173 } else if (proc.processName.equals(args[start])) { 10174 procs.add(proc); 10175 } 10176 } 10177 if (procs.size() <= 0) { 10178 pw.println("No process found for: " + args[start]); 10179 return null; 10180 } 10181 } else { 10182 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10183 } 10184 } 10185 return procs; 10186 } 10187 10188 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10189 PrintWriter pw, String[] args) { 10190 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10191 if (procs == null) { 10192 return; 10193 } 10194 10195 long uptime = SystemClock.uptimeMillis(); 10196 long realtime = SystemClock.elapsedRealtime(); 10197 pw.println("Applications Graphics Acceleration Info:"); 10198 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10199 10200 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10201 ProcessRecord r = procs.get(i); 10202 if (r.thread != null) { 10203 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10204 pw.flush(); 10205 try { 10206 TransferPipe tp = new TransferPipe(); 10207 try { 10208 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10209 tp.go(fd); 10210 } finally { 10211 tp.kill(); 10212 } 10213 } catch (IOException e) { 10214 pw.println("Failure while dumping the app: " + r); 10215 pw.flush(); 10216 } catch (RemoteException e) { 10217 pw.println("Got a RemoteException while dumping the app " + r); 10218 pw.flush(); 10219 } 10220 } 10221 } 10222 } 10223 10224 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10225 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10226 if (procs == null) { 10227 return; 10228 } 10229 10230 pw.println("Applications Database Info:"); 10231 10232 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10233 ProcessRecord r = procs.get(i); 10234 if (r.thread != null) { 10235 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10236 pw.flush(); 10237 try { 10238 TransferPipe tp = new TransferPipe(); 10239 try { 10240 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10241 tp.go(fd); 10242 } finally { 10243 tp.kill(); 10244 } 10245 } catch (IOException e) { 10246 pw.println("Failure while dumping the app: " + r); 10247 pw.flush(); 10248 } catch (RemoteException e) { 10249 pw.println("Got a RemoteException while dumping the app " + r); 10250 pw.flush(); 10251 } 10252 } 10253 } 10254 } 10255 10256 final static class MemItem { 10257 final String label; 10258 final String shortLabel; 10259 final long pss; 10260 final int id; 10261 ArrayList<MemItem> subitems; 10262 10263 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10264 label = _label; 10265 shortLabel = _shortLabel; 10266 pss = _pss; 10267 id = _id; 10268 } 10269 } 10270 10271 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10272 boolean sort) { 10273 if (sort) { 10274 Collections.sort(items, new Comparator<MemItem>() { 10275 @Override 10276 public int compare(MemItem lhs, MemItem rhs) { 10277 if (lhs.pss < rhs.pss) { 10278 return 1; 10279 } else if (lhs.pss > rhs.pss) { 10280 return -1; 10281 } 10282 return 0; 10283 } 10284 }); 10285 } 10286 10287 for (int i=0; i<items.size(); i++) { 10288 MemItem mi = items.get(i); 10289 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10290 if (mi.subitems != null) { 10291 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10292 } 10293 } 10294 } 10295 10296 // These are in KB. 10297 static final long[] DUMP_MEM_BUCKETS = new long[] { 10298 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10299 120*1024, 160*1024, 200*1024, 10300 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10301 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10302 }; 10303 10304 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10305 boolean stackLike) { 10306 int start = label.lastIndexOf('.'); 10307 if (start >= 0) start++; 10308 else start = 0; 10309 int end = label.length(); 10310 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10311 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10312 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10313 out.append(bucket); 10314 out.append(stackLike ? "MB." : "MB "); 10315 out.append(label, start, end); 10316 return; 10317 } 10318 } 10319 out.append(memKB/1024); 10320 out.append(stackLike ? "MB." : "MB "); 10321 out.append(label, start, end); 10322 } 10323 10324 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10325 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10326 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10327 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10328 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10329 }; 10330 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10331 "System", "Persistent", "Foreground", 10332 "Visible", "Perceptible", "Heavy Weight", 10333 "Backup", "A Services", "Home", "Previous", 10334 "B Services", "Background" 10335 }; 10336 10337 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10338 PrintWriter pw, String prefix, String[] args, boolean brief, 10339 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10340 boolean dumpAll = false; 10341 boolean oomOnly = false; 10342 10343 int opti = 0; 10344 while (opti < args.length) { 10345 String opt = args[opti]; 10346 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10347 break; 10348 } 10349 opti++; 10350 if ("-a".equals(opt)) { 10351 dumpAll = true; 10352 } else if ("--oom".equals(opt)) { 10353 oomOnly = true; 10354 } else if ("-h".equals(opt)) { 10355 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10356 pw.println(" -a: include all available information for each process."); 10357 pw.println(" --oom: only show processes organized by oom adj."); 10358 pw.println("If [process] is specified it can be the name or "); 10359 pw.println("pid of a specific process to dump."); 10360 return; 10361 } else { 10362 pw.println("Unknown argument: " + opt + "; use -h for help"); 10363 } 10364 } 10365 10366 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10367 if (procs == null) { 10368 return; 10369 } 10370 10371 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10372 long uptime = SystemClock.uptimeMillis(); 10373 long realtime = SystemClock.elapsedRealtime(); 10374 10375 if (procs.size() == 1 || isCheckinRequest) { 10376 dumpAll = true; 10377 } 10378 10379 if (isCheckinRequest) { 10380 // short checkin version 10381 pw.println(uptime + "," + realtime); 10382 pw.flush(); 10383 } else { 10384 pw.println("Applications Memory Usage (kB):"); 10385 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10386 } 10387 10388 String[] innerArgs = new String[args.length-opti]; 10389 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10390 10391 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10392 long nativePss=0, dalvikPss=0, otherPss=0; 10393 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10394 10395 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10396 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10397 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10398 10399 long totalPss = 0; 10400 10401 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10402 ProcessRecord r = procs.get(i); 10403 if (r.thread != null) { 10404 if (!isCheckinRequest && dumpAll) { 10405 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10406 pw.flush(); 10407 } 10408 Debug.MemoryInfo mi = null; 10409 if (dumpAll) { 10410 try { 10411 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10412 } catch (RemoteException e) { 10413 if (!isCheckinRequest) { 10414 pw.println("Got RemoteException!"); 10415 pw.flush(); 10416 } 10417 } 10418 } else { 10419 mi = new Debug.MemoryInfo(); 10420 Debug.getMemoryInfo(r.pid, mi); 10421 } 10422 10423 if (!isCheckinRequest && mi != null) { 10424 long myTotalPss = mi.getTotalPss(); 10425 totalPss += myTotalPss; 10426 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10427 r.processName, myTotalPss, 0); 10428 procMems.add(pssItem); 10429 10430 nativePss += mi.nativePss; 10431 dalvikPss += mi.dalvikPss; 10432 otherPss += mi.otherPss; 10433 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10434 long mem = mi.getOtherPss(j); 10435 miscPss[j] += mem; 10436 otherPss -= mem; 10437 } 10438 10439 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10440 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10441 || oomIndex == (oomPss.length-1)) { 10442 oomPss[oomIndex] += myTotalPss; 10443 if (oomProcs[oomIndex] == null) { 10444 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10445 } 10446 oomProcs[oomIndex].add(pssItem); 10447 break; 10448 } 10449 } 10450 } 10451 } 10452 } 10453 10454 if (!isCheckinRequest && procs.size() > 1) { 10455 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10456 10457 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10458 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10459 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10460 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10461 String label = Debug.MemoryInfo.getOtherLabel(j); 10462 catMems.add(new MemItem(label, label, miscPss[j], j)); 10463 } 10464 10465 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10466 for (int j=0; j<oomPss.length; j++) { 10467 if (oomPss[j] != 0) { 10468 String label = DUMP_MEM_OOM_LABEL[j]; 10469 MemItem item = new MemItem(label, label, oomPss[j], 10470 DUMP_MEM_OOM_ADJ[j]); 10471 item.subitems = oomProcs[j]; 10472 oomMems.add(item); 10473 } 10474 } 10475 10476 if (outTag != null || outStack != null) { 10477 if (outTag != null) { 10478 appendMemBucket(outTag, totalPss, "total", false); 10479 } 10480 if (outStack != null) { 10481 appendMemBucket(outStack, totalPss, "total", true); 10482 } 10483 boolean firstLine = true; 10484 for (int i=0; i<oomMems.size(); i++) { 10485 MemItem miCat = oomMems.get(i); 10486 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10487 continue; 10488 } 10489 if (miCat.id < ProcessList.SERVICE_ADJ 10490 || miCat.id == ProcessList.HOME_APP_ADJ 10491 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10492 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10493 outTag.append(" / "); 10494 } 10495 if (outStack != null) { 10496 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10497 if (firstLine) { 10498 outStack.append(":"); 10499 firstLine = false; 10500 } 10501 outStack.append("\n\t at "); 10502 } else { 10503 outStack.append("$"); 10504 } 10505 } 10506 for (int j=0; j<miCat.subitems.size(); j++) { 10507 MemItem mi = miCat.subitems.get(j); 10508 if (j > 0) { 10509 if (outTag != null) { 10510 outTag.append(" "); 10511 } 10512 if (outStack != null) { 10513 outStack.append("$"); 10514 } 10515 } 10516 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10517 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10518 } 10519 if (outStack != null) { 10520 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10521 } 10522 } 10523 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10524 outStack.append("("); 10525 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10526 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10527 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10528 outStack.append(":"); 10529 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10530 } 10531 } 10532 outStack.append(")"); 10533 } 10534 } 10535 } 10536 } 10537 10538 if (!brief && !oomOnly) { 10539 pw.println(); 10540 pw.println("Total PSS by process:"); 10541 dumpMemItems(pw, " ", procMems, true); 10542 pw.println(); 10543 } 10544 pw.println("Total PSS by OOM adjustment:"); 10545 dumpMemItems(pw, " ", oomMems, false); 10546 if (!oomOnly) { 10547 PrintWriter out = categoryPw != null ? categoryPw : pw; 10548 out.println(); 10549 out.println("Total PSS by category:"); 10550 dumpMemItems(out, " ", catMems, true); 10551 } 10552 pw.println(); 10553 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10554 final int[] SINGLE_LONG_FORMAT = new int[] { 10555 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10556 }; 10557 long[] longOut = new long[1]; 10558 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10559 SINGLE_LONG_FORMAT, null, longOut, null); 10560 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10561 longOut[0] = 0; 10562 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10563 SINGLE_LONG_FORMAT, null, longOut, null); 10564 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10565 longOut[0] = 0; 10566 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10567 SINGLE_LONG_FORMAT, null, longOut, null); 10568 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10569 longOut[0] = 0; 10570 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10571 SINGLE_LONG_FORMAT, null, longOut, null); 10572 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10573 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10574 pw.print(shared); pw.println(" kB"); 10575 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10576 pw.print(voltile); pw.println(" kB volatile"); 10577 } 10578 } 10579 10580 /** 10581 * Searches array of arguments for the specified string 10582 * @param args array of argument strings 10583 * @param value value to search for 10584 * @return true if the value is contained in the array 10585 */ 10586 private static boolean scanArgs(String[] args, String value) { 10587 if (args != null) { 10588 for (String arg : args) { 10589 if (value.equals(arg)) { 10590 return true; 10591 } 10592 } 10593 } 10594 return false; 10595 } 10596 10597 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10598 ContentProviderRecord cpr, boolean always) { 10599 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10600 10601 if (!inLaunching || always) { 10602 synchronized (cpr) { 10603 cpr.launchingApp = null; 10604 cpr.notifyAll(); 10605 } 10606 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10607 String names[] = cpr.info.authority.split(";"); 10608 for (int j = 0; j < names.length; j++) { 10609 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10610 } 10611 } 10612 10613 for (int i=0; i<cpr.connections.size(); i++) { 10614 ContentProviderConnection conn = cpr.connections.get(i); 10615 if (conn.waiting) { 10616 // If this connection is waiting for the provider, then we don't 10617 // need to mess with its process unless we are always removing 10618 // or for some reason the provider is not currently launching. 10619 if (inLaunching && !always) { 10620 continue; 10621 } 10622 } 10623 ProcessRecord capp = conn.client; 10624 conn.dead = true; 10625 if (conn.stableCount > 0) { 10626 if (!capp.persistent && capp.thread != null 10627 && capp.pid != 0 10628 && capp.pid != MY_PID) { 10629 Slog.i(TAG, "Kill " + capp.processName 10630 + " (pid " + capp.pid + "): provider " + cpr.info.name 10631 + " in dying process " + (proc != null ? proc.processName : "??")); 10632 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10633 capp.processName, capp.setAdj, "dying provider " 10634 + cpr.name.toShortString()); 10635 Process.killProcessQuiet(capp.pid); 10636 } 10637 } else if (capp.thread != null && conn.provider.provider != null) { 10638 try { 10639 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10640 } catch (RemoteException e) { 10641 } 10642 // In the protocol here, we don't expect the client to correctly 10643 // clean up this connection, we'll just remove it. 10644 cpr.connections.remove(i); 10645 conn.client.conProviders.remove(conn); 10646 } 10647 } 10648 10649 if (inLaunching && always) { 10650 mLaunchingProviders.remove(cpr); 10651 } 10652 return inLaunching; 10653 } 10654 10655 /** 10656 * Main code for cleaning up a process when it has gone away. This is 10657 * called both as a result of the process dying, or directly when stopping 10658 * a process when running in single process mode. 10659 */ 10660 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10661 boolean restarting, boolean allowRestart, int index) { 10662 if (index >= 0) { 10663 mLruProcesses.remove(index); 10664 } 10665 10666 mProcessesToGc.remove(app); 10667 10668 // Dismiss any open dialogs. 10669 if (app.crashDialog != null) { 10670 app.crashDialog.dismiss(); 10671 app.crashDialog = null; 10672 } 10673 if (app.anrDialog != null) { 10674 app.anrDialog.dismiss(); 10675 app.anrDialog = null; 10676 } 10677 if (app.waitDialog != null) { 10678 app.waitDialog.dismiss(); 10679 app.waitDialog = null; 10680 } 10681 10682 app.crashing = false; 10683 app.notResponding = false; 10684 10685 app.resetPackageList(); 10686 app.unlinkDeathRecipient(); 10687 app.thread = null; 10688 app.forcingToForeground = null; 10689 app.foregroundServices = false; 10690 app.foregroundActivities = false; 10691 app.hasShownUi = false; 10692 app.hasAboveClient = false; 10693 10694 mServices.killServicesLocked(app, allowRestart); 10695 10696 boolean restart = false; 10697 10698 // Remove published content providers. 10699 if (!app.pubProviders.isEmpty()) { 10700 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10701 while (it.hasNext()) { 10702 ContentProviderRecord cpr = it.next(); 10703 10704 final boolean always = app.bad || !allowRestart; 10705 if (removeDyingProviderLocked(app, cpr, always) || always) { 10706 // We left the provider in the launching list, need to 10707 // restart it. 10708 restart = true; 10709 } 10710 10711 cpr.provider = null; 10712 cpr.proc = null; 10713 } 10714 app.pubProviders.clear(); 10715 } 10716 10717 // Take care of any launching providers waiting for this process. 10718 if (checkAppInLaunchingProvidersLocked(app, false)) { 10719 restart = true; 10720 } 10721 10722 // Unregister from connected content providers. 10723 if (!app.conProviders.isEmpty()) { 10724 for (int i=0; i<app.conProviders.size(); i++) { 10725 ContentProviderConnection conn = app.conProviders.get(i); 10726 conn.provider.connections.remove(conn); 10727 } 10728 app.conProviders.clear(); 10729 } 10730 10731 // At this point there may be remaining entries in mLaunchingProviders 10732 // where we were the only one waiting, so they are no longer of use. 10733 // Look for these and clean up if found. 10734 // XXX Commented out for now. Trying to figure out a way to reproduce 10735 // the actual situation to identify what is actually going on. 10736 if (false) { 10737 for (int i=0; i<mLaunchingProviders.size(); i++) { 10738 ContentProviderRecord cpr = (ContentProviderRecord) 10739 mLaunchingProviders.get(i); 10740 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10741 synchronized (cpr) { 10742 cpr.launchingApp = null; 10743 cpr.notifyAll(); 10744 } 10745 } 10746 } 10747 } 10748 10749 skipCurrentReceiverLocked(app); 10750 10751 // Unregister any receivers. 10752 if (app.receivers.size() > 0) { 10753 Iterator<ReceiverList> it = app.receivers.iterator(); 10754 while (it.hasNext()) { 10755 removeReceiverLocked(it.next()); 10756 } 10757 app.receivers.clear(); 10758 } 10759 10760 // If the app is undergoing backup, tell the backup manager about it 10761 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10762 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10763 + mBackupTarget.appInfo + " died during backup"); 10764 try { 10765 IBackupManager bm = IBackupManager.Stub.asInterface( 10766 ServiceManager.getService(Context.BACKUP_SERVICE)); 10767 bm.agentDisconnected(app.info.packageName); 10768 } catch (RemoteException e) { 10769 // can't happen; backup manager is local 10770 } 10771 } 10772 10773 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10774 ProcessChangeItem item = mPendingProcessChanges.get(i); 10775 if (item.pid == app.pid) { 10776 mPendingProcessChanges.remove(i); 10777 mAvailProcessChanges.add(item); 10778 } 10779 } 10780 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10781 10782 // If the caller is restarting this app, then leave it in its 10783 // current lists and let the caller take care of it. 10784 if (restarting) { 10785 return; 10786 } 10787 10788 if (!app.persistent || app.isolated) { 10789 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10790 "Removing non-persistent process during cleanup: " + app); 10791 mProcessNames.remove(app.processName, app.uid); 10792 mIsolatedProcesses.remove(app.uid); 10793 if (mHeavyWeightProcess == app) { 10794 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10795 mHeavyWeightProcess.userId, 0)); 10796 mHeavyWeightProcess = null; 10797 } 10798 } else if (!app.removed) { 10799 // This app is persistent, so we need to keep its record around. 10800 // If it is not already on the pending app list, add it there 10801 // and start a new process for it. 10802 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10803 mPersistentStartingProcesses.add(app); 10804 restart = true; 10805 } 10806 } 10807 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10808 "Clean-up removing on hold: " + app); 10809 mProcessesOnHold.remove(app); 10810 10811 if (app == mHomeProcess) { 10812 mHomeProcess = null; 10813 } 10814 if (app == mPreviousProcess) { 10815 mPreviousProcess = null; 10816 } 10817 10818 if (restart && !app.isolated) { 10819 // We have components that still need to be running in the 10820 // process, so re-launch it. 10821 mProcessNames.put(app.processName, app.uid, app); 10822 startProcessLocked(app, "restart", app.processName); 10823 } else if (app.pid > 0 && app.pid != MY_PID) { 10824 // Goodbye! 10825 synchronized (mPidsSelfLocked) { 10826 mPidsSelfLocked.remove(app.pid); 10827 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10828 } 10829 app.setPid(0); 10830 } 10831 } 10832 10833 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10834 // Look through the content providers we are waiting to have launched, 10835 // and if any run in this process then either schedule a restart of 10836 // the process or kill the client waiting for it if this process has 10837 // gone bad. 10838 int NL = mLaunchingProviders.size(); 10839 boolean restart = false; 10840 for (int i=0; i<NL; i++) { 10841 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10842 if (cpr.launchingApp == app) { 10843 if (!alwaysBad && !app.bad) { 10844 restart = true; 10845 } else { 10846 removeDyingProviderLocked(app, cpr, true); 10847 // cpr should have been removed from mLaunchingProviders 10848 NL = mLaunchingProviders.size(); 10849 i--; 10850 } 10851 } 10852 } 10853 return restart; 10854 } 10855 10856 // ========================================================= 10857 // SERVICES 10858 // ========================================================= 10859 10860 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10861 int flags) { 10862 enforceNotIsolatedCaller("getServices"); 10863 synchronized (this) { 10864 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10865 } 10866 } 10867 10868 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10869 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10870 synchronized (this) { 10871 return mServices.getRunningServiceControlPanelLocked(name); 10872 } 10873 } 10874 10875 public ComponentName startService(IApplicationThread caller, Intent service, 10876 String resolvedType, int userId) { 10877 enforceNotIsolatedCaller("startService"); 10878 // Refuse possible leaked file descriptors 10879 if (service != null && service.hasFileDescriptors() == true) { 10880 throw new IllegalArgumentException("File descriptors passed in Intent"); 10881 } 10882 10883 if (DEBUG_SERVICE) 10884 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10885 synchronized(this) { 10886 final int callingPid = Binder.getCallingPid(); 10887 final int callingUid = Binder.getCallingUid(); 10888 checkValidCaller(callingUid, userId); 10889 final long origId = Binder.clearCallingIdentity(); 10890 ComponentName res = mServices.startServiceLocked(caller, service, 10891 resolvedType, callingPid, callingUid, userId); 10892 Binder.restoreCallingIdentity(origId); 10893 return res; 10894 } 10895 } 10896 10897 ComponentName startServiceInPackage(int uid, 10898 Intent service, String resolvedType, int userId) { 10899 synchronized(this) { 10900 if (DEBUG_SERVICE) 10901 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10902 final long origId = Binder.clearCallingIdentity(); 10903 ComponentName res = mServices.startServiceLocked(null, service, 10904 resolvedType, -1, uid, userId); 10905 Binder.restoreCallingIdentity(origId); 10906 return res; 10907 } 10908 } 10909 10910 public int stopService(IApplicationThread caller, Intent service, 10911 String resolvedType, int userId) { 10912 enforceNotIsolatedCaller("stopService"); 10913 // Refuse possible leaked file descriptors 10914 if (service != null && service.hasFileDescriptors() == true) { 10915 throw new IllegalArgumentException("File descriptors passed in Intent"); 10916 } 10917 10918 checkValidCaller(Binder.getCallingUid(), userId); 10919 10920 synchronized(this) { 10921 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10922 } 10923 } 10924 10925 public IBinder peekService(Intent service, String resolvedType) { 10926 enforceNotIsolatedCaller("peekService"); 10927 // Refuse possible leaked file descriptors 10928 if (service != null && service.hasFileDescriptors() == true) { 10929 throw new IllegalArgumentException("File descriptors passed in Intent"); 10930 } 10931 synchronized(this) { 10932 return mServices.peekServiceLocked(service, resolvedType); 10933 } 10934 } 10935 10936 public boolean stopServiceToken(ComponentName className, IBinder token, 10937 int startId) { 10938 synchronized(this) { 10939 return mServices.stopServiceTokenLocked(className, token, startId); 10940 } 10941 } 10942 10943 public void setServiceForeground(ComponentName className, IBinder token, 10944 int id, Notification notification, boolean removeNotification) { 10945 synchronized(this) { 10946 mServices.setServiceForegroundLocked(className, token, id, notification, 10947 removeNotification); 10948 } 10949 } 10950 10951 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10952 boolean requireFull, String name, String callerPackage) { 10953 final int callingUserId = UserHandle.getUserId(callingUid); 10954 if (callingUserId != userId) { 10955 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10956 if ((requireFull || checkComponentPermission( 10957 android.Manifest.permission.INTERACT_ACROSS_USERS, 10958 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10959 && checkComponentPermission( 10960 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10961 callingPid, callingUid, -1, true) 10962 != PackageManager.PERMISSION_GRANTED) { 10963 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10964 // In this case, they would like to just execute as their 10965 // owner user instead of failing. 10966 userId = callingUserId; 10967 } else { 10968 StringBuilder builder = new StringBuilder(128); 10969 builder.append("Permission Denial: "); 10970 builder.append(name); 10971 if (callerPackage != null) { 10972 builder.append(" from "); 10973 builder.append(callerPackage); 10974 } 10975 builder.append(" asks to run as user "); 10976 builder.append(userId); 10977 builder.append(" but is calling from user "); 10978 builder.append(UserHandle.getUserId(callingUid)); 10979 builder.append("; this requires "); 10980 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10981 if (!requireFull) { 10982 builder.append(" or "); 10983 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10984 } 10985 String msg = builder.toString(); 10986 Slog.w(TAG, msg); 10987 throw new SecurityException(msg); 10988 } 10989 } 10990 } 10991 if (userId == UserHandle.USER_CURRENT 10992 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10993 // Note that we may be accessing this outside of a lock... 10994 // shouldn't be a big deal, if this is being called outside 10995 // of a locked context there is intrinsically a race with 10996 // the value the caller will receive and someone else changing it. 10997 userId = mCurrentUserId; 10998 } 10999 if (!allowAll && userId < 0) { 11000 throw new IllegalArgumentException( 11001 "Call does not support special user #" + userId); 11002 } 11003 } 11004 return userId; 11005 } 11006 11007 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11008 String className, int flags) { 11009 boolean result = false; 11010 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11011 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11012 if (ActivityManager.checkUidPermission( 11013 android.Manifest.permission.INTERACT_ACROSS_USERS, 11014 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11015 ComponentName comp = new ComponentName(aInfo.packageName, className); 11016 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11017 + " requests FLAG_SINGLE_USER, but app does not hold " 11018 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11019 Slog.w(TAG, msg); 11020 throw new SecurityException(msg); 11021 } 11022 result = true; 11023 } 11024 } else if (componentProcessName == aInfo.packageName) { 11025 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11026 } else if ("system".equals(componentProcessName)) { 11027 result = true; 11028 } 11029 if (DEBUG_MU) { 11030 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11031 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11032 } 11033 return result; 11034 } 11035 11036 public int bindService(IApplicationThread caller, IBinder token, 11037 Intent service, String resolvedType, 11038 IServiceConnection connection, int flags, int userId) { 11039 enforceNotIsolatedCaller("bindService"); 11040 // Refuse possible leaked file descriptors 11041 if (service != null && service.hasFileDescriptors() == true) { 11042 throw new IllegalArgumentException("File descriptors passed in Intent"); 11043 } 11044 11045 synchronized(this) { 11046 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11047 connection, flags, userId); 11048 } 11049 } 11050 11051 public boolean unbindService(IServiceConnection connection) { 11052 synchronized (this) { 11053 return mServices.unbindServiceLocked(connection); 11054 } 11055 } 11056 11057 public void publishService(IBinder token, Intent intent, IBinder service) { 11058 // Refuse possible leaked file descriptors 11059 if (intent != null && intent.hasFileDescriptors() == true) { 11060 throw new IllegalArgumentException("File descriptors passed in Intent"); 11061 } 11062 11063 synchronized(this) { 11064 if (!(token instanceof ServiceRecord)) { 11065 throw new IllegalArgumentException("Invalid service token"); 11066 } 11067 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11068 } 11069 } 11070 11071 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11072 // Refuse possible leaked file descriptors 11073 if (intent != null && intent.hasFileDescriptors() == true) { 11074 throw new IllegalArgumentException("File descriptors passed in Intent"); 11075 } 11076 11077 synchronized(this) { 11078 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11079 } 11080 } 11081 11082 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11083 synchronized(this) { 11084 if (!(token instanceof ServiceRecord)) { 11085 throw new IllegalArgumentException("Invalid service token"); 11086 } 11087 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11088 } 11089 } 11090 11091 // ========================================================= 11092 // BACKUP AND RESTORE 11093 // ========================================================= 11094 11095 // Cause the target app to be launched if necessary and its backup agent 11096 // instantiated. The backup agent will invoke backupAgentCreated() on the 11097 // activity manager to announce its creation. 11098 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11099 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11100 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11101 11102 synchronized(this) { 11103 // !!! TODO: currently no check here that we're already bound 11104 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11106 synchronized (stats) { 11107 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11108 } 11109 11110 // Backup agent is now in use, its package can't be stopped. 11111 try { 11112 AppGlobals.getPackageManager().setPackageStoppedState( 11113 app.packageName, false, UserHandle.getUserId(app.uid)); 11114 } catch (RemoteException e) { 11115 } catch (IllegalArgumentException e) { 11116 Slog.w(TAG, "Failed trying to unstop package " 11117 + app.packageName + ": " + e); 11118 } 11119 11120 BackupRecord r = new BackupRecord(ss, app, backupMode); 11121 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11122 ? new ComponentName(app.packageName, app.backupAgentName) 11123 : new ComponentName("android", "FullBackupAgent"); 11124 // startProcessLocked() returns existing proc's record if it's already running 11125 ProcessRecord proc = startProcessLocked(app.processName, app, 11126 false, 0, "backup", hostingName, false, false); 11127 if (proc == null) { 11128 Slog.e(TAG, "Unable to start backup agent process " + r); 11129 return false; 11130 } 11131 11132 r.app = proc; 11133 mBackupTarget = r; 11134 mBackupAppName = app.packageName; 11135 11136 // Try not to kill the process during backup 11137 updateOomAdjLocked(proc); 11138 11139 // If the process is already attached, schedule the creation of the backup agent now. 11140 // If it is not yet live, this will be done when it attaches to the framework. 11141 if (proc.thread != null) { 11142 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11143 try { 11144 proc.thread.scheduleCreateBackupAgent(app, 11145 compatibilityInfoForPackageLocked(app), backupMode); 11146 } catch (RemoteException e) { 11147 // Will time out on the backup manager side 11148 } 11149 } else { 11150 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11151 } 11152 // Invariants: at this point, the target app process exists and the application 11153 // is either already running or in the process of coming up. mBackupTarget and 11154 // mBackupAppName describe the app, so that when it binds back to the AM we 11155 // know that it's scheduled for a backup-agent operation. 11156 } 11157 11158 return true; 11159 } 11160 11161 // A backup agent has just come up 11162 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11163 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11164 + " = " + agent); 11165 11166 synchronized(this) { 11167 if (!agentPackageName.equals(mBackupAppName)) { 11168 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11169 return; 11170 } 11171 } 11172 11173 long oldIdent = Binder.clearCallingIdentity(); 11174 try { 11175 IBackupManager bm = IBackupManager.Stub.asInterface( 11176 ServiceManager.getService(Context.BACKUP_SERVICE)); 11177 bm.agentConnected(agentPackageName, agent); 11178 } catch (RemoteException e) { 11179 // can't happen; the backup manager service is local 11180 } catch (Exception e) { 11181 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11182 e.printStackTrace(); 11183 } finally { 11184 Binder.restoreCallingIdentity(oldIdent); 11185 } 11186 } 11187 11188 // done with this agent 11189 public void unbindBackupAgent(ApplicationInfo appInfo) { 11190 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11191 if (appInfo == null) { 11192 Slog.w(TAG, "unbind backup agent for null app"); 11193 return; 11194 } 11195 11196 synchronized(this) { 11197 if (mBackupAppName == null) { 11198 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11199 return; 11200 } 11201 11202 if (!mBackupAppName.equals(appInfo.packageName)) { 11203 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11204 return; 11205 } 11206 11207 ProcessRecord proc = mBackupTarget.app; 11208 mBackupTarget = null; 11209 mBackupAppName = null; 11210 11211 // Not backing this app up any more; reset its OOM adjustment 11212 updateOomAdjLocked(proc); 11213 11214 // If the app crashed during backup, 'thread' will be null here 11215 if (proc.thread != null) { 11216 try { 11217 proc.thread.scheduleDestroyBackupAgent(appInfo, 11218 compatibilityInfoForPackageLocked(appInfo)); 11219 } catch (Exception e) { 11220 Slog.e(TAG, "Exception when unbinding backup agent:"); 11221 e.printStackTrace(); 11222 } 11223 } 11224 } 11225 } 11226 // ========================================================= 11227 // BROADCASTS 11228 // ========================================================= 11229 11230 private final List getStickiesLocked(String action, IntentFilter filter, 11231 List cur, int userId) { 11232 final ContentResolver resolver = mContext.getContentResolver(); 11233 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11234 if (stickies == null) { 11235 return cur; 11236 } 11237 final ArrayList<Intent> list = stickies.get(action); 11238 if (list == null) { 11239 return cur; 11240 } 11241 int N = list.size(); 11242 for (int i=0; i<N; i++) { 11243 Intent intent = list.get(i); 11244 if (filter.match(resolver, intent, true, TAG) >= 0) { 11245 if (cur == null) { 11246 cur = new ArrayList<Intent>(); 11247 } 11248 cur.add(intent); 11249 } 11250 } 11251 return cur; 11252 } 11253 11254 boolean isPendingBroadcastProcessLocked(int pid) { 11255 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11256 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11257 } 11258 11259 void skipPendingBroadcastLocked(int pid) { 11260 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11261 for (BroadcastQueue queue : mBroadcastQueues) { 11262 queue.skipPendingBroadcastLocked(pid); 11263 } 11264 } 11265 11266 // The app just attached; send any pending broadcasts that it should receive 11267 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11268 boolean didSomething = false; 11269 for (BroadcastQueue queue : mBroadcastQueues) { 11270 didSomething |= queue.sendPendingBroadcastsLocked(app); 11271 } 11272 return didSomething; 11273 } 11274 11275 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11276 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11277 enforceNotIsolatedCaller("registerReceiver"); 11278 int callingUid; 11279 int callingPid; 11280 synchronized(this) { 11281 ProcessRecord callerApp = null; 11282 if (caller != null) { 11283 callerApp = getRecordForAppLocked(caller); 11284 if (callerApp == null) { 11285 throw new SecurityException( 11286 "Unable to find app for caller " + caller 11287 + " (pid=" + Binder.getCallingPid() 11288 + ") when registering receiver " + receiver); 11289 } 11290 if (callerApp.info.uid != Process.SYSTEM_UID && 11291 !callerApp.pkgList.contains(callerPackage)) { 11292 throw new SecurityException("Given caller package " + callerPackage 11293 + " is not running in process " + callerApp); 11294 } 11295 callingUid = callerApp.info.uid; 11296 callingPid = callerApp.pid; 11297 } else { 11298 callerPackage = null; 11299 callingUid = Binder.getCallingUid(); 11300 callingPid = Binder.getCallingPid(); 11301 } 11302 11303 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11304 true, true, "registerReceiver", callerPackage); 11305 11306 List allSticky = null; 11307 11308 // Look for any matching sticky broadcasts... 11309 Iterator actions = filter.actionsIterator(); 11310 if (actions != null) { 11311 while (actions.hasNext()) { 11312 String action = (String)actions.next(); 11313 allSticky = getStickiesLocked(action, filter, allSticky, 11314 UserHandle.USER_ALL); 11315 allSticky = getStickiesLocked(action, filter, allSticky, 11316 UserHandle.getUserId(callingUid)); 11317 } 11318 } else { 11319 allSticky = getStickiesLocked(null, filter, allSticky, 11320 UserHandle.USER_ALL); 11321 allSticky = getStickiesLocked(null, filter, allSticky, 11322 UserHandle.getUserId(callingUid)); 11323 } 11324 11325 // The first sticky in the list is returned directly back to 11326 // the client. 11327 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11328 11329 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11330 + ": " + sticky); 11331 11332 if (receiver == null) { 11333 return sticky; 11334 } 11335 11336 ReceiverList rl 11337 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11338 if (rl == null) { 11339 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11340 userId, receiver); 11341 if (rl.app != null) { 11342 rl.app.receivers.add(rl); 11343 } else { 11344 try { 11345 receiver.asBinder().linkToDeath(rl, 0); 11346 } catch (RemoteException e) { 11347 return sticky; 11348 } 11349 rl.linkedToDeath = true; 11350 } 11351 mRegisteredReceivers.put(receiver.asBinder(), rl); 11352 } else if (rl.uid != callingUid) { 11353 throw new IllegalArgumentException( 11354 "Receiver requested to register for uid " + callingUid 11355 + " was previously registered for uid " + rl.uid); 11356 } else if (rl.pid != callingPid) { 11357 throw new IllegalArgumentException( 11358 "Receiver requested to register for pid " + callingPid 11359 + " was previously registered for pid " + rl.pid); 11360 } else if (rl.userId != userId) { 11361 throw new IllegalArgumentException( 11362 "Receiver requested to register for user " + userId 11363 + " was previously registered for user " + rl.userId); 11364 } 11365 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11366 permission, callingUid, userId); 11367 rl.add(bf); 11368 if (!bf.debugCheck()) { 11369 Slog.w(TAG, "==> For Dynamic broadast"); 11370 } 11371 mReceiverResolver.addFilter(bf); 11372 11373 // Enqueue broadcasts for all existing stickies that match 11374 // this filter. 11375 if (allSticky != null) { 11376 ArrayList receivers = new ArrayList(); 11377 receivers.add(bf); 11378 11379 int N = allSticky.size(); 11380 for (int i=0; i<N; i++) { 11381 Intent intent = (Intent)allSticky.get(i); 11382 BroadcastQueue queue = broadcastQueueForIntent(intent); 11383 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11384 null, -1, -1, null, receivers, null, 0, null, null, 11385 false, true, true, -1); 11386 queue.enqueueParallelBroadcastLocked(r); 11387 queue.scheduleBroadcastsLocked(); 11388 } 11389 } 11390 11391 return sticky; 11392 } 11393 } 11394 11395 public void unregisterReceiver(IIntentReceiver receiver) { 11396 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11397 11398 final long origId = Binder.clearCallingIdentity(); 11399 try { 11400 boolean doTrim = false; 11401 11402 synchronized(this) { 11403 ReceiverList rl 11404 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11405 if (rl != null) { 11406 if (rl.curBroadcast != null) { 11407 BroadcastRecord r = rl.curBroadcast; 11408 final boolean doNext = finishReceiverLocked( 11409 receiver.asBinder(), r.resultCode, r.resultData, 11410 r.resultExtras, r.resultAbort, true); 11411 if (doNext) { 11412 doTrim = true; 11413 r.queue.processNextBroadcast(false); 11414 } 11415 } 11416 11417 if (rl.app != null) { 11418 rl.app.receivers.remove(rl); 11419 } 11420 removeReceiverLocked(rl); 11421 if (rl.linkedToDeath) { 11422 rl.linkedToDeath = false; 11423 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11424 } 11425 } 11426 } 11427 11428 // If we actually concluded any broadcasts, we might now be able 11429 // to trim the recipients' apps from our working set 11430 if (doTrim) { 11431 trimApplications(); 11432 return; 11433 } 11434 11435 } finally { 11436 Binder.restoreCallingIdentity(origId); 11437 } 11438 } 11439 11440 void removeReceiverLocked(ReceiverList rl) { 11441 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11442 int N = rl.size(); 11443 for (int i=0; i<N; i++) { 11444 mReceiverResolver.removeFilter(rl.get(i)); 11445 } 11446 } 11447 11448 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11449 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11450 ProcessRecord r = mLruProcesses.get(i); 11451 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11452 try { 11453 r.thread.dispatchPackageBroadcast(cmd, packages); 11454 } catch (RemoteException ex) { 11455 } 11456 } 11457 } 11458 } 11459 11460 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11461 int[] users) { 11462 List<ResolveInfo> receivers = null; 11463 try { 11464 HashSet<ComponentName> singleUserReceivers = null; 11465 boolean scannedFirstReceivers = false; 11466 for (int user : users) { 11467 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11468 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11469 if (user != 0 && newReceivers != null) { 11470 // If this is not the primary user, we need to check for 11471 // any receivers that should be filtered out. 11472 for (int i=0; i<newReceivers.size(); i++) { 11473 ResolveInfo ri = newReceivers.get(i); 11474 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11475 newReceivers.remove(i); 11476 i--; 11477 } 11478 } 11479 } 11480 if (newReceivers != null && newReceivers.size() == 0) { 11481 newReceivers = null; 11482 } 11483 if (receivers == null) { 11484 receivers = newReceivers; 11485 } else if (newReceivers != null) { 11486 // We need to concatenate the additional receivers 11487 // found with what we have do far. This would be easy, 11488 // but we also need to de-dup any receivers that are 11489 // singleUser. 11490 if (!scannedFirstReceivers) { 11491 // Collect any single user receivers we had already retrieved. 11492 scannedFirstReceivers = true; 11493 for (int i=0; i<receivers.size(); i++) { 11494 ResolveInfo ri = receivers.get(i); 11495 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11496 ComponentName cn = new ComponentName( 11497 ri.activityInfo.packageName, ri.activityInfo.name); 11498 if (singleUserReceivers == null) { 11499 singleUserReceivers = new HashSet<ComponentName>(); 11500 } 11501 singleUserReceivers.add(cn); 11502 } 11503 } 11504 } 11505 // Add the new results to the existing results, tracking 11506 // and de-dupping single user receivers. 11507 for (int i=0; i<newReceivers.size(); i++) { 11508 ResolveInfo ri = newReceivers.get(i); 11509 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11510 ComponentName cn = new ComponentName( 11511 ri.activityInfo.packageName, ri.activityInfo.name); 11512 if (singleUserReceivers == null) { 11513 singleUserReceivers = new HashSet<ComponentName>(); 11514 } 11515 if (!singleUserReceivers.contains(cn)) { 11516 singleUserReceivers.add(cn); 11517 receivers.add(ri); 11518 } 11519 } else { 11520 receivers.add(ri); 11521 } 11522 } 11523 } 11524 } 11525 } catch (RemoteException ex) { 11526 // pm is in same process, this will never happen. 11527 } 11528 return receivers; 11529 } 11530 11531 private final int broadcastIntentLocked(ProcessRecord callerApp, 11532 String callerPackage, Intent intent, String resolvedType, 11533 IIntentReceiver resultTo, int resultCode, String resultData, 11534 Bundle map, String requiredPermission, 11535 boolean ordered, boolean sticky, int callingPid, int callingUid, 11536 int userId) { 11537 intent = new Intent(intent); 11538 11539 // By default broadcasts do not go to stopped apps. 11540 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11541 11542 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11543 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11544 + " ordered=" + ordered + " userid=" + userId); 11545 if ((resultTo != null) && !ordered) { 11546 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11547 } 11548 11549 userId = handleIncomingUser(callingPid, callingUid, userId, 11550 true, false, "broadcast", callerPackage); 11551 11552 // Make sure that the user who is receiving this broadcast is started. 11553 // If not, we will just skip it. 11554 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11555 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11556 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11557 Slog.w(TAG, "Skipping broadcast of " + intent 11558 + ": user " + userId + " is stopped"); 11559 return ActivityManager.BROADCAST_SUCCESS; 11560 } 11561 } 11562 11563 /* 11564 * Prevent non-system code (defined here to be non-persistent 11565 * processes) from sending protected broadcasts. 11566 */ 11567 int callingAppId = UserHandle.getAppId(callingUid); 11568 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11569 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11570 callingUid == 0) { 11571 // Always okay. 11572 } else if (callerApp == null || !callerApp.persistent) { 11573 try { 11574 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11575 intent.getAction())) { 11576 String msg = "Permission Denial: not allowed to send broadcast " 11577 + intent.getAction() + " from pid=" 11578 + callingPid + ", uid=" + callingUid; 11579 Slog.w(TAG, msg); 11580 throw new SecurityException(msg); 11581 } 11582 } catch (RemoteException e) { 11583 Slog.w(TAG, "Remote exception", e); 11584 return ActivityManager.BROADCAST_SUCCESS; 11585 } 11586 } 11587 11588 // Handle special intents: if this broadcast is from the package 11589 // manager about a package being removed, we need to remove all of 11590 // its activities from the history stack. 11591 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11592 intent.getAction()); 11593 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11594 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11595 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11596 || uidRemoved) { 11597 if (checkComponentPermission( 11598 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11599 callingPid, callingUid, -1, true) 11600 == PackageManager.PERMISSION_GRANTED) { 11601 if (uidRemoved) { 11602 final Bundle intentExtras = intent.getExtras(); 11603 final int uid = intentExtras != null 11604 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11605 if (uid >= 0) { 11606 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11607 synchronized (bs) { 11608 bs.removeUidStatsLocked(uid); 11609 } 11610 } 11611 } else { 11612 // If resources are unavailable just force stop all 11613 // those packages and flush the attribute cache as well. 11614 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11615 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11616 if (list != null && (list.length > 0)) { 11617 for (String pkg : list) { 11618 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11619 } 11620 sendPackageBroadcastLocked( 11621 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11622 } 11623 } else { 11624 Uri data = intent.getData(); 11625 String ssp; 11626 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11627 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11628 forceStopPackageLocked(ssp, 11629 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11630 false, userId); 11631 } 11632 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11633 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11634 new String[] {ssp}, userId); 11635 } 11636 } 11637 } 11638 } 11639 } else { 11640 String msg = "Permission Denial: " + intent.getAction() 11641 + " broadcast from " + callerPackage + " (pid=" + callingPid 11642 + ", uid=" + callingUid + ")" 11643 + " requires " 11644 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11645 Slog.w(TAG, msg); 11646 throw new SecurityException(msg); 11647 } 11648 11649 // Special case for adding a package: by default turn on compatibility 11650 // mode. 11651 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11652 Uri data = intent.getData(); 11653 String ssp; 11654 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11655 mCompatModePackages.handlePackageAddedLocked(ssp, 11656 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11657 } 11658 } 11659 11660 /* 11661 * If this is the time zone changed action, queue up a message that will reset the timezone 11662 * of all currently running processes. This message will get queued up before the broadcast 11663 * happens. 11664 */ 11665 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11666 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11667 } 11668 11669 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11670 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11671 } 11672 11673 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11674 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11675 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11676 } 11677 11678 // Add to the sticky list if requested. 11679 if (sticky) { 11680 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11681 callingPid, callingUid) 11682 != PackageManager.PERMISSION_GRANTED) { 11683 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11684 + callingPid + ", uid=" + callingUid 11685 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11686 Slog.w(TAG, msg); 11687 throw new SecurityException(msg); 11688 } 11689 if (requiredPermission != null) { 11690 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11691 + " and enforce permission " + requiredPermission); 11692 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11693 } 11694 if (intent.getComponent() != null) { 11695 throw new SecurityException( 11696 "Sticky broadcasts can't target a specific component"); 11697 } 11698 // We use userId directly here, since the "all" target is maintained 11699 // as a separate set of sticky broadcasts. 11700 if (userId != UserHandle.USER_ALL) { 11701 // But first, if this is not a broadcast to all users, then 11702 // make sure it doesn't conflict with an existing broadcast to 11703 // all users. 11704 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11705 UserHandle.USER_ALL); 11706 if (stickies != null) { 11707 ArrayList<Intent> list = stickies.get(intent.getAction()); 11708 if (list != null) { 11709 int N = list.size(); 11710 int i; 11711 for (i=0; i<N; i++) { 11712 if (intent.filterEquals(list.get(i))) { 11713 throw new IllegalArgumentException( 11714 "Sticky broadcast " + intent + " for user " 11715 + userId + " conflicts with existing global broadcast"); 11716 } 11717 } 11718 } 11719 } 11720 } 11721 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11722 if (stickies == null) { 11723 stickies = new HashMap<String, ArrayList<Intent>>(); 11724 mStickyBroadcasts.put(userId, stickies); 11725 } 11726 ArrayList<Intent> list = stickies.get(intent.getAction()); 11727 if (list == null) { 11728 list = new ArrayList<Intent>(); 11729 stickies.put(intent.getAction(), list); 11730 } 11731 int N = list.size(); 11732 int i; 11733 for (i=0; i<N; i++) { 11734 if (intent.filterEquals(list.get(i))) { 11735 // This sticky already exists, replace it. 11736 list.set(i, new Intent(intent)); 11737 break; 11738 } 11739 } 11740 if (i >= N) { 11741 list.add(new Intent(intent)); 11742 } 11743 } 11744 11745 int[] users; 11746 if (userId == UserHandle.USER_ALL) { 11747 // Caller wants broadcast to go to all started users. 11748 users = mStartedUserArray; 11749 } else { 11750 // Caller wants broadcast to go to one specific user. 11751 users = new int[] {userId}; 11752 } 11753 11754 // Figure out who all will receive this broadcast. 11755 List receivers = null; 11756 List<BroadcastFilter> registeredReceivers = null; 11757 // Need to resolve the intent to interested receivers... 11758 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11759 == 0) { 11760 receivers = collectReceiverComponents(intent, resolvedType, users); 11761 } 11762 if (intent.getComponent() == null) { 11763 registeredReceivers = mReceiverResolver.queryIntent(intent, 11764 resolvedType, false, userId); 11765 } 11766 11767 final boolean replacePending = 11768 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11769 11770 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11771 + " replacePending=" + replacePending); 11772 11773 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11774 if (!ordered && NR > 0) { 11775 // If we are not serializing this broadcast, then send the 11776 // registered receivers separately so they don't wait for the 11777 // components to be launched. 11778 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11779 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11780 callerPackage, callingPid, callingUid, requiredPermission, 11781 registeredReceivers, resultTo, resultCode, resultData, map, 11782 ordered, sticky, false, userId); 11783 if (DEBUG_BROADCAST) Slog.v( 11784 TAG, "Enqueueing parallel broadcast " + r); 11785 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11786 if (!replaced) { 11787 queue.enqueueParallelBroadcastLocked(r); 11788 queue.scheduleBroadcastsLocked(); 11789 } 11790 registeredReceivers = null; 11791 NR = 0; 11792 } 11793 11794 // Merge into one list. 11795 int ir = 0; 11796 if (receivers != null) { 11797 // A special case for PACKAGE_ADDED: do not allow the package 11798 // being added to see this broadcast. This prevents them from 11799 // using this as a back door to get run as soon as they are 11800 // installed. Maybe in the future we want to have a special install 11801 // broadcast or such for apps, but we'd like to deliberately make 11802 // this decision. 11803 String skipPackages[] = null; 11804 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11805 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11806 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11807 Uri data = intent.getData(); 11808 if (data != null) { 11809 String pkgName = data.getSchemeSpecificPart(); 11810 if (pkgName != null) { 11811 skipPackages = new String[] { pkgName }; 11812 } 11813 } 11814 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11815 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11816 } 11817 if (skipPackages != null && (skipPackages.length > 0)) { 11818 for (String skipPackage : skipPackages) { 11819 if (skipPackage != null) { 11820 int NT = receivers.size(); 11821 for (int it=0; it<NT; it++) { 11822 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11823 if (curt.activityInfo.packageName.equals(skipPackage)) { 11824 receivers.remove(it); 11825 it--; 11826 NT--; 11827 } 11828 } 11829 } 11830 } 11831 } 11832 11833 int NT = receivers != null ? receivers.size() : 0; 11834 int it = 0; 11835 ResolveInfo curt = null; 11836 BroadcastFilter curr = null; 11837 while (it < NT && ir < NR) { 11838 if (curt == null) { 11839 curt = (ResolveInfo)receivers.get(it); 11840 } 11841 if (curr == null) { 11842 curr = registeredReceivers.get(ir); 11843 } 11844 if (curr.getPriority() >= curt.priority) { 11845 // Insert this broadcast record into the final list. 11846 receivers.add(it, curr); 11847 ir++; 11848 curr = null; 11849 it++; 11850 NT++; 11851 } else { 11852 // Skip to the next ResolveInfo in the final list. 11853 it++; 11854 curt = null; 11855 } 11856 } 11857 } 11858 while (ir < NR) { 11859 if (receivers == null) { 11860 receivers = new ArrayList(); 11861 } 11862 receivers.add(registeredReceivers.get(ir)); 11863 ir++; 11864 } 11865 11866 if ((receivers != null && receivers.size() > 0) 11867 || resultTo != null) { 11868 BroadcastQueue queue = broadcastQueueForIntent(intent); 11869 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11870 callerPackage, callingPid, callingUid, requiredPermission, 11871 receivers, resultTo, resultCode, resultData, map, ordered, 11872 sticky, false, userId); 11873 if (DEBUG_BROADCAST) Slog.v( 11874 TAG, "Enqueueing ordered broadcast " + r 11875 + ": prev had " + queue.mOrderedBroadcasts.size()); 11876 if (DEBUG_BROADCAST) { 11877 int seq = r.intent.getIntExtra("seq", -1); 11878 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11879 } 11880 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11881 if (!replaced) { 11882 queue.enqueueOrderedBroadcastLocked(r); 11883 queue.scheduleBroadcastsLocked(); 11884 } 11885 } 11886 11887 return ActivityManager.BROADCAST_SUCCESS; 11888 } 11889 11890 final Intent verifyBroadcastLocked(Intent intent) { 11891 // Refuse possible leaked file descriptors 11892 if (intent != null && intent.hasFileDescriptors() == true) { 11893 throw new IllegalArgumentException("File descriptors passed in Intent"); 11894 } 11895 11896 int flags = intent.getFlags(); 11897 11898 if (!mProcessesReady) { 11899 // if the caller really truly claims to know what they're doing, go 11900 // ahead and allow the broadcast without launching any receivers 11901 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11902 intent = new Intent(intent); 11903 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11904 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11905 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11906 + " before boot completion"); 11907 throw new IllegalStateException("Cannot broadcast before boot completed"); 11908 } 11909 } 11910 11911 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11912 throw new IllegalArgumentException( 11913 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11914 } 11915 11916 return intent; 11917 } 11918 11919 public final int broadcastIntent(IApplicationThread caller, 11920 Intent intent, String resolvedType, IIntentReceiver resultTo, 11921 int resultCode, String resultData, Bundle map, 11922 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11923 enforceNotIsolatedCaller("broadcastIntent"); 11924 synchronized(this) { 11925 intent = verifyBroadcastLocked(intent); 11926 11927 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11928 final int callingPid = Binder.getCallingPid(); 11929 final int callingUid = Binder.getCallingUid(); 11930 final long origId = Binder.clearCallingIdentity(); 11931 int res = broadcastIntentLocked(callerApp, 11932 callerApp != null ? callerApp.info.packageName : null, 11933 intent, resolvedType, resultTo, 11934 resultCode, resultData, map, requiredPermission, serialized, sticky, 11935 callingPid, callingUid, userId); 11936 Binder.restoreCallingIdentity(origId); 11937 return res; 11938 } 11939 } 11940 11941 int broadcastIntentInPackage(String packageName, int uid, 11942 Intent intent, String resolvedType, IIntentReceiver resultTo, 11943 int resultCode, String resultData, Bundle map, 11944 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11945 synchronized(this) { 11946 intent = verifyBroadcastLocked(intent); 11947 11948 final long origId = Binder.clearCallingIdentity(); 11949 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11950 resultTo, resultCode, resultData, map, requiredPermission, 11951 serialized, sticky, -1, uid, userId); 11952 Binder.restoreCallingIdentity(origId); 11953 return res; 11954 } 11955 } 11956 11957 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11958 // Refuse possible leaked file descriptors 11959 if (intent != null && intent.hasFileDescriptors() == true) { 11960 throw new IllegalArgumentException("File descriptors passed in Intent"); 11961 } 11962 11963 userId = handleIncomingUser(Binder.getCallingPid(), 11964 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11965 11966 synchronized(this) { 11967 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11968 != PackageManager.PERMISSION_GRANTED) { 11969 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11970 + Binder.getCallingPid() 11971 + ", uid=" + Binder.getCallingUid() 11972 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11973 Slog.w(TAG, msg); 11974 throw new SecurityException(msg); 11975 } 11976 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11977 if (stickies != null) { 11978 ArrayList<Intent> list = stickies.get(intent.getAction()); 11979 if (list != null) { 11980 int N = list.size(); 11981 int i; 11982 for (i=0; i<N; i++) { 11983 if (intent.filterEquals(list.get(i))) { 11984 list.remove(i); 11985 break; 11986 } 11987 } 11988 if (list.size() <= 0) { 11989 stickies.remove(intent.getAction()); 11990 } 11991 } 11992 if (stickies.size() <= 0) { 11993 mStickyBroadcasts.remove(userId); 11994 } 11995 } 11996 } 11997 } 11998 11999 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12000 String resultData, Bundle resultExtras, boolean resultAbort, 12001 boolean explicit) { 12002 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 12003 if (r == null) { 12004 Slog.w(TAG, "finishReceiver called but not found on queue"); 12005 return false; 12006 } 12007 12008 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12009 explicit); 12010 } 12011 12012 public void finishReceiver(IBinder who, int resultCode, String resultData, 12013 Bundle resultExtras, boolean resultAbort) { 12014 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12015 12016 // Refuse possible leaked file descriptors 12017 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12018 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12019 } 12020 12021 final long origId = Binder.clearCallingIdentity(); 12022 try { 12023 boolean doNext = false; 12024 BroadcastRecord r = null; 12025 12026 synchronized(this) { 12027 r = broadcastRecordForReceiverLocked(who); 12028 if (r != null) { 12029 doNext = r.queue.finishReceiverLocked(r, resultCode, 12030 resultData, resultExtras, resultAbort, true); 12031 } 12032 } 12033 12034 if (doNext) { 12035 r.queue.processNextBroadcast(false); 12036 } 12037 trimApplications(); 12038 } finally { 12039 Binder.restoreCallingIdentity(origId); 12040 } 12041 } 12042 12043 // ========================================================= 12044 // INSTRUMENTATION 12045 // ========================================================= 12046 12047 public boolean startInstrumentation(ComponentName className, 12048 String profileFile, int flags, Bundle arguments, 12049 IInstrumentationWatcher watcher, int userId) { 12050 enforceNotIsolatedCaller("startInstrumentation"); 12051 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12052 userId, false, true, "startInstrumentation", null); 12053 // Refuse possible leaked file descriptors 12054 if (arguments != null && arguments.hasFileDescriptors()) { 12055 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12056 } 12057 12058 synchronized(this) { 12059 InstrumentationInfo ii = null; 12060 ApplicationInfo ai = null; 12061 try { 12062 ii = mContext.getPackageManager().getInstrumentationInfo( 12063 className, STOCK_PM_FLAGS); 12064 ai = AppGlobals.getPackageManager().getApplicationInfo( 12065 ii.targetPackage, STOCK_PM_FLAGS, userId); 12066 } catch (PackageManager.NameNotFoundException e) { 12067 } catch (RemoteException e) { 12068 } 12069 if (ii == null) { 12070 reportStartInstrumentationFailure(watcher, className, 12071 "Unable to find instrumentation info for: " + className); 12072 return false; 12073 } 12074 if (ai == null) { 12075 reportStartInstrumentationFailure(watcher, className, 12076 "Unable to find instrumentation target package: " + ii.targetPackage); 12077 return false; 12078 } 12079 12080 int match = mContext.getPackageManager().checkSignatures( 12081 ii.targetPackage, ii.packageName); 12082 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12083 String msg = "Permission Denial: starting instrumentation " 12084 + className + " from pid=" 12085 + Binder.getCallingPid() 12086 + ", uid=" + Binder.getCallingPid() 12087 + " not allowed because package " + ii.packageName 12088 + " does not have a signature matching the target " 12089 + ii.targetPackage; 12090 reportStartInstrumentationFailure(watcher, className, msg); 12091 throw new SecurityException(msg); 12092 } 12093 12094 final long origId = Binder.clearCallingIdentity(); 12095 // Instrumentation can kill and relaunch even persistent processes 12096 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12097 ProcessRecord app = addAppLocked(ai, false); 12098 app.instrumentationClass = className; 12099 app.instrumentationInfo = ai; 12100 app.instrumentationProfileFile = profileFile; 12101 app.instrumentationArguments = arguments; 12102 app.instrumentationWatcher = watcher; 12103 app.instrumentationResultClass = className; 12104 Binder.restoreCallingIdentity(origId); 12105 } 12106 12107 return true; 12108 } 12109 12110 /** 12111 * Report errors that occur while attempting to start Instrumentation. Always writes the 12112 * error to the logs, but if somebody is watching, send the report there too. This enables 12113 * the "am" command to report errors with more information. 12114 * 12115 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12116 * @param cn The component name of the instrumentation. 12117 * @param report The error report. 12118 */ 12119 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12120 ComponentName cn, String report) { 12121 Slog.w(TAG, report); 12122 try { 12123 if (watcher != null) { 12124 Bundle results = new Bundle(); 12125 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12126 results.putString("Error", report); 12127 watcher.instrumentationStatus(cn, -1, results); 12128 } 12129 } catch (RemoteException e) { 12130 Slog.w(TAG, e); 12131 } 12132 } 12133 12134 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12135 if (app.instrumentationWatcher != null) { 12136 try { 12137 // NOTE: IInstrumentationWatcher *must* be oneway here 12138 app.instrumentationWatcher.instrumentationFinished( 12139 app.instrumentationClass, 12140 resultCode, 12141 results); 12142 } catch (RemoteException e) { 12143 } 12144 } 12145 app.instrumentationWatcher = null; 12146 app.instrumentationClass = null; 12147 app.instrumentationInfo = null; 12148 app.instrumentationProfileFile = null; 12149 app.instrumentationArguments = null; 12150 12151 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12152 } 12153 12154 public void finishInstrumentation(IApplicationThread target, 12155 int resultCode, Bundle results) { 12156 int userId = UserHandle.getCallingUserId(); 12157 // Refuse possible leaked file descriptors 12158 if (results != null && results.hasFileDescriptors()) { 12159 throw new IllegalArgumentException("File descriptors passed in Intent"); 12160 } 12161 12162 synchronized(this) { 12163 ProcessRecord app = getRecordForAppLocked(target); 12164 if (app == null) { 12165 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12166 return; 12167 } 12168 final long origId = Binder.clearCallingIdentity(); 12169 finishInstrumentationLocked(app, resultCode, results); 12170 Binder.restoreCallingIdentity(origId); 12171 } 12172 } 12173 12174 // ========================================================= 12175 // CONFIGURATION 12176 // ========================================================= 12177 12178 public ConfigurationInfo getDeviceConfigurationInfo() { 12179 ConfigurationInfo config = new ConfigurationInfo(); 12180 synchronized (this) { 12181 config.reqTouchScreen = mConfiguration.touchscreen; 12182 config.reqKeyboardType = mConfiguration.keyboard; 12183 config.reqNavigation = mConfiguration.navigation; 12184 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12185 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12186 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12187 } 12188 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12189 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12190 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12191 } 12192 config.reqGlEsVersion = GL_ES_VERSION; 12193 } 12194 return config; 12195 } 12196 12197 public Configuration getConfiguration() { 12198 Configuration ci; 12199 synchronized(this) { 12200 ci = new Configuration(mConfiguration); 12201 } 12202 return ci; 12203 } 12204 12205 public void updatePersistentConfiguration(Configuration values) { 12206 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12207 "updateConfiguration()"); 12208 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12209 "updateConfiguration()"); 12210 if (values == null) { 12211 throw new NullPointerException("Configuration must not be null"); 12212 } 12213 12214 synchronized(this) { 12215 final long origId = Binder.clearCallingIdentity(); 12216 updateConfigurationLocked(values, null, true, false); 12217 Binder.restoreCallingIdentity(origId); 12218 } 12219 } 12220 12221 public void updateConfiguration(Configuration values) { 12222 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12223 "updateConfiguration()"); 12224 12225 synchronized(this) { 12226 if (values == null && mWindowManager != null) { 12227 // sentinel: fetch the current configuration from the window manager 12228 values = mWindowManager.computeNewConfiguration(); 12229 } 12230 12231 if (mWindowManager != null) { 12232 mProcessList.applyDisplaySize(mWindowManager); 12233 } 12234 12235 final long origId = Binder.clearCallingIdentity(); 12236 if (values != null) { 12237 Settings.System.clearConfiguration(values); 12238 } 12239 updateConfigurationLocked(values, null, false, false); 12240 Binder.restoreCallingIdentity(origId); 12241 } 12242 } 12243 12244 /** 12245 * Do either or both things: (1) change the current configuration, and (2) 12246 * make sure the given activity is running with the (now) current 12247 * configuration. Returns true if the activity has been left running, or 12248 * false if <var>starting</var> is being destroyed to match the new 12249 * configuration. 12250 * @param persistent TODO 12251 */ 12252 boolean updateConfigurationLocked(Configuration values, 12253 ActivityRecord starting, boolean persistent, boolean initLocale) { 12254 // do nothing if we are headless 12255 if (mHeadless) return true; 12256 12257 int changes = 0; 12258 12259 boolean kept = true; 12260 12261 if (values != null) { 12262 Configuration newConfig = new Configuration(mConfiguration); 12263 changes = newConfig.updateFrom(values); 12264 if (changes != 0) { 12265 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12266 Slog.i(TAG, "Updating configuration to: " + values); 12267 } 12268 12269 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12270 12271 if (values.locale != null && !initLocale) { 12272 saveLocaleLocked(values.locale, 12273 !values.locale.equals(mConfiguration.locale), 12274 values.userSetLocale); 12275 } 12276 12277 mConfigurationSeq++; 12278 if (mConfigurationSeq <= 0) { 12279 mConfigurationSeq = 1; 12280 } 12281 newConfig.seq = mConfigurationSeq; 12282 mConfiguration = newConfig; 12283 Slog.i(TAG, "Config changed: " + newConfig); 12284 12285 final Configuration configCopy = new Configuration(mConfiguration); 12286 12287 // TODO: If our config changes, should we auto dismiss any currently 12288 // showing dialogs? 12289 mShowDialogs = shouldShowDialogs(newConfig); 12290 12291 AttributeCache ac = AttributeCache.instance(); 12292 if (ac != null) { 12293 ac.updateConfiguration(configCopy); 12294 } 12295 12296 // Make sure all resources in our process are updated 12297 // right now, so that anyone who is going to retrieve 12298 // resource values after we return will be sure to get 12299 // the new ones. This is especially important during 12300 // boot, where the first config change needs to guarantee 12301 // all resources have that config before following boot 12302 // code is executed. 12303 mSystemThread.applyConfigurationToResources(configCopy); 12304 12305 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12306 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12307 msg.obj = new Configuration(configCopy); 12308 mHandler.sendMessage(msg); 12309 } 12310 12311 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12312 ProcessRecord app = mLruProcesses.get(i); 12313 try { 12314 if (app.thread != null) { 12315 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12316 + app.processName + " new config " + mConfiguration); 12317 app.thread.scheduleConfigurationChanged(configCopy); 12318 } 12319 } catch (Exception e) { 12320 } 12321 } 12322 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12323 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12324 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12325 | Intent.FLAG_RECEIVER_FOREGROUND); 12326 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12327 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12328 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12329 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12330 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12331 broadcastIntentLocked(null, null, intent, 12332 null, null, 0, null, null, 12333 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12334 } 12335 } 12336 } 12337 12338 if (changes != 0 && starting == null) { 12339 // If the configuration changed, and the caller is not already 12340 // in the process of starting an activity, then find the top 12341 // activity to check if its configuration needs to change. 12342 starting = mMainStack.topRunningActivityLocked(null); 12343 } 12344 12345 if (starting != null) { 12346 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12347 // And we need to make sure at this point that all other activities 12348 // are made visible with the correct configuration. 12349 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12350 } 12351 12352 if (values != null && mWindowManager != null) { 12353 mWindowManager.setNewConfiguration(mConfiguration); 12354 } 12355 12356 return kept; 12357 } 12358 12359 /** 12360 * Decide based on the configuration whether we should shouw the ANR, 12361 * crash, etc dialogs. The idea is that if there is no affordnace to 12362 * press the on-screen buttons, we shouldn't show the dialog. 12363 * 12364 * A thought: SystemUI might also want to get told about this, the Power 12365 * dialog / global actions also might want different behaviors. 12366 */ 12367 private static final boolean shouldShowDialogs(Configuration config) { 12368 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12369 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12370 } 12371 12372 /** 12373 * Save the locale. You must be inside a synchronized (this) block. 12374 */ 12375 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12376 if(isDiff) { 12377 SystemProperties.set("user.language", l.getLanguage()); 12378 SystemProperties.set("user.region", l.getCountry()); 12379 } 12380 12381 if(isPersist) { 12382 SystemProperties.set("persist.sys.language", l.getLanguage()); 12383 SystemProperties.set("persist.sys.country", l.getCountry()); 12384 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12385 } 12386 } 12387 12388 @Override 12389 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12390 ActivityRecord srec = ActivityRecord.forToken(token); 12391 return srec != null && srec.task.affinity != null && 12392 srec.task.affinity.equals(destAffinity); 12393 } 12394 12395 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12396 Intent resultData) { 12397 ComponentName dest = destIntent.getComponent(); 12398 12399 synchronized (this) { 12400 ActivityRecord srec = ActivityRecord.forToken(token); 12401 if (srec == null) { 12402 return false; 12403 } 12404 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12405 final int start = history.indexOf(srec); 12406 if (start < 0) { 12407 // Current activity is not in history stack; do nothing. 12408 return false; 12409 } 12410 int finishTo = start - 1; 12411 ActivityRecord parent = null; 12412 boolean foundParentInTask = false; 12413 if (dest != null) { 12414 TaskRecord tr = srec.task; 12415 for (int i = start - 1; i >= 0; i--) { 12416 ActivityRecord r = history.get(i); 12417 if (tr != r.task) { 12418 // Couldn't find parent in the same task; stop at the one above this. 12419 // (Root of current task; in-app "home" behavior) 12420 // Always at least finish the current activity. 12421 finishTo = Math.min(start - 1, i + 1); 12422 parent = history.get(finishTo); 12423 break; 12424 } else if (r.info.packageName.equals(dest.getPackageName()) && 12425 r.info.name.equals(dest.getClassName())) { 12426 finishTo = i; 12427 parent = r; 12428 foundParentInTask = true; 12429 break; 12430 } 12431 } 12432 } 12433 12434 if (mController != null) { 12435 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12436 if (next != null) { 12437 // ask watcher if this is allowed 12438 boolean resumeOK = true; 12439 try { 12440 resumeOK = mController.activityResuming(next.packageName); 12441 } catch (RemoteException e) { 12442 mController = null; 12443 } 12444 12445 if (!resumeOK) { 12446 return false; 12447 } 12448 } 12449 } 12450 final long origId = Binder.clearCallingIdentity(); 12451 for (int i = start; i > finishTo; i--) { 12452 ActivityRecord r = history.get(i); 12453 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12454 "navigate-up", true); 12455 // Only return the supplied result for the first activity finished 12456 resultCode = Activity.RESULT_CANCELED; 12457 resultData = null; 12458 } 12459 12460 if (parent != null && foundParentInTask) { 12461 final int parentLaunchMode = parent.info.launchMode; 12462 final int destIntentFlags = destIntent.getFlags(); 12463 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12464 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12465 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12466 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12467 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12468 } else { 12469 try { 12470 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12471 destIntent.getComponent(), 0, srec.userId); 12472 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12473 null, aInfo, parent.appToken, null, 12474 0, -1, parent.launchedFromUid, 0, null, true, null); 12475 foundParentInTask = res == ActivityManager.START_SUCCESS; 12476 } catch (RemoteException e) { 12477 foundParentInTask = false; 12478 } 12479 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12480 resultData, "navigate-up", true); 12481 } 12482 } 12483 Binder.restoreCallingIdentity(origId); 12484 return foundParentInTask; 12485 } 12486 } 12487 12488 public int getLaunchedFromUid(IBinder activityToken) { 12489 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12490 if (srec == null) { 12491 return -1; 12492 } 12493 return srec.launchedFromUid; 12494 } 12495 12496 // ========================================================= 12497 // LIFETIME MANAGEMENT 12498 // ========================================================= 12499 12500 // Returns which broadcast queue the app is the current [or imminent] receiver 12501 // on, or 'null' if the app is not an active broadcast recipient. 12502 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12503 BroadcastRecord r = app.curReceiver; 12504 if (r != null) { 12505 return r.queue; 12506 } 12507 12508 // It's not the current receiver, but it might be starting up to become one 12509 synchronized (this) { 12510 for (BroadcastQueue queue : mBroadcastQueues) { 12511 r = queue.mPendingBroadcast; 12512 if (r != null && r.curApp == app) { 12513 // found it; report which queue it's in 12514 return queue; 12515 } 12516 } 12517 } 12518 12519 return null; 12520 } 12521 12522 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12523 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12524 if (mAdjSeq == app.adjSeq) { 12525 // This adjustment has already been computed. If we are calling 12526 // from the top, we may have already computed our adjustment with 12527 // an earlier hidden adjustment that isn't really for us... if 12528 // so, use the new hidden adjustment. 12529 if (!recursed && app.hidden) { 12530 if (app.hasActivities) { 12531 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12532 } else if (app.hasClientActivities) { 12533 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12534 } else { 12535 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12536 } 12537 } 12538 return app.curRawAdj; 12539 } 12540 12541 if (app.thread == null) { 12542 app.adjSeq = mAdjSeq; 12543 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12544 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12545 } 12546 12547 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12548 app.adjSource = null; 12549 app.adjTarget = null; 12550 app.empty = false; 12551 app.hidden = false; 12552 app.hasClientActivities = false; 12553 12554 final int activitiesSize = app.activities.size(); 12555 12556 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12557 // The max adjustment doesn't allow this app to be anything 12558 // below foreground, so it is not worth doing work for it. 12559 app.adjType = "fixed"; 12560 app.adjSeq = mAdjSeq; 12561 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12562 app.hasActivities = false; 12563 app.foregroundActivities = false; 12564 app.keeping = true; 12565 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12566 // System process can do UI, and when they do we want to have 12567 // them trim their memory after the user leaves the UI. To 12568 // facilitate this, here we need to determine whether or not it 12569 // is currently showing UI. 12570 app.systemNoUi = true; 12571 if (app == TOP_APP) { 12572 app.systemNoUi = false; 12573 app.hasActivities = true; 12574 } else if (activitiesSize > 0) { 12575 for (int j = 0; j < activitiesSize; j++) { 12576 final ActivityRecord r = app.activities.get(j); 12577 if (r.visible) { 12578 app.systemNoUi = false; 12579 } 12580 if (r.app == app) { 12581 app.hasActivities = true; 12582 } 12583 } 12584 } 12585 return (app.curAdj=app.maxAdj); 12586 } 12587 12588 app.keeping = false; 12589 app.systemNoUi = false; 12590 app.hasActivities = false; 12591 12592 // Determine the importance of the process, starting with most 12593 // important to least, and assign an appropriate OOM adjustment. 12594 int adj; 12595 int schedGroup; 12596 boolean foregroundActivities = false; 12597 boolean interesting = false; 12598 BroadcastQueue queue; 12599 if (app == TOP_APP) { 12600 // The last app on the list is the foreground app. 12601 adj = ProcessList.FOREGROUND_APP_ADJ; 12602 schedGroup = Process.THREAD_GROUP_DEFAULT; 12603 app.adjType = "top-activity"; 12604 foregroundActivities = true; 12605 interesting = true; 12606 app.hasActivities = true; 12607 } else if (app.instrumentationClass != null) { 12608 // Don't want to kill running instrumentation. 12609 adj = ProcessList.FOREGROUND_APP_ADJ; 12610 schedGroup = Process.THREAD_GROUP_DEFAULT; 12611 app.adjType = "instrumentation"; 12612 interesting = true; 12613 } else if ((queue = isReceivingBroadcast(app)) != null) { 12614 // An app that is currently receiving a broadcast also 12615 // counts as being in the foreground for OOM killer purposes. 12616 // It's placed in a sched group based on the nature of the 12617 // broadcast as reflected by which queue it's active in. 12618 adj = ProcessList.FOREGROUND_APP_ADJ; 12619 schedGroup = (queue == mFgBroadcastQueue) 12620 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12621 app.adjType = "broadcast"; 12622 } else if (app.executingServices.size() > 0) { 12623 // An app that is currently executing a service callback also 12624 // counts as being in the foreground. 12625 adj = ProcessList.FOREGROUND_APP_ADJ; 12626 schedGroup = Process.THREAD_GROUP_DEFAULT; 12627 app.adjType = "exec-service"; 12628 } else { 12629 // Assume process is hidden (has activities); we will correct 12630 // later if this is not the case. 12631 adj = hiddenAdj; 12632 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12633 app.hidden = true; 12634 app.adjType = "bg-act"; 12635 } 12636 12637 boolean hasStoppingActivities = false; 12638 12639 // Examine all activities if not already foreground. 12640 if (!foregroundActivities && activitiesSize > 0) { 12641 for (int j = 0; j < activitiesSize; j++) { 12642 final ActivityRecord r = app.activities.get(j); 12643 if (r.visible) { 12644 // App has a visible activity; only upgrade adjustment. 12645 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12646 adj = ProcessList.VISIBLE_APP_ADJ; 12647 app.adjType = "visible"; 12648 } 12649 schedGroup = Process.THREAD_GROUP_DEFAULT; 12650 app.hidden = false; 12651 app.hasActivities = true; 12652 foregroundActivities = true; 12653 break; 12654 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12655 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12656 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12657 app.adjType = "pausing"; 12658 } 12659 app.hidden = false; 12660 foregroundActivities = true; 12661 } else if (r.state == ActivityState.STOPPING) { 12662 // We will apply the actual adjustment later, because 12663 // we want to allow this process to immediately go through 12664 // any memory trimming that is in effect. 12665 app.hidden = false; 12666 foregroundActivities = true; 12667 hasStoppingActivities = true; 12668 } 12669 if (r.app == app) { 12670 app.hasActivities = true; 12671 } 12672 } 12673 } 12674 12675 if (adj == hiddenAdj && !app.hasActivities) { 12676 if (app.hasClientActivities) { 12677 adj = clientHiddenAdj; 12678 app.adjType = "bg-client-act"; 12679 } else { 12680 // Whoops, this process is completely empty as far as we know 12681 // at this point. 12682 adj = emptyAdj; 12683 app.empty = true; 12684 app.adjType = "bg-empty"; 12685 } 12686 } 12687 12688 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12689 if (app.foregroundServices) { 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 = "fg-service"; 12694 schedGroup = Process.THREAD_GROUP_DEFAULT; 12695 } else if (app.forcingToForeground != null) { 12696 // The user is aware of this app, so make it visible. 12697 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12698 app.hidden = false; 12699 app.adjType = "force-fg"; 12700 app.adjSource = app.forcingToForeground; 12701 schedGroup = Process.THREAD_GROUP_DEFAULT; 12702 } 12703 } 12704 12705 if (app.foregroundServices) { 12706 interesting = true; 12707 } 12708 12709 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12710 // We don't want to kill the current heavy-weight process. 12711 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12712 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12713 app.hidden = false; 12714 app.adjType = "heavy"; 12715 } 12716 12717 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12718 // This process is hosting what we currently consider to be the 12719 // home app, so we don't want to let it go into the background. 12720 adj = ProcessList.HOME_APP_ADJ; 12721 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12722 app.hidden = false; 12723 app.adjType = "home"; 12724 } 12725 12726 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12727 && app.activities.size() > 0) { 12728 // This was the previous process that showed UI to the user. 12729 // We want to try to keep it around more aggressively, to give 12730 // a good experience around switching between two apps. 12731 adj = ProcessList.PREVIOUS_APP_ADJ; 12732 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12733 app.hidden = false; 12734 app.adjType = "previous"; 12735 } 12736 12737 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12738 + " reason=" + app.adjType); 12739 12740 // By default, we use the computed adjustment. It may be changed if 12741 // there are applications dependent on our services or providers, but 12742 // this gives us a baseline and makes sure we don't get into an 12743 // infinite recursion. 12744 app.adjSeq = mAdjSeq; 12745 app.curRawAdj = app.nonStoppingAdj = adj; 12746 12747 if (mBackupTarget != null && app == mBackupTarget.app) { 12748 // If possible we want to avoid killing apps while they're being backed up 12749 if (adj > ProcessList.BACKUP_APP_ADJ) { 12750 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12751 adj = ProcessList.BACKUP_APP_ADJ; 12752 app.adjType = "backup"; 12753 app.hidden = false; 12754 } 12755 } 12756 12757 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12758 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12759 final long now = SystemClock.uptimeMillis(); 12760 // This process is more important if the top activity is 12761 // bound to the service. 12762 Iterator<ServiceRecord> jt = app.services.iterator(); 12763 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12764 ServiceRecord s = jt.next(); 12765 if (s.startRequested) { 12766 if (app.hasShownUi && app != mHomeProcess) { 12767 // If this process has shown some UI, let it immediately 12768 // go to the LRU list because it may be pretty heavy with 12769 // UI stuff. We'll tag it with a label just to help 12770 // debug and understand what is going on. 12771 if (adj > ProcessList.SERVICE_ADJ) { 12772 app.adjType = "started-bg-ui-services"; 12773 } 12774 } else { 12775 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12776 // This service has seen some activity within 12777 // recent memory, so we will keep its process ahead 12778 // of the background processes. 12779 if (adj > ProcessList.SERVICE_ADJ) { 12780 adj = ProcessList.SERVICE_ADJ; 12781 app.adjType = "started-services"; 12782 app.hidden = false; 12783 } 12784 } 12785 // If we have let the service slide into the background 12786 // state, still have some text describing what it is doing 12787 // even though the service no longer has an impact. 12788 if (adj > ProcessList.SERVICE_ADJ) { 12789 app.adjType = "started-bg-services"; 12790 } 12791 } 12792 // Don't kill this process because it is doing work; it 12793 // has said it is doing work. 12794 app.keeping = true; 12795 } 12796 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12797 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12798 Iterator<ArrayList<ConnectionRecord>> kt 12799 = s.connections.values().iterator(); 12800 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12801 ArrayList<ConnectionRecord> clist = kt.next(); 12802 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12803 // XXX should compute this based on the max of 12804 // all connected clients. 12805 ConnectionRecord cr = clist.get(i); 12806 if (cr.binding.client == app) { 12807 // Binding to ourself is not interesting. 12808 continue; 12809 } 12810 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12811 ProcessRecord client = cr.binding.client; 12812 int clientAdj = adj; 12813 int myHiddenAdj = hiddenAdj; 12814 if (myHiddenAdj > client.hiddenAdj) { 12815 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12816 myHiddenAdj = client.hiddenAdj; 12817 } else { 12818 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12819 } 12820 } 12821 int myClientHiddenAdj = clientHiddenAdj; 12822 if (myClientHiddenAdj > client.clientHiddenAdj) { 12823 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12824 myClientHiddenAdj = client.clientHiddenAdj; 12825 } else { 12826 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12827 } 12828 } 12829 int myEmptyAdj = emptyAdj; 12830 if (myEmptyAdj > client.emptyAdj) { 12831 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12832 myEmptyAdj = client.emptyAdj; 12833 } else { 12834 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12835 } 12836 } 12837 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12838 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12839 String adjType = null; 12840 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12841 // Not doing bind OOM management, so treat 12842 // this guy more like a started service. 12843 if (app.hasShownUi && app != mHomeProcess) { 12844 // If this process has shown some UI, let it immediately 12845 // go to the LRU list because it may be pretty heavy with 12846 // UI stuff. We'll tag it with a label just to help 12847 // debug and understand what is going on. 12848 if (adj > clientAdj) { 12849 adjType = "bound-bg-ui-services"; 12850 } 12851 app.hidden = false; 12852 clientAdj = adj; 12853 } else { 12854 if (now >= (s.lastActivity 12855 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12856 // This service has not seen activity within 12857 // recent memory, so allow it to drop to the 12858 // LRU list if there is no other reason to keep 12859 // it around. We'll also tag it with a label just 12860 // to help debug and undertand what is going on. 12861 if (adj > clientAdj) { 12862 adjType = "bound-bg-services"; 12863 } 12864 clientAdj = adj; 12865 } 12866 } 12867 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12868 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12869 // If this connection is keeping the service 12870 // created, then we want to try to better follow 12871 // its memory management semantics for activities. 12872 // That is, if it is sitting in the background 12873 // LRU list as a hidden process (with activities), 12874 // we don't want the service it is connected to 12875 // to go into the empty LRU and quickly get killed, 12876 // because I'll we'll do is just end up restarting 12877 // the service. 12878 app.hasClientActivities |= client.hasActivities; 12879 } 12880 } 12881 if (adj > clientAdj) { 12882 // If this process has recently shown UI, and 12883 // the process that is binding to it is less 12884 // important than being visible, then we don't 12885 // care about the binding as much as we care 12886 // about letting this process get into the LRU 12887 // list to be killed and restarted if needed for 12888 // memory. 12889 if (app.hasShownUi && app != mHomeProcess 12890 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12891 adjType = "bound-bg-ui-services"; 12892 } else { 12893 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12894 |Context.BIND_IMPORTANT)) != 0) { 12895 adj = clientAdj; 12896 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12897 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12898 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12899 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12900 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12901 adj = clientAdj; 12902 } else { 12903 app.pendingUiClean = true; 12904 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12905 adj = ProcessList.VISIBLE_APP_ADJ; 12906 } 12907 } 12908 if (!client.hidden) { 12909 app.hidden = false; 12910 } 12911 if (client.keeping) { 12912 app.keeping = true; 12913 } 12914 adjType = "service"; 12915 } 12916 } 12917 if (adjType != null) { 12918 app.adjType = adjType; 12919 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12920 .REASON_SERVICE_IN_USE; 12921 app.adjSource = cr.binding.client; 12922 app.adjSourceOom = clientAdj; 12923 app.adjTarget = s.name; 12924 } 12925 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12926 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12927 schedGroup = Process.THREAD_GROUP_DEFAULT; 12928 } 12929 } 12930 } 12931 final ActivityRecord a = cr.activity; 12932 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12933 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12934 (a.visible || a.state == ActivityState.RESUMED 12935 || a.state == ActivityState.PAUSING)) { 12936 adj = ProcessList.FOREGROUND_APP_ADJ; 12937 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12938 schedGroup = Process.THREAD_GROUP_DEFAULT; 12939 } 12940 app.hidden = false; 12941 app.adjType = "service"; 12942 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12943 .REASON_SERVICE_IN_USE; 12944 app.adjSource = a; 12945 app.adjSourceOom = adj; 12946 app.adjTarget = s.name; 12947 } 12948 } 12949 } 12950 } 12951 } 12952 } 12953 12954 // Finally, if this process has active services running in it, we 12955 // would like to avoid killing it unless it would prevent the current 12956 // application from running. By default we put the process in 12957 // with the rest of the background processes; as we scan through 12958 // its services we may bump it up from there. 12959 if (adj > hiddenAdj) { 12960 adj = hiddenAdj; 12961 app.hidden = false; 12962 app.adjType = "bg-services"; 12963 } 12964 } 12965 12966 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12967 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12968 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12969 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12970 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12971 ContentProviderRecord cpr = jt.next(); 12972 for (int i = cpr.connections.size()-1; 12973 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12974 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12975 i--) { 12976 ContentProviderConnection conn = cpr.connections.get(i); 12977 ProcessRecord client = conn.client; 12978 if (client == app) { 12979 // Being our own client is not interesting. 12980 continue; 12981 } 12982 int myHiddenAdj = hiddenAdj; 12983 if (myHiddenAdj > client.hiddenAdj) { 12984 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12985 myHiddenAdj = client.hiddenAdj; 12986 } else { 12987 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12988 } 12989 } 12990 int myClientHiddenAdj = clientHiddenAdj; 12991 if (myClientHiddenAdj > client.clientHiddenAdj) { 12992 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 12993 myClientHiddenAdj = client.clientHiddenAdj; 12994 } else { 12995 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12996 } 12997 } 12998 int myEmptyAdj = emptyAdj; 12999 if (myEmptyAdj > client.emptyAdj) { 13000 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 13001 myEmptyAdj = client.emptyAdj; 13002 } else { 13003 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 13004 } 13005 } 13006 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13007 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13008 if (adj > clientAdj) { 13009 if (app.hasShownUi && app != mHomeProcess 13010 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13011 app.adjType = "bg-ui-provider"; 13012 } else { 13013 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13014 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13015 app.adjType = "provider"; 13016 } 13017 if (!client.hidden) { 13018 app.hidden = false; 13019 } 13020 if (client.keeping) { 13021 app.keeping = true; 13022 } 13023 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13024 .REASON_PROVIDER_IN_USE; 13025 app.adjSource = client; 13026 app.adjSourceOom = clientAdj; 13027 app.adjTarget = cpr.name; 13028 } 13029 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13030 schedGroup = Process.THREAD_GROUP_DEFAULT; 13031 } 13032 } 13033 // If the provider has external (non-framework) process 13034 // dependencies, ensure that its adjustment is at least 13035 // FOREGROUND_APP_ADJ. 13036 if (cpr.hasExternalProcessHandles()) { 13037 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13038 adj = ProcessList.FOREGROUND_APP_ADJ; 13039 schedGroup = Process.THREAD_GROUP_DEFAULT; 13040 app.hidden = false; 13041 app.keeping = true; 13042 app.adjType = "provider"; 13043 app.adjTarget = cpr.name; 13044 } 13045 } 13046 } 13047 } 13048 13049 if (adj == ProcessList.SERVICE_ADJ) { 13050 if (doingAll) { 13051 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13052 mNewNumServiceProcs++; 13053 } 13054 if (app.serviceb) { 13055 adj = ProcessList.SERVICE_B_ADJ; 13056 } 13057 } else { 13058 app.serviceb = false; 13059 } 13060 13061 app.nonStoppingAdj = adj; 13062 13063 if (hasStoppingActivities) { 13064 // Only upgrade adjustment. 13065 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13066 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13067 app.adjType = "stopping"; 13068 } 13069 } 13070 13071 app.curRawAdj = adj; 13072 13073 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13074 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13075 if (adj > app.maxAdj) { 13076 adj = app.maxAdj; 13077 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13078 schedGroup = Process.THREAD_GROUP_DEFAULT; 13079 } 13080 } 13081 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13082 app.keeping = true; 13083 } 13084 13085 if (app.hasAboveClient) { 13086 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13087 // then we need to drop its adjustment to be lower than the service's 13088 // in order to honor the request. We want to drop it by one adjustment 13089 // level... but there is special meaning applied to various levels so 13090 // we will skip some of them. 13091 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13092 // System process will not get dropped, ever 13093 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13094 adj = ProcessList.VISIBLE_APP_ADJ; 13095 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13096 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13097 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13098 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13099 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13100 adj++; 13101 } 13102 } 13103 13104 int importance = app.memImportance; 13105 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13106 app.curAdj = adj; 13107 app.curSchedGroup = schedGroup; 13108 if (!interesting) { 13109 // For this reporting, if there is not something explicitly 13110 // interesting in this process then we will push it to the 13111 // background importance. 13112 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13113 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13114 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13115 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13116 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13117 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13118 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13119 } else if (adj >= ProcessList.SERVICE_ADJ) { 13120 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13121 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13122 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13123 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13124 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13125 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13126 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13127 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13128 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13129 } else { 13130 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13131 } 13132 } 13133 13134 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13135 if (foregroundActivities != app.foregroundActivities) { 13136 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13137 } 13138 if (changes != 0) { 13139 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13140 app.memImportance = importance; 13141 app.foregroundActivities = foregroundActivities; 13142 int i = mPendingProcessChanges.size()-1; 13143 ProcessChangeItem item = null; 13144 while (i >= 0) { 13145 item = mPendingProcessChanges.get(i); 13146 if (item.pid == app.pid) { 13147 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13148 break; 13149 } 13150 i--; 13151 } 13152 if (i < 0) { 13153 // No existing item in pending changes; need a new one. 13154 final int NA = mAvailProcessChanges.size(); 13155 if (NA > 0) { 13156 item = mAvailProcessChanges.remove(NA-1); 13157 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13158 } else { 13159 item = new ProcessChangeItem(); 13160 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13161 } 13162 item.changes = 0; 13163 item.pid = app.pid; 13164 item.uid = app.info.uid; 13165 if (mPendingProcessChanges.size() == 0) { 13166 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13167 "*** Enqueueing dispatch processes changed!"); 13168 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13169 } 13170 mPendingProcessChanges.add(item); 13171 } 13172 item.changes |= changes; 13173 item.importance = importance; 13174 item.foregroundActivities = foregroundActivities; 13175 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13176 + Integer.toHexString(System.identityHashCode(item)) 13177 + " " + app.toShortString() + ": changes=" + item.changes 13178 + " importance=" + item.importance 13179 + " foreground=" + item.foregroundActivities 13180 + " type=" + app.adjType + " source=" + app.adjSource 13181 + " target=" + app.adjTarget); 13182 } 13183 13184 return app.curRawAdj; 13185 } 13186 13187 /** 13188 * Ask a given process to GC right now. 13189 */ 13190 final void performAppGcLocked(ProcessRecord app) { 13191 try { 13192 app.lastRequestedGc = SystemClock.uptimeMillis(); 13193 if (app.thread != null) { 13194 if (app.reportLowMemory) { 13195 app.reportLowMemory = false; 13196 app.thread.scheduleLowMemory(); 13197 } else { 13198 app.thread.processInBackground(); 13199 } 13200 } 13201 } catch (Exception e) { 13202 // whatever. 13203 } 13204 } 13205 13206 /** 13207 * Returns true if things are idle enough to perform GCs. 13208 */ 13209 private final boolean canGcNowLocked() { 13210 boolean processingBroadcasts = false; 13211 for (BroadcastQueue q : mBroadcastQueues) { 13212 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13213 processingBroadcasts = true; 13214 } 13215 } 13216 return !processingBroadcasts 13217 && (mSleeping || (mMainStack.mResumedActivity != null && 13218 mMainStack.mResumedActivity.idle)); 13219 } 13220 13221 /** 13222 * Perform GCs on all processes that are waiting for it, but only 13223 * if things are idle. 13224 */ 13225 final void performAppGcsLocked() { 13226 final int N = mProcessesToGc.size(); 13227 if (N <= 0) { 13228 return; 13229 } 13230 if (canGcNowLocked()) { 13231 while (mProcessesToGc.size() > 0) { 13232 ProcessRecord proc = mProcessesToGc.remove(0); 13233 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13234 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13235 <= SystemClock.uptimeMillis()) { 13236 // To avoid spamming the system, we will GC processes one 13237 // at a time, waiting a few seconds between each. 13238 performAppGcLocked(proc); 13239 scheduleAppGcsLocked(); 13240 return; 13241 } else { 13242 // It hasn't been long enough since we last GCed this 13243 // process... put it in the list to wait for its time. 13244 addProcessToGcListLocked(proc); 13245 break; 13246 } 13247 } 13248 } 13249 13250 scheduleAppGcsLocked(); 13251 } 13252 } 13253 13254 /** 13255 * If all looks good, perform GCs on all processes waiting for them. 13256 */ 13257 final void performAppGcsIfAppropriateLocked() { 13258 if (canGcNowLocked()) { 13259 performAppGcsLocked(); 13260 return; 13261 } 13262 // Still not idle, wait some more. 13263 scheduleAppGcsLocked(); 13264 } 13265 13266 /** 13267 * Schedule the execution of all pending app GCs. 13268 */ 13269 final void scheduleAppGcsLocked() { 13270 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13271 13272 if (mProcessesToGc.size() > 0) { 13273 // Schedule a GC for the time to the next process. 13274 ProcessRecord proc = mProcessesToGc.get(0); 13275 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13276 13277 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13278 long now = SystemClock.uptimeMillis(); 13279 if (when < (now+GC_TIMEOUT)) { 13280 when = now + GC_TIMEOUT; 13281 } 13282 mHandler.sendMessageAtTime(msg, when); 13283 } 13284 } 13285 13286 /** 13287 * Add a process to the array of processes waiting to be GCed. Keeps the 13288 * list in sorted order by the last GC time. The process can't already be 13289 * on the list. 13290 */ 13291 final void addProcessToGcListLocked(ProcessRecord proc) { 13292 boolean added = false; 13293 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13294 if (mProcessesToGc.get(i).lastRequestedGc < 13295 proc.lastRequestedGc) { 13296 added = true; 13297 mProcessesToGc.add(i+1, proc); 13298 break; 13299 } 13300 } 13301 if (!added) { 13302 mProcessesToGc.add(0, proc); 13303 } 13304 } 13305 13306 /** 13307 * Set up to ask a process to GC itself. This will either do it 13308 * immediately, or put it on the list of processes to gc the next 13309 * time things are idle. 13310 */ 13311 final void scheduleAppGcLocked(ProcessRecord app) { 13312 long now = SystemClock.uptimeMillis(); 13313 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13314 return; 13315 } 13316 if (!mProcessesToGc.contains(app)) { 13317 addProcessToGcListLocked(app); 13318 scheduleAppGcsLocked(); 13319 } 13320 } 13321 13322 final void checkExcessivePowerUsageLocked(boolean doKills) { 13323 updateCpuStatsNow(); 13324 13325 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13326 boolean doWakeKills = doKills; 13327 boolean doCpuKills = doKills; 13328 if (mLastPowerCheckRealtime == 0) { 13329 doWakeKills = false; 13330 } 13331 if (mLastPowerCheckUptime == 0) { 13332 doCpuKills = false; 13333 } 13334 if (stats.isScreenOn()) { 13335 doWakeKills = false; 13336 } 13337 final long curRealtime = SystemClock.elapsedRealtime(); 13338 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13339 final long curUptime = SystemClock.uptimeMillis(); 13340 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13341 mLastPowerCheckRealtime = curRealtime; 13342 mLastPowerCheckUptime = curUptime; 13343 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13344 doWakeKills = false; 13345 } 13346 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13347 doCpuKills = false; 13348 } 13349 int i = mLruProcesses.size(); 13350 while (i > 0) { 13351 i--; 13352 ProcessRecord app = mLruProcesses.get(i); 13353 if (!app.keeping) { 13354 long wtime; 13355 synchronized (stats) { 13356 wtime = stats.getProcessWakeTime(app.info.uid, 13357 app.pid, curRealtime); 13358 } 13359 long wtimeUsed = wtime - app.lastWakeTime; 13360 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13361 if (DEBUG_POWER) { 13362 StringBuilder sb = new StringBuilder(128); 13363 sb.append("Wake for "); 13364 app.toShortString(sb); 13365 sb.append(": over "); 13366 TimeUtils.formatDuration(realtimeSince, sb); 13367 sb.append(" used "); 13368 TimeUtils.formatDuration(wtimeUsed, sb); 13369 sb.append(" ("); 13370 sb.append((wtimeUsed*100)/realtimeSince); 13371 sb.append("%)"); 13372 Slog.i(TAG, sb.toString()); 13373 sb.setLength(0); 13374 sb.append("CPU for "); 13375 app.toShortString(sb); 13376 sb.append(": over "); 13377 TimeUtils.formatDuration(uptimeSince, sb); 13378 sb.append(" used "); 13379 TimeUtils.formatDuration(cputimeUsed, sb); 13380 sb.append(" ("); 13381 sb.append((cputimeUsed*100)/uptimeSince); 13382 sb.append("%)"); 13383 Slog.i(TAG, sb.toString()); 13384 } 13385 // If a process has held a wake lock for more 13386 // than 50% of the time during this period, 13387 // that sounds bad. Kill! 13388 if (doWakeKills && realtimeSince > 0 13389 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13390 synchronized (stats) { 13391 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13392 realtimeSince, wtimeUsed); 13393 } 13394 Slog.w(TAG, "Excessive wake lock in " + app.processName 13395 + " (pid " + app.pid + "): held " + wtimeUsed 13396 + " during " + realtimeSince); 13397 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13398 app.processName, app.setAdj, "excessive wake lock"); 13399 Process.killProcessQuiet(app.pid); 13400 } else if (doCpuKills && uptimeSince > 0 13401 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13402 synchronized (stats) { 13403 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13404 uptimeSince, cputimeUsed); 13405 } 13406 Slog.w(TAG, "Excessive CPU in " + app.processName 13407 + " (pid " + app.pid + "): used " + cputimeUsed 13408 + " during " + uptimeSince); 13409 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13410 app.processName, app.setAdj, "excessive cpu"); 13411 Process.killProcessQuiet(app.pid); 13412 } else { 13413 app.lastWakeTime = wtime; 13414 app.lastCpuTime = app.curCpuTime; 13415 } 13416 } 13417 } 13418 } 13419 13420 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13421 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13422 app.hiddenAdj = hiddenAdj; 13423 app.clientHiddenAdj = clientHiddenAdj; 13424 app.emptyAdj = emptyAdj; 13425 13426 if (app.thread == null) { 13427 return false; 13428 } 13429 13430 final boolean wasKeeping = app.keeping; 13431 13432 boolean success = true; 13433 13434 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13435 13436 if (app.curRawAdj != app.setRawAdj) { 13437 if (wasKeeping && !app.keeping) { 13438 // This app is no longer something we want to keep. Note 13439 // its current wake lock time to later know to kill it if 13440 // it is not behaving well. 13441 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13442 synchronized (stats) { 13443 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13444 app.pid, SystemClock.elapsedRealtime()); 13445 } 13446 app.lastCpuTime = app.curCpuTime; 13447 } 13448 13449 app.setRawAdj = app.curRawAdj; 13450 } 13451 13452 if (app.curAdj != app.setAdj) { 13453 if (Process.setOomAdj(app.pid, app.curAdj)) { 13454 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13455 TAG, "Set " + app.pid + " " + app.processName + 13456 " adj " + app.curAdj + ": " + app.adjType); 13457 app.setAdj = app.curAdj; 13458 } else { 13459 success = false; 13460 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13461 } 13462 } 13463 if (app.setSchedGroup != app.curSchedGroup) { 13464 app.setSchedGroup = app.curSchedGroup; 13465 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13466 "Setting process group of " + app.processName 13467 + " to " + app.curSchedGroup); 13468 if (app.waitingToKill != null && 13469 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13470 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13471 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13472 app.processName, app.setAdj, app.waitingToKill); 13473 app.killedBackground = true; 13474 Process.killProcessQuiet(app.pid); 13475 success = false; 13476 } else { 13477 if (true) { 13478 long oldId = Binder.clearCallingIdentity(); 13479 try { 13480 Process.setProcessGroup(app.pid, app.curSchedGroup); 13481 } catch (Exception e) { 13482 Slog.w(TAG, "Failed setting process group of " + app.pid 13483 + " to " + app.curSchedGroup); 13484 e.printStackTrace(); 13485 } finally { 13486 Binder.restoreCallingIdentity(oldId); 13487 } 13488 } else { 13489 if (app.thread != null) { 13490 try { 13491 app.thread.setSchedulingGroup(app.curSchedGroup); 13492 } catch (RemoteException e) { 13493 } 13494 } 13495 } 13496 } 13497 } 13498 return success; 13499 } 13500 13501 private final ActivityRecord resumedAppLocked() { 13502 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13503 if (resumedActivity == null || resumedActivity.app == null) { 13504 resumedActivity = mMainStack.mPausingActivity; 13505 if (resumedActivity == null || resumedActivity.app == null) { 13506 resumedActivity = mMainStack.topRunningActivityLocked(null); 13507 } 13508 } 13509 return resumedActivity; 13510 } 13511 13512 final boolean updateOomAdjLocked(ProcessRecord app) { 13513 final ActivityRecord TOP_ACT = resumedAppLocked(); 13514 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13515 int curAdj = app.curAdj; 13516 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13517 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13518 13519 mAdjSeq++; 13520 13521 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13522 app.emptyAdj, TOP_APP, false); 13523 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13524 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13525 if (nowHidden != wasHidden) { 13526 // Changed to/from hidden state, so apps after it in the LRU 13527 // list may also be changed. 13528 updateOomAdjLocked(); 13529 } 13530 return success; 13531 } 13532 13533 final void updateOomAdjLocked() { 13534 final ActivityRecord TOP_ACT = resumedAppLocked(); 13535 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13536 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13537 13538 if (false) { 13539 RuntimeException e = new RuntimeException(); 13540 e.fillInStackTrace(); 13541 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13542 } 13543 13544 mAdjSeq++; 13545 mNewNumServiceProcs = 0; 13546 13547 final int emptyProcessLimit; 13548 final int hiddenProcessLimit; 13549 if (mProcessLimit <= 0) { 13550 emptyProcessLimit = hiddenProcessLimit = 0; 13551 } else if (mProcessLimit == 1) { 13552 emptyProcessLimit = 1; 13553 hiddenProcessLimit = 0; 13554 } else { 13555 emptyProcessLimit = (mProcessLimit*2)/3; 13556 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13557 } 13558 13559 // Let's determine how many processes we have running vs. 13560 // how many slots we have for background processes; we may want 13561 // to put multiple processes in a slot of there are enough of 13562 // them. 13563 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13564 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13565 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13566 if (numEmptyProcs > hiddenProcessLimit) { 13567 // If there are more empty processes than our limit on hidden 13568 // processes, then use the hidden process limit for the factor. 13569 // This ensures that the really old empty processes get pushed 13570 // down to the bottom, so if we are running low on memory we will 13571 // have a better chance at keeping around more hidden processes 13572 // instead of a gazillion empty processes. 13573 numEmptyProcs = hiddenProcessLimit; 13574 } 13575 int emptyFactor = numEmptyProcs/numSlots; 13576 if (emptyFactor < 1) emptyFactor = 1; 13577 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13578 if (hiddenFactor < 1) hiddenFactor = 1; 13579 int stepHidden = 0; 13580 int stepEmpty = 0; 13581 int numHidden = 0; 13582 int numEmpty = 0; 13583 int numTrimming = 0; 13584 13585 mNumNonHiddenProcs = 0; 13586 mNumHiddenProcs = 0; 13587 13588 // First update the OOM adjustment for each of the 13589 // application processes based on their current state. 13590 int i = mLruProcesses.size(); 13591 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13592 int nextHiddenAdj = curHiddenAdj+1; 13593 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13594 int nextEmptyAdj = curEmptyAdj+2; 13595 int curClientHiddenAdj = curEmptyAdj; 13596 while (i > 0) { 13597 i--; 13598 ProcessRecord app = mLruProcesses.get(i); 13599 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13600 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13601 if (!app.killedBackground) { 13602 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13603 // This process was assigned as a hidden process... step the 13604 // hidden level. 13605 mNumHiddenProcs++; 13606 if (curHiddenAdj != nextHiddenAdj) { 13607 stepHidden++; 13608 if (stepHidden >= hiddenFactor) { 13609 stepHidden = 0; 13610 curHiddenAdj = nextHiddenAdj; 13611 nextHiddenAdj += 2; 13612 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13613 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13614 } 13615 if (curClientHiddenAdj <= curHiddenAdj) { 13616 curClientHiddenAdj = curHiddenAdj + 1; 13617 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13618 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13619 } 13620 } 13621 } 13622 } 13623 numHidden++; 13624 if (numHidden > hiddenProcessLimit) { 13625 Slog.i(TAG, "No longer want " + app.processName 13626 + " (pid " + app.pid + "): hidden #" + numHidden); 13627 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13628 app.processName, app.setAdj, "too many background"); 13629 app.killedBackground = true; 13630 Process.killProcessQuiet(app.pid); 13631 } 13632 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13633 // This process has a client that has activities. We will have 13634 // given it the current hidden adj; here we will just leave it 13635 // without stepping the hidden adj. 13636 curClientHiddenAdj++; 13637 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13638 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13639 } 13640 } else { 13641 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13642 // This process was assigned as an empty process... step the 13643 // empty level. 13644 if (curEmptyAdj != nextEmptyAdj) { 13645 stepEmpty++; 13646 if (stepEmpty >= emptyFactor) { 13647 stepEmpty = 0; 13648 curEmptyAdj = nextEmptyAdj; 13649 nextEmptyAdj += 2; 13650 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13651 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13652 } 13653 } 13654 } 13655 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13656 mNumNonHiddenProcs++; 13657 } 13658 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13659 && !app.hasClientActivities) { 13660 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13661 && app.lastActivityTime < oldTime) { 13662 Slog.i(TAG, "No longer want " + app.processName 13663 + " (pid " + app.pid + "): empty for " 13664 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13665 / 1000) + "s"); 13666 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13667 app.processName, app.setAdj, "old background process"); 13668 app.killedBackground = true; 13669 Process.killProcessQuiet(app.pid); 13670 } else { 13671 numEmpty++; 13672 if (numEmpty > emptyProcessLimit) { 13673 Slog.i(TAG, "No longer want " + app.processName 13674 + " (pid " + app.pid + "): empty #" + numEmpty); 13675 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13676 app.processName, app.setAdj, "too many background"); 13677 app.killedBackground = true; 13678 Process.killProcessQuiet(app.pid); 13679 } 13680 } 13681 } 13682 } 13683 if (app.isolated && app.services.size() <= 0) { 13684 // If this is an isolated process, and there are no 13685 // services running in it, then the process is no longer 13686 // needed. We agressively kill these because we can by 13687 // definition not re-use the same process again, and it is 13688 // good to avoid having whatever code was running in them 13689 // left sitting around after no longer needed. 13690 Slog.i(TAG, "Isolated process " + app.processName 13691 + " (pid " + app.pid + ") no longer needed"); 13692 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13693 app.processName, app.setAdj, "isolated not needed"); 13694 app.killedBackground = true; 13695 Process.killProcessQuiet(app.pid); 13696 } 13697 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13698 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13699 && !app.killedBackground) { 13700 numTrimming++; 13701 } 13702 } 13703 } 13704 13705 mNumServiceProcs = mNewNumServiceProcs; 13706 13707 // Now determine the memory trimming level of background processes. 13708 // Unfortunately we need to start at the back of the list to do this 13709 // properly. We only do this if the number of background apps we 13710 // are managing to keep around is less than half the maximum we desire; 13711 // if we are keeping a good number around, we'll let them use whatever 13712 // memory they want. 13713 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13714 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13715 final int numHiddenAndEmpty = numHidden + numEmpty; 13716 final int N = mLruProcesses.size(); 13717 int factor = numTrimming/3; 13718 int minFactor = 2; 13719 if (mHomeProcess != null) minFactor++; 13720 if (mPreviousProcess != null) minFactor++; 13721 if (factor < minFactor) factor = minFactor; 13722 int step = 0; 13723 int fgTrimLevel; 13724 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13725 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13726 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13727 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13728 } else { 13729 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13730 } 13731 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13732 for (i=0; i<N; i++) { 13733 ProcessRecord app = mLruProcesses.get(i); 13734 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13735 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13736 && !app.killedBackground) { 13737 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13738 try { 13739 app.thread.scheduleTrimMemory(curLevel); 13740 } catch (RemoteException e) { 13741 } 13742 if (false) { 13743 // For now we won't do this; our memory trimming seems 13744 // to be good enough at this point that destroying 13745 // activities causes more harm than good. 13746 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13747 && app != mHomeProcess && app != mPreviousProcess) { 13748 // Need to do this on its own message because the stack may not 13749 // be in a consistent state at this point. 13750 // For these apps we will also finish their activities 13751 // to help them free memory. 13752 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13753 } 13754 } 13755 } 13756 app.trimMemoryLevel = curLevel; 13757 step++; 13758 if (step >= factor) { 13759 step = 0; 13760 switch (curLevel) { 13761 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13762 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13763 break; 13764 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13765 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13766 break; 13767 } 13768 } 13769 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13770 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13771 && app.thread != null) { 13772 try { 13773 app.thread.scheduleTrimMemory( 13774 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13775 } catch (RemoteException e) { 13776 } 13777 } 13778 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13779 } else { 13780 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13781 && app.pendingUiClean) { 13782 // If this application is now in the background and it 13783 // had done UI, then give it the special trim level to 13784 // have it free UI resources. 13785 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13786 if (app.trimMemoryLevel < level && app.thread != null) { 13787 try { 13788 app.thread.scheduleTrimMemory(level); 13789 } catch (RemoteException e) { 13790 } 13791 } 13792 app.pendingUiClean = false; 13793 } 13794 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13795 try { 13796 app.thread.scheduleTrimMemory(fgTrimLevel); 13797 } catch (RemoteException e) { 13798 } 13799 } 13800 app.trimMemoryLevel = fgTrimLevel; 13801 } 13802 } 13803 } else { 13804 final int N = mLruProcesses.size(); 13805 for (i=0; i<N; i++) { 13806 ProcessRecord app = mLruProcesses.get(i); 13807 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13808 && app.pendingUiClean) { 13809 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13810 && app.thread != null) { 13811 try { 13812 app.thread.scheduleTrimMemory( 13813 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13814 } catch (RemoteException e) { 13815 } 13816 } 13817 app.pendingUiClean = false; 13818 } 13819 app.trimMemoryLevel = 0; 13820 } 13821 } 13822 13823 if (mAlwaysFinishActivities) { 13824 // Need to do this on its own message because the stack may not 13825 // be in a consistent state at this point. 13826 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13827 } 13828 } 13829 13830 final void trimApplications() { 13831 synchronized (this) { 13832 int i; 13833 13834 // First remove any unused application processes whose package 13835 // has been removed. 13836 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13837 final ProcessRecord app = mRemovedProcesses.get(i); 13838 if (app.activities.size() == 0 13839 && app.curReceiver == null && app.services.size() == 0) { 13840 Slog.i( 13841 TAG, "Exiting empty application process " 13842 + app.processName + " (" 13843 + (app.thread != null ? app.thread.asBinder() : null) 13844 + ")\n"); 13845 if (app.pid > 0 && app.pid != MY_PID) { 13846 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13847 app.processName, app.setAdj, "empty"); 13848 Process.killProcessQuiet(app.pid); 13849 } else { 13850 try { 13851 app.thread.scheduleExit(); 13852 } catch (Exception e) { 13853 // Ignore exceptions. 13854 } 13855 } 13856 cleanUpApplicationRecordLocked(app, false, true, -1); 13857 mRemovedProcesses.remove(i); 13858 13859 if (app.persistent) { 13860 if (app.persistent) { 13861 addAppLocked(app.info, false); 13862 } 13863 } 13864 } 13865 } 13866 13867 // Now update the oom adj for all processes. 13868 updateOomAdjLocked(); 13869 } 13870 } 13871 13872 /** This method sends the specified signal to each of the persistent apps */ 13873 public void signalPersistentProcesses(int sig) throws RemoteException { 13874 if (sig != Process.SIGNAL_USR1) { 13875 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13876 } 13877 13878 synchronized (this) { 13879 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13880 != PackageManager.PERMISSION_GRANTED) { 13881 throw new SecurityException("Requires permission " 13882 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13883 } 13884 13885 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13886 ProcessRecord r = mLruProcesses.get(i); 13887 if (r.thread != null && r.persistent) { 13888 Process.sendSignal(r.pid, sig); 13889 } 13890 } 13891 } 13892 } 13893 13894 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13895 if (proc == null || proc == mProfileProc) { 13896 proc = mProfileProc; 13897 path = mProfileFile; 13898 profileType = mProfileType; 13899 clearProfilerLocked(); 13900 } 13901 if (proc == null) { 13902 return; 13903 } 13904 try { 13905 proc.thread.profilerControl(false, path, null, profileType); 13906 } catch (RemoteException e) { 13907 throw new IllegalStateException("Process disappeared"); 13908 } 13909 } 13910 13911 private void clearProfilerLocked() { 13912 if (mProfileFd != null) { 13913 try { 13914 mProfileFd.close(); 13915 } catch (IOException e) { 13916 } 13917 } 13918 mProfileApp = null; 13919 mProfileProc = null; 13920 mProfileFile = null; 13921 mProfileType = 0; 13922 mAutoStopProfiler = false; 13923 } 13924 13925 public boolean profileControl(String process, int userId, boolean start, 13926 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13927 13928 try { 13929 synchronized (this) { 13930 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13931 // its own permission. 13932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13933 != PackageManager.PERMISSION_GRANTED) { 13934 throw new SecurityException("Requires permission " 13935 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13936 } 13937 13938 if (start && fd == null) { 13939 throw new IllegalArgumentException("null fd"); 13940 } 13941 13942 ProcessRecord proc = null; 13943 if (process != null) { 13944 proc = findProcessLocked(process, userId, "profileControl"); 13945 } 13946 13947 if (start && (proc == null || proc.thread == null)) { 13948 throw new IllegalArgumentException("Unknown process: " + process); 13949 } 13950 13951 if (start) { 13952 stopProfilerLocked(null, null, 0); 13953 setProfileApp(proc.info, proc.processName, path, fd, false); 13954 mProfileProc = proc; 13955 mProfileType = profileType; 13956 try { 13957 fd = fd.dup(); 13958 } catch (IOException e) { 13959 fd = null; 13960 } 13961 proc.thread.profilerControl(start, path, fd, profileType); 13962 fd = null; 13963 mProfileFd = null; 13964 } else { 13965 stopProfilerLocked(proc, path, profileType); 13966 if (fd != null) { 13967 try { 13968 fd.close(); 13969 } catch (IOException e) { 13970 } 13971 } 13972 } 13973 13974 return true; 13975 } 13976 } catch (RemoteException e) { 13977 throw new IllegalStateException("Process disappeared"); 13978 } finally { 13979 if (fd != null) { 13980 try { 13981 fd.close(); 13982 } catch (IOException e) { 13983 } 13984 } 13985 } 13986 } 13987 13988 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13989 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13990 userId, true, true, callName, null); 13991 ProcessRecord proc = null; 13992 try { 13993 int pid = Integer.parseInt(process); 13994 synchronized (mPidsSelfLocked) { 13995 proc = mPidsSelfLocked.get(pid); 13996 } 13997 } catch (NumberFormatException e) { 13998 } 13999 14000 if (proc == null) { 14001 HashMap<String, SparseArray<ProcessRecord>> all 14002 = mProcessNames.getMap(); 14003 SparseArray<ProcessRecord> procs = all.get(process); 14004 if (procs != null && procs.size() > 0) { 14005 proc = procs.valueAt(0); 14006 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14007 for (int i=1; i<procs.size(); i++) { 14008 ProcessRecord thisProc = procs.valueAt(i); 14009 if (thisProc.userId == userId) { 14010 proc = thisProc; 14011 break; 14012 } 14013 } 14014 } 14015 } 14016 } 14017 14018 return proc; 14019 } 14020 14021 public boolean dumpHeap(String process, int userId, boolean managed, 14022 String path, ParcelFileDescriptor fd) throws RemoteException { 14023 14024 try { 14025 synchronized (this) { 14026 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14027 // its own permission (same as profileControl). 14028 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14029 != PackageManager.PERMISSION_GRANTED) { 14030 throw new SecurityException("Requires permission " 14031 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14032 } 14033 14034 if (fd == null) { 14035 throw new IllegalArgumentException("null fd"); 14036 } 14037 14038 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14039 if (proc == null || proc.thread == null) { 14040 throw new IllegalArgumentException("Unknown process: " + process); 14041 } 14042 14043 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14044 if (!isDebuggable) { 14045 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14046 throw new SecurityException("Process not debuggable: " + proc); 14047 } 14048 } 14049 14050 proc.thread.dumpHeap(managed, path, fd); 14051 fd = null; 14052 return true; 14053 } 14054 } catch (RemoteException e) { 14055 throw new IllegalStateException("Process disappeared"); 14056 } finally { 14057 if (fd != null) { 14058 try { 14059 fd.close(); 14060 } catch (IOException e) { 14061 } 14062 } 14063 } 14064 } 14065 14066 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14067 public void monitor() { 14068 synchronized (this) { } 14069 } 14070 14071 void onCoreSettingsChange(Bundle settings) { 14072 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14073 ProcessRecord processRecord = mLruProcesses.get(i); 14074 try { 14075 if (processRecord.thread != null) { 14076 processRecord.thread.setCoreSettings(settings); 14077 } 14078 } catch (RemoteException re) { 14079 /* ignore */ 14080 } 14081 } 14082 } 14083 14084 // Multi-user methods 14085 14086 @Override 14087 public boolean switchUser(int userId) { 14088 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14089 != PackageManager.PERMISSION_GRANTED) { 14090 String msg = "Permission Denial: switchUser() from pid=" 14091 + Binder.getCallingPid() 14092 + ", uid=" + Binder.getCallingUid() 14093 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14094 Slog.w(TAG, msg); 14095 throw new SecurityException(msg); 14096 } 14097 14098 final long ident = Binder.clearCallingIdentity(); 14099 try { 14100 synchronized (this) { 14101 final int oldUserId = mCurrentUserId; 14102 if (oldUserId == userId) { 14103 return true; 14104 } 14105 14106 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14107 if (userInfo == null) { 14108 Slog.w(TAG, "No user info for user #" + userId); 14109 return false; 14110 } 14111 14112 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14113 R.anim.screen_user_enter); 14114 14115 // If the user we are switching to is not currently started, then 14116 // we need to start it now. 14117 if (mStartedUsers.get(userId) == null) { 14118 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14119 updateStartedUserArrayLocked(); 14120 } 14121 14122 mCurrentUserId = userId; 14123 mCurrentUserArray = new int[] { userId }; 14124 final Integer userIdInt = Integer.valueOf(userId); 14125 mUserLru.remove(userIdInt); 14126 mUserLru.add(userIdInt); 14127 14128 mWindowManager.setCurrentUser(userId); 14129 14130 // Once the internal notion of the active user has switched, we lock the device 14131 // with the option to show the user switcher on the keyguard. 14132 mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS); 14133 14134 final UserStartedState uss = mStartedUsers.get(userId); 14135 14136 // Make sure user is in the started state. If it is currently 14137 // stopping, we need to knock that off. 14138 if (uss.mState == UserStartedState.STATE_STOPPING) { 14139 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 14140 // so we can just fairly silently bring the user back from 14141 // the almost-dead. 14142 uss.mState = UserStartedState.STATE_RUNNING; 14143 updateStartedUserArrayLocked(); 14144 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 14145 // This means ACTION_SHUTDOWN has been sent, so we will 14146 // need to treat this as a new boot of the user. 14147 uss.mState = UserStartedState.STATE_BOOTING; 14148 updateStartedUserArrayLocked(); 14149 } 14150 14151 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14152 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14153 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14154 oldUserId, userId, uss)); 14155 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14156 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14157 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14158 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14159 | Intent.FLAG_RECEIVER_FOREGROUND); 14160 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14161 broadcastIntentLocked(null, null, intent, 14162 null, null, 0, null, null, null, 14163 false, false, MY_PID, Process.SYSTEM_UID, userId); 14164 14165 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14166 if (userId != 0) { 14167 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14168 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14169 broadcastIntentLocked(null, null, intent, null, 14170 new IIntentReceiver.Stub() { 14171 public void performReceive(Intent intent, int resultCode, 14172 String data, Bundle extras, boolean ordered, 14173 boolean sticky, int sendingUser) { 14174 userInitialized(uss); 14175 } 14176 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14177 userId); 14178 uss.initializing = true; 14179 } else { 14180 getUserManagerLocked().makeInitialized(userInfo.id); 14181 } 14182 } 14183 14184 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14185 if (!haveActivities) { 14186 startHomeActivityLocked(userId); 14187 } 14188 14189 getUserManagerLocked().userForeground(userId); 14190 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14191 } 14192 } finally { 14193 Binder.restoreCallingIdentity(ident); 14194 } 14195 14196 return true; 14197 } 14198 14199 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14200 long ident = Binder.clearCallingIdentity(); 14201 try { 14202 Intent intent; 14203 if (oldUserId >= 0) { 14204 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14205 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14206 | Intent.FLAG_RECEIVER_FOREGROUND); 14207 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14208 broadcastIntentLocked(null, null, intent, 14209 null, null, 0, null, null, null, 14210 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14211 } 14212 if (newUserId >= 0) { 14213 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14214 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14215 | Intent.FLAG_RECEIVER_FOREGROUND); 14216 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14217 broadcastIntentLocked(null, null, intent, 14218 null, null, 0, null, null, null, 14219 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14220 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14221 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14222 | Intent.FLAG_RECEIVER_FOREGROUND); 14223 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14224 broadcastIntentLocked(null, null, intent, 14225 null, null, 0, null, null, 14226 android.Manifest.permission.MANAGE_USERS, 14227 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14228 intent = new Intent(Intent.ACTION_USER_STARTING); 14229 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14230 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14231 broadcastIntentLocked(null, null, intent, 14232 null, new IIntentReceiver.Stub() { 14233 @Override 14234 public void performReceive(Intent intent, int resultCode, String data, 14235 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14236 throws RemoteException { 14237 } 14238 }, 0, null, null, 14239 android.Manifest.permission.INTERACT_ACROSS_USERS, 14240 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14241 } 14242 } finally { 14243 Binder.restoreCallingIdentity(ident); 14244 } 14245 } 14246 14247 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14248 final int newUserId) { 14249 final int N = mUserSwitchObservers.beginBroadcast(); 14250 if (N > 0) { 14251 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14252 int mCount = 0; 14253 @Override 14254 public void sendResult(Bundle data) throws RemoteException { 14255 synchronized (ActivityManagerService.this) { 14256 if (mCurUserSwitchCallback == this) { 14257 mCount++; 14258 if (mCount == N) { 14259 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14260 } 14261 } 14262 } 14263 } 14264 }; 14265 synchronized (this) { 14266 uss.switching = true; 14267 mCurUserSwitchCallback = callback; 14268 } 14269 for (int i=0; i<N; i++) { 14270 try { 14271 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14272 newUserId, callback); 14273 } catch (RemoteException e) { 14274 } 14275 } 14276 } else { 14277 synchronized (this) { 14278 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14279 } 14280 } 14281 mUserSwitchObservers.finishBroadcast(); 14282 } 14283 14284 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14285 synchronized (this) { 14286 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14287 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14288 } 14289 } 14290 14291 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14292 mCurUserSwitchCallback = null; 14293 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14294 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14295 oldUserId, newUserId, uss)); 14296 } 14297 14298 void userInitialized(UserStartedState uss) { 14299 synchronized (ActivityManagerService.this) { 14300 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14301 uss.initializing = false; 14302 completeSwitchAndInitalizeLocked(uss); 14303 } 14304 } 14305 14306 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14307 final int N = mUserSwitchObservers.beginBroadcast(); 14308 for (int i=0; i<N; i++) { 14309 try { 14310 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14311 } catch (RemoteException e) { 14312 } 14313 } 14314 mUserSwitchObservers.finishBroadcast(); 14315 synchronized (this) { 14316 uss.switching = false; 14317 completeSwitchAndInitalizeLocked(uss); 14318 } 14319 } 14320 14321 void completeSwitchAndInitalizeLocked(UserStartedState uss) { 14322 if (!uss.switching && !uss.initializing) { 14323 mWindowManager.stopFreezingScreen(); 14324 } 14325 } 14326 14327 void finishUserSwitch(UserStartedState uss) { 14328 synchronized (this) { 14329 if (uss.mState == UserStartedState.STATE_BOOTING 14330 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14331 uss.mState = UserStartedState.STATE_RUNNING; 14332 final int userId = uss.mHandle.getIdentifier(); 14333 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14334 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14335 broadcastIntentLocked(null, null, intent, 14336 null, null, 0, null, null, 14337 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14338 false, false, MY_PID, Process.SYSTEM_UID, userId); 14339 } 14340 int num = mUserLru.size(); 14341 int i = 0; 14342 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14343 Integer oldUserId = mUserLru.get(i); 14344 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14345 if (oldUss == null) { 14346 // Shouldn't happen, but be sane if it does. 14347 mUserLru.remove(i); 14348 num--; 14349 continue; 14350 } 14351 if (oldUss.mState == UserStartedState.STATE_STOPPING 14352 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 14353 // This user is already stopping, doesn't count. 14354 num--; 14355 i++; 14356 continue; 14357 } 14358 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14359 // Owner and current can't be stopped, but count as running. 14360 i++; 14361 continue; 14362 } 14363 // This is a user to be stopped. 14364 stopUserLocked(oldUserId, null); 14365 num--; 14366 i++; 14367 } 14368 } 14369 } 14370 14371 @Override 14372 public int stopUser(final int userId, final IStopUserCallback callback) { 14373 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14374 != PackageManager.PERMISSION_GRANTED) { 14375 String msg = "Permission Denial: switchUser() from pid=" 14376 + Binder.getCallingPid() 14377 + ", uid=" + Binder.getCallingUid() 14378 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14379 Slog.w(TAG, msg); 14380 throw new SecurityException(msg); 14381 } 14382 if (userId <= 0) { 14383 throw new IllegalArgumentException("Can't stop primary user " + userId); 14384 } 14385 synchronized (this) { 14386 return stopUserLocked(userId, callback); 14387 } 14388 } 14389 14390 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14391 if (mCurrentUserId == userId) { 14392 return ActivityManager.USER_OP_IS_CURRENT; 14393 } 14394 14395 final UserStartedState uss = mStartedUsers.get(userId); 14396 if (uss == null) { 14397 // User is not started, nothing to do... but we do need to 14398 // callback if requested. 14399 if (callback != null) { 14400 mHandler.post(new Runnable() { 14401 @Override 14402 public void run() { 14403 try { 14404 callback.userStopped(userId); 14405 } catch (RemoteException e) { 14406 } 14407 } 14408 }); 14409 } 14410 return ActivityManager.USER_OP_SUCCESS; 14411 } 14412 14413 if (callback != null) { 14414 uss.mStopCallbacks.add(callback); 14415 } 14416 14417 if (uss.mState != UserStartedState.STATE_STOPPING 14418 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14419 uss.mState = UserStartedState.STATE_STOPPING; 14420 updateStartedUserArrayLocked(); 14421 14422 long ident = Binder.clearCallingIdentity(); 14423 try { 14424 // We are going to broadcast ACTION_USER_STOPPING and then 14425 // once that is down send a final ACTION_SHUTDOWN and then 14426 // stop the user. 14427 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 14428 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14429 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14430 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 14431 // This is the result receiver for the final shutdown broadcast. 14432 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 14433 @Override 14434 public void performReceive(Intent intent, int resultCode, String data, 14435 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14436 finishUserStop(uss); 14437 } 14438 }; 14439 // This is the result receiver for the initial stopping broadcast. 14440 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 14441 @Override 14442 public void performReceive(Intent intent, int resultCode, String data, 14443 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14444 // On to the next. 14445 synchronized (ActivityManagerService.this) { 14446 if (uss.mState != UserStartedState.STATE_STOPPING) { 14447 // Whoops, we are being started back up. Abort, abort! 14448 return; 14449 } 14450 uss.mState = UserStartedState.STATE_SHUTDOWN; 14451 } 14452 broadcastIntentLocked(null, null, shutdownIntent, 14453 null, shutdownReceiver, 0, null, null, null, 14454 true, false, MY_PID, Process.SYSTEM_UID, userId); 14455 } 14456 }; 14457 // Kick things off. 14458 broadcastIntentLocked(null, null, stoppingIntent, 14459 null, stoppingReceiver, 0, null, null, 14460 android.Manifest.permission.INTERACT_ACROSS_USERS, 14461 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14462 } finally { 14463 Binder.restoreCallingIdentity(ident); 14464 } 14465 } 14466 14467 return ActivityManager.USER_OP_SUCCESS; 14468 } 14469 14470 void finishUserStop(UserStartedState uss) { 14471 final int userId = uss.mHandle.getIdentifier(); 14472 boolean stopped; 14473 ArrayList<IStopUserCallback> callbacks; 14474 synchronized (this) { 14475 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14476 if (mStartedUsers.get(userId) != uss) { 14477 stopped = false; 14478 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 14479 stopped = false; 14480 } else { 14481 stopped = true; 14482 // User can no longer run. 14483 mStartedUsers.remove(userId); 14484 mUserLru.remove(Integer.valueOf(userId)); 14485 updateStartedUserArrayLocked(); 14486 14487 // Clean up all state and processes associated with the user. 14488 // Kill all the processes for the user. 14489 forceStopUserLocked(userId); 14490 } 14491 } 14492 14493 for (int i=0; i<callbacks.size(); i++) { 14494 try { 14495 if (stopped) callbacks.get(i).userStopped(userId); 14496 else callbacks.get(i).userStopAborted(userId); 14497 } catch (RemoteException e) { 14498 } 14499 } 14500 } 14501 14502 @Override 14503 public UserInfo getCurrentUser() { 14504 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14505 != PackageManager.PERMISSION_GRANTED) && ( 14506 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14507 != PackageManager.PERMISSION_GRANTED)) { 14508 String msg = "Permission Denial: getCurrentUser() from pid=" 14509 + Binder.getCallingPid() 14510 + ", uid=" + Binder.getCallingUid() 14511 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14512 Slog.w(TAG, msg); 14513 throw new SecurityException(msg); 14514 } 14515 synchronized (this) { 14516 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14517 } 14518 } 14519 14520 int getCurrentUserIdLocked() { 14521 return mCurrentUserId; 14522 } 14523 14524 @Override 14525 public boolean isUserRunning(int userId, boolean orStopped) { 14526 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14527 != PackageManager.PERMISSION_GRANTED) { 14528 String msg = "Permission Denial: isUserRunning() from pid=" 14529 + Binder.getCallingPid() 14530 + ", uid=" + Binder.getCallingUid() 14531 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14532 Slog.w(TAG, msg); 14533 throw new SecurityException(msg); 14534 } 14535 synchronized (this) { 14536 return isUserRunningLocked(userId, orStopped); 14537 } 14538 } 14539 14540 boolean isUserRunningLocked(int userId, boolean orStopped) { 14541 UserStartedState state = mStartedUsers.get(userId); 14542 if (state == null) { 14543 return false; 14544 } 14545 if (orStopped) { 14546 return true; 14547 } 14548 return state.mState != UserStartedState.STATE_STOPPING 14549 && state.mState != UserStartedState.STATE_SHUTDOWN; 14550 } 14551 14552 @Override 14553 public int[] getRunningUserIds() { 14554 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14555 != PackageManager.PERMISSION_GRANTED) { 14556 String msg = "Permission Denial: isUserRunning() from pid=" 14557 + Binder.getCallingPid() 14558 + ", uid=" + Binder.getCallingUid() 14559 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14560 Slog.w(TAG, msg); 14561 throw new SecurityException(msg); 14562 } 14563 synchronized (this) { 14564 return mStartedUserArray; 14565 } 14566 } 14567 14568 private void updateStartedUserArrayLocked() { 14569 int num = 0; 14570 for (int i=0; i<mStartedUsers.size(); i++) { 14571 UserStartedState uss = mStartedUsers.valueAt(i); 14572 // This list does not include stopping users. 14573 if (uss.mState != UserStartedState.STATE_STOPPING 14574 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14575 num++; 14576 } 14577 } 14578 mStartedUserArray = new int[num]; 14579 num = 0; 14580 for (int i=0; i<mStartedUsers.size(); i++) { 14581 UserStartedState uss = mStartedUsers.valueAt(i); 14582 if (uss.mState != UserStartedState.STATE_STOPPING 14583 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14584 mStartedUserArray[num] = mStartedUsers.keyAt(i); 14585 num++; 14586 } 14587 } 14588 } 14589 14590 @Override 14591 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14592 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14593 != PackageManager.PERMISSION_GRANTED) { 14594 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14595 + Binder.getCallingPid() 14596 + ", uid=" + Binder.getCallingUid() 14597 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14598 Slog.w(TAG, msg); 14599 throw new SecurityException(msg); 14600 } 14601 14602 mUserSwitchObservers.register(observer); 14603 } 14604 14605 @Override 14606 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14607 mUserSwitchObservers.unregister(observer); 14608 } 14609 14610 private boolean userExists(int userId) { 14611 if (userId == 0) { 14612 return true; 14613 } 14614 UserManagerService ums = getUserManagerLocked(); 14615 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14616 } 14617 14618 int[] getUsersLocked() { 14619 UserManagerService ums = getUserManagerLocked(); 14620 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14621 } 14622 14623 UserManagerService getUserManagerLocked() { 14624 if (mUserManager == null) { 14625 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14626 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14627 } 14628 return mUserManager; 14629 } 14630 14631 private void checkValidCaller(int uid, int userId) { 14632 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14633 14634 throw new SecurityException("Caller uid=" + uid 14635 + " is not privileged to communicate with user=" + userId); 14636 } 14637 14638 private int applyUserId(int uid, int userId) { 14639 return UserHandle.getUid(userId, uid); 14640 } 14641 14642 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14643 if (info == null) return null; 14644 ApplicationInfo newInfo = new ApplicationInfo(info); 14645 newInfo.uid = applyUserId(info.uid, userId); 14646 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14647 + info.packageName; 14648 return newInfo; 14649 } 14650 14651 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14652 if (aInfo == null 14653 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14654 return aInfo; 14655 } 14656 14657 ActivityInfo info = new ActivityInfo(aInfo); 14658 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14659 return info; 14660 } 14661} 14662