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.FLAG_RECEIVER_FOREGROUND); 3744 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3745 broadcastIntentLocked(null, null, intent, 3746 null, null, 0, null, null, null, 3747 false, false, 3748 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3749 } 3750 3751 private final boolean killPackageProcessesLocked(String packageName, int appId, 3752 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3753 boolean doit, boolean evenPersistent, String reason) { 3754 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3755 3756 // Remove all processes this package may have touched: all with the 3757 // same UID (except for the system or root user), and all whose name 3758 // matches the package name. 3759 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3760 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3761 final int NA = apps.size(); 3762 for (int ia=0; ia<NA; ia++) { 3763 ProcessRecord app = apps.valueAt(ia); 3764 if (app.persistent && !evenPersistent) { 3765 // we don't kill persistent processes 3766 continue; 3767 } 3768 if (app.removed) { 3769 if (doit) { 3770 procs.add(app); 3771 } 3772 continue; 3773 } 3774 3775 // Skip process if it doesn't meet our oom adj requirement. 3776 if (app.setAdj < minOomAdj) { 3777 continue; 3778 } 3779 3780 // If no package is specified, we call all processes under the 3781 // give user id. 3782 if (packageName == null) { 3783 if (app.userId != userId) { 3784 continue; 3785 } 3786 // Package has been specified, we want to hit all processes 3787 // that match it. We need to qualify this by the processes 3788 // that are running under the specified app and user ID. 3789 } else { 3790 if (UserHandle.getAppId(app.uid) != appId) { 3791 continue; 3792 } 3793 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3794 continue; 3795 } 3796 if (!app.pkgList.contains(packageName)) { 3797 continue; 3798 } 3799 } 3800 3801 // Process has passed all conditions, kill it! 3802 if (!doit) { 3803 return true; 3804 } 3805 app.removed = true; 3806 procs.add(app); 3807 } 3808 } 3809 3810 int N = procs.size(); 3811 for (int i=0; i<N; i++) { 3812 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3813 } 3814 return N > 0; 3815 } 3816 3817 private final boolean forceStopPackageLocked(String name, int appId, 3818 boolean callerWillRestart, boolean purgeCache, boolean doit, 3819 boolean evenPersistent, int userId) { 3820 int i; 3821 int N; 3822 3823 if (userId == UserHandle.USER_ALL && name == null) { 3824 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3825 } 3826 3827 if (appId < 0 && name != null) { 3828 try { 3829 appId = UserHandle.getAppId( 3830 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3831 } catch (RemoteException e) { 3832 } 3833 } 3834 3835 if (doit) { 3836 if (name != null) { 3837 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3838 + " user=" + userId); 3839 } else { 3840 Slog.i(TAG, "Force stopping user " + userId); 3841 } 3842 3843 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3844 while (badApps.hasNext()) { 3845 SparseArray<Long> ba = badApps.next(); 3846 for (i=ba.size()-1; i>=0; i--) { 3847 boolean remove = false; 3848 final int entUid = ba.keyAt(i); 3849 if (name != null) { 3850 if (userId == UserHandle.USER_ALL) { 3851 if (UserHandle.getAppId(entUid) == appId) { 3852 remove = true; 3853 } 3854 } else { 3855 if (entUid == UserHandle.getUid(userId, appId)) { 3856 remove = true; 3857 } 3858 } 3859 } else if (UserHandle.getUserId(entUid) == userId) { 3860 remove = true; 3861 } 3862 if (remove) { 3863 ba.removeAt(i); 3864 } 3865 } 3866 if (ba.size() == 0) { 3867 badApps.remove(); 3868 } 3869 } 3870 } 3871 3872 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3873 -100, callerWillRestart, false, doit, evenPersistent, 3874 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3875 3876 TaskRecord lastTask = null; 3877 for (i=0; i<mMainStack.mHistory.size(); i++) { 3878 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3879 final boolean samePackage = r.packageName.equals(name) 3880 || (name == null && r.userId == userId); 3881 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3882 && (samePackage || r.task == lastTask) 3883 && (r.app == null || evenPersistent || !r.app.persistent)) { 3884 if (!doit) { 3885 if (r.finishing) { 3886 // If this activity is just finishing, then it is not 3887 // interesting as far as something to stop. 3888 continue; 3889 } 3890 return true; 3891 } 3892 didSomething = true; 3893 Slog.i(TAG, " Force finishing activity " + r); 3894 if (samePackage) { 3895 if (r.app != null) { 3896 r.app.removed = true; 3897 } 3898 r.app = null; 3899 } 3900 lastTask = r.task; 3901 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3902 null, "force-stop", true)) { 3903 i--; 3904 } 3905 } 3906 } 3907 3908 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3909 if (!doit) { 3910 return true; 3911 } 3912 didSomething = true; 3913 } 3914 3915 if (name == null) { 3916 // Remove all sticky broadcasts from this user. 3917 mStickyBroadcasts.remove(userId); 3918 } 3919 3920 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3921 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3922 userId, providers)) { 3923 if (!doit) { 3924 return true; 3925 } 3926 didSomething = true; 3927 } 3928 N = providers.size(); 3929 for (i=0; i<N; i++) { 3930 removeDyingProviderLocked(null, providers.get(i), true); 3931 } 3932 3933 if (name == null) { 3934 // Remove pending intents. For now we only do this when force 3935 // stopping users, because we have some problems when doing this 3936 // for packages -- app widgets are not currently cleaned up for 3937 // such packages, so they can be left with bad pending intents. 3938 if (mIntentSenderRecords.size() > 0) { 3939 Iterator<WeakReference<PendingIntentRecord>> it 3940 = mIntentSenderRecords.values().iterator(); 3941 while (it.hasNext()) { 3942 WeakReference<PendingIntentRecord> wpir = it.next(); 3943 if (wpir == null) { 3944 it.remove(); 3945 continue; 3946 } 3947 PendingIntentRecord pir = wpir.get(); 3948 if (pir == null) { 3949 it.remove(); 3950 continue; 3951 } 3952 if (name == null) { 3953 // Stopping user, remove all objects for the user. 3954 if (pir.key.userId != userId) { 3955 // Not the same user, skip it. 3956 continue; 3957 } 3958 } else { 3959 if (UserHandle.getAppId(pir.uid) != appId) { 3960 // Different app id, skip it. 3961 continue; 3962 } 3963 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3964 // Different user, skip it. 3965 continue; 3966 } 3967 if (!pir.key.packageName.equals(name)) { 3968 // Different package, skip it. 3969 continue; 3970 } 3971 } 3972 if (!doit) { 3973 return true; 3974 } 3975 didSomething = true; 3976 it.remove(); 3977 pir.canceled = true; 3978 if (pir.key.activity != null) { 3979 pir.key.activity.pendingResults.remove(pir.ref); 3980 } 3981 } 3982 } 3983 } 3984 3985 if (doit) { 3986 if (purgeCache && name != null) { 3987 AttributeCache ac = AttributeCache.instance(); 3988 if (ac != null) { 3989 ac.removePackage(name); 3990 } 3991 } 3992 if (mBooted) { 3993 mMainStack.resumeTopActivityLocked(null); 3994 mMainStack.scheduleIdleLocked(); 3995 } 3996 } 3997 3998 return didSomething; 3999 } 4000 4001 private final boolean removeProcessLocked(ProcessRecord app, 4002 boolean callerWillRestart, boolean allowRestart, String reason) { 4003 final String name = app.processName; 4004 final int uid = app.uid; 4005 if (DEBUG_PROCESSES) Slog.d( 4006 TAG, "Force removing proc " + app.toShortString() + " (" + name 4007 + "/" + uid + ")"); 4008 4009 mProcessNames.remove(name, uid); 4010 mIsolatedProcesses.remove(app.uid); 4011 if (mHeavyWeightProcess == app) { 4012 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4013 mHeavyWeightProcess.userId, 0)); 4014 mHeavyWeightProcess = null; 4015 } 4016 boolean needRestart = false; 4017 if (app.pid > 0 && app.pid != MY_PID) { 4018 int pid = app.pid; 4019 synchronized (mPidsSelfLocked) { 4020 mPidsSelfLocked.remove(pid); 4021 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4022 } 4023 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4024 handleAppDiedLocked(app, true, allowRestart); 4025 mLruProcesses.remove(app); 4026 Process.killProcessQuiet(pid); 4027 4028 if (app.persistent && !app.isolated) { 4029 if (!callerWillRestart) { 4030 addAppLocked(app.info, false); 4031 } else { 4032 needRestart = true; 4033 } 4034 } 4035 } else { 4036 mRemovedProcesses.add(app); 4037 } 4038 4039 return needRestart; 4040 } 4041 4042 private final void processStartTimedOutLocked(ProcessRecord app) { 4043 final int pid = app.pid; 4044 boolean gone = false; 4045 synchronized (mPidsSelfLocked) { 4046 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4047 if (knownApp != null && knownApp.thread == null) { 4048 mPidsSelfLocked.remove(pid); 4049 gone = true; 4050 } 4051 } 4052 4053 if (gone) { 4054 Slog.w(TAG, "Process " + app + " failed to attach"); 4055 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4056 pid, app.uid, app.processName); 4057 mProcessNames.remove(app.processName, app.uid); 4058 mIsolatedProcesses.remove(app.uid); 4059 if (mHeavyWeightProcess == app) { 4060 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4061 mHeavyWeightProcess.userId, 0)); 4062 mHeavyWeightProcess = null; 4063 } 4064 // Take care of any launching providers waiting for this process. 4065 checkAppInLaunchingProvidersLocked(app, true); 4066 // Take care of any services that are waiting for the process. 4067 mServices.processStartTimedOutLocked(app); 4068 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4069 app.processName, app.setAdj, "start timeout"); 4070 Process.killProcessQuiet(pid); 4071 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4072 Slog.w(TAG, "Unattached app died before backup, skipping"); 4073 try { 4074 IBackupManager bm = IBackupManager.Stub.asInterface( 4075 ServiceManager.getService(Context.BACKUP_SERVICE)); 4076 bm.agentDisconnected(app.info.packageName); 4077 } catch (RemoteException e) { 4078 // Can't happen; the backup manager is local 4079 } 4080 } 4081 if (isPendingBroadcastProcessLocked(pid)) { 4082 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4083 skipPendingBroadcastLocked(pid); 4084 } 4085 } else { 4086 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4087 } 4088 } 4089 4090 private final boolean attachApplicationLocked(IApplicationThread thread, 4091 int pid) { 4092 4093 // Find the application record that is being attached... either via 4094 // the pid if we are running in multiple processes, or just pull the 4095 // next app record if we are emulating process with anonymous threads. 4096 ProcessRecord app; 4097 if (pid != MY_PID && pid >= 0) { 4098 synchronized (mPidsSelfLocked) { 4099 app = mPidsSelfLocked.get(pid); 4100 } 4101 } else { 4102 app = null; 4103 } 4104 4105 if (app == null) { 4106 Slog.w(TAG, "No pending application record for pid " + pid 4107 + " (IApplicationThread " + thread + "); dropping process"); 4108 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4109 if (pid > 0 && pid != MY_PID) { 4110 Process.killProcessQuiet(pid); 4111 } else { 4112 try { 4113 thread.scheduleExit(); 4114 } catch (Exception e) { 4115 // Ignore exceptions. 4116 } 4117 } 4118 return false; 4119 } 4120 4121 // If this application record is still attached to a previous 4122 // process, clean it up now. 4123 if (app.thread != null) { 4124 handleAppDiedLocked(app, true, true); 4125 } 4126 4127 // Tell the process all about itself. 4128 4129 if (localLOGV) Slog.v( 4130 TAG, "Binding process pid " + pid + " to record " + app); 4131 4132 String processName = app.processName; 4133 try { 4134 AppDeathRecipient adr = new AppDeathRecipient( 4135 app, pid, thread); 4136 thread.asBinder().linkToDeath(adr, 0); 4137 app.deathRecipient = adr; 4138 } catch (RemoteException e) { 4139 app.resetPackageList(); 4140 startProcessLocked(app, "link fail", processName); 4141 return false; 4142 } 4143 4144 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4145 4146 app.thread = thread; 4147 app.curAdj = app.setAdj = -100; 4148 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4149 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4150 app.forcingToForeground = null; 4151 app.foregroundServices = false; 4152 app.hasShownUi = false; 4153 app.debugging = false; 4154 4155 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4156 4157 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4158 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4159 4160 if (!normalMode) { 4161 Slog.i(TAG, "Launching preboot mode app: " + app); 4162 } 4163 4164 if (localLOGV) Slog.v( 4165 TAG, "New app record " + app 4166 + " thread=" + thread.asBinder() + " pid=" + pid); 4167 try { 4168 int testMode = IApplicationThread.DEBUG_OFF; 4169 if (mDebugApp != null && mDebugApp.equals(processName)) { 4170 testMode = mWaitForDebugger 4171 ? IApplicationThread.DEBUG_WAIT 4172 : IApplicationThread.DEBUG_ON; 4173 app.debugging = true; 4174 if (mDebugTransient) { 4175 mDebugApp = mOrigDebugApp; 4176 mWaitForDebugger = mOrigWaitForDebugger; 4177 } 4178 } 4179 String profileFile = app.instrumentationProfileFile; 4180 ParcelFileDescriptor profileFd = null; 4181 boolean profileAutoStop = false; 4182 if (mProfileApp != null && mProfileApp.equals(processName)) { 4183 mProfileProc = app; 4184 profileFile = mProfileFile; 4185 profileFd = mProfileFd; 4186 profileAutoStop = mAutoStopProfiler; 4187 } 4188 boolean enableOpenGlTrace = false; 4189 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4190 enableOpenGlTrace = true; 4191 mOpenGlTraceApp = null; 4192 } 4193 4194 // If the app is being launched for restore or full backup, set it up specially 4195 boolean isRestrictedBackupMode = false; 4196 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4197 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4198 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4199 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4200 } 4201 4202 ensurePackageDexOpt(app.instrumentationInfo != null 4203 ? app.instrumentationInfo.packageName 4204 : app.info.packageName); 4205 if (app.instrumentationClass != null) { 4206 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4207 } 4208 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4209 + processName + " with config " + mConfiguration); 4210 ApplicationInfo appInfo = app.instrumentationInfo != null 4211 ? app.instrumentationInfo : app.info; 4212 app.compat = compatibilityInfoForPackageLocked(appInfo); 4213 if (profileFd != null) { 4214 profileFd = profileFd.dup(); 4215 } 4216 thread.bindApplication(processName, appInfo, providers, 4217 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4218 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4219 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4220 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4221 mCoreSettingsObserver.getCoreSettingsLocked()); 4222 updateLruProcessLocked(app, false); 4223 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4224 } catch (Exception e) { 4225 // todo: Yikes! What should we do? For now we will try to 4226 // start another process, but that could easily get us in 4227 // an infinite loop of restarting processes... 4228 Slog.w(TAG, "Exception thrown during bind!", e); 4229 4230 app.resetPackageList(); 4231 app.unlinkDeathRecipient(); 4232 startProcessLocked(app, "bind fail", processName); 4233 return false; 4234 } 4235 4236 // Remove this record from the list of starting applications. 4237 mPersistentStartingProcesses.remove(app); 4238 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4239 "Attach application locked removing on hold: " + app); 4240 mProcessesOnHold.remove(app); 4241 4242 boolean badApp = false; 4243 boolean didSomething = false; 4244 4245 // See if the top visible activity is waiting to run in this process... 4246 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4247 if (hr != null && normalMode) { 4248 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4249 && processName.equals(hr.processName)) { 4250 try { 4251 if (mHeadless) { 4252 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4253 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4254 didSomething = true; 4255 } 4256 } catch (Exception e) { 4257 Slog.w(TAG, "Exception in new application when starting activity " 4258 + hr.intent.getComponent().flattenToShortString(), e); 4259 badApp = true; 4260 } 4261 } else { 4262 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4263 } 4264 } 4265 4266 // Find any services that should be running in this process... 4267 if (!badApp) { 4268 try { 4269 didSomething |= mServices.attachApplicationLocked(app, processName); 4270 } catch (Exception e) { 4271 badApp = true; 4272 } 4273 } 4274 4275 // Check if a next-broadcast receiver is in this process... 4276 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4277 try { 4278 didSomething = sendPendingBroadcastsLocked(app); 4279 } catch (Exception e) { 4280 // If the app died trying to launch the receiver we declare it 'bad' 4281 badApp = true; 4282 } 4283 } 4284 4285 // Check whether the next backup agent is in this process... 4286 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4287 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4288 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4289 try { 4290 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4291 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4292 mBackupTarget.backupMode); 4293 } catch (Exception e) { 4294 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4295 e.printStackTrace(); 4296 } 4297 } 4298 4299 if (badApp) { 4300 // todo: Also need to kill application to deal with all 4301 // kinds of exceptions. 4302 handleAppDiedLocked(app, false, true); 4303 return false; 4304 } 4305 4306 if (!didSomething) { 4307 updateOomAdjLocked(); 4308 } 4309 4310 return true; 4311 } 4312 4313 public final void attachApplication(IApplicationThread thread) { 4314 synchronized (this) { 4315 int callingPid = Binder.getCallingPid(); 4316 final long origId = Binder.clearCallingIdentity(); 4317 attachApplicationLocked(thread, callingPid); 4318 Binder.restoreCallingIdentity(origId); 4319 } 4320 } 4321 4322 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4323 final long origId = Binder.clearCallingIdentity(); 4324 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4325 if (stopProfiling) { 4326 synchronized (this) { 4327 if (mProfileProc == r.app) { 4328 if (mProfileFd != null) { 4329 try { 4330 mProfileFd.close(); 4331 } catch (IOException e) { 4332 } 4333 clearProfilerLocked(); 4334 } 4335 } 4336 } 4337 } 4338 Binder.restoreCallingIdentity(origId); 4339 } 4340 4341 void enableScreenAfterBoot() { 4342 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4343 SystemClock.uptimeMillis()); 4344 mWindowManager.enableScreenAfterBoot(); 4345 4346 synchronized (this) { 4347 updateEventDispatchingLocked(); 4348 } 4349 } 4350 4351 public void showBootMessage(final CharSequence msg, final boolean always) { 4352 enforceNotIsolatedCaller("showBootMessage"); 4353 mWindowManager.showBootMessage(msg, always); 4354 } 4355 4356 public void dismissKeyguardOnNextActivity() { 4357 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4358 final long token = Binder.clearCallingIdentity(); 4359 try { 4360 synchronized (this) { 4361 if (mLockScreenShown) { 4362 mLockScreenShown = false; 4363 comeOutOfSleepIfNeededLocked(); 4364 } 4365 mMainStack.dismissKeyguardOnNextActivityLocked(); 4366 } 4367 } finally { 4368 Binder.restoreCallingIdentity(token); 4369 } 4370 } 4371 4372 final void finishBooting() { 4373 IntentFilter pkgFilter = new IntentFilter(); 4374 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4375 pkgFilter.addDataScheme("package"); 4376 mContext.registerReceiver(new BroadcastReceiver() { 4377 @Override 4378 public void onReceive(Context context, Intent intent) { 4379 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4380 if (pkgs != null) { 4381 for (String pkg : pkgs) { 4382 synchronized (ActivityManagerService.this) { 4383 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4384 setResultCode(Activity.RESULT_OK); 4385 return; 4386 } 4387 } 4388 } 4389 } 4390 } 4391 }, pkgFilter); 4392 4393 synchronized (this) { 4394 // Ensure that any processes we had put on hold are now started 4395 // up. 4396 final int NP = mProcessesOnHold.size(); 4397 if (NP > 0) { 4398 ArrayList<ProcessRecord> procs = 4399 new ArrayList<ProcessRecord>(mProcessesOnHold); 4400 for (int ip=0; ip<NP; ip++) { 4401 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4402 + procs.get(ip)); 4403 startProcessLocked(procs.get(ip), "on-hold", null); 4404 } 4405 } 4406 4407 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4408 // Start looking for apps that are abusing wake locks. 4409 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4410 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4411 // Tell anyone interested that we are done booting! 4412 SystemProperties.set("sys.boot_completed", "1"); 4413 SystemProperties.set("dev.bootcomplete", "1"); 4414 for (int i=0; i<mStartedUsers.size(); i++) { 4415 UserStartedState uss = mStartedUsers.valueAt(i); 4416 if (uss.mState == UserStartedState.STATE_BOOTING) { 4417 uss.mState = UserStartedState.STATE_RUNNING; 4418 final int userId = mStartedUsers.keyAt(i); 4419 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4420 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4421 broadcastIntentLocked(null, null, intent, 4422 null, null, 0, null, null, 4423 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4424 false, false, MY_PID, Process.SYSTEM_UID, userId); 4425 } 4426 } 4427 } 4428 } 4429 } 4430 4431 final void ensureBootCompleted() { 4432 boolean booting; 4433 boolean enableScreen; 4434 synchronized (this) { 4435 booting = mBooting; 4436 mBooting = false; 4437 enableScreen = !mBooted; 4438 mBooted = true; 4439 } 4440 4441 if (booting) { 4442 finishBooting(); 4443 } 4444 4445 if (enableScreen) { 4446 enableScreenAfterBoot(); 4447 } 4448 } 4449 4450 public final void activityResumed(IBinder token) { 4451 final long origId = Binder.clearCallingIdentity(); 4452 mMainStack.activityResumed(token); 4453 Binder.restoreCallingIdentity(origId); 4454 } 4455 4456 public final void activityPaused(IBinder token) { 4457 final long origId = Binder.clearCallingIdentity(); 4458 mMainStack.activityPaused(token, false); 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 4462 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4463 CharSequence description) { 4464 if (localLOGV) Slog.v( 4465 TAG, "Activity stopped: token=" + token); 4466 4467 // Refuse possible leaked file descriptors 4468 if (icicle != null && icicle.hasFileDescriptors()) { 4469 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4470 } 4471 4472 ActivityRecord r = null; 4473 4474 final long origId = Binder.clearCallingIdentity(); 4475 4476 synchronized (this) { 4477 r = mMainStack.isInStackLocked(token); 4478 if (r != null) { 4479 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4480 } 4481 } 4482 4483 if (r != null) { 4484 sendPendingThumbnail(r, null, null, null, false); 4485 } 4486 4487 trimApplications(); 4488 4489 Binder.restoreCallingIdentity(origId); 4490 } 4491 4492 public final void activityDestroyed(IBinder token) { 4493 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4494 mMainStack.activityDestroyed(token); 4495 } 4496 4497 public String getCallingPackage(IBinder token) { 4498 synchronized (this) { 4499 ActivityRecord r = getCallingRecordLocked(token); 4500 return r != null && r.app != null ? r.info.packageName : null; 4501 } 4502 } 4503 4504 public ComponentName getCallingActivity(IBinder token) { 4505 synchronized (this) { 4506 ActivityRecord r = getCallingRecordLocked(token); 4507 return r != null ? r.intent.getComponent() : null; 4508 } 4509 } 4510 4511 private ActivityRecord getCallingRecordLocked(IBinder token) { 4512 ActivityRecord r = mMainStack.isInStackLocked(token); 4513 if (r == null) { 4514 return null; 4515 } 4516 return r.resultTo; 4517 } 4518 4519 public ComponentName getActivityClassForToken(IBinder token) { 4520 synchronized(this) { 4521 ActivityRecord r = mMainStack.isInStackLocked(token); 4522 if (r == null) { 4523 return null; 4524 } 4525 return r.intent.getComponent(); 4526 } 4527 } 4528 4529 public String getPackageForToken(IBinder token) { 4530 synchronized(this) { 4531 ActivityRecord r = mMainStack.isInStackLocked(token); 4532 if (r == null) { 4533 return null; 4534 } 4535 return r.packageName; 4536 } 4537 } 4538 4539 public IIntentSender getIntentSender(int type, 4540 String packageName, IBinder token, String resultWho, 4541 int requestCode, Intent[] intents, String[] resolvedTypes, 4542 int flags, Bundle options, int userId) { 4543 enforceNotIsolatedCaller("getIntentSender"); 4544 // Refuse possible leaked file descriptors 4545 if (intents != null) { 4546 if (intents.length < 1) { 4547 throw new IllegalArgumentException("Intents array length must be >= 1"); 4548 } 4549 for (int i=0; i<intents.length; i++) { 4550 Intent intent = intents[i]; 4551 if (intent != null) { 4552 if (intent.hasFileDescriptors()) { 4553 throw new IllegalArgumentException("File descriptors passed in Intent"); 4554 } 4555 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4556 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4557 throw new IllegalArgumentException( 4558 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4559 } 4560 intents[i] = new Intent(intent); 4561 } 4562 } 4563 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4564 throw new IllegalArgumentException( 4565 "Intent array length does not match resolvedTypes length"); 4566 } 4567 } 4568 if (options != null) { 4569 if (options.hasFileDescriptors()) { 4570 throw new IllegalArgumentException("File descriptors passed in options"); 4571 } 4572 } 4573 4574 synchronized(this) { 4575 int callingUid = Binder.getCallingUid(); 4576 int origUserId = userId; 4577 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4578 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 4579 "getIntentSender", null); 4580 if (origUserId == UserHandle.USER_CURRENT) { 4581 // We don't want to evaluate this until the pending intent is 4582 // actually executed. However, we do want to always do the 4583 // security checking for it above. 4584 userId = UserHandle.USER_CURRENT; 4585 } 4586 try { 4587 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4588 int uid = AppGlobals.getPackageManager() 4589 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4590 if (!UserHandle.isSameApp(callingUid, uid)) { 4591 String msg = "Permission Denial: getIntentSender() from pid=" 4592 + Binder.getCallingPid() 4593 + ", uid=" + Binder.getCallingUid() 4594 + ", (need uid=" + uid + ")" 4595 + " is not allowed to send as package " + packageName; 4596 Slog.w(TAG, msg); 4597 throw new SecurityException(msg); 4598 } 4599 } 4600 4601 return getIntentSenderLocked(type, packageName, callingUid, userId, 4602 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4603 4604 } catch (RemoteException e) { 4605 throw new SecurityException(e); 4606 } 4607 } 4608 } 4609 4610 IIntentSender getIntentSenderLocked(int type, String packageName, 4611 int callingUid, int userId, IBinder token, String resultWho, 4612 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4613 Bundle options) { 4614 if (DEBUG_MU) 4615 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4616 ActivityRecord activity = null; 4617 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4618 activity = mMainStack.isInStackLocked(token); 4619 if (activity == null) { 4620 return null; 4621 } 4622 if (activity.finishing) { 4623 return null; 4624 } 4625 } 4626 4627 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4628 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4629 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4630 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4631 |PendingIntent.FLAG_UPDATE_CURRENT); 4632 4633 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4634 type, packageName, activity, resultWho, 4635 requestCode, intents, resolvedTypes, flags, options, userId); 4636 WeakReference<PendingIntentRecord> ref; 4637 ref = mIntentSenderRecords.get(key); 4638 PendingIntentRecord rec = ref != null ? ref.get() : null; 4639 if (rec != null) { 4640 if (!cancelCurrent) { 4641 if (updateCurrent) { 4642 if (rec.key.requestIntent != null) { 4643 rec.key.requestIntent.replaceExtras(intents != null ? 4644 intents[intents.length - 1] : null); 4645 } 4646 if (intents != null) { 4647 intents[intents.length-1] = rec.key.requestIntent; 4648 rec.key.allIntents = intents; 4649 rec.key.allResolvedTypes = resolvedTypes; 4650 } else { 4651 rec.key.allIntents = null; 4652 rec.key.allResolvedTypes = null; 4653 } 4654 } 4655 return rec; 4656 } 4657 rec.canceled = true; 4658 mIntentSenderRecords.remove(key); 4659 } 4660 if (noCreate) { 4661 return rec; 4662 } 4663 rec = new PendingIntentRecord(this, key, callingUid); 4664 mIntentSenderRecords.put(key, rec.ref); 4665 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4666 if (activity.pendingResults == null) { 4667 activity.pendingResults 4668 = new HashSet<WeakReference<PendingIntentRecord>>(); 4669 } 4670 activity.pendingResults.add(rec.ref); 4671 } 4672 return rec; 4673 } 4674 4675 public void cancelIntentSender(IIntentSender sender) { 4676 if (!(sender instanceof PendingIntentRecord)) { 4677 return; 4678 } 4679 synchronized(this) { 4680 PendingIntentRecord rec = (PendingIntentRecord)sender; 4681 try { 4682 int uid = AppGlobals.getPackageManager() 4683 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4684 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4685 String msg = "Permission Denial: cancelIntentSender() from pid=" 4686 + Binder.getCallingPid() 4687 + ", uid=" + Binder.getCallingUid() 4688 + " is not allowed to cancel packges " 4689 + rec.key.packageName; 4690 Slog.w(TAG, msg); 4691 throw new SecurityException(msg); 4692 } 4693 } catch (RemoteException e) { 4694 throw new SecurityException(e); 4695 } 4696 cancelIntentSenderLocked(rec, true); 4697 } 4698 } 4699 4700 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4701 rec.canceled = true; 4702 mIntentSenderRecords.remove(rec.key); 4703 if (cleanActivity && rec.key.activity != null) { 4704 rec.key.activity.pendingResults.remove(rec.ref); 4705 } 4706 } 4707 4708 public String getPackageForIntentSender(IIntentSender pendingResult) { 4709 if (!(pendingResult instanceof PendingIntentRecord)) { 4710 return null; 4711 } 4712 try { 4713 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4714 return res.key.packageName; 4715 } catch (ClassCastException e) { 4716 } 4717 return null; 4718 } 4719 4720 public int getUidForIntentSender(IIntentSender sender) { 4721 if (sender instanceof PendingIntentRecord) { 4722 try { 4723 PendingIntentRecord res = (PendingIntentRecord)sender; 4724 return res.uid; 4725 } catch (ClassCastException e) { 4726 } 4727 } 4728 return -1; 4729 } 4730 4731 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4732 if (!(pendingResult instanceof PendingIntentRecord)) { 4733 return false; 4734 } 4735 try { 4736 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4737 if (res.key.allIntents == null) { 4738 return false; 4739 } 4740 for (int i=0; i<res.key.allIntents.length; i++) { 4741 Intent intent = res.key.allIntents[i]; 4742 if (intent.getPackage() != null && intent.getComponent() != null) { 4743 return false; 4744 } 4745 } 4746 return true; 4747 } catch (ClassCastException e) { 4748 } 4749 return false; 4750 } 4751 4752 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4753 if (!(pendingResult instanceof PendingIntentRecord)) { 4754 return false; 4755 } 4756 try { 4757 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4758 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4759 return true; 4760 } 4761 return false; 4762 } catch (ClassCastException e) { 4763 } 4764 return false; 4765 } 4766 4767 public void setProcessLimit(int max) { 4768 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4769 "setProcessLimit()"); 4770 synchronized (this) { 4771 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4772 mProcessLimitOverride = max; 4773 } 4774 trimApplications(); 4775 } 4776 4777 public int getProcessLimit() { 4778 synchronized (this) { 4779 return mProcessLimitOverride; 4780 } 4781 } 4782 4783 void foregroundTokenDied(ForegroundToken token) { 4784 synchronized (ActivityManagerService.this) { 4785 synchronized (mPidsSelfLocked) { 4786 ForegroundToken cur 4787 = mForegroundProcesses.get(token.pid); 4788 if (cur != token) { 4789 return; 4790 } 4791 mForegroundProcesses.remove(token.pid); 4792 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4793 if (pr == null) { 4794 return; 4795 } 4796 pr.forcingToForeground = null; 4797 pr.foregroundServices = false; 4798 } 4799 updateOomAdjLocked(); 4800 } 4801 } 4802 4803 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4804 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4805 "setProcessForeground()"); 4806 synchronized(this) { 4807 boolean changed = false; 4808 4809 synchronized (mPidsSelfLocked) { 4810 ProcessRecord pr = mPidsSelfLocked.get(pid); 4811 if (pr == null && isForeground) { 4812 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4813 return; 4814 } 4815 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4816 if (oldToken != null) { 4817 oldToken.token.unlinkToDeath(oldToken, 0); 4818 mForegroundProcesses.remove(pid); 4819 if (pr != null) { 4820 pr.forcingToForeground = null; 4821 } 4822 changed = true; 4823 } 4824 if (isForeground && token != null) { 4825 ForegroundToken newToken = new ForegroundToken() { 4826 public void binderDied() { 4827 foregroundTokenDied(this); 4828 } 4829 }; 4830 newToken.pid = pid; 4831 newToken.token = token; 4832 try { 4833 token.linkToDeath(newToken, 0); 4834 mForegroundProcesses.put(pid, newToken); 4835 pr.forcingToForeground = token; 4836 changed = true; 4837 } catch (RemoteException e) { 4838 // If the process died while doing this, we will later 4839 // do the cleanup with the process death link. 4840 } 4841 } 4842 } 4843 4844 if (changed) { 4845 updateOomAdjLocked(); 4846 } 4847 } 4848 } 4849 4850 // ========================================================= 4851 // PERMISSIONS 4852 // ========================================================= 4853 4854 static class PermissionController extends IPermissionController.Stub { 4855 ActivityManagerService mActivityManagerService; 4856 PermissionController(ActivityManagerService activityManagerService) { 4857 mActivityManagerService = activityManagerService; 4858 } 4859 4860 public boolean checkPermission(String permission, int pid, int uid) { 4861 return mActivityManagerService.checkPermission(permission, pid, 4862 uid) == PackageManager.PERMISSION_GRANTED; 4863 } 4864 } 4865 4866 /** 4867 * This can be called with or without the global lock held. 4868 */ 4869 int checkComponentPermission(String permission, int pid, int uid, 4870 int owningUid, boolean exported) { 4871 // We might be performing an operation on behalf of an indirect binder 4872 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4873 // client identity accordingly before proceeding. 4874 Identity tlsIdentity = sCallerIdentity.get(); 4875 if (tlsIdentity != null) { 4876 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4877 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4878 uid = tlsIdentity.uid; 4879 pid = tlsIdentity.pid; 4880 } 4881 4882 if (pid == MY_PID) { 4883 return PackageManager.PERMISSION_GRANTED; 4884 } 4885 4886 return ActivityManager.checkComponentPermission(permission, uid, 4887 owningUid, exported); 4888 } 4889 4890 /** 4891 * As the only public entry point for permissions checking, this method 4892 * can enforce the semantic that requesting a check on a null global 4893 * permission is automatically denied. (Internally a null permission 4894 * string is used when calling {@link #checkComponentPermission} in cases 4895 * when only uid-based security is needed.) 4896 * 4897 * This can be called with or without the global lock held. 4898 */ 4899 public int checkPermission(String permission, int pid, int uid) { 4900 if (permission == null) { 4901 return PackageManager.PERMISSION_DENIED; 4902 } 4903 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4904 } 4905 4906 /** 4907 * Binder IPC calls go through the public entry point. 4908 * This can be called with or without the global lock held. 4909 */ 4910 int checkCallingPermission(String permission) { 4911 return checkPermission(permission, 4912 Binder.getCallingPid(), 4913 UserHandle.getAppId(Binder.getCallingUid())); 4914 } 4915 4916 /** 4917 * This can be called with or without the global lock held. 4918 */ 4919 void enforceCallingPermission(String permission, String func) { 4920 if (checkCallingPermission(permission) 4921 == PackageManager.PERMISSION_GRANTED) { 4922 return; 4923 } 4924 4925 String msg = "Permission Denial: " + func + " from pid=" 4926 + Binder.getCallingPid() 4927 + ", uid=" + Binder.getCallingUid() 4928 + " requires " + permission; 4929 Slog.w(TAG, msg); 4930 throw new SecurityException(msg); 4931 } 4932 4933 /** 4934 * Determine if UID is holding permissions required to access {@link Uri} in 4935 * the given {@link ProviderInfo}. Final permission checking is always done 4936 * in {@link ContentProvider}. 4937 */ 4938 private final boolean checkHoldingPermissionsLocked( 4939 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4940 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4941 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4942 4943 if (pi.applicationInfo.uid == uid) { 4944 return true; 4945 } else if (!pi.exported) { 4946 return false; 4947 } 4948 4949 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4950 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4951 try { 4952 // check if target holds top-level <provider> permissions 4953 if (!readMet && pi.readPermission != null 4954 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4955 readMet = true; 4956 } 4957 if (!writeMet && pi.writePermission != null 4958 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4959 writeMet = true; 4960 } 4961 4962 // track if unprotected read/write is allowed; any denied 4963 // <path-permission> below removes this ability 4964 boolean allowDefaultRead = pi.readPermission == null; 4965 boolean allowDefaultWrite = pi.writePermission == null; 4966 4967 // check if target holds any <path-permission> that match uri 4968 final PathPermission[] pps = pi.pathPermissions; 4969 if (pps != null) { 4970 final String path = uri.getPath(); 4971 int i = pps.length; 4972 while (i > 0 && (!readMet || !writeMet)) { 4973 i--; 4974 PathPermission pp = pps[i]; 4975 if (pp.match(path)) { 4976 if (!readMet) { 4977 final String pprperm = pp.getReadPermission(); 4978 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4979 + pprperm + " for " + pp.getPath() 4980 + ": match=" + pp.match(path) 4981 + " check=" + pm.checkUidPermission(pprperm, uid)); 4982 if (pprperm != null) { 4983 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4984 readMet = true; 4985 } else { 4986 allowDefaultRead = false; 4987 } 4988 } 4989 } 4990 if (!writeMet) { 4991 final String ppwperm = pp.getWritePermission(); 4992 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4993 + ppwperm + " for " + pp.getPath() 4994 + ": match=" + pp.match(path) 4995 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4996 if (ppwperm != null) { 4997 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4998 writeMet = true; 4999 } else { 5000 allowDefaultWrite = false; 5001 } 5002 } 5003 } 5004 } 5005 } 5006 } 5007 5008 // grant unprotected <provider> read/write, if not blocked by 5009 // <path-permission> above 5010 if (allowDefaultRead) readMet = true; 5011 if (allowDefaultWrite) writeMet = true; 5012 5013 } catch (RemoteException e) { 5014 return false; 5015 } 5016 5017 return readMet && writeMet; 5018 } 5019 5020 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5021 int modeFlags) { 5022 // Root gets to do everything. 5023 if (uid == 0) { 5024 return true; 5025 } 5026 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5027 if (perms == null) return false; 5028 UriPermission perm = perms.get(uri); 5029 if (perm == null) return false; 5030 return (modeFlags&perm.modeFlags) == modeFlags; 5031 } 5032 5033 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5034 enforceNotIsolatedCaller("checkUriPermission"); 5035 5036 // Another redirected-binder-call permissions check as in 5037 // {@link checkComponentPermission}. 5038 Identity tlsIdentity = sCallerIdentity.get(); 5039 if (tlsIdentity != null) { 5040 uid = tlsIdentity.uid; 5041 pid = tlsIdentity.pid; 5042 } 5043 5044 // Our own process gets to do everything. 5045 if (pid == MY_PID) { 5046 return PackageManager.PERMISSION_GRANTED; 5047 } 5048 synchronized(this) { 5049 return checkUriPermissionLocked(uri, uid, modeFlags) 5050 ? PackageManager.PERMISSION_GRANTED 5051 : PackageManager.PERMISSION_DENIED; 5052 } 5053 } 5054 5055 /** 5056 * Check if the targetPkg can be granted permission to access uri by 5057 * the callingUid using the given modeFlags. Throws a security exception 5058 * if callingUid is not allowed to do this. Returns the uid of the target 5059 * if the URI permission grant should be performed; returns -1 if it is not 5060 * needed (for example targetPkg already has permission to access the URI). 5061 * If you already know the uid of the target, you can supply it in 5062 * lastTargetUid else set that to -1. 5063 */ 5064 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5065 Uri uri, int modeFlags, int lastTargetUid) { 5066 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5067 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5068 if (modeFlags == 0) { 5069 return -1; 5070 } 5071 5072 if (targetPkg != null) { 5073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5074 "Checking grant " + targetPkg + " permission to " + uri); 5075 } 5076 5077 final IPackageManager pm = AppGlobals.getPackageManager(); 5078 5079 // If this is not a content: uri, we can't do anything with it. 5080 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5082 "Can't grant URI permission for non-content URI: " + uri); 5083 return -1; 5084 } 5085 5086 String name = uri.getAuthority(); 5087 ProviderInfo pi = null; 5088 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5089 UserHandle.getUserId(callingUid)); 5090 if (cpr != null) { 5091 pi = cpr.info; 5092 } else { 5093 try { 5094 pi = pm.resolveContentProvider(name, 5095 PackageManager.GET_URI_PERMISSION_PATTERNS, 5096 UserHandle.getUserId(callingUid)); 5097 } catch (RemoteException ex) { 5098 } 5099 } 5100 if (pi == null) { 5101 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5102 return -1; 5103 } 5104 5105 int targetUid = lastTargetUid; 5106 if (targetUid < 0 && targetPkg != null) { 5107 try { 5108 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5109 if (targetUid < 0) { 5110 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5111 "Can't grant URI permission no uid for: " + targetPkg); 5112 return -1; 5113 } 5114 } catch (RemoteException ex) { 5115 return -1; 5116 } 5117 } 5118 5119 if (targetUid >= 0) { 5120 // First... does the target actually need this permission? 5121 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5122 // No need to grant the target this permission. 5123 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5124 "Target " + targetPkg + " already has full permission to " + uri); 5125 return -1; 5126 } 5127 } else { 5128 // First... there is no target package, so can anyone access it? 5129 boolean allowed = pi.exported; 5130 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5131 if (pi.readPermission != null) { 5132 allowed = false; 5133 } 5134 } 5135 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5136 if (pi.writePermission != null) { 5137 allowed = false; 5138 } 5139 } 5140 if (allowed) { 5141 return -1; 5142 } 5143 } 5144 5145 // Second... is the provider allowing granting of URI permissions? 5146 if (!pi.grantUriPermissions) { 5147 throw new SecurityException("Provider " + pi.packageName 5148 + "/" + pi.name 5149 + " does not allow granting of Uri permissions (uri " 5150 + uri + ")"); 5151 } 5152 if (pi.uriPermissionPatterns != null) { 5153 final int N = pi.uriPermissionPatterns.length; 5154 boolean allowed = false; 5155 for (int i=0; i<N; i++) { 5156 if (pi.uriPermissionPatterns[i] != null 5157 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5158 allowed = true; 5159 break; 5160 } 5161 } 5162 if (!allowed) { 5163 throw new SecurityException("Provider " + pi.packageName 5164 + "/" + pi.name 5165 + " does not allow granting of permission to path of Uri " 5166 + uri); 5167 } 5168 } 5169 5170 // Third... does the caller itself have permission to access 5171 // this uri? 5172 if (callingUid != Process.myUid()) { 5173 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5174 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5175 throw new SecurityException("Uid " + callingUid 5176 + " does not have permission to uri " + uri); 5177 } 5178 } 5179 } 5180 5181 return targetUid; 5182 } 5183 5184 public int checkGrantUriPermission(int callingUid, String targetPkg, 5185 Uri uri, int modeFlags) { 5186 enforceNotIsolatedCaller("checkGrantUriPermission"); 5187 synchronized(this) { 5188 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5189 } 5190 } 5191 5192 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5193 Uri uri, int modeFlags, UriPermissionOwner owner) { 5194 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5195 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5196 if (modeFlags == 0) { 5197 return; 5198 } 5199 5200 // So here we are: the caller has the assumed permission 5201 // to the uri, and the target doesn't. Let's now give this to 5202 // the target. 5203 5204 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5205 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5206 5207 HashMap<Uri, UriPermission> targetUris 5208 = mGrantedUriPermissions.get(targetUid); 5209 if (targetUris == null) { 5210 targetUris = new HashMap<Uri, UriPermission>(); 5211 mGrantedUriPermissions.put(targetUid, targetUris); 5212 } 5213 5214 UriPermission perm = targetUris.get(uri); 5215 if (perm == null) { 5216 perm = new UriPermission(targetUid, uri); 5217 targetUris.put(uri, perm); 5218 } 5219 5220 perm.modeFlags |= modeFlags; 5221 if (owner == null) { 5222 perm.globalModeFlags |= modeFlags; 5223 } else { 5224 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5225 perm.readOwners.add(owner); 5226 owner.addReadPermission(perm); 5227 } 5228 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5229 perm.writeOwners.add(owner); 5230 owner.addWritePermission(perm); 5231 } 5232 } 5233 } 5234 5235 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5236 int modeFlags, UriPermissionOwner owner) { 5237 if (targetPkg == null) { 5238 throw new NullPointerException("targetPkg"); 5239 } 5240 5241 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5242 if (targetUid < 0) { 5243 return; 5244 } 5245 5246 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5247 } 5248 5249 static class NeededUriGrants extends ArrayList<Uri> { 5250 final String targetPkg; 5251 final int targetUid; 5252 final int flags; 5253 5254 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5255 targetPkg = _targetPkg; 5256 targetUid = _targetUid; 5257 flags = _flags; 5258 } 5259 } 5260 5261 /** 5262 * Like checkGrantUriPermissionLocked, but takes an Intent. 5263 */ 5264 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5265 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5266 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5267 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5268 + " clip=" + (intent != null ? intent.getClipData() : null) 5269 + " from " + intent + "; flags=0x" 5270 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5271 5272 if (targetPkg == null) { 5273 throw new NullPointerException("targetPkg"); 5274 } 5275 5276 if (intent == null) { 5277 return null; 5278 } 5279 Uri data = intent.getData(); 5280 ClipData clip = intent.getClipData(); 5281 if (data == null && clip == null) { 5282 return null; 5283 } 5284 if (data != null) { 5285 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5286 mode, needed != null ? needed.targetUid : -1); 5287 if (target > 0) { 5288 if (needed == null) { 5289 needed = new NeededUriGrants(targetPkg, target, mode); 5290 } 5291 needed.add(data); 5292 } 5293 } 5294 if (clip != null) { 5295 for (int i=0; i<clip.getItemCount(); i++) { 5296 Uri uri = clip.getItemAt(i).getUri(); 5297 if (uri != null) { 5298 int target = -1; 5299 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5300 mode, needed != null ? needed.targetUid : -1); 5301 if (target > 0) { 5302 if (needed == null) { 5303 needed = new NeededUriGrants(targetPkg, target, mode); 5304 } 5305 needed.add(uri); 5306 } 5307 } else { 5308 Intent clipIntent = clip.getItemAt(i).getIntent(); 5309 if (clipIntent != null) { 5310 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5311 callingUid, targetPkg, clipIntent, mode, needed); 5312 if (newNeeded != null) { 5313 needed = newNeeded; 5314 } 5315 } 5316 } 5317 } 5318 } 5319 5320 return needed; 5321 } 5322 5323 /** 5324 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5325 */ 5326 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5327 UriPermissionOwner owner) { 5328 if (needed != null) { 5329 for (int i=0; i<needed.size(); i++) { 5330 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5331 needed.get(i), needed.flags, owner); 5332 } 5333 } 5334 } 5335 5336 void grantUriPermissionFromIntentLocked(int callingUid, 5337 String targetPkg, Intent intent, UriPermissionOwner owner) { 5338 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5339 intent, intent != null ? intent.getFlags() : 0, null); 5340 if (needed == null) { 5341 return; 5342 } 5343 5344 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5345 } 5346 5347 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5348 Uri uri, int modeFlags) { 5349 enforceNotIsolatedCaller("grantUriPermission"); 5350 synchronized(this) { 5351 final ProcessRecord r = getRecordForAppLocked(caller); 5352 if (r == null) { 5353 throw new SecurityException("Unable to find app for caller " 5354 + caller 5355 + " when granting permission to uri " + uri); 5356 } 5357 if (targetPkg == null) { 5358 throw new IllegalArgumentException("null target"); 5359 } 5360 if (uri == null) { 5361 throw new IllegalArgumentException("null uri"); 5362 } 5363 5364 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5365 null); 5366 } 5367 } 5368 5369 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5370 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5371 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5372 HashMap<Uri, UriPermission> perms 5373 = mGrantedUriPermissions.get(perm.uid); 5374 if (perms != null) { 5375 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5376 "Removing " + perm.uid + " permission to " + perm.uri); 5377 perms.remove(perm.uri); 5378 if (perms.size() == 0) { 5379 mGrantedUriPermissions.remove(perm.uid); 5380 } 5381 } 5382 } 5383 } 5384 5385 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5386 int modeFlags) { 5387 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5388 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5389 if (modeFlags == 0) { 5390 return; 5391 } 5392 5393 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5394 "Revoking all granted permissions to " + uri); 5395 5396 final IPackageManager pm = AppGlobals.getPackageManager(); 5397 5398 final String authority = uri.getAuthority(); 5399 ProviderInfo pi = null; 5400 int userId = UserHandle.getUserId(callingUid); 5401 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5402 if (cpr != null) { 5403 pi = cpr.info; 5404 } else { 5405 try { 5406 pi = pm.resolveContentProvider(authority, 5407 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5408 } catch (RemoteException ex) { 5409 } 5410 } 5411 if (pi == null) { 5412 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5413 return; 5414 } 5415 5416 // Does the caller have this permission on the URI? 5417 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5418 // Right now, if you are not the original owner of the permission, 5419 // you are not allowed to revoke it. 5420 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5421 throw new SecurityException("Uid " + callingUid 5422 + " does not have permission to uri " + uri); 5423 //} 5424 } 5425 5426 // Go through all of the permissions and remove any that match. 5427 final List<String> SEGMENTS = uri.getPathSegments(); 5428 if (SEGMENTS != null) { 5429 final int NS = SEGMENTS.size(); 5430 int N = mGrantedUriPermissions.size(); 5431 for (int i=0; i<N; i++) { 5432 HashMap<Uri, UriPermission> perms 5433 = mGrantedUriPermissions.valueAt(i); 5434 Iterator<UriPermission> it = perms.values().iterator(); 5435 toploop: 5436 while (it.hasNext()) { 5437 UriPermission perm = it.next(); 5438 Uri targetUri = perm.uri; 5439 if (!authority.equals(targetUri.getAuthority())) { 5440 continue; 5441 } 5442 List<String> targetSegments = targetUri.getPathSegments(); 5443 if (targetSegments == null) { 5444 continue; 5445 } 5446 if (targetSegments.size() < NS) { 5447 continue; 5448 } 5449 for (int j=0; j<NS; j++) { 5450 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5451 continue toploop; 5452 } 5453 } 5454 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5455 "Revoking " + perm.uid + " permission to " + perm.uri); 5456 perm.clearModes(modeFlags); 5457 if (perm.modeFlags == 0) { 5458 it.remove(); 5459 } 5460 } 5461 if (perms.size() == 0) { 5462 mGrantedUriPermissions.remove( 5463 mGrantedUriPermissions.keyAt(i)); 5464 N--; 5465 i--; 5466 } 5467 } 5468 } 5469 } 5470 5471 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5472 int modeFlags) { 5473 enforceNotIsolatedCaller("revokeUriPermission"); 5474 synchronized(this) { 5475 final ProcessRecord r = getRecordForAppLocked(caller); 5476 if (r == null) { 5477 throw new SecurityException("Unable to find app for caller " 5478 + caller 5479 + " when revoking permission to uri " + uri); 5480 } 5481 if (uri == null) { 5482 Slog.w(TAG, "revokeUriPermission: null uri"); 5483 return; 5484 } 5485 5486 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5487 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5488 if (modeFlags == 0) { 5489 return; 5490 } 5491 5492 final IPackageManager pm = AppGlobals.getPackageManager(); 5493 5494 final String authority = uri.getAuthority(); 5495 ProviderInfo pi = null; 5496 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5497 if (cpr != null) { 5498 pi = cpr.info; 5499 } else { 5500 try { 5501 pi = pm.resolveContentProvider(authority, 5502 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5503 } catch (RemoteException ex) { 5504 } 5505 } 5506 if (pi == null) { 5507 Slog.w(TAG, "No content provider found for permission revoke: " 5508 + uri.toSafeString()); 5509 return; 5510 } 5511 5512 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5513 } 5514 } 5515 5516 @Override 5517 public IBinder newUriPermissionOwner(String name) { 5518 enforceNotIsolatedCaller("newUriPermissionOwner"); 5519 synchronized(this) { 5520 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5521 return owner.getExternalTokenLocked(); 5522 } 5523 } 5524 5525 @Override 5526 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5527 Uri uri, int modeFlags) { 5528 synchronized(this) { 5529 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5530 if (owner == null) { 5531 throw new IllegalArgumentException("Unknown owner: " + token); 5532 } 5533 if (fromUid != Binder.getCallingUid()) { 5534 if (Binder.getCallingUid() != Process.myUid()) { 5535 // Only system code can grant URI permissions on behalf 5536 // of other users. 5537 throw new SecurityException("nice try"); 5538 } 5539 } 5540 if (targetPkg == null) { 5541 throw new IllegalArgumentException("null target"); 5542 } 5543 if (uri == null) { 5544 throw new IllegalArgumentException("null uri"); 5545 } 5546 5547 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5548 } 5549 } 5550 5551 @Override 5552 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5553 synchronized(this) { 5554 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5555 if (owner == null) { 5556 throw new IllegalArgumentException("Unknown owner: " + token); 5557 } 5558 5559 if (uri == null) { 5560 owner.removeUriPermissionsLocked(mode); 5561 } else { 5562 owner.removeUriPermissionLocked(uri, mode); 5563 } 5564 } 5565 } 5566 5567 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5568 synchronized (this) { 5569 ProcessRecord app = 5570 who != null ? getRecordForAppLocked(who) : null; 5571 if (app == null) return; 5572 5573 Message msg = Message.obtain(); 5574 msg.what = WAIT_FOR_DEBUGGER_MSG; 5575 msg.obj = app; 5576 msg.arg1 = waiting ? 1 : 0; 5577 mHandler.sendMessage(msg); 5578 } 5579 } 5580 5581 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5582 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5583 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5584 outInfo.availMem = Process.getFreeMemory(); 5585 outInfo.totalMem = Process.getTotalMemory(); 5586 outInfo.threshold = homeAppMem; 5587 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5588 outInfo.hiddenAppThreshold = hiddenAppMem; 5589 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5590 ProcessList.SERVICE_ADJ); 5591 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5592 ProcessList.VISIBLE_APP_ADJ); 5593 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5594 ProcessList.FOREGROUND_APP_ADJ); 5595 } 5596 5597 // ========================================================= 5598 // TASK MANAGEMENT 5599 // ========================================================= 5600 5601 public List getTasks(int maxNum, int flags, 5602 IThumbnailReceiver receiver) { 5603 ArrayList list = new ArrayList(); 5604 5605 PendingThumbnailsRecord pending = null; 5606 IApplicationThread topThumbnail = null; 5607 ActivityRecord topRecord = null; 5608 5609 synchronized(this) { 5610 if (localLOGV) Slog.v( 5611 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5612 + ", receiver=" + receiver); 5613 5614 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5615 != PackageManager.PERMISSION_GRANTED) { 5616 if (receiver != null) { 5617 // If the caller wants to wait for pending thumbnails, 5618 // it ain't gonna get them. 5619 try { 5620 receiver.finished(); 5621 } catch (RemoteException ex) { 5622 } 5623 } 5624 String msg = "Permission Denial: getTasks() from pid=" 5625 + Binder.getCallingPid() 5626 + ", uid=" + Binder.getCallingUid() 5627 + " requires " + android.Manifest.permission.GET_TASKS; 5628 Slog.w(TAG, msg); 5629 throw new SecurityException(msg); 5630 } 5631 5632 int pos = mMainStack.mHistory.size()-1; 5633 ActivityRecord next = 5634 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5635 ActivityRecord top = null; 5636 TaskRecord curTask = null; 5637 int numActivities = 0; 5638 int numRunning = 0; 5639 while (pos >= 0 && maxNum > 0) { 5640 final ActivityRecord r = next; 5641 pos--; 5642 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5643 5644 // Initialize state for next task if needed. 5645 if (top == null || 5646 (top.state == ActivityState.INITIALIZING 5647 && top.task == r.task)) { 5648 top = r; 5649 curTask = r.task; 5650 numActivities = numRunning = 0; 5651 } 5652 5653 // Add 'r' into the current task. 5654 numActivities++; 5655 if (r.app != null && r.app.thread != null) { 5656 numRunning++; 5657 } 5658 5659 if (localLOGV) Slog.v( 5660 TAG, r.intent.getComponent().flattenToShortString() 5661 + ": task=" + r.task); 5662 5663 // If the next one is a different task, generate a new 5664 // TaskInfo entry for what we have. 5665 if (next == null || next.task != curTask) { 5666 ActivityManager.RunningTaskInfo ci 5667 = new ActivityManager.RunningTaskInfo(); 5668 ci.id = curTask.taskId; 5669 ci.baseActivity = r.intent.getComponent(); 5670 ci.topActivity = top.intent.getComponent(); 5671 if (top.thumbHolder != null) { 5672 ci.description = top.thumbHolder.lastDescription; 5673 } 5674 ci.numActivities = numActivities; 5675 ci.numRunning = numRunning; 5676 //System.out.println( 5677 // "#" + maxNum + ": " + " descr=" + ci.description); 5678 if (ci.thumbnail == null && receiver != null) { 5679 if (localLOGV) Slog.v( 5680 TAG, "State=" + top.state + "Idle=" + top.idle 5681 + " app=" + top.app 5682 + " thr=" + (top.app != null ? top.app.thread : null)); 5683 if (top.state == ActivityState.RESUMED 5684 || top.state == ActivityState.PAUSING) { 5685 if (top.idle && top.app != null 5686 && top.app.thread != null) { 5687 topRecord = top; 5688 topThumbnail = top.app.thread; 5689 } else { 5690 top.thumbnailNeeded = true; 5691 } 5692 } 5693 if (pending == null) { 5694 pending = new PendingThumbnailsRecord(receiver); 5695 } 5696 pending.pendingRecords.add(top); 5697 } 5698 list.add(ci); 5699 maxNum--; 5700 top = null; 5701 } 5702 } 5703 5704 if (pending != null) { 5705 mPendingThumbnails.add(pending); 5706 } 5707 } 5708 5709 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5710 5711 if (topThumbnail != null) { 5712 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5713 try { 5714 topThumbnail.requestThumbnail(topRecord.appToken); 5715 } catch (Exception e) { 5716 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5717 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5718 } 5719 } 5720 5721 if (pending == null && receiver != null) { 5722 // In this case all thumbnails were available and the client 5723 // is being asked to be told when the remaining ones come in... 5724 // which is unusually, since the top-most currently running 5725 // activity should never have a canned thumbnail! Oh well. 5726 try { 5727 receiver.finished(); 5728 } catch (RemoteException ex) { 5729 } 5730 } 5731 5732 return list; 5733 } 5734 5735 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5736 int flags, int userId) { 5737 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5738 false, true, "getRecentTasks", null); 5739 5740 synchronized (this) { 5741 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5742 "getRecentTasks()"); 5743 final boolean detailed = checkCallingPermission( 5744 android.Manifest.permission.GET_DETAILED_TASKS) 5745 == PackageManager.PERMISSION_GRANTED; 5746 5747 IPackageManager pm = AppGlobals.getPackageManager(); 5748 5749 final int N = mRecentTasks.size(); 5750 ArrayList<ActivityManager.RecentTaskInfo> res 5751 = new ArrayList<ActivityManager.RecentTaskInfo>( 5752 maxNum < N ? maxNum : N); 5753 for (int i=0; i<N && maxNum > 0; i++) { 5754 TaskRecord tr = mRecentTasks.get(i); 5755 // Only add calling user's recent tasks 5756 if (tr.userId != userId) continue; 5757 // Return the entry if desired by the caller. We always return 5758 // the first entry, because callers always expect this to be the 5759 // foreground app. We may filter others if the caller has 5760 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5761 // we should exclude the entry. 5762 5763 if (i == 0 5764 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5765 || (tr.intent == null) 5766 || ((tr.intent.getFlags() 5767 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5768 ActivityManager.RecentTaskInfo rti 5769 = new ActivityManager.RecentTaskInfo(); 5770 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5771 rti.persistentId = tr.taskId; 5772 rti.baseIntent = new Intent( 5773 tr.intent != null ? tr.intent : tr.affinityIntent); 5774 if (!detailed) { 5775 rti.baseIntent.replaceExtras((Bundle)null); 5776 } 5777 rti.origActivity = tr.origActivity; 5778 rti.description = tr.lastDescription; 5779 5780 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5781 // Check whether this activity is currently available. 5782 try { 5783 if (rti.origActivity != null) { 5784 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5785 == null) { 5786 continue; 5787 } 5788 } else if (rti.baseIntent != null) { 5789 if (pm.queryIntentActivities(rti.baseIntent, 5790 null, 0, userId) == null) { 5791 continue; 5792 } 5793 } 5794 } catch (RemoteException e) { 5795 // Will never happen. 5796 } 5797 } 5798 5799 res.add(rti); 5800 maxNum--; 5801 } 5802 } 5803 return res; 5804 } 5805 } 5806 5807 private TaskRecord taskForIdLocked(int id) { 5808 final int N = mRecentTasks.size(); 5809 for (int i=0; i<N; i++) { 5810 TaskRecord tr = mRecentTasks.get(i); 5811 if (tr.taskId == id) { 5812 return tr; 5813 } 5814 } 5815 return null; 5816 } 5817 5818 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5819 synchronized (this) { 5820 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5821 "getTaskThumbnails()"); 5822 TaskRecord tr = taskForIdLocked(id); 5823 if (tr != null) { 5824 return mMainStack.getTaskThumbnailsLocked(tr); 5825 } 5826 } 5827 return null; 5828 } 5829 5830 public Bitmap getTaskTopThumbnail(int id) { 5831 synchronized (this) { 5832 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5833 "getTaskTopThumbnail()"); 5834 TaskRecord tr = taskForIdLocked(id); 5835 if (tr != null) { 5836 return mMainStack.getTaskTopThumbnailLocked(tr); 5837 } 5838 } 5839 return null; 5840 } 5841 5842 public boolean removeSubTask(int taskId, int subTaskIndex) { 5843 synchronized (this) { 5844 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5845 "removeSubTask()"); 5846 long ident = Binder.clearCallingIdentity(); 5847 try { 5848 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5849 true) != null; 5850 } finally { 5851 Binder.restoreCallingIdentity(ident); 5852 } 5853 } 5854 } 5855 5856 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5857 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5858 Intent baseIntent = new Intent( 5859 tr.intent != null ? tr.intent : tr.affinityIntent); 5860 ComponentName component = baseIntent.getComponent(); 5861 if (component == null) { 5862 Slog.w(TAG, "Now component for base intent of task: " + tr); 5863 return; 5864 } 5865 5866 // Find any running services associated with this app. 5867 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5868 5869 if (killProcesses) { 5870 // Find any running processes associated with this app. 5871 final String pkg = component.getPackageName(); 5872 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5873 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5874 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5875 for (int i=0; i<uids.size(); i++) { 5876 ProcessRecord proc = uids.valueAt(i); 5877 if (proc.userId != tr.userId) { 5878 continue; 5879 } 5880 if (!proc.pkgList.contains(pkg)) { 5881 continue; 5882 } 5883 procs.add(proc); 5884 } 5885 } 5886 5887 // Kill the running processes. 5888 for (int i=0; i<procs.size(); i++) { 5889 ProcessRecord pr = procs.get(i); 5890 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5891 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5892 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 5893 pr.processName, pr.setAdj, "remove task"); 5894 pr.killedBackground = true; 5895 Process.killProcessQuiet(pr.pid); 5896 } else { 5897 pr.waitingToKill = "remove task"; 5898 } 5899 } 5900 } 5901 } 5902 5903 public boolean removeTask(int taskId, int flags) { 5904 synchronized (this) { 5905 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5906 "removeTask()"); 5907 long ident = Binder.clearCallingIdentity(); 5908 try { 5909 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5910 false); 5911 if (r != null) { 5912 mRecentTasks.remove(r.task); 5913 cleanUpRemovedTaskLocked(r.task, flags); 5914 return true; 5915 } else { 5916 TaskRecord tr = null; 5917 int i=0; 5918 while (i < mRecentTasks.size()) { 5919 TaskRecord t = mRecentTasks.get(i); 5920 if (t.taskId == taskId) { 5921 tr = t; 5922 break; 5923 } 5924 i++; 5925 } 5926 if (tr != null) { 5927 if (tr.numActivities <= 0) { 5928 // Caller is just removing a recent task that is 5929 // not actively running. That is easy! 5930 mRecentTasks.remove(i); 5931 cleanUpRemovedTaskLocked(tr, flags); 5932 return true; 5933 } else { 5934 Slog.w(TAG, "removeTask: task " + taskId 5935 + " does not have activities to remove, " 5936 + " but numActivities=" + tr.numActivities 5937 + ": " + tr); 5938 } 5939 } 5940 } 5941 } finally { 5942 Binder.restoreCallingIdentity(ident); 5943 } 5944 } 5945 return false; 5946 } 5947 5948 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5949 int j; 5950 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5951 TaskRecord jt = startTask; 5952 5953 // First look backwards 5954 for (j=startIndex-1; j>=0; j--) { 5955 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5956 if (r.task != jt) { 5957 jt = r.task; 5958 if (affinity.equals(jt.affinity)) { 5959 return j; 5960 } 5961 } 5962 } 5963 5964 // Now look forwards 5965 final int N = mMainStack.mHistory.size(); 5966 jt = startTask; 5967 for (j=startIndex+1; j<N; j++) { 5968 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5969 if (r.task != jt) { 5970 if (affinity.equals(jt.affinity)) { 5971 return j; 5972 } 5973 jt = r.task; 5974 } 5975 } 5976 5977 // Might it be at the top? 5978 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5979 return N-1; 5980 } 5981 5982 return -1; 5983 } 5984 5985 /** 5986 * TODO: Add mController hook 5987 */ 5988 public void moveTaskToFront(int task, int flags, Bundle options) { 5989 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5990 "moveTaskToFront()"); 5991 5992 synchronized(this) { 5993 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5994 Binder.getCallingUid(), "Task to front")) { 5995 ActivityOptions.abort(options); 5996 return; 5997 } 5998 final long origId = Binder.clearCallingIdentity(); 5999 try { 6000 TaskRecord tr = taskForIdLocked(task); 6001 if (tr != null) { 6002 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6003 mMainStack.mUserLeaving = true; 6004 } 6005 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6006 // Caller wants the home activity moved with it. To accomplish this, 6007 // we'll just move the home task to the top first. 6008 mMainStack.moveHomeToFrontLocked(); 6009 } 6010 mMainStack.moveTaskToFrontLocked(tr, null, options); 6011 return; 6012 } 6013 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6014 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6015 if (hr.task.taskId == task) { 6016 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6017 mMainStack.mUserLeaving = true; 6018 } 6019 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6020 // Caller wants the home activity moved with it. To accomplish this, 6021 // we'll just move the home task to the top first. 6022 mMainStack.moveHomeToFrontLocked(); 6023 } 6024 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6025 return; 6026 } 6027 } 6028 } finally { 6029 Binder.restoreCallingIdentity(origId); 6030 } 6031 ActivityOptions.abort(options); 6032 } 6033 } 6034 6035 public void moveTaskToBack(int task) { 6036 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6037 "moveTaskToBack()"); 6038 6039 synchronized(this) { 6040 if (mMainStack.mResumedActivity != null 6041 && mMainStack.mResumedActivity.task.taskId == task) { 6042 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6043 Binder.getCallingUid(), "Task to back")) { 6044 return; 6045 } 6046 } 6047 final long origId = Binder.clearCallingIdentity(); 6048 mMainStack.moveTaskToBackLocked(task, null); 6049 Binder.restoreCallingIdentity(origId); 6050 } 6051 } 6052 6053 /** 6054 * Moves an activity, and all of the other activities within the same task, to the bottom 6055 * of the history stack. The activity's order within the task is unchanged. 6056 * 6057 * @param token A reference to the activity we wish to move 6058 * @param nonRoot If false then this only works if the activity is the root 6059 * of a task; if true it will work for any activity in a task. 6060 * @return Returns true if the move completed, false if not. 6061 */ 6062 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6063 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6064 synchronized(this) { 6065 final long origId = Binder.clearCallingIdentity(); 6066 int taskId = getTaskForActivityLocked(token, !nonRoot); 6067 if (taskId >= 0) { 6068 return mMainStack.moveTaskToBackLocked(taskId, null); 6069 } 6070 Binder.restoreCallingIdentity(origId); 6071 } 6072 return false; 6073 } 6074 6075 public void moveTaskBackwards(int task) { 6076 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6077 "moveTaskBackwards()"); 6078 6079 synchronized(this) { 6080 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6081 Binder.getCallingUid(), "Task backwards")) { 6082 return; 6083 } 6084 final long origId = Binder.clearCallingIdentity(); 6085 moveTaskBackwardsLocked(task); 6086 Binder.restoreCallingIdentity(origId); 6087 } 6088 } 6089 6090 private final void moveTaskBackwardsLocked(int task) { 6091 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6092 } 6093 6094 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6095 synchronized(this) { 6096 return getTaskForActivityLocked(token, onlyRoot); 6097 } 6098 } 6099 6100 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6101 final int N = mMainStack.mHistory.size(); 6102 TaskRecord lastTask = null; 6103 for (int i=0; i<N; i++) { 6104 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6105 if (r.appToken == token) { 6106 if (!onlyRoot || lastTask != r.task) { 6107 return r.task.taskId; 6108 } 6109 return -1; 6110 } 6111 lastTask = r.task; 6112 } 6113 6114 return -1; 6115 } 6116 6117 // ========================================================= 6118 // THUMBNAILS 6119 // ========================================================= 6120 6121 public void reportThumbnail(IBinder token, 6122 Bitmap thumbnail, CharSequence description) { 6123 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6124 final long origId = Binder.clearCallingIdentity(); 6125 sendPendingThumbnail(null, token, thumbnail, description, true); 6126 Binder.restoreCallingIdentity(origId); 6127 } 6128 6129 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6130 Bitmap thumbnail, CharSequence description, boolean always) { 6131 TaskRecord task = null; 6132 ArrayList receivers = null; 6133 6134 //System.out.println("Send pending thumbnail: " + r); 6135 6136 synchronized(this) { 6137 if (r == null) { 6138 r = mMainStack.isInStackLocked(token); 6139 if (r == null) { 6140 return; 6141 } 6142 } 6143 if (thumbnail == null && r.thumbHolder != null) { 6144 thumbnail = r.thumbHolder.lastThumbnail; 6145 description = r.thumbHolder.lastDescription; 6146 } 6147 if (thumbnail == null && !always) { 6148 // If there is no thumbnail, and this entry is not actually 6149 // going away, then abort for now and pick up the next 6150 // thumbnail we get. 6151 return; 6152 } 6153 task = r.task; 6154 6155 int N = mPendingThumbnails.size(); 6156 int i=0; 6157 while (i<N) { 6158 PendingThumbnailsRecord pr = 6159 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6160 //System.out.println("Looking in " + pr.pendingRecords); 6161 if (pr.pendingRecords.remove(r)) { 6162 if (receivers == null) { 6163 receivers = new ArrayList(); 6164 } 6165 receivers.add(pr); 6166 if (pr.pendingRecords.size() == 0) { 6167 pr.finished = true; 6168 mPendingThumbnails.remove(i); 6169 N--; 6170 continue; 6171 } 6172 } 6173 i++; 6174 } 6175 } 6176 6177 if (receivers != null) { 6178 final int N = receivers.size(); 6179 for (int i=0; i<N; i++) { 6180 try { 6181 PendingThumbnailsRecord pr = 6182 (PendingThumbnailsRecord)receivers.get(i); 6183 pr.receiver.newThumbnail( 6184 task != null ? task.taskId : -1, thumbnail, description); 6185 if (pr.finished) { 6186 pr.receiver.finished(); 6187 } 6188 } catch (Exception e) { 6189 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6190 } 6191 } 6192 } 6193 } 6194 6195 // ========================================================= 6196 // CONTENT PROVIDERS 6197 // ========================================================= 6198 6199 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6200 List<ProviderInfo> providers = null; 6201 try { 6202 providers = AppGlobals.getPackageManager(). 6203 queryContentProviders(app.processName, app.uid, 6204 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6205 } catch (RemoteException ex) { 6206 } 6207 if (DEBUG_MU) 6208 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6209 int userId = app.userId; 6210 if (providers != null) { 6211 int N = providers.size(); 6212 for (int i=0; i<N; i++) { 6213 ProviderInfo cpi = 6214 (ProviderInfo)providers.get(i); 6215 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6216 cpi.name, cpi.flags); 6217 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6218 // This is a singleton provider, but a user besides the 6219 // default user is asking to initialize a process it runs 6220 // in... well, no, it doesn't actually run in this process, 6221 // it runs in the process of the default user. Get rid of it. 6222 providers.remove(i); 6223 N--; 6224 continue; 6225 } 6226 6227 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6228 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6229 if (cpr == null) { 6230 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6231 mProviderMap.putProviderByClass(comp, cpr); 6232 } 6233 if (DEBUG_MU) 6234 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6235 app.pubProviders.put(cpi.name, cpr); 6236 app.addPackage(cpi.applicationInfo.packageName); 6237 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6238 } 6239 } 6240 return providers; 6241 } 6242 6243 /** 6244 * Check if {@link ProcessRecord} has a possible chance at accessing the 6245 * given {@link ProviderInfo}. Final permission checking is always done 6246 * in {@link ContentProvider}. 6247 */ 6248 private final String checkContentProviderPermissionLocked( 6249 ProviderInfo cpi, ProcessRecord r) { 6250 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6251 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6252 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6253 cpi.applicationInfo.uid, cpi.exported) 6254 == PackageManager.PERMISSION_GRANTED) { 6255 return null; 6256 } 6257 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6258 cpi.applicationInfo.uid, cpi.exported) 6259 == PackageManager.PERMISSION_GRANTED) { 6260 return null; 6261 } 6262 6263 PathPermission[] pps = cpi.pathPermissions; 6264 if (pps != null) { 6265 int i = pps.length; 6266 while (i > 0) { 6267 i--; 6268 PathPermission pp = pps[i]; 6269 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6270 cpi.applicationInfo.uid, cpi.exported) 6271 == PackageManager.PERMISSION_GRANTED) { 6272 return null; 6273 } 6274 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6275 cpi.applicationInfo.uid, cpi.exported) 6276 == PackageManager.PERMISSION_GRANTED) { 6277 return null; 6278 } 6279 } 6280 } 6281 6282 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6283 if (perms != null) { 6284 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6285 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6286 return null; 6287 } 6288 } 6289 } 6290 6291 String msg; 6292 if (!cpi.exported) { 6293 msg = "Permission Denial: opening provider " + cpi.name 6294 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6295 + ", uid=" + callingUid + ") that is not exported from uid " 6296 + cpi.applicationInfo.uid; 6297 } else { 6298 msg = "Permission Denial: opening provider " + cpi.name 6299 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6300 + ", uid=" + callingUid + ") requires " 6301 + cpi.readPermission + " or " + cpi.writePermission; 6302 } 6303 Slog.w(TAG, msg); 6304 return msg; 6305 } 6306 6307 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6308 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6309 if (r != null) { 6310 for (int i=0; i<r.conProviders.size(); i++) { 6311 ContentProviderConnection conn = r.conProviders.get(i); 6312 if (conn.provider == cpr) { 6313 if (DEBUG_PROVIDER) Slog.v(TAG, 6314 "Adding provider requested by " 6315 + r.processName + " from process " 6316 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6317 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6318 if (stable) { 6319 conn.stableCount++; 6320 conn.numStableIncs++; 6321 } else { 6322 conn.unstableCount++; 6323 conn.numUnstableIncs++; 6324 } 6325 return conn; 6326 } 6327 } 6328 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6329 if (stable) { 6330 conn.stableCount = 1; 6331 conn.numStableIncs = 1; 6332 } else { 6333 conn.unstableCount = 1; 6334 conn.numUnstableIncs = 1; 6335 } 6336 cpr.connections.add(conn); 6337 r.conProviders.add(conn); 6338 return conn; 6339 } 6340 cpr.addExternalProcessHandleLocked(externalProcessToken); 6341 return null; 6342 } 6343 6344 boolean decProviderCountLocked(ContentProviderConnection conn, 6345 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6346 if (conn != null) { 6347 cpr = conn.provider; 6348 if (DEBUG_PROVIDER) Slog.v(TAG, 6349 "Removing provider requested by " 6350 + conn.client.processName + " from process " 6351 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6352 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6353 if (stable) { 6354 conn.stableCount--; 6355 } else { 6356 conn.unstableCount--; 6357 } 6358 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6359 cpr.connections.remove(conn); 6360 conn.client.conProviders.remove(conn); 6361 return true; 6362 } 6363 return false; 6364 } 6365 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6366 return false; 6367 } 6368 6369 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6370 String name, IBinder token, boolean stable, int userId) { 6371 ContentProviderRecord cpr; 6372 ContentProviderConnection conn = null; 6373 ProviderInfo cpi = null; 6374 6375 synchronized(this) { 6376 ProcessRecord r = null; 6377 if (caller != null) { 6378 r = getRecordForAppLocked(caller); 6379 if (r == null) { 6380 throw new SecurityException( 6381 "Unable to find app for caller " + caller 6382 + " (pid=" + Binder.getCallingPid() 6383 + ") when getting content provider " + name); 6384 } 6385 } 6386 6387 // First check if this content provider has been published... 6388 cpr = mProviderMap.getProviderByName(name, userId); 6389 boolean providerRunning = cpr != null; 6390 if (providerRunning) { 6391 cpi = cpr.info; 6392 String msg; 6393 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6394 throw new SecurityException(msg); 6395 } 6396 6397 if (r != null && cpr.canRunHere(r)) { 6398 // This provider has been published or is in the process 6399 // of being published... but it is also allowed to run 6400 // in the caller's process, so don't make a connection 6401 // and just let the caller instantiate its own instance. 6402 ContentProviderHolder holder = cpr.newHolder(null); 6403 // don't give caller the provider object, it needs 6404 // to make its own. 6405 holder.provider = null; 6406 return holder; 6407 } 6408 6409 final long origId = Binder.clearCallingIdentity(); 6410 6411 // In this case the provider instance already exists, so we can 6412 // return it right away. 6413 conn = incProviderCountLocked(r, cpr, token, stable); 6414 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6415 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6416 // If this is a perceptible app accessing the provider, 6417 // make sure to count it as being accessed and thus 6418 // back up on the LRU list. This is good because 6419 // content providers are often expensive to start. 6420 updateLruProcessLocked(cpr.proc, false); 6421 } 6422 } 6423 6424 if (cpr.proc != null) { 6425 if (false) { 6426 if (cpr.name.flattenToShortString().equals( 6427 "com.android.providers.calendar/.CalendarProvider2")) { 6428 Slog.v(TAG, "****************** KILLING " 6429 + cpr.name.flattenToShortString()); 6430 Process.killProcess(cpr.proc.pid); 6431 } 6432 } 6433 boolean success = updateOomAdjLocked(cpr.proc); 6434 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6435 // NOTE: there is still a race here where a signal could be 6436 // pending on the process even though we managed to update its 6437 // adj level. Not sure what to do about this, but at least 6438 // the race is now smaller. 6439 if (!success) { 6440 // Uh oh... it looks like the provider's process 6441 // has been killed on us. We need to wait for a new 6442 // process to be started, and make sure its death 6443 // doesn't kill our process. 6444 Slog.i(TAG, 6445 "Existing provider " + cpr.name.flattenToShortString() 6446 + " is crashing; detaching " + r); 6447 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6448 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6449 if (!lastRef) { 6450 // This wasn't the last ref our process had on 6451 // the provider... we have now been killed, bail. 6452 return null; 6453 } 6454 providerRunning = false; 6455 conn = null; 6456 } 6457 } 6458 6459 Binder.restoreCallingIdentity(origId); 6460 } 6461 6462 boolean singleton; 6463 if (!providerRunning) { 6464 try { 6465 cpi = AppGlobals.getPackageManager(). 6466 resolveContentProvider(name, 6467 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6468 } catch (RemoteException ex) { 6469 } 6470 if (cpi == null) { 6471 return null; 6472 } 6473 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6474 cpi.name, cpi.flags); 6475 if (singleton) { 6476 userId = 0; 6477 } 6478 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6479 6480 String msg; 6481 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6482 throw new SecurityException(msg); 6483 } 6484 6485 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6486 && !cpi.processName.equals("system")) { 6487 // If this content provider does not run in the system 6488 // process, and the system is not yet ready to run other 6489 // processes, then fail fast instead of hanging. 6490 throw new IllegalArgumentException( 6491 "Attempt to launch content provider before system ready"); 6492 } 6493 6494 // Make sure that the user who owns this provider is started. If not, 6495 // we don't want to allow it to run. 6496 if (mStartedUsers.get(userId) == null) { 6497 Slog.w(TAG, "Unable to launch app " 6498 + cpi.applicationInfo.packageName + "/" 6499 + cpi.applicationInfo.uid + " for provider " 6500 + name + ": user " + userId + " is stopped"); 6501 return null; 6502 } 6503 6504 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6505 cpr = mProviderMap.getProviderByClass(comp, userId); 6506 final boolean firstClass = cpr == null; 6507 if (firstClass) { 6508 try { 6509 ApplicationInfo ai = 6510 AppGlobals.getPackageManager(). 6511 getApplicationInfo( 6512 cpi.applicationInfo.packageName, 6513 STOCK_PM_FLAGS, userId); 6514 if (ai == null) { 6515 Slog.w(TAG, "No package info for content provider " 6516 + cpi.name); 6517 return null; 6518 } 6519 ai = getAppInfoForUser(ai, userId); 6520 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6521 } catch (RemoteException ex) { 6522 // pm is in same process, this will never happen. 6523 } 6524 } 6525 6526 if (r != null && cpr.canRunHere(r)) { 6527 // If this is a multiprocess provider, then just return its 6528 // info and allow the caller to instantiate it. Only do 6529 // this if the provider is the same user as the caller's 6530 // process, or can run as root (so can be in any process). 6531 return cpr.newHolder(null); 6532 } 6533 6534 if (DEBUG_PROVIDER) { 6535 RuntimeException e = new RuntimeException("here"); 6536 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6537 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6538 } 6539 6540 // This is single process, and our app is now connecting to it. 6541 // See if we are already in the process of launching this 6542 // provider. 6543 final int N = mLaunchingProviders.size(); 6544 int i; 6545 for (i=0; i<N; i++) { 6546 if (mLaunchingProviders.get(i) == cpr) { 6547 break; 6548 } 6549 } 6550 6551 // If the provider is not already being launched, then get it 6552 // started. 6553 if (i >= N) { 6554 final long origId = Binder.clearCallingIdentity(); 6555 6556 try { 6557 // Content provider is now in use, its package can't be stopped. 6558 try { 6559 AppGlobals.getPackageManager().setPackageStoppedState( 6560 cpr.appInfo.packageName, false, userId); 6561 } catch (RemoteException e) { 6562 } catch (IllegalArgumentException e) { 6563 Slog.w(TAG, "Failed trying to unstop package " 6564 + cpr.appInfo.packageName + ": " + e); 6565 } 6566 6567 ProcessRecord proc = startProcessLocked(cpi.processName, 6568 cpr.appInfo, false, 0, "content provider", 6569 new ComponentName(cpi.applicationInfo.packageName, 6570 cpi.name), false, false); 6571 if (proc == null) { 6572 Slog.w(TAG, "Unable to launch app " 6573 + cpi.applicationInfo.packageName + "/" 6574 + cpi.applicationInfo.uid + " for provider " 6575 + name + ": process is bad"); 6576 return null; 6577 } 6578 cpr.launchingApp = proc; 6579 mLaunchingProviders.add(cpr); 6580 } finally { 6581 Binder.restoreCallingIdentity(origId); 6582 } 6583 } 6584 6585 // Make sure the provider is published (the same provider class 6586 // may be published under multiple names). 6587 if (firstClass) { 6588 mProviderMap.putProviderByClass(comp, cpr); 6589 } 6590 6591 mProviderMap.putProviderByName(name, cpr); 6592 conn = incProviderCountLocked(r, cpr, token, stable); 6593 if (conn != null) { 6594 conn.waiting = true; 6595 } 6596 } 6597 } 6598 6599 // Wait for the provider to be published... 6600 synchronized (cpr) { 6601 while (cpr.provider == null) { 6602 if (cpr.launchingApp == null) { 6603 Slog.w(TAG, "Unable to launch app " 6604 + cpi.applicationInfo.packageName + "/" 6605 + cpi.applicationInfo.uid + " for provider " 6606 + name + ": launching app became null"); 6607 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6608 UserHandle.getUserId(cpi.applicationInfo.uid), 6609 cpi.applicationInfo.packageName, 6610 cpi.applicationInfo.uid, name); 6611 return null; 6612 } 6613 try { 6614 if (DEBUG_MU) { 6615 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6616 + cpr.launchingApp); 6617 } 6618 if (conn != null) { 6619 conn.waiting = true; 6620 } 6621 cpr.wait(); 6622 } catch (InterruptedException ex) { 6623 } finally { 6624 if (conn != null) { 6625 conn.waiting = false; 6626 } 6627 } 6628 } 6629 } 6630 return cpr != null ? cpr.newHolder(conn) : null; 6631 } 6632 6633 public final ContentProviderHolder getContentProvider( 6634 IApplicationThread caller, String name, int userId, boolean stable) { 6635 enforceNotIsolatedCaller("getContentProvider"); 6636 if (caller == null) { 6637 String msg = "null IApplicationThread when getting content provider " 6638 + name; 6639 Slog.w(TAG, msg); 6640 throw new SecurityException(msg); 6641 } 6642 6643 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6644 false, true, "getContentProvider", null); 6645 return getContentProviderImpl(caller, name, null, stable, userId); 6646 } 6647 6648 public ContentProviderHolder getContentProviderExternal( 6649 String name, int userId, IBinder token) { 6650 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6651 "Do not have permission in call getContentProviderExternal()"); 6652 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6653 false, true, "getContentProvider", null); 6654 return getContentProviderExternalUnchecked(name, token, userId); 6655 } 6656 6657 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6658 IBinder token, int userId) { 6659 return getContentProviderImpl(null, name, token, true, userId); 6660 } 6661 6662 /** 6663 * Drop a content provider from a ProcessRecord's bookkeeping 6664 * @param cpr 6665 */ 6666 public void removeContentProvider(IBinder connection, boolean stable) { 6667 enforceNotIsolatedCaller("removeContentProvider"); 6668 synchronized (this) { 6669 ContentProviderConnection conn; 6670 try { 6671 conn = (ContentProviderConnection)connection; 6672 } catch (ClassCastException e) { 6673 String msg ="removeContentProvider: " + connection 6674 + " not a ContentProviderConnection"; 6675 Slog.w(TAG, msg); 6676 throw new IllegalArgumentException(msg); 6677 } 6678 if (conn == null) { 6679 throw new NullPointerException("connection is null"); 6680 } 6681 if (decProviderCountLocked(conn, null, null, stable)) { 6682 updateOomAdjLocked(); 6683 } 6684 } 6685 } 6686 6687 public void removeContentProviderExternal(String name, IBinder token) { 6688 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6689 "Do not have permission in call removeContentProviderExternal()"); 6690 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6691 } 6692 6693 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6694 synchronized (this) { 6695 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6696 if(cpr == null) { 6697 //remove from mProvidersByClass 6698 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6699 return; 6700 } 6701 6702 //update content provider record entry info 6703 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6704 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6705 if (localCpr.hasExternalProcessHandles()) { 6706 if (localCpr.removeExternalProcessHandleLocked(token)) { 6707 updateOomAdjLocked(); 6708 } else { 6709 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6710 + " with no external reference for token: " 6711 + token + "."); 6712 } 6713 } else { 6714 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6715 + " with no external references."); 6716 } 6717 } 6718 } 6719 6720 public final void publishContentProviders(IApplicationThread caller, 6721 List<ContentProviderHolder> providers) { 6722 if (providers == null) { 6723 return; 6724 } 6725 6726 enforceNotIsolatedCaller("publishContentProviders"); 6727 synchronized (this) { 6728 final ProcessRecord r = getRecordForAppLocked(caller); 6729 if (DEBUG_MU) 6730 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6731 if (r == null) { 6732 throw new SecurityException( 6733 "Unable to find app for caller " + caller 6734 + " (pid=" + Binder.getCallingPid() 6735 + ") when publishing content providers"); 6736 } 6737 6738 final long origId = Binder.clearCallingIdentity(); 6739 6740 final int N = providers.size(); 6741 for (int i=0; i<N; i++) { 6742 ContentProviderHolder src = providers.get(i); 6743 if (src == null || src.info == null || src.provider == null) { 6744 continue; 6745 } 6746 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6747 if (DEBUG_MU) 6748 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6749 if (dst != null) { 6750 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6751 mProviderMap.putProviderByClass(comp, dst); 6752 String names[] = dst.info.authority.split(";"); 6753 for (int j = 0; j < names.length; j++) { 6754 mProviderMap.putProviderByName(names[j], dst); 6755 } 6756 6757 int NL = mLaunchingProviders.size(); 6758 int j; 6759 for (j=0; j<NL; j++) { 6760 if (mLaunchingProviders.get(j) == dst) { 6761 mLaunchingProviders.remove(j); 6762 j--; 6763 NL--; 6764 } 6765 } 6766 synchronized (dst) { 6767 dst.provider = src.provider; 6768 dst.proc = r; 6769 dst.notifyAll(); 6770 } 6771 updateOomAdjLocked(r); 6772 } 6773 } 6774 6775 Binder.restoreCallingIdentity(origId); 6776 } 6777 } 6778 6779 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6780 ContentProviderConnection conn; 6781 try { 6782 conn = (ContentProviderConnection)connection; 6783 } catch (ClassCastException e) { 6784 String msg ="refContentProvider: " + connection 6785 + " not a ContentProviderConnection"; 6786 Slog.w(TAG, msg); 6787 throw new IllegalArgumentException(msg); 6788 } 6789 if (conn == null) { 6790 throw new NullPointerException("connection is null"); 6791 } 6792 6793 synchronized (this) { 6794 if (stable > 0) { 6795 conn.numStableIncs += stable; 6796 } 6797 stable = conn.stableCount + stable; 6798 if (stable < 0) { 6799 throw new IllegalStateException("stableCount < 0: " + stable); 6800 } 6801 6802 if (unstable > 0) { 6803 conn.numUnstableIncs += unstable; 6804 } 6805 unstable = conn.unstableCount + unstable; 6806 if (unstable < 0) { 6807 throw new IllegalStateException("unstableCount < 0: " + unstable); 6808 } 6809 6810 if ((stable+unstable) <= 0) { 6811 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6812 + stable + " unstable=" + unstable); 6813 } 6814 conn.stableCount = stable; 6815 conn.unstableCount = unstable; 6816 return !conn.dead; 6817 } 6818 } 6819 6820 public void unstableProviderDied(IBinder connection) { 6821 ContentProviderConnection conn; 6822 try { 6823 conn = (ContentProviderConnection)connection; 6824 } catch (ClassCastException e) { 6825 String msg ="refContentProvider: " + connection 6826 + " not a ContentProviderConnection"; 6827 Slog.w(TAG, msg); 6828 throw new IllegalArgumentException(msg); 6829 } 6830 if (conn == null) { 6831 throw new NullPointerException("connection is null"); 6832 } 6833 6834 // Safely retrieve the content provider associated with the connection. 6835 IContentProvider provider; 6836 synchronized (this) { 6837 provider = conn.provider.provider; 6838 } 6839 6840 if (provider == null) { 6841 // Um, yeah, we're way ahead of you. 6842 return; 6843 } 6844 6845 // Make sure the caller is being honest with us. 6846 if (provider.asBinder().pingBinder()) { 6847 // Er, no, still looks good to us. 6848 synchronized (this) { 6849 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6850 + " says " + conn + " died, but we don't agree"); 6851 return; 6852 } 6853 } 6854 6855 // Well look at that! It's dead! 6856 synchronized (this) { 6857 if (conn.provider.provider != provider) { 6858 // But something changed... good enough. 6859 return; 6860 } 6861 6862 ProcessRecord proc = conn.provider.proc; 6863 if (proc == null || proc.thread == null) { 6864 // Seems like the process is already cleaned up. 6865 return; 6866 } 6867 6868 // As far as we're concerned, this is just like receiving a 6869 // death notification... just a bit prematurely. 6870 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6871 + ") early provider death"); 6872 final long ident = Binder.clearCallingIdentity(); 6873 try { 6874 appDiedLocked(proc, proc.pid, proc.thread); 6875 } finally { 6876 Binder.restoreCallingIdentity(ident); 6877 } 6878 } 6879 } 6880 6881 public static final void installSystemProviders() { 6882 List<ProviderInfo> providers; 6883 synchronized (mSelf) { 6884 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6885 providers = mSelf.generateApplicationProvidersLocked(app); 6886 if (providers != null) { 6887 for (int i=providers.size()-1; i>=0; i--) { 6888 ProviderInfo pi = (ProviderInfo)providers.get(i); 6889 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6890 Slog.w(TAG, "Not installing system proc provider " + pi.name 6891 + ": not system .apk"); 6892 providers.remove(i); 6893 } 6894 } 6895 } 6896 } 6897 if (providers != null) { 6898 mSystemThread.installSystemProviders(providers); 6899 } 6900 6901 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6902 6903 mSelf.mUsageStatsService.monitorPackages(); 6904 } 6905 6906 /** 6907 * Allows app to retrieve the MIME type of a URI without having permission 6908 * to access its content provider. 6909 * 6910 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6911 * 6912 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6913 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6914 */ 6915 public String getProviderMimeType(Uri uri, int userId) { 6916 enforceNotIsolatedCaller("getProviderMimeType"); 6917 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6918 userId, false, true, "getProviderMimeType", null); 6919 final String name = uri.getAuthority(); 6920 final long ident = Binder.clearCallingIdentity(); 6921 ContentProviderHolder holder = null; 6922 6923 try { 6924 holder = getContentProviderExternalUnchecked(name, null, userId); 6925 if (holder != null) { 6926 return holder.provider.getType(uri); 6927 } 6928 } catch (RemoteException e) { 6929 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6930 return null; 6931 } finally { 6932 if (holder != null) { 6933 removeContentProviderExternalUnchecked(name, null, userId); 6934 } 6935 Binder.restoreCallingIdentity(ident); 6936 } 6937 6938 return null; 6939 } 6940 6941 // ========================================================= 6942 // GLOBAL MANAGEMENT 6943 // ========================================================= 6944 6945 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6946 ApplicationInfo info, String customProcess, boolean isolated) { 6947 String proc = customProcess != null ? customProcess : info.processName; 6948 BatteryStatsImpl.Uid.Proc ps = null; 6949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6950 int uid = info.uid; 6951 if (isolated) { 6952 int userId = UserHandle.getUserId(uid); 6953 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6954 uid = 0; 6955 while (true) { 6956 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6957 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6958 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6959 } 6960 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6961 mNextIsolatedProcessUid++; 6962 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6963 // No process for this uid, use it. 6964 break; 6965 } 6966 stepsLeft--; 6967 if (stepsLeft <= 0) { 6968 return null; 6969 } 6970 } 6971 } 6972 synchronized (stats) { 6973 ps = stats.getProcessStatsLocked(info.uid, proc); 6974 } 6975 return new ProcessRecord(ps, thread, info, proc, uid); 6976 } 6977 6978 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6979 ProcessRecord app; 6980 if (!isolated) { 6981 app = getProcessRecordLocked(info.processName, info.uid); 6982 } else { 6983 app = null; 6984 } 6985 6986 if (app == null) { 6987 app = newProcessRecordLocked(null, info, null, isolated); 6988 mProcessNames.put(info.processName, app.uid, app); 6989 if (isolated) { 6990 mIsolatedProcesses.put(app.uid, app); 6991 } 6992 updateLruProcessLocked(app, true); 6993 } 6994 6995 // This package really, really can not be stopped. 6996 try { 6997 AppGlobals.getPackageManager().setPackageStoppedState( 6998 info.packageName, false, UserHandle.getUserId(app.uid)); 6999 } catch (RemoteException e) { 7000 } catch (IllegalArgumentException e) { 7001 Slog.w(TAG, "Failed trying to unstop package " 7002 + info.packageName + ": " + e); 7003 } 7004 7005 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7006 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7007 app.persistent = true; 7008 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7009 } 7010 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7011 mPersistentStartingProcesses.add(app); 7012 startProcessLocked(app, "added application", app.processName); 7013 } 7014 7015 return app; 7016 } 7017 7018 public void unhandledBack() { 7019 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7020 "unhandledBack()"); 7021 7022 synchronized(this) { 7023 int count = mMainStack.mHistory.size(); 7024 if (DEBUG_SWITCH) Slog.d( 7025 TAG, "Performing unhandledBack(): stack size = " + count); 7026 if (count > 1) { 7027 final long origId = Binder.clearCallingIdentity(); 7028 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7029 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7030 Binder.restoreCallingIdentity(origId); 7031 } 7032 } 7033 } 7034 7035 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7036 enforceNotIsolatedCaller("openContentUri"); 7037 final int userId = UserHandle.getCallingUserId(); 7038 String name = uri.getAuthority(); 7039 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7040 ParcelFileDescriptor pfd = null; 7041 if (cph != null) { 7042 // We record the binder invoker's uid in thread-local storage before 7043 // going to the content provider to open the file. Later, in the code 7044 // that handles all permissions checks, we look for this uid and use 7045 // that rather than the Activity Manager's own uid. The effect is that 7046 // we do the check against the caller's permissions even though it looks 7047 // to the content provider like the Activity Manager itself is making 7048 // the request. 7049 sCallerIdentity.set(new Identity( 7050 Binder.getCallingPid(), Binder.getCallingUid())); 7051 try { 7052 pfd = cph.provider.openFile(uri, "r"); 7053 } catch (FileNotFoundException e) { 7054 // do nothing; pfd will be returned null 7055 } finally { 7056 // Ensure that whatever happens, we clean up the identity state 7057 sCallerIdentity.remove(); 7058 } 7059 7060 // We've got the fd now, so we're done with the provider. 7061 removeContentProviderExternalUnchecked(name, null, userId); 7062 } else { 7063 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7064 } 7065 return pfd; 7066 } 7067 7068 // Actually is sleeping or shutting down or whatever else in the future 7069 // is an inactive state. 7070 public boolean isSleeping() { 7071 return mSleeping || mShuttingDown; 7072 } 7073 7074 public void goingToSleep() { 7075 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7076 != PackageManager.PERMISSION_GRANTED) { 7077 throw new SecurityException("Requires permission " 7078 + android.Manifest.permission.DEVICE_POWER); 7079 } 7080 7081 synchronized(this) { 7082 mWentToSleep = true; 7083 updateEventDispatchingLocked(); 7084 7085 if (!mSleeping) { 7086 mSleeping = true; 7087 mMainStack.stopIfSleepingLocked(); 7088 7089 // Initialize the wake times of all processes. 7090 checkExcessivePowerUsageLocked(false); 7091 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7092 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7093 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7094 } 7095 } 7096 } 7097 7098 public boolean shutdown(int timeout) { 7099 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7100 != PackageManager.PERMISSION_GRANTED) { 7101 throw new SecurityException("Requires permission " 7102 + android.Manifest.permission.SHUTDOWN); 7103 } 7104 7105 boolean timedout = false; 7106 7107 synchronized(this) { 7108 mShuttingDown = true; 7109 updateEventDispatchingLocked(); 7110 7111 if (mMainStack.mResumedActivity != null) { 7112 mMainStack.stopIfSleepingLocked(); 7113 final long endTime = System.currentTimeMillis() + timeout; 7114 while (mMainStack.mResumedActivity != null 7115 || mMainStack.mPausingActivity != null) { 7116 long delay = endTime - System.currentTimeMillis(); 7117 if (delay <= 0) { 7118 Slog.w(TAG, "Activity manager shutdown timed out"); 7119 timedout = true; 7120 break; 7121 } 7122 try { 7123 this.wait(); 7124 } catch (InterruptedException e) { 7125 } 7126 } 7127 } 7128 } 7129 7130 mUsageStatsService.shutdown(); 7131 mBatteryStatsService.shutdown(); 7132 7133 return timedout; 7134 } 7135 7136 public final void activitySlept(IBinder token) { 7137 if (localLOGV) Slog.v( 7138 TAG, "Activity slept: token=" + token); 7139 7140 ActivityRecord r = null; 7141 7142 final long origId = Binder.clearCallingIdentity(); 7143 7144 synchronized (this) { 7145 r = mMainStack.isInStackLocked(token); 7146 if (r != null) { 7147 mMainStack.activitySleptLocked(r); 7148 } 7149 } 7150 7151 Binder.restoreCallingIdentity(origId); 7152 } 7153 7154 private void comeOutOfSleepIfNeededLocked() { 7155 if (!mWentToSleep && !mLockScreenShown) { 7156 if (mSleeping) { 7157 mSleeping = false; 7158 mMainStack.awakeFromSleepingLocked(); 7159 mMainStack.resumeTopActivityLocked(null); 7160 } 7161 } 7162 } 7163 7164 public void wakingUp() { 7165 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7166 != PackageManager.PERMISSION_GRANTED) { 7167 throw new SecurityException("Requires permission " 7168 + android.Manifest.permission.DEVICE_POWER); 7169 } 7170 7171 synchronized(this) { 7172 mWentToSleep = false; 7173 updateEventDispatchingLocked(); 7174 comeOutOfSleepIfNeededLocked(); 7175 } 7176 } 7177 7178 private void updateEventDispatchingLocked() { 7179 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7180 } 7181 7182 public void setLockScreenShown(boolean shown) { 7183 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7184 != PackageManager.PERMISSION_GRANTED) { 7185 throw new SecurityException("Requires permission " 7186 + android.Manifest.permission.DEVICE_POWER); 7187 } 7188 7189 synchronized(this) { 7190 mLockScreenShown = shown; 7191 comeOutOfSleepIfNeededLocked(); 7192 } 7193 } 7194 7195 public void stopAppSwitches() { 7196 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7197 != PackageManager.PERMISSION_GRANTED) { 7198 throw new SecurityException("Requires permission " 7199 + android.Manifest.permission.STOP_APP_SWITCHES); 7200 } 7201 7202 synchronized(this) { 7203 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7204 + APP_SWITCH_DELAY_TIME; 7205 mDidAppSwitch = false; 7206 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7207 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7208 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7209 } 7210 } 7211 7212 public void resumeAppSwitches() { 7213 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7214 != PackageManager.PERMISSION_GRANTED) { 7215 throw new SecurityException("Requires permission " 7216 + android.Manifest.permission.STOP_APP_SWITCHES); 7217 } 7218 7219 synchronized(this) { 7220 // Note that we don't execute any pending app switches... we will 7221 // let those wait until either the timeout, or the next start 7222 // activity request. 7223 mAppSwitchesAllowedTime = 0; 7224 } 7225 } 7226 7227 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7228 String name) { 7229 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7230 return true; 7231 } 7232 7233 final int perm = checkComponentPermission( 7234 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7235 callingUid, -1, true); 7236 if (perm == PackageManager.PERMISSION_GRANTED) { 7237 return true; 7238 } 7239 7240 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7241 return false; 7242 } 7243 7244 public void setDebugApp(String packageName, boolean waitForDebugger, 7245 boolean persistent) { 7246 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7247 "setDebugApp()"); 7248 7249 // Note that this is not really thread safe if there are multiple 7250 // callers into it at the same time, but that's not a situation we 7251 // care about. 7252 if (persistent) { 7253 final ContentResolver resolver = mContext.getContentResolver(); 7254 Settings.Global.putString( 7255 resolver, Settings.Global.DEBUG_APP, 7256 packageName); 7257 Settings.Global.putInt( 7258 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 7259 waitForDebugger ? 1 : 0); 7260 } 7261 7262 synchronized (this) { 7263 if (!persistent) { 7264 mOrigDebugApp = mDebugApp; 7265 mOrigWaitForDebugger = mWaitForDebugger; 7266 } 7267 mDebugApp = packageName; 7268 mWaitForDebugger = waitForDebugger; 7269 mDebugTransient = !persistent; 7270 if (packageName != null) { 7271 final long origId = Binder.clearCallingIdentity(); 7272 forceStopPackageLocked(packageName, -1, false, false, true, true, 7273 UserHandle.USER_ALL); 7274 Binder.restoreCallingIdentity(origId); 7275 } 7276 } 7277 } 7278 7279 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7280 synchronized (this) { 7281 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7282 if (!isDebuggable) { 7283 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7284 throw new SecurityException("Process not debuggable: " + app.packageName); 7285 } 7286 } 7287 7288 mOpenGlTraceApp = processName; 7289 } 7290 } 7291 7292 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7293 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7294 synchronized (this) { 7295 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7296 if (!isDebuggable) { 7297 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7298 throw new SecurityException("Process not debuggable: " + app.packageName); 7299 } 7300 } 7301 mProfileApp = processName; 7302 mProfileFile = profileFile; 7303 if (mProfileFd != null) { 7304 try { 7305 mProfileFd.close(); 7306 } catch (IOException e) { 7307 } 7308 mProfileFd = null; 7309 } 7310 mProfileFd = profileFd; 7311 mProfileType = 0; 7312 mAutoStopProfiler = autoStopProfiler; 7313 } 7314 } 7315 7316 public void setAlwaysFinish(boolean enabled) { 7317 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7318 "setAlwaysFinish()"); 7319 7320 Settings.Global.putInt( 7321 mContext.getContentResolver(), 7322 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7323 7324 synchronized (this) { 7325 mAlwaysFinishActivities = enabled; 7326 } 7327 } 7328 7329 public void setActivityController(IActivityController controller) { 7330 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7331 "setActivityController()"); 7332 synchronized (this) { 7333 mController = controller; 7334 } 7335 } 7336 7337 public boolean isUserAMonkey() { 7338 // For now the fact that there is a controller implies 7339 // we have a monkey. 7340 synchronized (this) { 7341 return mController != null; 7342 } 7343 } 7344 7345 public void requestBugReport() { 7346 // No permission check because this can't do anything harmful -- 7347 // it will just eventually cause the user to be presented with 7348 // a UI to select where the bug report goes. 7349 SystemProperties.set("ctl.start", "bugreport"); 7350 } 7351 7352 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) { 7353 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7354 != PackageManager.PERMISSION_GRANTED) { 7355 throw new SecurityException("Requires permission " 7356 + android.Manifest.permission.FILTER_EVENTS); 7357 } 7358 7359 ProcessRecord proc; 7360 7361 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut(). 7362 synchronized (this) { 7363 synchronized (mPidsSelfLocked) { 7364 proc = mPidsSelfLocked.get(pid); 7365 } 7366 if (proc != null) { 7367 if (proc.debugging) { 7368 return -1; 7369 } 7370 7371 if (mDidDexOpt) { 7372 // Give more time since we were dexopting. 7373 mDidDexOpt = false; 7374 return -1; 7375 } 7376 7377 if (proc.instrumentationClass != null) { 7378 Bundle info = new Bundle(); 7379 info.putString("shortMsg", "keyDispatchingTimedOut"); 7380 info.putString("longMsg", "Timed out while dispatching key event"); 7381 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 7382 proc = null; 7383 } 7384 } 7385 } 7386 7387 if (proc != null) { 7388 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut"); 7389 if (proc.instrumentationClass != null || proc.usingWrapper) { 7390 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 7391 } 7392 } 7393 7394 return KEY_DISPATCHING_TIMEOUT; 7395 } 7396 7397 public void registerProcessObserver(IProcessObserver observer) { 7398 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7399 "registerProcessObserver()"); 7400 synchronized (this) { 7401 mProcessObservers.register(observer); 7402 } 7403 } 7404 7405 public void unregisterProcessObserver(IProcessObserver observer) { 7406 synchronized (this) { 7407 mProcessObservers.unregister(observer); 7408 } 7409 } 7410 7411 public void setImmersive(IBinder token, boolean immersive) { 7412 synchronized(this) { 7413 ActivityRecord r = mMainStack.isInStackLocked(token); 7414 if (r == null) { 7415 throw new IllegalArgumentException(); 7416 } 7417 r.immersive = immersive; 7418 } 7419 } 7420 7421 public boolean isImmersive(IBinder token) { 7422 synchronized (this) { 7423 ActivityRecord r = mMainStack.isInStackLocked(token); 7424 if (r == null) { 7425 throw new IllegalArgumentException(); 7426 } 7427 return r.immersive; 7428 } 7429 } 7430 7431 public boolean isTopActivityImmersive() { 7432 enforceNotIsolatedCaller("startActivity"); 7433 synchronized (this) { 7434 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7435 return (r != null) ? r.immersive : false; 7436 } 7437 } 7438 7439 public final void enterSafeMode() { 7440 synchronized(this) { 7441 // It only makes sense to do this before the system is ready 7442 // and started launching other packages. 7443 if (!mSystemReady) { 7444 try { 7445 AppGlobals.getPackageManager().enterSafeMode(); 7446 } catch (RemoteException e) { 7447 } 7448 } 7449 } 7450 } 7451 7452 public final void showSafeModeOverlay() { 7453 View v = LayoutInflater.from(mContext).inflate( 7454 com.android.internal.R.layout.safe_mode, null); 7455 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7456 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7457 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7458 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7459 lp.gravity = Gravity.BOTTOM | Gravity.START; 7460 lp.format = v.getBackground().getOpacity(); 7461 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7462 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7463 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 7464 ((WindowManager)mContext.getSystemService( 7465 Context.WINDOW_SERVICE)).addView(v, lp); 7466 } 7467 7468 public void noteWakeupAlarm(IIntentSender sender) { 7469 if (!(sender instanceof PendingIntentRecord)) { 7470 return; 7471 } 7472 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7473 synchronized (stats) { 7474 if (mBatteryStatsService.isOnBattery()) { 7475 mBatteryStatsService.enforceCallingPermission(); 7476 PendingIntentRecord rec = (PendingIntentRecord)sender; 7477 int MY_UID = Binder.getCallingUid(); 7478 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7479 BatteryStatsImpl.Uid.Pkg pkg = 7480 stats.getPackageStatsLocked(uid, rec.key.packageName); 7481 pkg.incWakeupsLocked(); 7482 } 7483 } 7484 } 7485 7486 public boolean killPids(int[] pids, String pReason, boolean secure) { 7487 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7488 throw new SecurityException("killPids only available to the system"); 7489 } 7490 String reason = (pReason == null) ? "Unknown" : pReason; 7491 // XXX Note: don't acquire main activity lock here, because the window 7492 // manager calls in with its locks held. 7493 7494 boolean killed = false; 7495 synchronized (mPidsSelfLocked) { 7496 int[] types = new int[pids.length]; 7497 int worstType = 0; 7498 for (int i=0; i<pids.length; i++) { 7499 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7500 if (proc != null) { 7501 int type = proc.setAdj; 7502 types[i] = type; 7503 if (type > worstType) { 7504 worstType = type; 7505 } 7506 } 7507 } 7508 7509 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7510 // then constrain it so we will kill all hidden procs. 7511 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7512 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7513 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7514 } 7515 7516 // If this is not a secure call, don't let it kill processes that 7517 // are important. 7518 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7519 worstType = ProcessList.SERVICE_ADJ; 7520 } 7521 7522 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7523 for (int i=0; i<pids.length; i++) { 7524 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7525 if (proc == null) { 7526 continue; 7527 } 7528 int adj = proc.setAdj; 7529 if (adj >= worstType && !proc.killedBackground) { 7530 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7531 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7532 proc.processName, adj, reason); 7533 killed = true; 7534 proc.killedBackground = true; 7535 Process.killProcessQuiet(pids[i]); 7536 } 7537 } 7538 } 7539 return killed; 7540 } 7541 7542 @Override 7543 public boolean killProcessesBelowForeground(String reason) { 7544 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7545 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7546 } 7547 7548 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7549 } 7550 7551 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7552 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7553 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7554 } 7555 7556 boolean killed = false; 7557 synchronized (mPidsSelfLocked) { 7558 final int size = mPidsSelfLocked.size(); 7559 for (int i = 0; i < size; i++) { 7560 final int pid = mPidsSelfLocked.keyAt(i); 7561 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7562 if (proc == null) continue; 7563 7564 final int adj = proc.setAdj; 7565 if (adj > belowAdj && !proc.killedBackground) { 7566 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7567 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7568 proc.pid, proc.processName, adj, reason); 7569 killed = true; 7570 proc.killedBackground = true; 7571 Process.killProcessQuiet(pid); 7572 } 7573 } 7574 } 7575 return killed; 7576 } 7577 7578 public final void startRunning(String pkg, String cls, String action, 7579 String data) { 7580 synchronized(this) { 7581 if (mStartRunning) { 7582 return; 7583 } 7584 mStartRunning = true; 7585 mTopComponent = pkg != null && cls != null 7586 ? new ComponentName(pkg, cls) : null; 7587 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7588 mTopData = data; 7589 if (!mSystemReady) { 7590 return; 7591 } 7592 } 7593 7594 systemReady(null); 7595 } 7596 7597 private void retrieveSettings() { 7598 final ContentResolver resolver = mContext.getContentResolver(); 7599 String debugApp = Settings.Global.getString( 7600 resolver, Settings.Global.DEBUG_APP); 7601 boolean waitForDebugger = Settings.Global.getInt( 7602 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 7603 boolean alwaysFinishActivities = Settings.Global.getInt( 7604 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7605 7606 Configuration configuration = new Configuration(); 7607 Settings.System.getConfiguration(resolver, configuration); 7608 7609 synchronized (this) { 7610 mDebugApp = mOrigDebugApp = debugApp; 7611 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7612 mAlwaysFinishActivities = alwaysFinishActivities; 7613 // This happens before any activities are started, so we can 7614 // change mConfiguration in-place. 7615 updateConfigurationLocked(configuration, null, false, true); 7616 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7617 } 7618 } 7619 7620 public boolean testIsSystemReady() { 7621 // no need to synchronize(this) just to read & return the value 7622 return mSystemReady; 7623 } 7624 7625 private static File getCalledPreBootReceiversFile() { 7626 File dataDir = Environment.getDataDirectory(); 7627 File systemDir = new File(dataDir, "system"); 7628 File fname = new File(systemDir, "called_pre_boots.dat"); 7629 return fname; 7630 } 7631 7632 static final int LAST_DONE_VERSION = 10000; 7633 7634 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7635 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7636 File file = getCalledPreBootReceiversFile(); 7637 FileInputStream fis = null; 7638 try { 7639 fis = new FileInputStream(file); 7640 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7641 int fvers = dis.readInt(); 7642 if (fvers == LAST_DONE_VERSION) { 7643 String vers = dis.readUTF(); 7644 String codename = dis.readUTF(); 7645 String build = dis.readUTF(); 7646 if (android.os.Build.VERSION.RELEASE.equals(vers) 7647 && android.os.Build.VERSION.CODENAME.equals(codename) 7648 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7649 int num = dis.readInt(); 7650 while (num > 0) { 7651 num--; 7652 String pkg = dis.readUTF(); 7653 String cls = dis.readUTF(); 7654 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7655 } 7656 } 7657 } 7658 } catch (FileNotFoundException e) { 7659 } catch (IOException e) { 7660 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7661 } finally { 7662 if (fis != null) { 7663 try { 7664 fis.close(); 7665 } catch (IOException e) { 7666 } 7667 } 7668 } 7669 return lastDoneReceivers; 7670 } 7671 7672 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7673 File file = getCalledPreBootReceiversFile(); 7674 FileOutputStream fos = null; 7675 DataOutputStream dos = null; 7676 try { 7677 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7678 fos = new FileOutputStream(file); 7679 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7680 dos.writeInt(LAST_DONE_VERSION); 7681 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7682 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7683 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7684 dos.writeInt(list.size()); 7685 for (int i=0; i<list.size(); i++) { 7686 dos.writeUTF(list.get(i).getPackageName()); 7687 dos.writeUTF(list.get(i).getClassName()); 7688 } 7689 } catch (IOException e) { 7690 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7691 file.delete(); 7692 } finally { 7693 FileUtils.sync(fos); 7694 if (dos != null) { 7695 try { 7696 dos.close(); 7697 } catch (IOException e) { 7698 // TODO Auto-generated catch block 7699 e.printStackTrace(); 7700 } 7701 } 7702 } 7703 } 7704 7705 public void systemReady(final Runnable goingCallback) { 7706 synchronized(this) { 7707 if (mSystemReady) { 7708 if (goingCallback != null) goingCallback.run(); 7709 return; 7710 } 7711 7712 // Check to see if there are any update receivers to run. 7713 if (!mDidUpdate) { 7714 if (mWaitingUpdate) { 7715 return; 7716 } 7717 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7718 List<ResolveInfo> ris = null; 7719 try { 7720 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7721 intent, null, 0, 0); 7722 } catch (RemoteException e) { 7723 } 7724 if (ris != null) { 7725 for (int i=ris.size()-1; i>=0; i--) { 7726 if ((ris.get(i).activityInfo.applicationInfo.flags 7727 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7728 ris.remove(i); 7729 } 7730 } 7731 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7732 7733 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7734 7735 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7736 for (int i=0; i<ris.size(); i++) { 7737 ActivityInfo ai = ris.get(i).activityInfo; 7738 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7739 if (lastDoneReceivers.contains(comp)) { 7740 ris.remove(i); 7741 i--; 7742 } 7743 } 7744 7745 final int[] users = getUsersLocked(); 7746 for (int i=0; i<ris.size(); i++) { 7747 ActivityInfo ai = ris.get(i).activityInfo; 7748 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7749 doneReceivers.add(comp); 7750 intent.setComponent(comp); 7751 for (int j=0; j<users.length; j++) { 7752 IIntentReceiver finisher = null; 7753 if (i == ris.size()-1 && j == users.length-1) { 7754 finisher = new IIntentReceiver.Stub() { 7755 public void performReceive(Intent intent, int resultCode, 7756 String data, Bundle extras, boolean ordered, 7757 boolean sticky, int sendingUser) { 7758 // The raw IIntentReceiver interface is called 7759 // with the AM lock held, so redispatch to 7760 // execute our code without the lock. 7761 mHandler.post(new Runnable() { 7762 public void run() { 7763 synchronized (ActivityManagerService.this) { 7764 mDidUpdate = true; 7765 } 7766 writeLastDonePreBootReceivers(doneReceivers); 7767 showBootMessage(mContext.getText( 7768 R.string.android_upgrading_complete), 7769 false); 7770 systemReady(goingCallback); 7771 } 7772 }); 7773 } 7774 }; 7775 } 7776 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7777 + " for user " + users[j]); 7778 broadcastIntentLocked(null, null, intent, null, finisher, 7779 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7780 users[j]); 7781 if (finisher != null) { 7782 mWaitingUpdate = true; 7783 } 7784 } 7785 } 7786 } 7787 if (mWaitingUpdate) { 7788 return; 7789 } 7790 mDidUpdate = true; 7791 } 7792 7793 mSystemReady = true; 7794 if (!mStartRunning) { 7795 return; 7796 } 7797 } 7798 7799 ArrayList<ProcessRecord> procsToKill = null; 7800 synchronized(mPidsSelfLocked) { 7801 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7802 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7803 if (!isAllowedWhileBooting(proc.info)){ 7804 if (procsToKill == null) { 7805 procsToKill = new ArrayList<ProcessRecord>(); 7806 } 7807 procsToKill.add(proc); 7808 } 7809 } 7810 } 7811 7812 synchronized(this) { 7813 if (procsToKill != null) { 7814 for (int i=procsToKill.size()-1; i>=0; i--) { 7815 ProcessRecord proc = procsToKill.get(i); 7816 Slog.i(TAG, "Removing system update proc: " + proc); 7817 removeProcessLocked(proc, true, false, "system update done"); 7818 } 7819 } 7820 7821 // Now that we have cleaned up any update processes, we 7822 // are ready to start launching real processes and know that 7823 // we won't trample on them any more. 7824 mProcessesReady = true; 7825 } 7826 7827 Slog.i(TAG, "System now ready"); 7828 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7829 SystemClock.uptimeMillis()); 7830 7831 synchronized(this) { 7832 // Make sure we have no pre-ready processes sitting around. 7833 7834 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7835 ResolveInfo ri = mContext.getPackageManager() 7836 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7837 STOCK_PM_FLAGS); 7838 CharSequence errorMsg = null; 7839 if (ri != null) { 7840 ActivityInfo ai = ri.activityInfo; 7841 ApplicationInfo app = ai.applicationInfo; 7842 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7843 mTopAction = Intent.ACTION_FACTORY_TEST; 7844 mTopData = null; 7845 mTopComponent = new ComponentName(app.packageName, 7846 ai.name); 7847 } else { 7848 errorMsg = mContext.getResources().getText( 7849 com.android.internal.R.string.factorytest_not_system); 7850 } 7851 } else { 7852 errorMsg = mContext.getResources().getText( 7853 com.android.internal.R.string.factorytest_no_action); 7854 } 7855 if (errorMsg != null) { 7856 mTopAction = null; 7857 mTopData = null; 7858 mTopComponent = null; 7859 Message msg = Message.obtain(); 7860 msg.what = SHOW_FACTORY_ERROR_MSG; 7861 msg.getData().putCharSequence("msg", errorMsg); 7862 mHandler.sendMessage(msg); 7863 } 7864 } 7865 } 7866 7867 retrieveSettings(); 7868 7869 if (goingCallback != null) goingCallback.run(); 7870 7871 synchronized (this) { 7872 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7873 try { 7874 List apps = AppGlobals.getPackageManager(). 7875 getPersistentApplications(STOCK_PM_FLAGS); 7876 if (apps != null) { 7877 int N = apps.size(); 7878 int i; 7879 for (i=0; i<N; i++) { 7880 ApplicationInfo info 7881 = (ApplicationInfo)apps.get(i); 7882 if (info != null && 7883 !info.packageName.equals("android")) { 7884 addAppLocked(info, false); 7885 } 7886 } 7887 } 7888 } catch (RemoteException ex) { 7889 // pm is in same process, this will never happen. 7890 } 7891 } 7892 7893 // Start up initial activity. 7894 mBooting = true; 7895 7896 try { 7897 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7898 Message msg = Message.obtain(); 7899 msg.what = SHOW_UID_ERROR_MSG; 7900 mHandler.sendMessage(msg); 7901 } 7902 } catch (RemoteException e) { 7903 } 7904 7905 long ident = Binder.clearCallingIdentity(); 7906 try { 7907 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7908 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 7909 | Intent.FLAG_RECEIVER_FOREGROUND); 7910 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7911 broadcastIntentLocked(null, null, intent, 7912 null, null, 0, null, null, null, 7913 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7914 intent = new Intent(Intent.ACTION_USER_STARTING); 7915 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7916 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7917 broadcastIntentLocked(null, null, intent, 7918 null, new IIntentReceiver.Stub() { 7919 @Override 7920 public void performReceive(Intent intent, int resultCode, String data, 7921 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 7922 throws RemoteException { 7923 } 7924 }, 0, null, null, 7925 android.Manifest.permission.INTERACT_ACROSS_USERS, 7926 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 7927 } finally { 7928 Binder.restoreCallingIdentity(ident); 7929 } 7930 mMainStack.resumeTopActivityLocked(null); 7931 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7932 } 7933 } 7934 7935 private boolean makeAppCrashingLocked(ProcessRecord app, 7936 String shortMsg, String longMsg, String stackTrace) { 7937 app.crashing = true; 7938 app.crashingReport = generateProcessError(app, 7939 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7940 startAppProblemLocked(app); 7941 app.stopFreezingAllLocked(); 7942 return handleAppCrashLocked(app); 7943 } 7944 7945 private void makeAppNotRespondingLocked(ProcessRecord app, 7946 String activity, String shortMsg, String longMsg) { 7947 app.notResponding = true; 7948 app.notRespondingReport = generateProcessError(app, 7949 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7950 activity, shortMsg, longMsg, null); 7951 startAppProblemLocked(app); 7952 app.stopFreezingAllLocked(); 7953 } 7954 7955 /** 7956 * Generate a process error record, suitable for attachment to a ProcessRecord. 7957 * 7958 * @param app The ProcessRecord in which the error occurred. 7959 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7960 * ActivityManager.AppErrorStateInfo 7961 * @param activity The activity associated with the crash, if known. 7962 * @param shortMsg Short message describing the crash. 7963 * @param longMsg Long message describing the crash. 7964 * @param stackTrace Full crash stack trace, may be null. 7965 * 7966 * @return Returns a fully-formed AppErrorStateInfo record. 7967 */ 7968 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7969 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7970 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7971 7972 report.condition = condition; 7973 report.processName = app.processName; 7974 report.pid = app.pid; 7975 report.uid = app.info.uid; 7976 report.tag = activity; 7977 report.shortMsg = shortMsg; 7978 report.longMsg = longMsg; 7979 report.stackTrace = stackTrace; 7980 7981 return report; 7982 } 7983 7984 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7985 synchronized (this) { 7986 app.crashing = false; 7987 app.crashingReport = null; 7988 app.notResponding = false; 7989 app.notRespondingReport = null; 7990 if (app.anrDialog == fromDialog) { 7991 app.anrDialog = null; 7992 } 7993 if (app.waitDialog == fromDialog) { 7994 app.waitDialog = null; 7995 } 7996 if (app.pid > 0 && app.pid != MY_PID) { 7997 handleAppCrashLocked(app); 7998 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7999 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 8000 app.processName, app.setAdj, "user's request after error"); 8001 Process.killProcessQuiet(app.pid); 8002 } 8003 } 8004 } 8005 8006 private boolean handleAppCrashLocked(ProcessRecord app) { 8007 if (mHeadless) { 8008 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 8009 return false; 8010 } 8011 long now = SystemClock.uptimeMillis(); 8012 8013 Long crashTime; 8014 if (!app.isolated) { 8015 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 8016 } else { 8017 crashTime = null; 8018 } 8019 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 8020 // This process loses! 8021 Slog.w(TAG, "Process " + app.info.processName 8022 + " has crashed too many times: killing!"); 8023 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8024 app.userId, app.info.processName, app.uid); 8025 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8026 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8027 if (r.app == app) { 8028 Slog.w(TAG, " Force finishing activity " 8029 + r.intent.getComponent().flattenToShortString()); 8030 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8031 null, "crashed", false); 8032 } 8033 } 8034 if (!app.persistent) { 8035 // We don't want to start this process again until the user 8036 // explicitly does so... but for persistent process, we really 8037 // need to keep it running. If a persistent process is actually 8038 // repeatedly crashing, then badness for everyone. 8039 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 8040 app.info.processName); 8041 if (!app.isolated) { 8042 // XXX We don't have a way to mark isolated processes 8043 // as bad, since they don't have a peristent identity. 8044 mBadProcesses.put(app.info.processName, app.uid, now); 8045 mProcessCrashTimes.remove(app.info.processName, app.uid); 8046 } 8047 app.bad = true; 8048 app.removed = true; 8049 // Don't let services in this process be restarted and potentially 8050 // annoy the user repeatedly. Unless it is persistent, since those 8051 // processes run critical code. 8052 removeProcessLocked(app, false, false, "crash"); 8053 mMainStack.resumeTopActivityLocked(null); 8054 return false; 8055 } 8056 mMainStack.resumeTopActivityLocked(null); 8057 } else { 8058 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8059 if (r != null && r.app == app) { 8060 // If the top running activity is from this crashing 8061 // process, then terminate it to avoid getting in a loop. 8062 Slog.w(TAG, " Force finishing activity " 8063 + r.intent.getComponent().flattenToShortString()); 8064 int index = mMainStack.indexOfActivityLocked(r); 8065 r.stack.finishActivityLocked(r, index, 8066 Activity.RESULT_CANCELED, null, "crashed", false); 8067 // Also terminate any activities below it that aren't yet 8068 // stopped, to avoid a situation where one will get 8069 // re-start our crashing activity once it gets resumed again. 8070 index--; 8071 if (index >= 0) { 8072 r = (ActivityRecord)mMainStack.mHistory.get(index); 8073 if (r.state == ActivityState.RESUMED 8074 || r.state == ActivityState.PAUSING 8075 || r.state == ActivityState.PAUSED) { 8076 if (!r.isHomeActivity || mHomeProcess != r.app) { 8077 Slog.w(TAG, " Force finishing activity " 8078 + r.intent.getComponent().flattenToShortString()); 8079 r.stack.finishActivityLocked(r, index, 8080 Activity.RESULT_CANCELED, null, "crashed", false); 8081 } 8082 } 8083 } 8084 } 8085 } 8086 8087 // Bump up the crash count of any services currently running in the proc. 8088 if (app.services.size() != 0) { 8089 // Any services running in the application need to be placed 8090 // back in the pending list. 8091 Iterator<ServiceRecord> it = app.services.iterator(); 8092 while (it.hasNext()) { 8093 ServiceRecord sr = it.next(); 8094 sr.crashCount++; 8095 } 8096 } 8097 8098 // If the crashing process is what we consider to be the "home process" and it has been 8099 // replaced by a third-party app, clear the package preferred activities from packages 8100 // with a home activity running in the process to prevent a repeatedly crashing app 8101 // from blocking the user to manually clear the list. 8102 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8103 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8104 Iterator it = mHomeProcess.activities.iterator(); 8105 while (it.hasNext()) { 8106 ActivityRecord r = (ActivityRecord)it.next(); 8107 if (r.isHomeActivity) { 8108 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8109 try { 8110 ActivityThread.getPackageManager() 8111 .clearPackagePreferredActivities(r.packageName); 8112 } catch (RemoteException c) { 8113 // pm is in same process, this will never happen. 8114 } 8115 } 8116 } 8117 } 8118 8119 if (!app.isolated) { 8120 // XXX Can't keep track of crash times for isolated processes, 8121 // because they don't have a perisistent identity. 8122 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8123 } 8124 8125 return true; 8126 } 8127 8128 void startAppProblemLocked(ProcessRecord app) { 8129 if (app.userId == mCurrentUserId) { 8130 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8131 mContext, app.info.packageName, app.info.flags); 8132 } else { 8133 // If this app is not running under the current user, then we 8134 // can't give it a report button because that would require 8135 // launching the report UI under a different user. 8136 app.errorReportReceiver = null; 8137 } 8138 skipCurrentReceiverLocked(app); 8139 } 8140 8141 void skipCurrentReceiverLocked(ProcessRecord app) { 8142 for (BroadcastQueue queue : mBroadcastQueues) { 8143 queue.skipCurrentReceiverLocked(app); 8144 } 8145 } 8146 8147 /** 8148 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8149 * The application process will exit immediately after this call returns. 8150 * @param app object of the crashing app, null for the system server 8151 * @param crashInfo describing the exception 8152 */ 8153 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8154 ProcessRecord r = findAppProcess(app, "Crash"); 8155 final String processName = app == null ? "system_server" 8156 : (r == null ? "unknown" : r.processName); 8157 8158 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8159 UserHandle.getUserId(Binder.getCallingUid()), processName, 8160 r == null ? -1 : r.info.flags, 8161 crashInfo.exceptionClassName, 8162 crashInfo.exceptionMessage, 8163 crashInfo.throwFileName, 8164 crashInfo.throwLineNumber); 8165 8166 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8167 8168 crashApplication(r, crashInfo); 8169 } 8170 8171 public void handleApplicationStrictModeViolation( 8172 IBinder app, 8173 int violationMask, 8174 StrictMode.ViolationInfo info) { 8175 ProcessRecord r = findAppProcess(app, "StrictMode"); 8176 if (r == null) { 8177 return; 8178 } 8179 8180 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8181 Integer stackFingerprint = info.hashCode(); 8182 boolean logIt = true; 8183 synchronized (mAlreadyLoggedViolatedStacks) { 8184 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8185 logIt = false; 8186 // TODO: sub-sample into EventLog for these, with 8187 // the info.durationMillis? Then we'd get 8188 // the relative pain numbers, without logging all 8189 // the stack traces repeatedly. We'd want to do 8190 // likewise in the client code, which also does 8191 // dup suppression, before the Binder call. 8192 } else { 8193 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8194 mAlreadyLoggedViolatedStacks.clear(); 8195 } 8196 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8197 } 8198 } 8199 if (logIt) { 8200 logStrictModeViolationToDropBox(r, info); 8201 } 8202 } 8203 8204 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8205 AppErrorResult result = new AppErrorResult(); 8206 synchronized (this) { 8207 final long origId = Binder.clearCallingIdentity(); 8208 8209 Message msg = Message.obtain(); 8210 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8211 HashMap<String, Object> data = new HashMap<String, Object>(); 8212 data.put("result", result); 8213 data.put("app", r); 8214 data.put("violationMask", violationMask); 8215 data.put("info", info); 8216 msg.obj = data; 8217 mHandler.sendMessage(msg); 8218 8219 Binder.restoreCallingIdentity(origId); 8220 } 8221 int res = result.get(); 8222 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8223 } 8224 } 8225 8226 // Depending on the policy in effect, there could be a bunch of 8227 // these in quick succession so we try to batch these together to 8228 // minimize disk writes, number of dropbox entries, and maximize 8229 // compression, by having more fewer, larger records. 8230 private void logStrictModeViolationToDropBox( 8231 ProcessRecord process, 8232 StrictMode.ViolationInfo info) { 8233 if (info == null) { 8234 return; 8235 } 8236 final boolean isSystemApp = process == null || 8237 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8238 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8239 final String processName = process == null ? "unknown" : process.processName; 8240 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8241 final DropBoxManager dbox = (DropBoxManager) 8242 mContext.getSystemService(Context.DROPBOX_SERVICE); 8243 8244 // Exit early if the dropbox isn't configured to accept this report type. 8245 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8246 8247 boolean bufferWasEmpty; 8248 boolean needsFlush; 8249 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8250 synchronized (sb) { 8251 bufferWasEmpty = sb.length() == 0; 8252 appendDropBoxProcessHeaders(process, processName, sb); 8253 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8254 sb.append("System-App: ").append(isSystemApp).append("\n"); 8255 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8256 if (info.violationNumThisLoop != 0) { 8257 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8258 } 8259 if (info.numAnimationsRunning != 0) { 8260 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8261 } 8262 if (info.broadcastIntentAction != null) { 8263 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8264 } 8265 if (info.durationMillis != -1) { 8266 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8267 } 8268 if (info.numInstances != -1) { 8269 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8270 } 8271 if (info.tags != null) { 8272 for (String tag : info.tags) { 8273 sb.append("Span-Tag: ").append(tag).append("\n"); 8274 } 8275 } 8276 sb.append("\n"); 8277 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8278 sb.append(info.crashInfo.stackTrace); 8279 } 8280 sb.append("\n"); 8281 8282 // Only buffer up to ~64k. Various logging bits truncate 8283 // things at 128k. 8284 needsFlush = (sb.length() > 64 * 1024); 8285 } 8286 8287 // Flush immediately if the buffer's grown too large, or this 8288 // is a non-system app. Non-system apps are isolated with a 8289 // different tag & policy and not batched. 8290 // 8291 // Batching is useful during internal testing with 8292 // StrictMode settings turned up high. Without batching, 8293 // thousands of separate files could be created on boot. 8294 if (!isSystemApp || needsFlush) { 8295 new Thread("Error dump: " + dropboxTag) { 8296 @Override 8297 public void run() { 8298 String report; 8299 synchronized (sb) { 8300 report = sb.toString(); 8301 sb.delete(0, sb.length()); 8302 sb.trimToSize(); 8303 } 8304 if (report.length() != 0) { 8305 dbox.addText(dropboxTag, report); 8306 } 8307 } 8308 }.start(); 8309 return; 8310 } 8311 8312 // System app batching: 8313 if (!bufferWasEmpty) { 8314 // An existing dropbox-writing thread is outstanding, so 8315 // we don't need to start it up. The existing thread will 8316 // catch the buffer appends we just did. 8317 return; 8318 } 8319 8320 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8321 // (After this point, we shouldn't access AMS internal data structures.) 8322 new Thread("Error dump: " + dropboxTag) { 8323 @Override 8324 public void run() { 8325 // 5 second sleep to let stacks arrive and be batched together 8326 try { 8327 Thread.sleep(5000); // 5 seconds 8328 } catch (InterruptedException e) {} 8329 8330 String errorReport; 8331 synchronized (mStrictModeBuffer) { 8332 errorReport = mStrictModeBuffer.toString(); 8333 if (errorReport.length() == 0) { 8334 return; 8335 } 8336 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8337 mStrictModeBuffer.trimToSize(); 8338 } 8339 dbox.addText(dropboxTag, errorReport); 8340 } 8341 }.start(); 8342 } 8343 8344 /** 8345 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8346 * @param app object of the crashing app, null for the system server 8347 * @param tag reported by the caller 8348 * @param crashInfo describing the context of the error 8349 * @return true if the process should exit immediately (WTF is fatal) 8350 */ 8351 public boolean handleApplicationWtf(IBinder app, String tag, 8352 ApplicationErrorReport.CrashInfo crashInfo) { 8353 ProcessRecord r = findAppProcess(app, "WTF"); 8354 final String processName = app == null ? "system_server" 8355 : (r == null ? "unknown" : r.processName); 8356 8357 EventLog.writeEvent(EventLogTags.AM_WTF, 8358 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8359 processName, 8360 r == null ? -1 : r.info.flags, 8361 tag, crashInfo.exceptionMessage); 8362 8363 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8364 8365 if (r != null && r.pid != Process.myPid() && 8366 Settings.Global.getInt(mContext.getContentResolver(), 8367 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8368 crashApplication(r, crashInfo); 8369 return true; 8370 } else { 8371 return false; 8372 } 8373 } 8374 8375 /** 8376 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8377 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8378 */ 8379 private ProcessRecord findAppProcess(IBinder app, String reason) { 8380 if (app == null) { 8381 return null; 8382 } 8383 8384 synchronized (this) { 8385 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8386 final int NA = apps.size(); 8387 for (int ia=0; ia<NA; ia++) { 8388 ProcessRecord p = apps.valueAt(ia); 8389 if (p.thread != null && p.thread.asBinder() == app) { 8390 return p; 8391 } 8392 } 8393 } 8394 8395 Slog.w(TAG, "Can't find mystery application for " + reason 8396 + " from pid=" + Binder.getCallingPid() 8397 + " uid=" + Binder.getCallingUid() + ": " + app); 8398 return null; 8399 } 8400 } 8401 8402 /** 8403 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8404 * to append various headers to the dropbox log text. 8405 */ 8406 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8407 StringBuilder sb) { 8408 // Watchdog thread ends up invoking this function (with 8409 // a null ProcessRecord) to add the stack file to dropbox. 8410 // Do not acquire a lock on this (am) in such cases, as it 8411 // could cause a potential deadlock, if and when watchdog 8412 // is invoked due to unavailability of lock on am and it 8413 // would prevent watchdog from killing system_server. 8414 if (process == null) { 8415 sb.append("Process: ").append(processName).append("\n"); 8416 return; 8417 } 8418 // Note: ProcessRecord 'process' is guarded by the service 8419 // instance. (notably process.pkgList, which could otherwise change 8420 // concurrently during execution of this method) 8421 synchronized (this) { 8422 sb.append("Process: ").append(processName).append("\n"); 8423 int flags = process.info.flags; 8424 IPackageManager pm = AppGlobals.getPackageManager(); 8425 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8426 for (String pkg : process.pkgList) { 8427 sb.append("Package: ").append(pkg); 8428 try { 8429 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8430 if (pi != null) { 8431 sb.append(" v").append(pi.versionCode); 8432 if (pi.versionName != null) { 8433 sb.append(" (").append(pi.versionName).append(")"); 8434 } 8435 } 8436 } catch (RemoteException e) { 8437 Slog.e(TAG, "Error getting package info: " + pkg, e); 8438 } 8439 sb.append("\n"); 8440 } 8441 } 8442 } 8443 8444 private static String processClass(ProcessRecord process) { 8445 if (process == null || process.pid == MY_PID) { 8446 return "system_server"; 8447 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8448 return "system_app"; 8449 } else { 8450 return "data_app"; 8451 } 8452 } 8453 8454 /** 8455 * Write a description of an error (crash, WTF, ANR) to the drop box. 8456 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8457 * @param process which caused the error, null means the system server 8458 * @param activity which triggered the error, null if unknown 8459 * @param parent activity related to the error, null if unknown 8460 * @param subject line related to the error, null if absent 8461 * @param report in long form describing the error, null if absent 8462 * @param logFile to include in the report, null if none 8463 * @param crashInfo giving an application stack trace, null if absent 8464 */ 8465 public void addErrorToDropBox(String eventType, 8466 ProcessRecord process, String processName, ActivityRecord activity, 8467 ActivityRecord parent, String subject, 8468 final String report, final File logFile, 8469 final ApplicationErrorReport.CrashInfo crashInfo) { 8470 // NOTE -- this must never acquire the ActivityManagerService lock, 8471 // otherwise the watchdog may be prevented from resetting the system. 8472 8473 final String dropboxTag = processClass(process) + "_" + eventType; 8474 final DropBoxManager dbox = (DropBoxManager) 8475 mContext.getSystemService(Context.DROPBOX_SERVICE); 8476 8477 // Exit early if the dropbox isn't configured to accept this report type. 8478 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8479 8480 final StringBuilder sb = new StringBuilder(1024); 8481 appendDropBoxProcessHeaders(process, processName, sb); 8482 if (activity != null) { 8483 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8484 } 8485 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8486 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8487 } 8488 if (parent != null && parent != activity) { 8489 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8490 } 8491 if (subject != null) { 8492 sb.append("Subject: ").append(subject).append("\n"); 8493 } 8494 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8495 if (Debug.isDebuggerConnected()) { 8496 sb.append("Debugger: Connected\n"); 8497 } 8498 sb.append("\n"); 8499 8500 // Do the rest in a worker thread to avoid blocking the caller on I/O 8501 // (After this point, we shouldn't access AMS internal data structures.) 8502 Thread worker = new Thread("Error dump: " + dropboxTag) { 8503 @Override 8504 public void run() { 8505 if (report != null) { 8506 sb.append(report); 8507 } 8508 if (logFile != null) { 8509 try { 8510 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8511 } catch (IOException e) { 8512 Slog.e(TAG, "Error reading " + logFile, e); 8513 } 8514 } 8515 if (crashInfo != null && crashInfo.stackTrace != null) { 8516 sb.append(crashInfo.stackTrace); 8517 } 8518 8519 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8520 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8521 if (lines > 0) { 8522 sb.append("\n"); 8523 8524 // Merge several logcat streams, and take the last N lines 8525 InputStreamReader input = null; 8526 try { 8527 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8528 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8529 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8530 8531 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8532 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8533 input = new InputStreamReader(logcat.getInputStream()); 8534 8535 int num; 8536 char[] buf = new char[8192]; 8537 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8538 } catch (IOException e) { 8539 Slog.e(TAG, "Error running logcat", e); 8540 } finally { 8541 if (input != null) try { input.close(); } catch (IOException e) {} 8542 } 8543 } 8544 8545 dbox.addText(dropboxTag, sb.toString()); 8546 } 8547 }; 8548 8549 if (process == null) { 8550 // If process is null, we are being called from some internal code 8551 // and may be about to die -- run this synchronously. 8552 worker.run(); 8553 } else { 8554 worker.start(); 8555 } 8556 } 8557 8558 /** 8559 * Bring up the "unexpected error" dialog box for a crashing app. 8560 * Deal with edge cases (intercepts from instrumented applications, 8561 * ActivityController, error intent receivers, that sort of thing). 8562 * @param r the application crashing 8563 * @param crashInfo describing the failure 8564 */ 8565 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8566 long timeMillis = System.currentTimeMillis(); 8567 String shortMsg = crashInfo.exceptionClassName; 8568 String longMsg = crashInfo.exceptionMessage; 8569 String stackTrace = crashInfo.stackTrace; 8570 if (shortMsg != null && longMsg != null) { 8571 longMsg = shortMsg + ": " + longMsg; 8572 } else if (shortMsg != null) { 8573 longMsg = shortMsg; 8574 } 8575 8576 AppErrorResult result = new AppErrorResult(); 8577 synchronized (this) { 8578 if (mController != null) { 8579 try { 8580 String name = r != null ? r.processName : null; 8581 int pid = r != null ? r.pid : Binder.getCallingPid(); 8582 if (!mController.appCrashed(name, pid, 8583 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8584 Slog.w(TAG, "Force-killing crashed app " + name 8585 + " at watcher's request"); 8586 Process.killProcess(pid); 8587 return; 8588 } 8589 } catch (RemoteException e) { 8590 mController = null; 8591 } 8592 } 8593 8594 final long origId = Binder.clearCallingIdentity(); 8595 8596 // If this process is running instrumentation, finish it. 8597 if (r != null && r.instrumentationClass != null) { 8598 Slog.w(TAG, "Error in app " + r.processName 8599 + " running instrumentation " + r.instrumentationClass + ":"); 8600 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8601 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8602 Bundle info = new Bundle(); 8603 info.putString("shortMsg", shortMsg); 8604 info.putString("longMsg", longMsg); 8605 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8606 Binder.restoreCallingIdentity(origId); 8607 return; 8608 } 8609 8610 // If we can't identify the process or it's already exceeded its crash quota, 8611 // quit right away without showing a crash dialog. 8612 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8613 Binder.restoreCallingIdentity(origId); 8614 return; 8615 } 8616 8617 Message msg = Message.obtain(); 8618 msg.what = SHOW_ERROR_MSG; 8619 HashMap data = new HashMap(); 8620 data.put("result", result); 8621 data.put("app", r); 8622 msg.obj = data; 8623 mHandler.sendMessage(msg); 8624 8625 Binder.restoreCallingIdentity(origId); 8626 } 8627 8628 int res = result.get(); 8629 8630 Intent appErrorIntent = null; 8631 synchronized (this) { 8632 if (r != null && !r.isolated) { 8633 // XXX Can't keep track of crash time for isolated processes, 8634 // since they don't have a persistent identity. 8635 mProcessCrashTimes.put(r.info.processName, r.uid, 8636 SystemClock.uptimeMillis()); 8637 } 8638 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8639 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8640 } 8641 } 8642 8643 if (appErrorIntent != null) { 8644 try { 8645 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8646 } catch (ActivityNotFoundException e) { 8647 Slog.w(TAG, "bug report receiver dissappeared", e); 8648 } 8649 } 8650 } 8651 8652 Intent createAppErrorIntentLocked(ProcessRecord r, 8653 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8654 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8655 if (report == null) { 8656 return null; 8657 } 8658 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8659 result.setComponent(r.errorReportReceiver); 8660 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8661 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8662 return result; 8663 } 8664 8665 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8666 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8667 if (r.errorReportReceiver == null) { 8668 return null; 8669 } 8670 8671 if (!r.crashing && !r.notResponding) { 8672 return null; 8673 } 8674 8675 ApplicationErrorReport report = new ApplicationErrorReport(); 8676 report.packageName = r.info.packageName; 8677 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8678 report.processName = r.processName; 8679 report.time = timeMillis; 8680 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8681 8682 if (r.crashing) { 8683 report.type = ApplicationErrorReport.TYPE_CRASH; 8684 report.crashInfo = crashInfo; 8685 } else if (r.notResponding) { 8686 report.type = ApplicationErrorReport.TYPE_ANR; 8687 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8688 8689 report.anrInfo.activity = r.notRespondingReport.tag; 8690 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8691 report.anrInfo.info = r.notRespondingReport.longMsg; 8692 } 8693 8694 return report; 8695 } 8696 8697 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8698 enforceNotIsolatedCaller("getProcessesInErrorState"); 8699 // assume our apps are happy - lazy create the list 8700 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8701 8702 final boolean allUsers = ActivityManager.checkUidPermission( 8703 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8704 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8705 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8706 8707 synchronized (this) { 8708 8709 // iterate across all processes 8710 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8711 ProcessRecord app = mLruProcesses.get(i); 8712 if (!allUsers && app.userId != userId) { 8713 continue; 8714 } 8715 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8716 // This one's in trouble, so we'll generate a report for it 8717 // crashes are higher priority (in case there's a crash *and* an anr) 8718 ActivityManager.ProcessErrorStateInfo report = null; 8719 if (app.crashing) { 8720 report = app.crashingReport; 8721 } else if (app.notResponding) { 8722 report = app.notRespondingReport; 8723 } 8724 8725 if (report != null) { 8726 if (errList == null) { 8727 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8728 } 8729 errList.add(report); 8730 } else { 8731 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8732 " crashing = " + app.crashing + 8733 " notResponding = " + app.notResponding); 8734 } 8735 } 8736 } 8737 } 8738 8739 return errList; 8740 } 8741 8742 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8743 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8744 if (currApp != null) { 8745 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8746 } 8747 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8748 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8749 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8750 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8751 if (currApp != null) { 8752 currApp.lru = 0; 8753 } 8754 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8755 } else if (adj >= ProcessList.SERVICE_ADJ) { 8756 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8757 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8758 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8759 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8760 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8761 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8762 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8763 } else { 8764 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8765 } 8766 } 8767 8768 private void fillInProcMemInfo(ProcessRecord app, 8769 ActivityManager.RunningAppProcessInfo outInfo) { 8770 outInfo.pid = app.pid; 8771 outInfo.uid = app.info.uid; 8772 if (mHeavyWeightProcess == app) { 8773 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8774 } 8775 if (app.persistent) { 8776 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8777 } 8778 if (app.hasActivities) { 8779 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8780 } 8781 outInfo.lastTrimLevel = app.trimMemoryLevel; 8782 int adj = app.curAdj; 8783 outInfo.importance = oomAdjToImportance(adj, outInfo); 8784 outInfo.importanceReasonCode = app.adjTypeCode; 8785 } 8786 8787 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8788 enforceNotIsolatedCaller("getRunningAppProcesses"); 8789 // Lazy instantiation of list 8790 List<ActivityManager.RunningAppProcessInfo> runList = null; 8791 final boolean allUsers = ActivityManager.checkUidPermission( 8792 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8793 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8794 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8795 synchronized (this) { 8796 // Iterate across all processes 8797 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8798 ProcessRecord app = mLruProcesses.get(i); 8799 if (!allUsers && app.userId != userId) { 8800 continue; 8801 } 8802 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8803 // Generate process state info for running application 8804 ActivityManager.RunningAppProcessInfo currApp = 8805 new ActivityManager.RunningAppProcessInfo(app.processName, 8806 app.pid, app.getPackageList()); 8807 fillInProcMemInfo(app, currApp); 8808 if (app.adjSource instanceof ProcessRecord) { 8809 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8810 currApp.importanceReasonImportance = oomAdjToImportance( 8811 app.adjSourceOom, null); 8812 } else if (app.adjSource instanceof ActivityRecord) { 8813 ActivityRecord r = (ActivityRecord)app.adjSource; 8814 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8815 } 8816 if (app.adjTarget instanceof ComponentName) { 8817 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8818 } 8819 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8820 // + " lru=" + currApp.lru); 8821 if (runList == null) { 8822 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8823 } 8824 runList.add(currApp); 8825 } 8826 } 8827 } 8828 return runList; 8829 } 8830 8831 public List<ApplicationInfo> getRunningExternalApplications() { 8832 enforceNotIsolatedCaller("getRunningExternalApplications"); 8833 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8834 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8835 if (runningApps != null && runningApps.size() > 0) { 8836 Set<String> extList = new HashSet<String>(); 8837 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8838 if (app.pkgList != null) { 8839 for (String pkg : app.pkgList) { 8840 extList.add(pkg); 8841 } 8842 } 8843 } 8844 IPackageManager pm = AppGlobals.getPackageManager(); 8845 for (String pkg : extList) { 8846 try { 8847 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8848 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8849 retList.add(info); 8850 } 8851 } catch (RemoteException e) { 8852 } 8853 } 8854 } 8855 return retList; 8856 } 8857 8858 @Override 8859 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8860 enforceNotIsolatedCaller("getMyMemoryState"); 8861 synchronized (this) { 8862 ProcessRecord proc; 8863 synchronized (mPidsSelfLocked) { 8864 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8865 } 8866 fillInProcMemInfo(proc, outInfo); 8867 } 8868 } 8869 8870 @Override 8871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8872 if (checkCallingPermission(android.Manifest.permission.DUMP) 8873 != PackageManager.PERMISSION_GRANTED) { 8874 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8875 + Binder.getCallingPid() 8876 + ", uid=" + Binder.getCallingUid() 8877 + " without permission " 8878 + android.Manifest.permission.DUMP); 8879 return; 8880 } 8881 8882 boolean dumpAll = false; 8883 boolean dumpClient = false; 8884 String dumpPackage = null; 8885 8886 int opti = 0; 8887 while (opti < args.length) { 8888 String opt = args[opti]; 8889 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8890 break; 8891 } 8892 opti++; 8893 if ("-a".equals(opt)) { 8894 dumpAll = true; 8895 } else if ("-c".equals(opt)) { 8896 dumpClient = true; 8897 } else if ("-h".equals(opt)) { 8898 pw.println("Activity manager dump options:"); 8899 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8900 pw.println(" cmd may be one of:"); 8901 pw.println(" a[ctivities]: activity stack state"); 8902 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 8903 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8904 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8905 pw.println(" o[om]: out of memory management"); 8906 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8907 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8908 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8909 pw.println(" service [COMP_SPEC]: service client-side state"); 8910 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8911 pw.println(" all: dump all activities"); 8912 pw.println(" top: dump the top activity"); 8913 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8914 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8915 pw.println(" a partial substring in a component name, a"); 8916 pw.println(" hex object identifier."); 8917 pw.println(" -a: include all available server state."); 8918 pw.println(" -c: include client state."); 8919 return; 8920 } else { 8921 pw.println("Unknown argument: " + opt + "; use -h for help"); 8922 } 8923 } 8924 8925 long origId = Binder.clearCallingIdentity(); 8926 boolean more = false; 8927 // Is the caller requesting to dump a particular piece of data? 8928 if (opti < args.length) { 8929 String cmd = args[opti]; 8930 opti++; 8931 if ("activities".equals(cmd) || "a".equals(cmd)) { 8932 synchronized (this) { 8933 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8934 } 8935 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8936 String[] newArgs; 8937 String name; 8938 if (opti >= args.length) { 8939 name = null; 8940 newArgs = EMPTY_STRING_ARRAY; 8941 } else { 8942 name = args[opti]; 8943 opti++; 8944 newArgs = new String[args.length - opti]; 8945 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8946 args.length - opti); 8947 } 8948 synchronized (this) { 8949 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8950 } 8951 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8952 String[] newArgs; 8953 String name; 8954 if (opti >= args.length) { 8955 name = null; 8956 newArgs = EMPTY_STRING_ARRAY; 8957 } else { 8958 name = args[opti]; 8959 opti++; 8960 newArgs = new String[args.length - opti]; 8961 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8962 args.length - opti); 8963 } 8964 synchronized (this) { 8965 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8966 } 8967 } else if ("processes".equals(cmd) || "p".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, 8978 args.length - opti); 8979 } 8980 synchronized (this) { 8981 dumpProcessesLocked(fd, pw, args, opti, true, name); 8982 } 8983 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8984 synchronized (this) { 8985 dumpOomLocked(fd, pw, args, opti, true); 8986 } 8987 } else if ("provider".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, args.length - opti); 8998 } 8999 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 9000 pw.println("No providers match: " + name); 9001 pw.println("Use -h for help."); 9002 } 9003 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9004 synchronized (this) { 9005 dumpProvidersLocked(fd, pw, args, opti, true, null); 9006 } 9007 } else if ("service".equals(cmd)) { 9008 String[] newArgs; 9009 String name; 9010 if (opti >= args.length) { 9011 name = null; 9012 newArgs = EMPTY_STRING_ARRAY; 9013 } else { 9014 name = args[opti]; 9015 opti++; 9016 newArgs = new String[args.length - opti]; 9017 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9018 args.length - opti); 9019 } 9020 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 9021 pw.println("No services match: " + name); 9022 pw.println("Use -h for help."); 9023 } 9024 } else if ("package".equals(cmd)) { 9025 String[] newArgs; 9026 if (opti >= args.length) { 9027 pw.println("package: no package name specified"); 9028 pw.println("Use -h for help."); 9029 } else { 9030 dumpPackage = args[opti]; 9031 opti++; 9032 newArgs = new String[args.length - opti]; 9033 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9034 args.length - opti); 9035 args = newArgs; 9036 opti = 0; 9037 more = true; 9038 } 9039 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9040 synchronized (this) { 9041 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9042 } 9043 } else { 9044 // Dumping a single activity? 9045 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9046 pw.println("Bad activity command, or no activities match: " + cmd); 9047 pw.println("Use -h for help."); 9048 } 9049 } 9050 if (!more) { 9051 Binder.restoreCallingIdentity(origId); 9052 return; 9053 } 9054 } 9055 9056 // No piece of data specified, dump everything. 9057 synchronized (this) { 9058 boolean needSep; 9059 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9060 if (needSep) { 9061 pw.println(" "); 9062 } 9063 if (dumpAll) { 9064 pw.println("-------------------------------------------------------------------------------"); 9065 } 9066 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9067 if (needSep) { 9068 pw.println(" "); 9069 } 9070 if (dumpAll) { 9071 pw.println("-------------------------------------------------------------------------------"); 9072 } 9073 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9074 if (needSep) { 9075 pw.println(" "); 9076 } 9077 if (dumpAll) { 9078 pw.println("-------------------------------------------------------------------------------"); 9079 } 9080 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9081 if (needSep) { 9082 pw.println(" "); 9083 } 9084 if (dumpAll) { 9085 pw.println("-------------------------------------------------------------------------------"); 9086 } 9087 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9088 if (needSep) { 9089 pw.println(" "); 9090 } 9091 if (dumpAll) { 9092 pw.println("-------------------------------------------------------------------------------"); 9093 } 9094 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9095 } 9096 Binder.restoreCallingIdentity(origId); 9097 } 9098 9099 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9100 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9101 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9102 pw.println(" Main stack:"); 9103 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9104 dumpPackage); 9105 pw.println(" "); 9106 pw.println(" Running activities (most recent first):"); 9107 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9108 dumpPackage); 9109 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9110 pw.println(" "); 9111 pw.println(" Activities waiting for another to become visible:"); 9112 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9113 !dumpAll, false, dumpPackage); 9114 } 9115 if (mMainStack.mStoppingActivities.size() > 0) { 9116 pw.println(" "); 9117 pw.println(" Activities waiting to stop:"); 9118 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9119 !dumpAll, false, dumpPackage); 9120 } 9121 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9122 pw.println(" "); 9123 pw.println(" Activities waiting to sleep:"); 9124 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9125 !dumpAll, false, dumpPackage); 9126 } 9127 if (mMainStack.mFinishingActivities.size() > 0) { 9128 pw.println(" "); 9129 pw.println(" Activities waiting to finish:"); 9130 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9131 !dumpAll, false, dumpPackage); 9132 } 9133 9134 pw.println(" "); 9135 if (mMainStack.mPausingActivity != null) { 9136 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9137 } 9138 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9139 pw.println(" mFocusedActivity: " + mFocusedActivity); 9140 if (dumpAll) { 9141 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9142 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9143 pw.println(" mDismissKeyguardOnNextActivity: " 9144 + mMainStack.mDismissKeyguardOnNextActivity); 9145 } 9146 9147 if (mRecentTasks.size() > 0) { 9148 pw.println(); 9149 pw.println(" Recent tasks:"); 9150 9151 final int N = mRecentTasks.size(); 9152 for (int i=0; i<N; i++) { 9153 TaskRecord tr = mRecentTasks.get(i); 9154 if (dumpPackage != null) { 9155 if (tr.realActivity == null || 9156 !dumpPackage.equals(tr.realActivity)) { 9157 continue; 9158 } 9159 } 9160 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9161 pw.println(tr); 9162 if (dumpAll) { 9163 mRecentTasks.get(i).dump(pw, " "); 9164 } 9165 } 9166 } 9167 9168 if (dumpAll) { 9169 pw.println(" "); 9170 pw.println(" mCurTask: " + mCurTask); 9171 } 9172 9173 return true; 9174 } 9175 9176 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9177 int opti, boolean dumpAll, String dumpPackage) { 9178 boolean needSep = false; 9179 int numPers = 0; 9180 9181 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9182 9183 if (dumpAll) { 9184 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9185 final int NA = procs.size(); 9186 for (int ia=0; ia<NA; ia++) { 9187 ProcessRecord r = procs.valueAt(ia); 9188 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9189 continue; 9190 } 9191 if (!needSep) { 9192 pw.println(" All known processes:"); 9193 needSep = true; 9194 } 9195 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9196 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9197 pw.print(" "); pw.println(r); 9198 r.dump(pw, " "); 9199 if (r.persistent) { 9200 numPers++; 9201 } 9202 } 9203 } 9204 } 9205 9206 if (mIsolatedProcesses.size() > 0) { 9207 if (needSep) pw.println(" "); 9208 needSep = true; 9209 pw.println(" Isolated process list (sorted by uid):"); 9210 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9211 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9212 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9213 continue; 9214 } 9215 pw.println(String.format("%sIsolated #%2d: %s", 9216 " ", i, r.toString())); 9217 } 9218 } 9219 9220 if (mLruProcesses.size() > 0) { 9221 if (needSep) pw.println(" "); 9222 needSep = true; 9223 pw.println(" Process LRU list (sorted by oom_adj):"); 9224 dumpProcessOomList(pw, this, mLruProcesses, " ", 9225 "Proc", "PERS", false, dumpPackage); 9226 needSep = true; 9227 } 9228 9229 if (dumpAll) { 9230 synchronized (mPidsSelfLocked) { 9231 boolean printed = false; 9232 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9233 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9234 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9235 continue; 9236 } 9237 if (!printed) { 9238 if (needSep) pw.println(" "); 9239 needSep = true; 9240 pw.println(" PID mappings:"); 9241 printed = true; 9242 } 9243 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9244 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9245 } 9246 } 9247 } 9248 9249 if (mForegroundProcesses.size() > 0) { 9250 synchronized (mPidsSelfLocked) { 9251 boolean printed = false; 9252 for (int i=0; i<mForegroundProcesses.size(); i++) { 9253 ProcessRecord r = mPidsSelfLocked.get( 9254 mForegroundProcesses.valueAt(i).pid); 9255 if (dumpPackage != null && (r == null 9256 || !dumpPackage.equals(r.info.packageName))) { 9257 continue; 9258 } 9259 if (!printed) { 9260 if (needSep) pw.println(" "); 9261 needSep = true; 9262 pw.println(" Foreground Processes:"); 9263 printed = true; 9264 } 9265 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9266 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9267 } 9268 } 9269 } 9270 9271 if (mPersistentStartingProcesses.size() > 0) { 9272 if (needSep) pw.println(" "); 9273 needSep = true; 9274 pw.println(" Persisent processes that are starting:"); 9275 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9276 "Starting Norm", "Restarting PERS", dumpPackage); 9277 } 9278 9279 if (mRemovedProcesses.size() > 0) { 9280 if (needSep) pw.println(" "); 9281 needSep = true; 9282 pw.println(" Processes that are being removed:"); 9283 dumpProcessList(pw, this, mRemovedProcesses, " ", 9284 "Removed Norm", "Removed PERS", dumpPackage); 9285 } 9286 9287 if (mProcessesOnHold.size() > 0) { 9288 if (needSep) pw.println(" "); 9289 needSep = true; 9290 pw.println(" Processes that are on old until the system is ready:"); 9291 dumpProcessList(pw, this, mProcessesOnHold, " ", 9292 "OnHold Norm", "OnHold PERS", dumpPackage); 9293 } 9294 9295 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9296 9297 if (mProcessCrashTimes.getMap().size() > 0) { 9298 boolean printed = false; 9299 long now = SystemClock.uptimeMillis(); 9300 for (Map.Entry<String, SparseArray<Long>> procs 9301 : mProcessCrashTimes.getMap().entrySet()) { 9302 String pname = procs.getKey(); 9303 SparseArray<Long> uids = procs.getValue(); 9304 final int N = uids.size(); 9305 for (int i=0; i<N; i++) { 9306 int puid = uids.keyAt(i); 9307 ProcessRecord r = mProcessNames.get(pname, puid); 9308 if (dumpPackage != null && (r == null 9309 || !dumpPackage.equals(r.info.packageName))) { 9310 continue; 9311 } 9312 if (!printed) { 9313 if (needSep) pw.println(" "); 9314 needSep = true; 9315 pw.println(" Time since processes crashed:"); 9316 printed = true; 9317 } 9318 pw.print(" Process "); pw.print(pname); 9319 pw.print(" uid "); pw.print(puid); 9320 pw.print(": last crashed "); 9321 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9322 pw.println(" ago"); 9323 } 9324 } 9325 } 9326 9327 if (mBadProcesses.getMap().size() > 0) { 9328 boolean printed = false; 9329 for (Map.Entry<String, SparseArray<Long>> procs 9330 : mBadProcesses.getMap().entrySet()) { 9331 String pname = procs.getKey(); 9332 SparseArray<Long> uids = procs.getValue(); 9333 final int N = uids.size(); 9334 for (int i=0; i<N; i++) { 9335 int puid = uids.keyAt(i); 9336 ProcessRecord r = mProcessNames.get(pname, puid); 9337 if (dumpPackage != null && (r == null 9338 || !dumpPackage.equals(r.info.packageName))) { 9339 continue; 9340 } 9341 if (!printed) { 9342 if (needSep) pw.println(" "); 9343 needSep = true; 9344 pw.println(" Bad processes:"); 9345 } 9346 pw.print(" Bad process "); pw.print(pname); 9347 pw.print(" uid "); pw.print(puid); 9348 pw.print(": crashed at time "); 9349 pw.println(uids.valueAt(i)); 9350 } 9351 } 9352 } 9353 9354 pw.println(); 9355 pw.println(" mStartedUsers:"); 9356 for (int i=0; i<mStartedUsers.size(); i++) { 9357 UserStartedState uss = mStartedUsers.valueAt(i); 9358 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9359 pw.print(": "); uss.dump("", pw); 9360 } 9361 pw.print(" mStartedUserArray: ["); 9362 for (int i=0; i<mStartedUserArray.length; i++) { 9363 if (i > 0) pw.print(", "); 9364 pw.print(mStartedUserArray[i]); 9365 } 9366 pw.println("]"); 9367 pw.print(" mUserLru: ["); 9368 for (int i=0; i<mUserLru.size(); i++) { 9369 if (i > 0) pw.print(", "); 9370 pw.print(mUserLru.get(i)); 9371 } 9372 pw.println("]"); 9373 if (dumpAll) { 9374 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9375 } 9376 pw.println(" mHomeProcess: " + mHomeProcess); 9377 pw.println(" mPreviousProcess: " + mPreviousProcess); 9378 if (dumpAll) { 9379 StringBuilder sb = new StringBuilder(128); 9380 sb.append(" mPreviousProcessVisibleTime: "); 9381 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9382 pw.println(sb); 9383 } 9384 if (mHeavyWeightProcess != null) { 9385 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9386 } 9387 pw.println(" mConfiguration: " + mConfiguration); 9388 if (dumpAll) { 9389 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9390 if (mCompatModePackages.getPackages().size() > 0) { 9391 boolean printed = false; 9392 for (Map.Entry<String, Integer> entry 9393 : mCompatModePackages.getPackages().entrySet()) { 9394 String pkg = entry.getKey(); 9395 int mode = entry.getValue(); 9396 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9397 continue; 9398 } 9399 if (!printed) { 9400 pw.println(" mScreenCompatPackages:"); 9401 printed = true; 9402 } 9403 pw.print(" "); pw.print(pkg); pw.print(": "); 9404 pw.print(mode); pw.println(); 9405 } 9406 } 9407 } 9408 if (mSleeping || mWentToSleep || mLockScreenShown) { 9409 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9410 + " mLockScreenShown " + mLockScreenShown); 9411 } 9412 if (mShuttingDown) { 9413 pw.println(" mShuttingDown=" + mShuttingDown); 9414 } 9415 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9416 || mOrigWaitForDebugger) { 9417 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9418 + " mDebugTransient=" + mDebugTransient 9419 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9420 } 9421 if (mOpenGlTraceApp != null) { 9422 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9423 } 9424 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9425 || mProfileFd != null) { 9426 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9427 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9428 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9429 + mAutoStopProfiler); 9430 } 9431 if (mAlwaysFinishActivities || mController != null) { 9432 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9433 + " mController=" + mController); 9434 } 9435 if (dumpAll) { 9436 pw.println(" Total persistent processes: " + numPers); 9437 pw.println(" mStartRunning=" + mStartRunning 9438 + " mProcessesReady=" + mProcessesReady 9439 + " mSystemReady=" + mSystemReady); 9440 pw.println(" mBooting=" + mBooting 9441 + " mBooted=" + mBooted 9442 + " mFactoryTest=" + mFactoryTest); 9443 pw.print(" mLastPowerCheckRealtime="); 9444 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9445 pw.println(""); 9446 pw.print(" mLastPowerCheckUptime="); 9447 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9448 pw.println(""); 9449 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9450 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9451 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9452 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9453 + " mNumHiddenProcs=" + mNumHiddenProcs 9454 + " mNumServiceProcs=" + mNumServiceProcs 9455 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9456 } 9457 9458 return true; 9459 } 9460 9461 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9462 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9463 if (mProcessesToGc.size() > 0) { 9464 boolean printed = false; 9465 long now = SystemClock.uptimeMillis(); 9466 for (int i=0; i<mProcessesToGc.size(); i++) { 9467 ProcessRecord proc = mProcessesToGc.get(i); 9468 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9469 continue; 9470 } 9471 if (!printed) { 9472 if (needSep) pw.println(" "); 9473 needSep = true; 9474 pw.println(" Processes that are waiting to GC:"); 9475 printed = true; 9476 } 9477 pw.print(" Process "); pw.println(proc); 9478 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9479 pw.print(", last gced="); 9480 pw.print(now-proc.lastRequestedGc); 9481 pw.print(" ms ago, last lowMem="); 9482 pw.print(now-proc.lastLowMemory); 9483 pw.println(" ms ago"); 9484 9485 } 9486 } 9487 return needSep; 9488 } 9489 9490 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9491 int opti, boolean dumpAll) { 9492 boolean needSep = false; 9493 9494 if (mLruProcesses.size() > 0) { 9495 if (needSep) pw.println(" "); 9496 needSep = true; 9497 pw.println(" OOM levels:"); 9498 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9499 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9500 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9501 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9502 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9503 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9504 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9505 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9506 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9507 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9508 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9509 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9510 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9511 9512 if (needSep) pw.println(" "); 9513 needSep = true; 9514 pw.println(" Process OOM control:"); 9515 dumpProcessOomList(pw, this, mLruProcesses, " ", 9516 "Proc", "PERS", true, null); 9517 needSep = true; 9518 } 9519 9520 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9521 9522 pw.println(); 9523 pw.println(" mHomeProcess: " + mHomeProcess); 9524 pw.println(" mPreviousProcess: " + mPreviousProcess); 9525 if (mHeavyWeightProcess != null) { 9526 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9527 } 9528 9529 return true; 9530 } 9531 9532 /** 9533 * There are three ways to call this: 9534 * - no provider specified: dump all the providers 9535 * - a flattened component name that matched an existing provider was specified as the 9536 * first arg: dump that one provider 9537 * - the first arg isn't the flattened component name of an existing provider: 9538 * dump all providers whose component contains the first arg as a substring 9539 */ 9540 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9541 int opti, boolean dumpAll) { 9542 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9543 } 9544 9545 static class ItemMatcher { 9546 ArrayList<ComponentName> components; 9547 ArrayList<String> strings; 9548 ArrayList<Integer> objects; 9549 boolean all; 9550 9551 ItemMatcher() { 9552 all = true; 9553 } 9554 9555 void build(String name) { 9556 ComponentName componentName = ComponentName.unflattenFromString(name); 9557 if (componentName != null) { 9558 if (components == null) { 9559 components = new ArrayList<ComponentName>(); 9560 } 9561 components.add(componentName); 9562 all = false; 9563 } else { 9564 int objectId = 0; 9565 // Not a '/' separated full component name; maybe an object ID? 9566 try { 9567 objectId = Integer.parseInt(name, 16); 9568 if (objects == null) { 9569 objects = new ArrayList<Integer>(); 9570 } 9571 objects.add(objectId); 9572 all = false; 9573 } catch (RuntimeException e) { 9574 // Not an integer; just do string match. 9575 if (strings == null) { 9576 strings = new ArrayList<String>(); 9577 } 9578 strings.add(name); 9579 all = false; 9580 } 9581 } 9582 } 9583 9584 int build(String[] args, int opti) { 9585 for (; opti<args.length; opti++) { 9586 String name = args[opti]; 9587 if ("--".equals(name)) { 9588 return opti+1; 9589 } 9590 build(name); 9591 } 9592 return opti; 9593 } 9594 9595 boolean match(Object object, ComponentName comp) { 9596 if (all) { 9597 return true; 9598 } 9599 if (components != null) { 9600 for (int i=0; i<components.size(); i++) { 9601 if (components.get(i).equals(comp)) { 9602 return true; 9603 } 9604 } 9605 } 9606 if (objects != null) { 9607 for (int i=0; i<objects.size(); i++) { 9608 if (System.identityHashCode(object) == objects.get(i)) { 9609 return true; 9610 } 9611 } 9612 } 9613 if (strings != null) { 9614 String flat = comp.flattenToString(); 9615 for (int i=0; i<strings.size(); i++) { 9616 if (flat.contains(strings.get(i))) { 9617 return true; 9618 } 9619 } 9620 } 9621 return false; 9622 } 9623 } 9624 9625 /** 9626 * There are three things that cmd can be: 9627 * - a flattened component name that matches an existing activity 9628 * - the cmd arg isn't the flattened component name of an existing activity: 9629 * dump all activity whose component contains the cmd as a substring 9630 * - A hex number of the ActivityRecord object instance. 9631 */ 9632 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9633 int opti, boolean dumpAll) { 9634 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9635 9636 if ("all".equals(name)) { 9637 synchronized (this) { 9638 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9639 activities.add(r1); 9640 } 9641 } 9642 } else if ("top".equals(name)) { 9643 synchronized (this) { 9644 final int N = mMainStack.mHistory.size(); 9645 if (N > 0) { 9646 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9647 } 9648 } 9649 } else { 9650 ItemMatcher matcher = new ItemMatcher(); 9651 matcher.build(name); 9652 9653 synchronized (this) { 9654 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9655 if (matcher.match(r1, r1.intent.getComponent())) { 9656 activities.add(r1); 9657 } 9658 } 9659 } 9660 } 9661 9662 if (activities.size() <= 0) { 9663 return false; 9664 } 9665 9666 String[] newArgs = new String[args.length - opti]; 9667 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9668 9669 TaskRecord lastTask = null; 9670 boolean needSep = false; 9671 for (int i=activities.size()-1; i>=0; i--) { 9672 ActivityRecord r = (ActivityRecord)activities.get(i); 9673 if (needSep) { 9674 pw.println(); 9675 } 9676 needSep = true; 9677 synchronized (this) { 9678 if (lastTask != r.task) { 9679 lastTask = r.task; 9680 pw.print("TASK "); pw.print(lastTask.affinity); 9681 pw.print(" id="); pw.println(lastTask.taskId); 9682 if (dumpAll) { 9683 lastTask.dump(pw, " "); 9684 } 9685 } 9686 } 9687 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9688 } 9689 return true; 9690 } 9691 9692 /** 9693 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9694 * there is a thread associated with the activity. 9695 */ 9696 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9697 final ActivityRecord r, String[] args, boolean dumpAll) { 9698 String innerPrefix = prefix + " "; 9699 synchronized (this) { 9700 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9701 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9702 pw.print(" pid="); 9703 if (r.app != null) pw.println(r.app.pid); 9704 else pw.println("(not running)"); 9705 if (dumpAll) { 9706 r.dump(pw, innerPrefix); 9707 } 9708 } 9709 if (r.app != null && r.app.thread != null) { 9710 // flush anything that is already in the PrintWriter since the thread is going 9711 // to write to the file descriptor directly 9712 pw.flush(); 9713 try { 9714 TransferPipe tp = new TransferPipe(); 9715 try { 9716 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9717 r.appToken, innerPrefix, args); 9718 tp.go(fd); 9719 } finally { 9720 tp.kill(); 9721 } 9722 } catch (IOException e) { 9723 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9724 } catch (RemoteException e) { 9725 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9726 } 9727 } 9728 } 9729 9730 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9731 int opti, boolean dumpAll, String dumpPackage) { 9732 boolean needSep = false; 9733 boolean onlyHistory = false; 9734 9735 if ("history".equals(dumpPackage)) { 9736 if (opti < args.length && "-s".equals(args[opti])) { 9737 dumpAll = false; 9738 } 9739 onlyHistory = true; 9740 dumpPackage = null; 9741 } 9742 9743 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9744 if (!onlyHistory && dumpAll) { 9745 if (mRegisteredReceivers.size() > 0) { 9746 boolean printed = false; 9747 Iterator it = mRegisteredReceivers.values().iterator(); 9748 while (it.hasNext()) { 9749 ReceiverList r = (ReceiverList)it.next(); 9750 if (dumpPackage != null && (r.app == null || 9751 !dumpPackage.equals(r.app.info.packageName))) { 9752 continue; 9753 } 9754 if (!printed) { 9755 pw.println(" Registered Receivers:"); 9756 needSep = true; 9757 printed = true; 9758 } 9759 pw.print(" * "); pw.println(r); 9760 r.dump(pw, " "); 9761 } 9762 } 9763 9764 if (mReceiverResolver.dump(pw, needSep ? 9765 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9766 " ", dumpPackage, false)) { 9767 needSep = true; 9768 } 9769 } 9770 9771 for (BroadcastQueue q : mBroadcastQueues) { 9772 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9773 } 9774 9775 needSep = true; 9776 9777 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9778 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9779 if (needSep) { 9780 pw.println(); 9781 } 9782 needSep = true; 9783 pw.print(" Sticky broadcasts for user "); 9784 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9785 StringBuilder sb = new StringBuilder(128); 9786 for (Map.Entry<String, ArrayList<Intent>> ent 9787 : mStickyBroadcasts.valueAt(user).entrySet()) { 9788 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9789 if (dumpAll) { 9790 pw.println(":"); 9791 ArrayList<Intent> intents = ent.getValue(); 9792 final int N = intents.size(); 9793 for (int i=0; i<N; i++) { 9794 sb.setLength(0); 9795 sb.append(" Intent: "); 9796 intents.get(i).toShortString(sb, false, true, false, false); 9797 pw.println(sb.toString()); 9798 Bundle bundle = intents.get(i).getExtras(); 9799 if (bundle != null) { 9800 pw.print(" "); 9801 pw.println(bundle.toString()); 9802 } 9803 } 9804 } else { 9805 pw.println(""); 9806 } 9807 } 9808 } 9809 } 9810 9811 if (!onlyHistory && dumpAll) { 9812 pw.println(); 9813 for (BroadcastQueue queue : mBroadcastQueues) { 9814 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9815 + queue.mBroadcastsScheduled); 9816 } 9817 pw.println(" mHandler:"); 9818 mHandler.dump(new PrintWriterPrinter(pw), " "); 9819 needSep = true; 9820 } 9821 9822 return needSep; 9823 } 9824 9825 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9826 int opti, boolean dumpAll, String dumpPackage) { 9827 boolean needSep = true; 9828 9829 ItemMatcher matcher = new ItemMatcher(); 9830 matcher.build(args, opti); 9831 9832 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9833 9834 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9835 9836 if (mLaunchingProviders.size() > 0) { 9837 boolean printed = false; 9838 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9839 ContentProviderRecord r = mLaunchingProviders.get(i); 9840 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9841 continue; 9842 } 9843 if (!printed) { 9844 if (needSep) pw.println(" "); 9845 needSep = true; 9846 pw.println(" Launching content providers:"); 9847 printed = true; 9848 } 9849 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9850 pw.println(r); 9851 } 9852 } 9853 9854 if (mGrantedUriPermissions.size() > 0) { 9855 if (needSep) pw.println(); 9856 needSep = true; 9857 pw.println("Granted Uri Permissions:"); 9858 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9859 int uid = mGrantedUriPermissions.keyAt(i); 9860 HashMap<Uri, UriPermission> perms 9861 = mGrantedUriPermissions.valueAt(i); 9862 pw.print(" * UID "); pw.print(uid); 9863 pw.println(" holds:"); 9864 for (UriPermission perm : perms.values()) { 9865 pw.print(" "); pw.println(perm); 9866 if (dumpAll) { 9867 perm.dump(pw, " "); 9868 } 9869 } 9870 } 9871 needSep = true; 9872 } 9873 9874 return needSep; 9875 } 9876 9877 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9878 int opti, boolean dumpAll, String dumpPackage) { 9879 boolean needSep = false; 9880 9881 if (mIntentSenderRecords.size() > 0) { 9882 boolean printed = false; 9883 Iterator<WeakReference<PendingIntentRecord>> it 9884 = mIntentSenderRecords.values().iterator(); 9885 while (it.hasNext()) { 9886 WeakReference<PendingIntentRecord> ref = it.next(); 9887 PendingIntentRecord rec = ref != null ? ref.get(): null; 9888 if (dumpPackage != null && (rec == null 9889 || !dumpPackage.equals(rec.key.packageName))) { 9890 continue; 9891 } 9892 if (!printed) { 9893 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9894 printed = true; 9895 } 9896 needSep = true; 9897 if (rec != null) { 9898 pw.print(" * "); pw.println(rec); 9899 if (dumpAll) { 9900 rec.dump(pw, " "); 9901 } 9902 } else { 9903 pw.print(" * "); pw.println(ref); 9904 } 9905 } 9906 } 9907 9908 return needSep; 9909 } 9910 9911 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9912 String prefix, String label, boolean complete, boolean brief, boolean client, 9913 String dumpPackage) { 9914 TaskRecord lastTask = null; 9915 boolean needNL = false; 9916 final String innerPrefix = prefix + " "; 9917 final String[] args = new String[0]; 9918 for (int i=list.size()-1; i>=0; i--) { 9919 final ActivityRecord r = (ActivityRecord)list.get(i); 9920 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9921 continue; 9922 } 9923 final boolean full = !brief && (complete || !r.isInHistory()); 9924 if (needNL) { 9925 pw.println(" "); 9926 needNL = false; 9927 } 9928 if (lastTask != r.task) { 9929 lastTask = r.task; 9930 pw.print(prefix); 9931 pw.print(full ? "* " : " "); 9932 pw.println(lastTask); 9933 if (full) { 9934 lastTask.dump(pw, prefix + " "); 9935 } else if (complete) { 9936 // Complete + brief == give a summary. Isn't that obvious?!? 9937 if (lastTask.intent != null) { 9938 pw.print(prefix); pw.print(" "); 9939 pw.println(lastTask.intent.toInsecureStringWithClip()); 9940 } 9941 } 9942 } 9943 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9944 pw.print(" #"); pw.print(i); pw.print(": "); 9945 pw.println(r); 9946 if (full) { 9947 r.dump(pw, innerPrefix); 9948 } else if (complete) { 9949 // Complete + brief == give a summary. Isn't that obvious?!? 9950 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9951 if (r.app != null) { 9952 pw.print(innerPrefix); pw.println(r.app); 9953 } 9954 } 9955 if (client && r.app != null && r.app.thread != null) { 9956 // flush anything that is already in the PrintWriter since the thread is going 9957 // to write to the file descriptor directly 9958 pw.flush(); 9959 try { 9960 TransferPipe tp = new TransferPipe(); 9961 try { 9962 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9963 r.appToken, innerPrefix, args); 9964 // Short timeout, since blocking here can 9965 // deadlock with the application. 9966 tp.go(fd, 2000); 9967 } finally { 9968 tp.kill(); 9969 } 9970 } catch (IOException e) { 9971 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9972 } catch (RemoteException e) { 9973 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9974 } 9975 needNL = true; 9976 } 9977 } 9978 } 9979 9980 private static String buildOomTag(String prefix, String space, int val, int base) { 9981 if (val == base) { 9982 if (space == null) return prefix; 9983 return prefix + " "; 9984 } 9985 return prefix + "+" + Integer.toString(val-base); 9986 } 9987 9988 private static final int dumpProcessList(PrintWriter pw, 9989 ActivityManagerService service, List list, 9990 String prefix, String normalLabel, String persistentLabel, 9991 String dumpPackage) { 9992 int numPers = 0; 9993 final int N = list.size()-1; 9994 for (int i=N; i>=0; i--) { 9995 ProcessRecord r = (ProcessRecord)list.get(i); 9996 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9997 continue; 9998 } 9999 pw.println(String.format("%s%s #%2d: %s", 10000 prefix, (r.persistent ? persistentLabel : normalLabel), 10001 i, r.toString())); 10002 if (r.persistent) { 10003 numPers++; 10004 } 10005 } 10006 return numPers; 10007 } 10008 10009 private static final boolean dumpProcessOomList(PrintWriter pw, 10010 ActivityManagerService service, List<ProcessRecord> origList, 10011 String prefix, String normalLabel, String persistentLabel, 10012 boolean inclDetails, String dumpPackage) { 10013 10014 ArrayList<Pair<ProcessRecord, Integer>> list 10015 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 10016 for (int i=0; i<origList.size(); i++) { 10017 ProcessRecord r = origList.get(i); 10018 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10019 continue; 10020 } 10021 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 10022 } 10023 10024 if (list.size() <= 0) { 10025 return false; 10026 } 10027 10028 Comparator<Pair<ProcessRecord, Integer>> comparator 10029 = new Comparator<Pair<ProcessRecord, Integer>>() { 10030 @Override 10031 public int compare(Pair<ProcessRecord, Integer> object1, 10032 Pair<ProcessRecord, Integer> object2) { 10033 if (object1.first.setAdj != object2.first.setAdj) { 10034 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10035 } 10036 if (object1.second.intValue() != object2.second.intValue()) { 10037 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10038 } 10039 return 0; 10040 } 10041 }; 10042 10043 Collections.sort(list, comparator); 10044 10045 final long curRealtime = SystemClock.elapsedRealtime(); 10046 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10047 final long curUptime = SystemClock.uptimeMillis(); 10048 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10049 10050 for (int i=list.size()-1; i>=0; i--) { 10051 ProcessRecord r = list.get(i).first; 10052 String oomAdj; 10053 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10054 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10055 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10056 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10057 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10058 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10059 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10060 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10061 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10062 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10063 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10064 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10065 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10066 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10067 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10068 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10069 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10070 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10071 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10072 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10073 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10074 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10075 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10076 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10077 } else { 10078 oomAdj = Integer.toString(r.setAdj); 10079 } 10080 String schedGroup; 10081 switch (r.setSchedGroup) { 10082 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10083 schedGroup = "B"; 10084 break; 10085 case Process.THREAD_GROUP_DEFAULT: 10086 schedGroup = "F"; 10087 break; 10088 default: 10089 schedGroup = Integer.toString(r.setSchedGroup); 10090 break; 10091 } 10092 String foreground; 10093 if (r.foregroundActivities) { 10094 foreground = "A"; 10095 } else if (r.foregroundServices) { 10096 foreground = "S"; 10097 } else { 10098 foreground = " "; 10099 } 10100 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10101 prefix, (r.persistent ? persistentLabel : normalLabel), 10102 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10103 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10104 if (r.adjSource != null || r.adjTarget != null) { 10105 pw.print(prefix); 10106 pw.print(" "); 10107 if (r.adjTarget instanceof ComponentName) { 10108 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10109 } else if (r.adjTarget != null) { 10110 pw.print(r.adjTarget.toString()); 10111 } else { 10112 pw.print("{null}"); 10113 } 10114 pw.print("<="); 10115 if (r.adjSource instanceof ProcessRecord) { 10116 pw.print("Proc{"); 10117 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10118 pw.println("}"); 10119 } else if (r.adjSource != null) { 10120 pw.println(r.adjSource.toString()); 10121 } else { 10122 pw.println("{null}"); 10123 } 10124 } 10125 if (inclDetails) { 10126 pw.print(prefix); 10127 pw.print(" "); 10128 pw.print("oom: max="); pw.print(r.maxAdj); 10129 pw.print(" hidden="); pw.print(r.hiddenAdj); 10130 pw.print(" client="); pw.print(r.clientHiddenAdj); 10131 pw.print(" empty="); pw.print(r.emptyAdj); 10132 pw.print(" curRaw="); pw.print(r.curRawAdj); 10133 pw.print(" setRaw="); pw.print(r.setRawAdj); 10134 pw.print(" cur="); pw.print(r.curAdj); 10135 pw.print(" set="); pw.println(r.setAdj); 10136 pw.print(prefix); 10137 pw.print(" "); 10138 pw.print("keeping="); pw.print(r.keeping); 10139 pw.print(" hidden="); pw.print(r.hidden); 10140 pw.print(" empty="); pw.print(r.empty); 10141 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10142 10143 if (!r.keeping) { 10144 if (r.lastWakeTime != 0) { 10145 long wtime; 10146 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10147 synchronized (stats) { 10148 wtime = stats.getProcessWakeTime(r.info.uid, 10149 r.pid, curRealtime); 10150 } 10151 long timeUsed = wtime - r.lastWakeTime; 10152 pw.print(prefix); 10153 pw.print(" "); 10154 pw.print("keep awake over "); 10155 TimeUtils.formatDuration(realtimeSince, pw); 10156 pw.print(" used "); 10157 TimeUtils.formatDuration(timeUsed, pw); 10158 pw.print(" ("); 10159 pw.print((timeUsed*100)/realtimeSince); 10160 pw.println("%)"); 10161 } 10162 if (r.lastCpuTime != 0) { 10163 long timeUsed = r.curCpuTime - r.lastCpuTime; 10164 pw.print(prefix); 10165 pw.print(" "); 10166 pw.print("run cpu over "); 10167 TimeUtils.formatDuration(uptimeSince, pw); 10168 pw.print(" used "); 10169 TimeUtils.formatDuration(timeUsed, pw); 10170 pw.print(" ("); 10171 pw.print((timeUsed*100)/uptimeSince); 10172 pw.println("%)"); 10173 } 10174 } 10175 } 10176 } 10177 return true; 10178 } 10179 10180 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10181 ArrayList<ProcessRecord> procs; 10182 synchronized (this) { 10183 if (args != null && args.length > start 10184 && args[start].charAt(0) != '-') { 10185 procs = new ArrayList<ProcessRecord>(); 10186 int pid = -1; 10187 try { 10188 pid = Integer.parseInt(args[start]); 10189 } catch (NumberFormatException e) { 10190 10191 } 10192 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10193 ProcessRecord proc = mLruProcesses.get(i); 10194 if (proc.pid == pid) { 10195 procs.add(proc); 10196 } else if (proc.processName.equals(args[start])) { 10197 procs.add(proc); 10198 } 10199 } 10200 if (procs.size() <= 0) { 10201 pw.println("No process found for: " + args[start]); 10202 return null; 10203 } 10204 } else { 10205 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10206 } 10207 } 10208 return procs; 10209 } 10210 10211 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10212 PrintWriter pw, String[] args) { 10213 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10214 if (procs == null) { 10215 return; 10216 } 10217 10218 long uptime = SystemClock.uptimeMillis(); 10219 long realtime = SystemClock.elapsedRealtime(); 10220 pw.println("Applications Graphics Acceleration Info:"); 10221 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10222 10223 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10224 ProcessRecord r = procs.get(i); 10225 if (r.thread != null) { 10226 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10227 pw.flush(); 10228 try { 10229 TransferPipe tp = new TransferPipe(); 10230 try { 10231 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10232 tp.go(fd); 10233 } finally { 10234 tp.kill(); 10235 } 10236 } catch (IOException e) { 10237 pw.println("Failure while dumping the app: " + r); 10238 pw.flush(); 10239 } catch (RemoteException e) { 10240 pw.println("Got a RemoteException while dumping the app " + r); 10241 pw.flush(); 10242 } 10243 } 10244 } 10245 } 10246 10247 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10248 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10249 if (procs == null) { 10250 return; 10251 } 10252 10253 pw.println("Applications Database Info:"); 10254 10255 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10256 ProcessRecord r = procs.get(i); 10257 if (r.thread != null) { 10258 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10259 pw.flush(); 10260 try { 10261 TransferPipe tp = new TransferPipe(); 10262 try { 10263 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10264 tp.go(fd); 10265 } finally { 10266 tp.kill(); 10267 } 10268 } catch (IOException e) { 10269 pw.println("Failure while dumping the app: " + r); 10270 pw.flush(); 10271 } catch (RemoteException e) { 10272 pw.println("Got a RemoteException while dumping the app " + r); 10273 pw.flush(); 10274 } 10275 } 10276 } 10277 } 10278 10279 final static class MemItem { 10280 final String label; 10281 final String shortLabel; 10282 final long pss; 10283 final int id; 10284 ArrayList<MemItem> subitems; 10285 10286 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10287 label = _label; 10288 shortLabel = _shortLabel; 10289 pss = _pss; 10290 id = _id; 10291 } 10292 } 10293 10294 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10295 boolean sort) { 10296 if (sort) { 10297 Collections.sort(items, new Comparator<MemItem>() { 10298 @Override 10299 public int compare(MemItem lhs, MemItem rhs) { 10300 if (lhs.pss < rhs.pss) { 10301 return 1; 10302 } else if (lhs.pss > rhs.pss) { 10303 return -1; 10304 } 10305 return 0; 10306 } 10307 }); 10308 } 10309 10310 for (int i=0; i<items.size(); i++) { 10311 MemItem mi = items.get(i); 10312 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10313 if (mi.subitems != null) { 10314 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10315 } 10316 } 10317 } 10318 10319 // These are in KB. 10320 static final long[] DUMP_MEM_BUCKETS = new long[] { 10321 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10322 120*1024, 160*1024, 200*1024, 10323 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10324 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10325 }; 10326 10327 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10328 boolean stackLike) { 10329 int start = label.lastIndexOf('.'); 10330 if (start >= 0) start++; 10331 else start = 0; 10332 int end = label.length(); 10333 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10334 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10335 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10336 out.append(bucket); 10337 out.append(stackLike ? "MB." : "MB "); 10338 out.append(label, start, end); 10339 return; 10340 } 10341 } 10342 out.append(memKB/1024); 10343 out.append(stackLike ? "MB." : "MB "); 10344 out.append(label, start, end); 10345 } 10346 10347 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10348 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10349 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10350 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10351 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10352 }; 10353 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10354 "System", "Persistent", "Foreground", 10355 "Visible", "Perceptible", "Heavy Weight", 10356 "Backup", "A Services", "Home", "Previous", 10357 "B Services", "Background" 10358 }; 10359 10360 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10361 PrintWriter pw, String prefix, String[] args, boolean brief, 10362 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10363 boolean dumpAll = false; 10364 boolean oomOnly = false; 10365 10366 int opti = 0; 10367 while (opti < args.length) { 10368 String opt = args[opti]; 10369 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10370 break; 10371 } 10372 opti++; 10373 if ("-a".equals(opt)) { 10374 dumpAll = true; 10375 } else if ("--oom".equals(opt)) { 10376 oomOnly = true; 10377 } else if ("-h".equals(opt)) { 10378 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10379 pw.println(" -a: include all available information for each process."); 10380 pw.println(" --oom: only show processes organized by oom adj."); 10381 pw.println("If [process] is specified it can be the name or "); 10382 pw.println("pid of a specific process to dump."); 10383 return; 10384 } else { 10385 pw.println("Unknown argument: " + opt + "; use -h for help"); 10386 } 10387 } 10388 10389 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10390 if (procs == null) { 10391 return; 10392 } 10393 10394 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10395 long uptime = SystemClock.uptimeMillis(); 10396 long realtime = SystemClock.elapsedRealtime(); 10397 10398 if (procs.size() == 1 || isCheckinRequest) { 10399 dumpAll = true; 10400 } 10401 10402 if (isCheckinRequest) { 10403 // short checkin version 10404 pw.println(uptime + "," + realtime); 10405 pw.flush(); 10406 } else { 10407 pw.println("Applications Memory Usage (kB):"); 10408 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10409 } 10410 10411 String[] innerArgs = new String[args.length-opti]; 10412 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10413 10414 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10415 long nativePss=0, dalvikPss=0, otherPss=0; 10416 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10417 10418 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10419 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10420 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10421 10422 long totalPss = 0; 10423 10424 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10425 ProcessRecord r = procs.get(i); 10426 if (r.thread != null) { 10427 if (!isCheckinRequest && dumpAll) { 10428 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10429 pw.flush(); 10430 } 10431 Debug.MemoryInfo mi = null; 10432 if (dumpAll) { 10433 try { 10434 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10435 } catch (RemoteException e) { 10436 if (!isCheckinRequest) { 10437 pw.println("Got RemoteException!"); 10438 pw.flush(); 10439 } 10440 } 10441 } else { 10442 mi = new Debug.MemoryInfo(); 10443 Debug.getMemoryInfo(r.pid, mi); 10444 } 10445 10446 if (!isCheckinRequest && mi != null) { 10447 long myTotalPss = mi.getTotalPss(); 10448 totalPss += myTotalPss; 10449 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10450 r.processName, myTotalPss, 0); 10451 procMems.add(pssItem); 10452 10453 nativePss += mi.nativePss; 10454 dalvikPss += mi.dalvikPss; 10455 otherPss += mi.otherPss; 10456 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10457 long mem = mi.getOtherPss(j); 10458 miscPss[j] += mem; 10459 otherPss -= mem; 10460 } 10461 10462 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10463 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10464 || oomIndex == (oomPss.length-1)) { 10465 oomPss[oomIndex] += myTotalPss; 10466 if (oomProcs[oomIndex] == null) { 10467 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10468 } 10469 oomProcs[oomIndex].add(pssItem); 10470 break; 10471 } 10472 } 10473 } 10474 } 10475 } 10476 10477 if (!isCheckinRequest && procs.size() > 1) { 10478 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10479 10480 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10481 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10482 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10483 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10484 String label = Debug.MemoryInfo.getOtherLabel(j); 10485 catMems.add(new MemItem(label, label, miscPss[j], j)); 10486 } 10487 10488 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10489 for (int j=0; j<oomPss.length; j++) { 10490 if (oomPss[j] != 0) { 10491 String label = DUMP_MEM_OOM_LABEL[j]; 10492 MemItem item = new MemItem(label, label, oomPss[j], 10493 DUMP_MEM_OOM_ADJ[j]); 10494 item.subitems = oomProcs[j]; 10495 oomMems.add(item); 10496 } 10497 } 10498 10499 if (outTag != null || outStack != null) { 10500 if (outTag != null) { 10501 appendMemBucket(outTag, totalPss, "total", false); 10502 } 10503 if (outStack != null) { 10504 appendMemBucket(outStack, totalPss, "total", true); 10505 } 10506 boolean firstLine = true; 10507 for (int i=0; i<oomMems.size(); i++) { 10508 MemItem miCat = oomMems.get(i); 10509 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10510 continue; 10511 } 10512 if (miCat.id < ProcessList.SERVICE_ADJ 10513 || miCat.id == ProcessList.HOME_APP_ADJ 10514 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10515 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10516 outTag.append(" / "); 10517 } 10518 if (outStack != null) { 10519 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10520 if (firstLine) { 10521 outStack.append(":"); 10522 firstLine = false; 10523 } 10524 outStack.append("\n\t at "); 10525 } else { 10526 outStack.append("$"); 10527 } 10528 } 10529 for (int j=0; j<miCat.subitems.size(); j++) { 10530 MemItem mi = miCat.subitems.get(j); 10531 if (j > 0) { 10532 if (outTag != null) { 10533 outTag.append(" "); 10534 } 10535 if (outStack != null) { 10536 outStack.append("$"); 10537 } 10538 } 10539 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10540 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10541 } 10542 if (outStack != null) { 10543 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10544 } 10545 } 10546 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10547 outStack.append("("); 10548 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10549 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10550 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10551 outStack.append(":"); 10552 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10553 } 10554 } 10555 outStack.append(")"); 10556 } 10557 } 10558 } 10559 } 10560 10561 if (!brief && !oomOnly) { 10562 pw.println(); 10563 pw.println("Total PSS by process:"); 10564 dumpMemItems(pw, " ", procMems, true); 10565 pw.println(); 10566 } 10567 pw.println("Total PSS by OOM adjustment:"); 10568 dumpMemItems(pw, " ", oomMems, false); 10569 if (!oomOnly) { 10570 PrintWriter out = categoryPw != null ? categoryPw : pw; 10571 out.println(); 10572 out.println("Total PSS by category:"); 10573 dumpMemItems(out, " ", catMems, true); 10574 } 10575 pw.println(); 10576 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10577 final int[] SINGLE_LONG_FORMAT = new int[] { 10578 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10579 }; 10580 long[] longOut = new long[1]; 10581 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10582 SINGLE_LONG_FORMAT, null, longOut, null); 10583 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10584 longOut[0] = 0; 10585 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10586 SINGLE_LONG_FORMAT, null, longOut, null); 10587 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10588 longOut[0] = 0; 10589 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10590 SINGLE_LONG_FORMAT, null, longOut, null); 10591 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10592 longOut[0] = 0; 10593 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10594 SINGLE_LONG_FORMAT, null, longOut, null); 10595 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10596 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10597 pw.print(shared); pw.println(" kB"); 10598 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10599 pw.print(voltile); pw.println(" kB volatile"); 10600 } 10601 } 10602 10603 /** 10604 * Searches array of arguments for the specified string 10605 * @param args array of argument strings 10606 * @param value value to search for 10607 * @return true if the value is contained in the array 10608 */ 10609 private static boolean scanArgs(String[] args, String value) { 10610 if (args != null) { 10611 for (String arg : args) { 10612 if (value.equals(arg)) { 10613 return true; 10614 } 10615 } 10616 } 10617 return false; 10618 } 10619 10620 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10621 ContentProviderRecord cpr, boolean always) { 10622 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10623 10624 if (!inLaunching || always) { 10625 synchronized (cpr) { 10626 cpr.launchingApp = null; 10627 cpr.notifyAll(); 10628 } 10629 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10630 String names[] = cpr.info.authority.split(";"); 10631 for (int j = 0; j < names.length; j++) { 10632 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10633 } 10634 } 10635 10636 for (int i=0; i<cpr.connections.size(); i++) { 10637 ContentProviderConnection conn = cpr.connections.get(i); 10638 if (conn.waiting) { 10639 // If this connection is waiting for the provider, then we don't 10640 // need to mess with its process unless we are always removing 10641 // or for some reason the provider is not currently launching. 10642 if (inLaunching && !always) { 10643 continue; 10644 } 10645 } 10646 ProcessRecord capp = conn.client; 10647 conn.dead = true; 10648 if (conn.stableCount > 0) { 10649 if (!capp.persistent && capp.thread != null 10650 && capp.pid != 0 10651 && capp.pid != MY_PID) { 10652 Slog.i(TAG, "Kill " + capp.processName 10653 + " (pid " + capp.pid + "): provider " + cpr.info.name 10654 + " in dying process " + (proc != null ? proc.processName : "??")); 10655 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10656 capp.processName, capp.setAdj, "dying provider " 10657 + cpr.name.toShortString()); 10658 Process.killProcessQuiet(capp.pid); 10659 } 10660 } else if (capp.thread != null && conn.provider.provider != null) { 10661 try { 10662 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10663 } catch (RemoteException e) { 10664 } 10665 // In the protocol here, we don't expect the client to correctly 10666 // clean up this connection, we'll just remove it. 10667 cpr.connections.remove(i); 10668 conn.client.conProviders.remove(conn); 10669 } 10670 } 10671 10672 if (inLaunching && always) { 10673 mLaunchingProviders.remove(cpr); 10674 } 10675 return inLaunching; 10676 } 10677 10678 /** 10679 * Main code for cleaning up a process when it has gone away. This is 10680 * called both as a result of the process dying, or directly when stopping 10681 * a process when running in single process mode. 10682 */ 10683 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10684 boolean restarting, boolean allowRestart, int index) { 10685 if (index >= 0) { 10686 mLruProcesses.remove(index); 10687 } 10688 10689 mProcessesToGc.remove(app); 10690 10691 // Dismiss any open dialogs. 10692 if (app.crashDialog != null) { 10693 app.crashDialog.dismiss(); 10694 app.crashDialog = null; 10695 } 10696 if (app.anrDialog != null) { 10697 app.anrDialog.dismiss(); 10698 app.anrDialog = null; 10699 } 10700 if (app.waitDialog != null) { 10701 app.waitDialog.dismiss(); 10702 app.waitDialog = null; 10703 } 10704 10705 app.crashing = false; 10706 app.notResponding = false; 10707 10708 app.resetPackageList(); 10709 app.unlinkDeathRecipient(); 10710 app.thread = null; 10711 app.forcingToForeground = null; 10712 app.foregroundServices = false; 10713 app.foregroundActivities = false; 10714 app.hasShownUi = false; 10715 app.hasAboveClient = false; 10716 10717 mServices.killServicesLocked(app, allowRestart); 10718 10719 boolean restart = false; 10720 10721 // Remove published content providers. 10722 if (!app.pubProviders.isEmpty()) { 10723 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10724 while (it.hasNext()) { 10725 ContentProviderRecord cpr = it.next(); 10726 10727 final boolean always = app.bad || !allowRestart; 10728 if (removeDyingProviderLocked(app, cpr, always) || always) { 10729 // We left the provider in the launching list, need to 10730 // restart it. 10731 restart = true; 10732 } 10733 10734 cpr.provider = null; 10735 cpr.proc = null; 10736 } 10737 app.pubProviders.clear(); 10738 } 10739 10740 // Take care of any launching providers waiting for this process. 10741 if (checkAppInLaunchingProvidersLocked(app, false)) { 10742 restart = true; 10743 } 10744 10745 // Unregister from connected content providers. 10746 if (!app.conProviders.isEmpty()) { 10747 for (int i=0; i<app.conProviders.size(); i++) { 10748 ContentProviderConnection conn = app.conProviders.get(i); 10749 conn.provider.connections.remove(conn); 10750 } 10751 app.conProviders.clear(); 10752 } 10753 10754 // At this point there may be remaining entries in mLaunchingProviders 10755 // where we were the only one waiting, so they are no longer of use. 10756 // Look for these and clean up if found. 10757 // XXX Commented out for now. Trying to figure out a way to reproduce 10758 // the actual situation to identify what is actually going on. 10759 if (false) { 10760 for (int i=0; i<mLaunchingProviders.size(); i++) { 10761 ContentProviderRecord cpr = (ContentProviderRecord) 10762 mLaunchingProviders.get(i); 10763 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10764 synchronized (cpr) { 10765 cpr.launchingApp = null; 10766 cpr.notifyAll(); 10767 } 10768 } 10769 } 10770 } 10771 10772 skipCurrentReceiverLocked(app); 10773 10774 // Unregister any receivers. 10775 if (app.receivers.size() > 0) { 10776 Iterator<ReceiverList> it = app.receivers.iterator(); 10777 while (it.hasNext()) { 10778 removeReceiverLocked(it.next()); 10779 } 10780 app.receivers.clear(); 10781 } 10782 10783 // If the app is undergoing backup, tell the backup manager about it 10784 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10785 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10786 + mBackupTarget.appInfo + " died during backup"); 10787 try { 10788 IBackupManager bm = IBackupManager.Stub.asInterface( 10789 ServiceManager.getService(Context.BACKUP_SERVICE)); 10790 bm.agentDisconnected(app.info.packageName); 10791 } catch (RemoteException e) { 10792 // can't happen; backup manager is local 10793 } 10794 } 10795 10796 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10797 ProcessChangeItem item = mPendingProcessChanges.get(i); 10798 if (item.pid == app.pid) { 10799 mPendingProcessChanges.remove(i); 10800 mAvailProcessChanges.add(item); 10801 } 10802 } 10803 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10804 10805 // If the caller is restarting this app, then leave it in its 10806 // current lists and let the caller take care of it. 10807 if (restarting) { 10808 return; 10809 } 10810 10811 if (!app.persistent || app.isolated) { 10812 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10813 "Removing non-persistent process during cleanup: " + app); 10814 mProcessNames.remove(app.processName, app.uid); 10815 mIsolatedProcesses.remove(app.uid); 10816 if (mHeavyWeightProcess == app) { 10817 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10818 mHeavyWeightProcess.userId, 0)); 10819 mHeavyWeightProcess = null; 10820 } 10821 } else if (!app.removed) { 10822 // This app is persistent, so we need to keep its record around. 10823 // If it is not already on the pending app list, add it there 10824 // and start a new process for it. 10825 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10826 mPersistentStartingProcesses.add(app); 10827 restart = true; 10828 } 10829 } 10830 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10831 "Clean-up removing on hold: " + app); 10832 mProcessesOnHold.remove(app); 10833 10834 if (app == mHomeProcess) { 10835 mHomeProcess = null; 10836 } 10837 if (app == mPreviousProcess) { 10838 mPreviousProcess = null; 10839 } 10840 10841 if (restart && !app.isolated) { 10842 // We have components that still need to be running in the 10843 // process, so re-launch it. 10844 mProcessNames.put(app.processName, app.uid, app); 10845 startProcessLocked(app, "restart", app.processName); 10846 } else if (app.pid > 0 && app.pid != MY_PID) { 10847 // Goodbye! 10848 synchronized (mPidsSelfLocked) { 10849 mPidsSelfLocked.remove(app.pid); 10850 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10851 } 10852 app.setPid(0); 10853 } 10854 } 10855 10856 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10857 // Look through the content providers we are waiting to have launched, 10858 // and if any run in this process then either schedule a restart of 10859 // the process or kill the client waiting for it if this process has 10860 // gone bad. 10861 int NL = mLaunchingProviders.size(); 10862 boolean restart = false; 10863 for (int i=0; i<NL; i++) { 10864 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10865 if (cpr.launchingApp == app) { 10866 if (!alwaysBad && !app.bad) { 10867 restart = true; 10868 } else { 10869 removeDyingProviderLocked(app, cpr, true); 10870 // cpr should have been removed from mLaunchingProviders 10871 NL = mLaunchingProviders.size(); 10872 i--; 10873 } 10874 } 10875 } 10876 return restart; 10877 } 10878 10879 // ========================================================= 10880 // SERVICES 10881 // ========================================================= 10882 10883 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10884 int flags) { 10885 enforceNotIsolatedCaller("getServices"); 10886 synchronized (this) { 10887 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10888 } 10889 } 10890 10891 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10892 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10893 synchronized (this) { 10894 return mServices.getRunningServiceControlPanelLocked(name); 10895 } 10896 } 10897 10898 public ComponentName startService(IApplicationThread caller, Intent service, 10899 String resolvedType, int userId) { 10900 enforceNotIsolatedCaller("startService"); 10901 // Refuse possible leaked file descriptors 10902 if (service != null && service.hasFileDescriptors() == true) { 10903 throw new IllegalArgumentException("File descriptors passed in Intent"); 10904 } 10905 10906 if (DEBUG_SERVICE) 10907 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10908 synchronized(this) { 10909 final int callingPid = Binder.getCallingPid(); 10910 final int callingUid = Binder.getCallingUid(); 10911 checkValidCaller(callingUid, userId); 10912 final long origId = Binder.clearCallingIdentity(); 10913 ComponentName res = mServices.startServiceLocked(caller, service, 10914 resolvedType, callingPid, callingUid, userId); 10915 Binder.restoreCallingIdentity(origId); 10916 return res; 10917 } 10918 } 10919 10920 ComponentName startServiceInPackage(int uid, 10921 Intent service, String resolvedType, int userId) { 10922 synchronized(this) { 10923 if (DEBUG_SERVICE) 10924 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10925 final long origId = Binder.clearCallingIdentity(); 10926 ComponentName res = mServices.startServiceLocked(null, service, 10927 resolvedType, -1, uid, userId); 10928 Binder.restoreCallingIdentity(origId); 10929 return res; 10930 } 10931 } 10932 10933 public int stopService(IApplicationThread caller, Intent service, 10934 String resolvedType, int userId) { 10935 enforceNotIsolatedCaller("stopService"); 10936 // Refuse possible leaked file descriptors 10937 if (service != null && service.hasFileDescriptors() == true) { 10938 throw new IllegalArgumentException("File descriptors passed in Intent"); 10939 } 10940 10941 checkValidCaller(Binder.getCallingUid(), userId); 10942 10943 synchronized(this) { 10944 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10945 } 10946 } 10947 10948 public IBinder peekService(Intent service, String resolvedType) { 10949 enforceNotIsolatedCaller("peekService"); 10950 // Refuse possible leaked file descriptors 10951 if (service != null && service.hasFileDescriptors() == true) { 10952 throw new IllegalArgumentException("File descriptors passed in Intent"); 10953 } 10954 synchronized(this) { 10955 return mServices.peekServiceLocked(service, resolvedType); 10956 } 10957 } 10958 10959 public boolean stopServiceToken(ComponentName className, IBinder token, 10960 int startId) { 10961 synchronized(this) { 10962 return mServices.stopServiceTokenLocked(className, token, startId); 10963 } 10964 } 10965 10966 public void setServiceForeground(ComponentName className, IBinder token, 10967 int id, Notification notification, boolean removeNotification) { 10968 synchronized(this) { 10969 mServices.setServiceForegroundLocked(className, token, id, notification, 10970 removeNotification); 10971 } 10972 } 10973 10974 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10975 boolean requireFull, String name, String callerPackage) { 10976 final int callingUserId = UserHandle.getUserId(callingUid); 10977 if (callingUserId != userId) { 10978 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10979 if ((requireFull || checkComponentPermission( 10980 android.Manifest.permission.INTERACT_ACROSS_USERS, 10981 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10982 && checkComponentPermission( 10983 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10984 callingPid, callingUid, -1, true) 10985 != PackageManager.PERMISSION_GRANTED) { 10986 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10987 // In this case, they would like to just execute as their 10988 // owner user instead of failing. 10989 userId = callingUserId; 10990 } else { 10991 StringBuilder builder = new StringBuilder(128); 10992 builder.append("Permission Denial: "); 10993 builder.append(name); 10994 if (callerPackage != null) { 10995 builder.append(" from "); 10996 builder.append(callerPackage); 10997 } 10998 builder.append(" asks to run as user "); 10999 builder.append(userId); 11000 builder.append(" but is calling from user "); 11001 builder.append(UserHandle.getUserId(callingUid)); 11002 builder.append("; this requires "); 11003 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 11004 if (!requireFull) { 11005 builder.append(" or "); 11006 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 11007 } 11008 String msg = builder.toString(); 11009 Slog.w(TAG, msg); 11010 throw new SecurityException(msg); 11011 } 11012 } 11013 } 11014 if (userId == UserHandle.USER_CURRENT 11015 || userId == UserHandle.USER_CURRENT_OR_SELF) { 11016 // Note that we may be accessing this outside of a lock... 11017 // shouldn't be a big deal, if this is being called outside 11018 // of a locked context there is intrinsically a race with 11019 // the value the caller will receive and someone else changing it. 11020 userId = mCurrentUserId; 11021 } 11022 if (!allowAll && userId < 0) { 11023 throw new IllegalArgumentException( 11024 "Call does not support special user #" + userId); 11025 } 11026 } 11027 return userId; 11028 } 11029 11030 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11031 String className, int flags) { 11032 boolean result = false; 11033 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11034 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11035 if (ActivityManager.checkUidPermission( 11036 android.Manifest.permission.INTERACT_ACROSS_USERS, 11037 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11038 ComponentName comp = new ComponentName(aInfo.packageName, className); 11039 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11040 + " requests FLAG_SINGLE_USER, but app does not hold " 11041 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11042 Slog.w(TAG, msg); 11043 throw new SecurityException(msg); 11044 } 11045 result = true; 11046 } 11047 } else if (componentProcessName == aInfo.packageName) { 11048 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11049 } else if ("system".equals(componentProcessName)) { 11050 result = true; 11051 } 11052 if (DEBUG_MU) { 11053 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11054 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11055 } 11056 return result; 11057 } 11058 11059 public int bindService(IApplicationThread caller, IBinder token, 11060 Intent service, String resolvedType, 11061 IServiceConnection connection, int flags, int userId) { 11062 enforceNotIsolatedCaller("bindService"); 11063 // Refuse possible leaked file descriptors 11064 if (service != null && service.hasFileDescriptors() == true) { 11065 throw new IllegalArgumentException("File descriptors passed in Intent"); 11066 } 11067 11068 synchronized(this) { 11069 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11070 connection, flags, userId); 11071 } 11072 } 11073 11074 public boolean unbindService(IServiceConnection connection) { 11075 synchronized (this) { 11076 return mServices.unbindServiceLocked(connection); 11077 } 11078 } 11079 11080 public void publishService(IBinder token, Intent intent, IBinder service) { 11081 // Refuse possible leaked file descriptors 11082 if (intent != null && intent.hasFileDescriptors() == true) { 11083 throw new IllegalArgumentException("File descriptors passed in Intent"); 11084 } 11085 11086 synchronized(this) { 11087 if (!(token instanceof ServiceRecord)) { 11088 throw new IllegalArgumentException("Invalid service token"); 11089 } 11090 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11091 } 11092 } 11093 11094 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11095 // Refuse possible leaked file descriptors 11096 if (intent != null && intent.hasFileDescriptors() == true) { 11097 throw new IllegalArgumentException("File descriptors passed in Intent"); 11098 } 11099 11100 synchronized(this) { 11101 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11102 } 11103 } 11104 11105 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11106 synchronized(this) { 11107 if (!(token instanceof ServiceRecord)) { 11108 throw new IllegalArgumentException("Invalid service token"); 11109 } 11110 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11111 } 11112 } 11113 11114 // ========================================================= 11115 // BACKUP AND RESTORE 11116 // ========================================================= 11117 11118 // Cause the target app to be launched if necessary and its backup agent 11119 // instantiated. The backup agent will invoke backupAgentCreated() on the 11120 // activity manager to announce its creation. 11121 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11122 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 11123 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 11124 11125 synchronized(this) { 11126 // !!! TODO: currently no check here that we're already bound 11127 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11128 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11129 synchronized (stats) { 11130 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11131 } 11132 11133 // Backup agent is now in use, its package can't be stopped. 11134 try { 11135 AppGlobals.getPackageManager().setPackageStoppedState( 11136 app.packageName, false, UserHandle.getUserId(app.uid)); 11137 } catch (RemoteException e) { 11138 } catch (IllegalArgumentException e) { 11139 Slog.w(TAG, "Failed trying to unstop package " 11140 + app.packageName + ": " + e); 11141 } 11142 11143 BackupRecord r = new BackupRecord(ss, app, backupMode); 11144 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11145 ? new ComponentName(app.packageName, app.backupAgentName) 11146 : new ComponentName("android", "FullBackupAgent"); 11147 // startProcessLocked() returns existing proc's record if it's already running 11148 ProcessRecord proc = startProcessLocked(app.processName, app, 11149 false, 0, "backup", hostingName, false, false); 11150 if (proc == null) { 11151 Slog.e(TAG, "Unable to start backup agent process " + r); 11152 return false; 11153 } 11154 11155 r.app = proc; 11156 mBackupTarget = r; 11157 mBackupAppName = app.packageName; 11158 11159 // Try not to kill the process during backup 11160 updateOomAdjLocked(proc); 11161 11162 // If the process is already attached, schedule the creation of the backup agent now. 11163 // If it is not yet live, this will be done when it attaches to the framework. 11164 if (proc.thread != null) { 11165 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11166 try { 11167 proc.thread.scheduleCreateBackupAgent(app, 11168 compatibilityInfoForPackageLocked(app), backupMode); 11169 } catch (RemoteException e) { 11170 // Will time out on the backup manager side 11171 } 11172 } else { 11173 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11174 } 11175 // Invariants: at this point, the target app process exists and the application 11176 // is either already running or in the process of coming up. mBackupTarget and 11177 // mBackupAppName describe the app, so that when it binds back to the AM we 11178 // know that it's scheduled for a backup-agent operation. 11179 } 11180 11181 return true; 11182 } 11183 11184 @Override 11185 public void clearPendingBackup() { 11186 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 11187 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 11188 11189 synchronized (this) { 11190 mBackupTarget = null; 11191 mBackupAppName = null; 11192 } 11193 } 11194 11195 // A backup agent has just come up 11196 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11197 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11198 + " = " + agent); 11199 11200 synchronized(this) { 11201 if (!agentPackageName.equals(mBackupAppName)) { 11202 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11203 return; 11204 } 11205 } 11206 11207 long oldIdent = Binder.clearCallingIdentity(); 11208 try { 11209 IBackupManager bm = IBackupManager.Stub.asInterface( 11210 ServiceManager.getService(Context.BACKUP_SERVICE)); 11211 bm.agentConnected(agentPackageName, agent); 11212 } catch (RemoteException e) { 11213 // can't happen; the backup manager service is local 11214 } catch (Exception e) { 11215 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11216 e.printStackTrace(); 11217 } finally { 11218 Binder.restoreCallingIdentity(oldIdent); 11219 } 11220 } 11221 11222 // done with this agent 11223 public void unbindBackupAgent(ApplicationInfo appInfo) { 11224 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11225 if (appInfo == null) { 11226 Slog.w(TAG, "unbind backup agent for null app"); 11227 return; 11228 } 11229 11230 synchronized(this) { 11231 try { 11232 if (mBackupAppName == null) { 11233 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11234 return; 11235 } 11236 11237 if (!mBackupAppName.equals(appInfo.packageName)) { 11238 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11239 return; 11240 } 11241 11242 // Not backing this app up any more; reset its OOM adjustment 11243 final ProcessRecord proc = mBackupTarget.app; 11244 updateOomAdjLocked(proc); 11245 11246 // If the app crashed during backup, 'thread' will be null here 11247 if (proc.thread != null) { 11248 try { 11249 proc.thread.scheduleDestroyBackupAgent(appInfo, 11250 compatibilityInfoForPackageLocked(appInfo)); 11251 } catch (Exception e) { 11252 Slog.e(TAG, "Exception when unbinding backup agent:"); 11253 e.printStackTrace(); 11254 } 11255 } 11256 } finally { 11257 mBackupTarget = null; 11258 mBackupAppName = null; 11259 } 11260 } 11261 } 11262 // ========================================================= 11263 // BROADCASTS 11264 // ========================================================= 11265 11266 private final List getStickiesLocked(String action, IntentFilter filter, 11267 List cur, int userId) { 11268 final ContentResolver resolver = mContext.getContentResolver(); 11269 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11270 if (stickies == null) { 11271 return cur; 11272 } 11273 final ArrayList<Intent> list = stickies.get(action); 11274 if (list == null) { 11275 return cur; 11276 } 11277 int N = list.size(); 11278 for (int i=0; i<N; i++) { 11279 Intent intent = list.get(i); 11280 if (filter.match(resolver, intent, true, TAG) >= 0) { 11281 if (cur == null) { 11282 cur = new ArrayList<Intent>(); 11283 } 11284 cur.add(intent); 11285 } 11286 } 11287 return cur; 11288 } 11289 11290 boolean isPendingBroadcastProcessLocked(int pid) { 11291 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11292 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11293 } 11294 11295 void skipPendingBroadcastLocked(int pid) { 11296 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11297 for (BroadcastQueue queue : mBroadcastQueues) { 11298 queue.skipPendingBroadcastLocked(pid); 11299 } 11300 } 11301 11302 // The app just attached; send any pending broadcasts that it should receive 11303 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11304 boolean didSomething = false; 11305 for (BroadcastQueue queue : mBroadcastQueues) { 11306 didSomething |= queue.sendPendingBroadcastsLocked(app); 11307 } 11308 return didSomething; 11309 } 11310 11311 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11312 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11313 enforceNotIsolatedCaller("registerReceiver"); 11314 int callingUid; 11315 int callingPid; 11316 synchronized(this) { 11317 ProcessRecord callerApp = null; 11318 if (caller != null) { 11319 callerApp = getRecordForAppLocked(caller); 11320 if (callerApp == null) { 11321 throw new SecurityException( 11322 "Unable to find app for caller " + caller 11323 + " (pid=" + Binder.getCallingPid() 11324 + ") when registering receiver " + receiver); 11325 } 11326 if (callerApp.info.uid != Process.SYSTEM_UID && 11327 !callerApp.pkgList.contains(callerPackage)) { 11328 throw new SecurityException("Given caller package " + callerPackage 11329 + " is not running in process " + callerApp); 11330 } 11331 callingUid = callerApp.info.uid; 11332 callingPid = callerApp.pid; 11333 } else { 11334 callerPackage = null; 11335 callingUid = Binder.getCallingUid(); 11336 callingPid = Binder.getCallingPid(); 11337 } 11338 11339 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11340 true, true, "registerReceiver", callerPackage); 11341 11342 List allSticky = null; 11343 11344 // Look for any matching sticky broadcasts... 11345 Iterator actions = filter.actionsIterator(); 11346 if (actions != null) { 11347 while (actions.hasNext()) { 11348 String action = (String)actions.next(); 11349 allSticky = getStickiesLocked(action, filter, allSticky, 11350 UserHandle.USER_ALL); 11351 allSticky = getStickiesLocked(action, filter, allSticky, 11352 UserHandle.getUserId(callingUid)); 11353 } 11354 } else { 11355 allSticky = getStickiesLocked(null, filter, allSticky, 11356 UserHandle.USER_ALL); 11357 allSticky = getStickiesLocked(null, filter, allSticky, 11358 UserHandle.getUserId(callingUid)); 11359 } 11360 11361 // The first sticky in the list is returned directly back to 11362 // the client. 11363 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11364 11365 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11366 + ": " + sticky); 11367 11368 if (receiver == null) { 11369 return sticky; 11370 } 11371 11372 ReceiverList rl 11373 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11374 if (rl == null) { 11375 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11376 userId, receiver); 11377 if (rl.app != null) { 11378 rl.app.receivers.add(rl); 11379 } else { 11380 try { 11381 receiver.asBinder().linkToDeath(rl, 0); 11382 } catch (RemoteException e) { 11383 return sticky; 11384 } 11385 rl.linkedToDeath = true; 11386 } 11387 mRegisteredReceivers.put(receiver.asBinder(), rl); 11388 } else if (rl.uid != callingUid) { 11389 throw new IllegalArgumentException( 11390 "Receiver requested to register for uid " + callingUid 11391 + " was previously registered for uid " + rl.uid); 11392 } else if (rl.pid != callingPid) { 11393 throw new IllegalArgumentException( 11394 "Receiver requested to register for pid " + callingPid 11395 + " was previously registered for pid " + rl.pid); 11396 } else if (rl.userId != userId) { 11397 throw new IllegalArgumentException( 11398 "Receiver requested to register for user " + userId 11399 + " was previously registered for user " + rl.userId); 11400 } 11401 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11402 permission, callingUid, userId); 11403 rl.add(bf); 11404 if (!bf.debugCheck()) { 11405 Slog.w(TAG, "==> For Dynamic broadast"); 11406 } 11407 mReceiverResolver.addFilter(bf); 11408 11409 // Enqueue broadcasts for all existing stickies that match 11410 // this filter. 11411 if (allSticky != null) { 11412 ArrayList receivers = new ArrayList(); 11413 receivers.add(bf); 11414 11415 int N = allSticky.size(); 11416 for (int i=0; i<N; i++) { 11417 Intent intent = (Intent)allSticky.get(i); 11418 BroadcastQueue queue = broadcastQueueForIntent(intent); 11419 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11420 null, -1, -1, null, receivers, null, 0, null, null, 11421 false, true, true, -1); 11422 queue.enqueueParallelBroadcastLocked(r); 11423 queue.scheduleBroadcastsLocked(); 11424 } 11425 } 11426 11427 return sticky; 11428 } 11429 } 11430 11431 public void unregisterReceiver(IIntentReceiver receiver) { 11432 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11433 11434 final long origId = Binder.clearCallingIdentity(); 11435 try { 11436 boolean doTrim = false; 11437 11438 synchronized(this) { 11439 ReceiverList rl 11440 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11441 if (rl != null) { 11442 if (rl.curBroadcast != null) { 11443 BroadcastRecord r = rl.curBroadcast; 11444 final boolean doNext = finishReceiverLocked( 11445 receiver.asBinder(), r.resultCode, r.resultData, 11446 r.resultExtras, r.resultAbort, true); 11447 if (doNext) { 11448 doTrim = true; 11449 r.queue.processNextBroadcast(false); 11450 } 11451 } 11452 11453 if (rl.app != null) { 11454 rl.app.receivers.remove(rl); 11455 } 11456 removeReceiverLocked(rl); 11457 if (rl.linkedToDeath) { 11458 rl.linkedToDeath = false; 11459 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11460 } 11461 } 11462 } 11463 11464 // If we actually concluded any broadcasts, we might now be able 11465 // to trim the recipients' apps from our working set 11466 if (doTrim) { 11467 trimApplications(); 11468 return; 11469 } 11470 11471 } finally { 11472 Binder.restoreCallingIdentity(origId); 11473 } 11474 } 11475 11476 void removeReceiverLocked(ReceiverList rl) { 11477 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11478 int N = rl.size(); 11479 for (int i=0; i<N; i++) { 11480 mReceiverResolver.removeFilter(rl.get(i)); 11481 } 11482 } 11483 11484 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11485 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11486 ProcessRecord r = mLruProcesses.get(i); 11487 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11488 try { 11489 r.thread.dispatchPackageBroadcast(cmd, packages); 11490 } catch (RemoteException ex) { 11491 } 11492 } 11493 } 11494 } 11495 11496 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11497 int[] users) { 11498 List<ResolveInfo> receivers = null; 11499 try { 11500 HashSet<ComponentName> singleUserReceivers = null; 11501 boolean scannedFirstReceivers = false; 11502 for (int user : users) { 11503 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11504 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11505 if (user != 0 && newReceivers != null) { 11506 // If this is not the primary user, we need to check for 11507 // any receivers that should be filtered out. 11508 for (int i=0; i<newReceivers.size(); i++) { 11509 ResolveInfo ri = newReceivers.get(i); 11510 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11511 newReceivers.remove(i); 11512 i--; 11513 } 11514 } 11515 } 11516 if (newReceivers != null && newReceivers.size() == 0) { 11517 newReceivers = null; 11518 } 11519 if (receivers == null) { 11520 receivers = newReceivers; 11521 } else if (newReceivers != null) { 11522 // We need to concatenate the additional receivers 11523 // found with what we have do far. This would be easy, 11524 // but we also need to de-dup any receivers that are 11525 // singleUser. 11526 if (!scannedFirstReceivers) { 11527 // Collect any single user receivers we had already retrieved. 11528 scannedFirstReceivers = true; 11529 for (int i=0; i<receivers.size(); i++) { 11530 ResolveInfo ri = receivers.get(i); 11531 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11532 ComponentName cn = new ComponentName( 11533 ri.activityInfo.packageName, ri.activityInfo.name); 11534 if (singleUserReceivers == null) { 11535 singleUserReceivers = new HashSet<ComponentName>(); 11536 } 11537 singleUserReceivers.add(cn); 11538 } 11539 } 11540 } 11541 // Add the new results to the existing results, tracking 11542 // and de-dupping single user receivers. 11543 for (int i=0; i<newReceivers.size(); i++) { 11544 ResolveInfo ri = newReceivers.get(i); 11545 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11546 ComponentName cn = new ComponentName( 11547 ri.activityInfo.packageName, ri.activityInfo.name); 11548 if (singleUserReceivers == null) { 11549 singleUserReceivers = new HashSet<ComponentName>(); 11550 } 11551 if (!singleUserReceivers.contains(cn)) { 11552 singleUserReceivers.add(cn); 11553 receivers.add(ri); 11554 } 11555 } else { 11556 receivers.add(ri); 11557 } 11558 } 11559 } 11560 } 11561 } catch (RemoteException ex) { 11562 // pm is in same process, this will never happen. 11563 } 11564 return receivers; 11565 } 11566 11567 private final int broadcastIntentLocked(ProcessRecord callerApp, 11568 String callerPackage, Intent intent, String resolvedType, 11569 IIntentReceiver resultTo, int resultCode, String resultData, 11570 Bundle map, String requiredPermission, 11571 boolean ordered, boolean sticky, int callingPid, int callingUid, 11572 int userId) { 11573 intent = new Intent(intent); 11574 11575 // By default broadcasts do not go to stopped apps. 11576 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11577 11578 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11579 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11580 + " ordered=" + ordered + " userid=" + userId); 11581 if ((resultTo != null) && !ordered) { 11582 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11583 } 11584 11585 userId = handleIncomingUser(callingPid, callingUid, userId, 11586 true, false, "broadcast", callerPackage); 11587 11588 // Make sure that the user who is receiving this broadcast is started. 11589 // If not, we will just skip it. 11590 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11591 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11592 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11593 Slog.w(TAG, "Skipping broadcast of " + intent 11594 + ": user " + userId + " is stopped"); 11595 return ActivityManager.BROADCAST_SUCCESS; 11596 } 11597 } 11598 11599 /* 11600 * Prevent non-system code (defined here to be non-persistent 11601 * processes) from sending protected broadcasts. 11602 */ 11603 int callingAppId = UserHandle.getAppId(callingUid); 11604 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11605 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11606 callingUid == 0) { 11607 // Always okay. 11608 } else if (callerApp == null || !callerApp.persistent) { 11609 try { 11610 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11611 intent.getAction())) { 11612 String msg = "Permission Denial: not allowed to send broadcast " 11613 + intent.getAction() + " from pid=" 11614 + callingPid + ", uid=" + callingUid; 11615 Slog.w(TAG, msg); 11616 throw new SecurityException(msg); 11617 } 11618 } catch (RemoteException e) { 11619 Slog.w(TAG, "Remote exception", e); 11620 return ActivityManager.BROADCAST_SUCCESS; 11621 } 11622 } 11623 11624 // Handle special intents: if this broadcast is from the package 11625 // manager about a package being removed, we need to remove all of 11626 // its activities from the history stack. 11627 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11628 intent.getAction()); 11629 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11630 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11631 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11632 || uidRemoved) { 11633 if (checkComponentPermission( 11634 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11635 callingPid, callingUid, -1, true) 11636 == PackageManager.PERMISSION_GRANTED) { 11637 if (uidRemoved) { 11638 final Bundle intentExtras = intent.getExtras(); 11639 final int uid = intentExtras != null 11640 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11641 if (uid >= 0) { 11642 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11643 synchronized (bs) { 11644 bs.removeUidStatsLocked(uid); 11645 } 11646 } 11647 } else { 11648 // If resources are unavailable just force stop all 11649 // those packages and flush the attribute cache as well. 11650 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11651 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11652 if (list != null && (list.length > 0)) { 11653 for (String pkg : list) { 11654 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11655 } 11656 sendPackageBroadcastLocked( 11657 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11658 } 11659 } else { 11660 Uri data = intent.getData(); 11661 String ssp; 11662 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11663 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11664 forceStopPackageLocked(ssp, 11665 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11666 false, userId); 11667 } 11668 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11669 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11670 new String[] {ssp}, userId); 11671 } 11672 } 11673 } 11674 } 11675 } else { 11676 String msg = "Permission Denial: " + intent.getAction() 11677 + " broadcast from " + callerPackage + " (pid=" + callingPid 11678 + ", uid=" + callingUid + ")" 11679 + " requires " 11680 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11681 Slog.w(TAG, msg); 11682 throw new SecurityException(msg); 11683 } 11684 11685 // Special case for adding a package: by default turn on compatibility 11686 // mode. 11687 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11688 Uri data = intent.getData(); 11689 String ssp; 11690 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11691 mCompatModePackages.handlePackageAddedLocked(ssp, 11692 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11693 } 11694 } 11695 11696 /* 11697 * If this is the time zone changed action, queue up a message that will reset the timezone 11698 * of all currently running processes. This message will get queued up before the broadcast 11699 * happens. 11700 */ 11701 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11702 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11703 } 11704 11705 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11706 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11707 } 11708 11709 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11710 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11711 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11712 } 11713 11714 // Add to the sticky list if requested. 11715 if (sticky) { 11716 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11717 callingPid, callingUid) 11718 != PackageManager.PERMISSION_GRANTED) { 11719 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11720 + callingPid + ", uid=" + callingUid 11721 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11722 Slog.w(TAG, msg); 11723 throw new SecurityException(msg); 11724 } 11725 if (requiredPermission != null) { 11726 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11727 + " and enforce permission " + requiredPermission); 11728 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11729 } 11730 if (intent.getComponent() != null) { 11731 throw new SecurityException( 11732 "Sticky broadcasts can't target a specific component"); 11733 } 11734 // We use userId directly here, since the "all" target is maintained 11735 // as a separate set of sticky broadcasts. 11736 if (userId != UserHandle.USER_ALL) { 11737 // But first, if this is not a broadcast to all users, then 11738 // make sure it doesn't conflict with an existing broadcast to 11739 // all users. 11740 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11741 UserHandle.USER_ALL); 11742 if (stickies != null) { 11743 ArrayList<Intent> list = stickies.get(intent.getAction()); 11744 if (list != null) { 11745 int N = list.size(); 11746 int i; 11747 for (i=0; i<N; i++) { 11748 if (intent.filterEquals(list.get(i))) { 11749 throw new IllegalArgumentException( 11750 "Sticky broadcast " + intent + " for user " 11751 + userId + " conflicts with existing global broadcast"); 11752 } 11753 } 11754 } 11755 } 11756 } 11757 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11758 if (stickies == null) { 11759 stickies = new HashMap<String, ArrayList<Intent>>(); 11760 mStickyBroadcasts.put(userId, stickies); 11761 } 11762 ArrayList<Intent> list = stickies.get(intent.getAction()); 11763 if (list == null) { 11764 list = new ArrayList<Intent>(); 11765 stickies.put(intent.getAction(), list); 11766 } 11767 int N = list.size(); 11768 int i; 11769 for (i=0; i<N; i++) { 11770 if (intent.filterEquals(list.get(i))) { 11771 // This sticky already exists, replace it. 11772 list.set(i, new Intent(intent)); 11773 break; 11774 } 11775 } 11776 if (i >= N) { 11777 list.add(new Intent(intent)); 11778 } 11779 } 11780 11781 int[] users; 11782 if (userId == UserHandle.USER_ALL) { 11783 // Caller wants broadcast to go to all started users. 11784 users = mStartedUserArray; 11785 } else { 11786 // Caller wants broadcast to go to one specific user. 11787 users = new int[] {userId}; 11788 } 11789 11790 // Figure out who all will receive this broadcast. 11791 List receivers = null; 11792 List<BroadcastFilter> registeredReceivers = null; 11793 // Need to resolve the intent to interested receivers... 11794 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11795 == 0) { 11796 receivers = collectReceiverComponents(intent, resolvedType, users); 11797 } 11798 if (intent.getComponent() == null) { 11799 registeredReceivers = mReceiverResolver.queryIntent(intent, 11800 resolvedType, false, userId); 11801 } 11802 11803 final boolean replacePending = 11804 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11805 11806 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11807 + " replacePending=" + replacePending); 11808 11809 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11810 if (!ordered && NR > 0) { 11811 // If we are not serializing this broadcast, then send the 11812 // registered receivers separately so they don't wait for the 11813 // components to be launched. 11814 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11815 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11816 callerPackage, callingPid, callingUid, requiredPermission, 11817 registeredReceivers, resultTo, resultCode, resultData, map, 11818 ordered, sticky, false, userId); 11819 if (DEBUG_BROADCAST) Slog.v( 11820 TAG, "Enqueueing parallel broadcast " + r); 11821 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11822 if (!replaced) { 11823 queue.enqueueParallelBroadcastLocked(r); 11824 queue.scheduleBroadcastsLocked(); 11825 } 11826 registeredReceivers = null; 11827 NR = 0; 11828 } 11829 11830 // Merge into one list. 11831 int ir = 0; 11832 if (receivers != null) { 11833 // A special case for PACKAGE_ADDED: do not allow the package 11834 // being added to see this broadcast. This prevents them from 11835 // using this as a back door to get run as soon as they are 11836 // installed. Maybe in the future we want to have a special install 11837 // broadcast or such for apps, but we'd like to deliberately make 11838 // this decision. 11839 String skipPackages[] = null; 11840 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11841 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11842 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11843 Uri data = intent.getData(); 11844 if (data != null) { 11845 String pkgName = data.getSchemeSpecificPart(); 11846 if (pkgName != null) { 11847 skipPackages = new String[] { pkgName }; 11848 } 11849 } 11850 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11851 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11852 } 11853 if (skipPackages != null && (skipPackages.length > 0)) { 11854 for (String skipPackage : skipPackages) { 11855 if (skipPackage != null) { 11856 int NT = receivers.size(); 11857 for (int it=0; it<NT; it++) { 11858 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11859 if (curt.activityInfo.packageName.equals(skipPackage)) { 11860 receivers.remove(it); 11861 it--; 11862 NT--; 11863 } 11864 } 11865 } 11866 } 11867 } 11868 11869 int NT = receivers != null ? receivers.size() : 0; 11870 int it = 0; 11871 ResolveInfo curt = null; 11872 BroadcastFilter curr = null; 11873 while (it < NT && ir < NR) { 11874 if (curt == null) { 11875 curt = (ResolveInfo)receivers.get(it); 11876 } 11877 if (curr == null) { 11878 curr = registeredReceivers.get(ir); 11879 } 11880 if (curr.getPriority() >= curt.priority) { 11881 // Insert this broadcast record into the final list. 11882 receivers.add(it, curr); 11883 ir++; 11884 curr = null; 11885 it++; 11886 NT++; 11887 } else { 11888 // Skip to the next ResolveInfo in the final list. 11889 it++; 11890 curt = null; 11891 } 11892 } 11893 } 11894 while (ir < NR) { 11895 if (receivers == null) { 11896 receivers = new ArrayList(); 11897 } 11898 receivers.add(registeredReceivers.get(ir)); 11899 ir++; 11900 } 11901 11902 if ((receivers != null && receivers.size() > 0) 11903 || resultTo != null) { 11904 BroadcastQueue queue = broadcastQueueForIntent(intent); 11905 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11906 callerPackage, callingPid, callingUid, requiredPermission, 11907 receivers, resultTo, resultCode, resultData, map, ordered, 11908 sticky, false, userId); 11909 if (DEBUG_BROADCAST) Slog.v( 11910 TAG, "Enqueueing ordered broadcast " + r 11911 + ": prev had " + queue.mOrderedBroadcasts.size()); 11912 if (DEBUG_BROADCAST) { 11913 int seq = r.intent.getIntExtra("seq", -1); 11914 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11915 } 11916 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11917 if (!replaced) { 11918 queue.enqueueOrderedBroadcastLocked(r); 11919 queue.scheduleBroadcastsLocked(); 11920 } 11921 } 11922 11923 return ActivityManager.BROADCAST_SUCCESS; 11924 } 11925 11926 final Intent verifyBroadcastLocked(Intent intent) { 11927 // Refuse possible leaked file descriptors 11928 if (intent != null && intent.hasFileDescriptors() == true) { 11929 throw new IllegalArgumentException("File descriptors passed in Intent"); 11930 } 11931 11932 int flags = intent.getFlags(); 11933 11934 if (!mProcessesReady) { 11935 // if the caller really truly claims to know what they're doing, go 11936 // ahead and allow the broadcast without launching any receivers 11937 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11938 intent = new Intent(intent); 11939 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11940 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11941 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11942 + " before boot completion"); 11943 throw new IllegalStateException("Cannot broadcast before boot completed"); 11944 } 11945 } 11946 11947 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11948 throw new IllegalArgumentException( 11949 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11950 } 11951 11952 return intent; 11953 } 11954 11955 public final int broadcastIntent(IApplicationThread caller, 11956 Intent intent, String resolvedType, IIntentReceiver resultTo, 11957 int resultCode, String resultData, Bundle map, 11958 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11959 enforceNotIsolatedCaller("broadcastIntent"); 11960 synchronized(this) { 11961 intent = verifyBroadcastLocked(intent); 11962 11963 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11964 final int callingPid = Binder.getCallingPid(); 11965 final int callingUid = Binder.getCallingUid(); 11966 final long origId = Binder.clearCallingIdentity(); 11967 int res = broadcastIntentLocked(callerApp, 11968 callerApp != null ? callerApp.info.packageName : null, 11969 intent, resolvedType, resultTo, 11970 resultCode, resultData, map, requiredPermission, serialized, sticky, 11971 callingPid, callingUid, userId); 11972 Binder.restoreCallingIdentity(origId); 11973 return res; 11974 } 11975 } 11976 11977 int broadcastIntentInPackage(String packageName, int uid, 11978 Intent intent, String resolvedType, IIntentReceiver resultTo, 11979 int resultCode, String resultData, Bundle map, 11980 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11981 synchronized(this) { 11982 intent = verifyBroadcastLocked(intent); 11983 11984 final long origId = Binder.clearCallingIdentity(); 11985 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11986 resultTo, resultCode, resultData, map, requiredPermission, 11987 serialized, sticky, -1, uid, userId); 11988 Binder.restoreCallingIdentity(origId); 11989 return res; 11990 } 11991 } 11992 11993 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11994 // Refuse possible leaked file descriptors 11995 if (intent != null && intent.hasFileDescriptors() == true) { 11996 throw new IllegalArgumentException("File descriptors passed in Intent"); 11997 } 11998 11999 userId = handleIncomingUser(Binder.getCallingPid(), 12000 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 12001 12002 synchronized(this) { 12003 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12004 != PackageManager.PERMISSION_GRANTED) { 12005 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12006 + Binder.getCallingPid() 12007 + ", uid=" + Binder.getCallingUid() 12008 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12009 Slog.w(TAG, msg); 12010 throw new SecurityException(msg); 12011 } 12012 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12013 if (stickies != null) { 12014 ArrayList<Intent> list = stickies.get(intent.getAction()); 12015 if (list != null) { 12016 int N = list.size(); 12017 int i; 12018 for (i=0; i<N; i++) { 12019 if (intent.filterEquals(list.get(i))) { 12020 list.remove(i); 12021 break; 12022 } 12023 } 12024 if (list.size() <= 0) { 12025 stickies.remove(intent.getAction()); 12026 } 12027 } 12028 if (stickies.size() <= 0) { 12029 mStickyBroadcasts.remove(userId); 12030 } 12031 } 12032 } 12033 } 12034 12035 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12036 String resultData, Bundle resultExtras, boolean resultAbort, 12037 boolean explicit) { 12038 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 12039 if (r == null) { 12040 Slog.w(TAG, "finishReceiver called but not found on queue"); 12041 return false; 12042 } 12043 12044 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12045 explicit); 12046 } 12047 12048 public void finishReceiver(IBinder who, int resultCode, String resultData, 12049 Bundle resultExtras, boolean resultAbort) { 12050 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12051 12052 // Refuse possible leaked file descriptors 12053 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12054 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12055 } 12056 12057 final long origId = Binder.clearCallingIdentity(); 12058 try { 12059 boolean doNext = false; 12060 BroadcastRecord r = null; 12061 12062 synchronized(this) { 12063 r = broadcastRecordForReceiverLocked(who); 12064 if (r != null) { 12065 doNext = r.queue.finishReceiverLocked(r, resultCode, 12066 resultData, resultExtras, resultAbort, true); 12067 } 12068 } 12069 12070 if (doNext) { 12071 r.queue.processNextBroadcast(false); 12072 } 12073 trimApplications(); 12074 } finally { 12075 Binder.restoreCallingIdentity(origId); 12076 } 12077 } 12078 12079 // ========================================================= 12080 // INSTRUMENTATION 12081 // ========================================================= 12082 12083 public boolean startInstrumentation(ComponentName className, 12084 String profileFile, int flags, Bundle arguments, 12085 IInstrumentationWatcher watcher, int userId) { 12086 enforceNotIsolatedCaller("startInstrumentation"); 12087 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12088 userId, false, true, "startInstrumentation", null); 12089 // Refuse possible leaked file descriptors 12090 if (arguments != null && arguments.hasFileDescriptors()) { 12091 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12092 } 12093 12094 synchronized(this) { 12095 InstrumentationInfo ii = null; 12096 ApplicationInfo ai = null; 12097 try { 12098 ii = mContext.getPackageManager().getInstrumentationInfo( 12099 className, STOCK_PM_FLAGS); 12100 ai = AppGlobals.getPackageManager().getApplicationInfo( 12101 ii.targetPackage, STOCK_PM_FLAGS, userId); 12102 } catch (PackageManager.NameNotFoundException e) { 12103 } catch (RemoteException e) { 12104 } 12105 if (ii == null) { 12106 reportStartInstrumentationFailure(watcher, className, 12107 "Unable to find instrumentation info for: " + className); 12108 return false; 12109 } 12110 if (ai == null) { 12111 reportStartInstrumentationFailure(watcher, className, 12112 "Unable to find instrumentation target package: " + ii.targetPackage); 12113 return false; 12114 } 12115 12116 int match = mContext.getPackageManager().checkSignatures( 12117 ii.targetPackage, ii.packageName); 12118 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12119 String msg = "Permission Denial: starting instrumentation " 12120 + className + " from pid=" 12121 + Binder.getCallingPid() 12122 + ", uid=" + Binder.getCallingPid() 12123 + " not allowed because package " + ii.packageName 12124 + " does not have a signature matching the target " 12125 + ii.targetPackage; 12126 reportStartInstrumentationFailure(watcher, className, msg); 12127 throw new SecurityException(msg); 12128 } 12129 12130 final long origId = Binder.clearCallingIdentity(); 12131 // Instrumentation can kill and relaunch even persistent processes 12132 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12133 ProcessRecord app = addAppLocked(ai, false); 12134 app.instrumentationClass = className; 12135 app.instrumentationInfo = ai; 12136 app.instrumentationProfileFile = profileFile; 12137 app.instrumentationArguments = arguments; 12138 app.instrumentationWatcher = watcher; 12139 app.instrumentationResultClass = className; 12140 Binder.restoreCallingIdentity(origId); 12141 } 12142 12143 return true; 12144 } 12145 12146 /** 12147 * Report errors that occur while attempting to start Instrumentation. Always writes the 12148 * error to the logs, but if somebody is watching, send the report there too. This enables 12149 * the "am" command to report errors with more information. 12150 * 12151 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12152 * @param cn The component name of the instrumentation. 12153 * @param report The error report. 12154 */ 12155 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12156 ComponentName cn, String report) { 12157 Slog.w(TAG, report); 12158 try { 12159 if (watcher != null) { 12160 Bundle results = new Bundle(); 12161 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12162 results.putString("Error", report); 12163 watcher.instrumentationStatus(cn, -1, results); 12164 } 12165 } catch (RemoteException e) { 12166 Slog.w(TAG, e); 12167 } 12168 } 12169 12170 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12171 if (app.instrumentationWatcher != null) { 12172 try { 12173 // NOTE: IInstrumentationWatcher *must* be oneway here 12174 app.instrumentationWatcher.instrumentationFinished( 12175 app.instrumentationClass, 12176 resultCode, 12177 results); 12178 } catch (RemoteException e) { 12179 } 12180 } 12181 app.instrumentationWatcher = null; 12182 app.instrumentationClass = null; 12183 app.instrumentationInfo = null; 12184 app.instrumentationProfileFile = null; 12185 app.instrumentationArguments = null; 12186 12187 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12188 } 12189 12190 public void finishInstrumentation(IApplicationThread target, 12191 int resultCode, Bundle results) { 12192 int userId = UserHandle.getCallingUserId(); 12193 // Refuse possible leaked file descriptors 12194 if (results != null && results.hasFileDescriptors()) { 12195 throw new IllegalArgumentException("File descriptors passed in Intent"); 12196 } 12197 12198 synchronized(this) { 12199 ProcessRecord app = getRecordForAppLocked(target); 12200 if (app == null) { 12201 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12202 return; 12203 } 12204 final long origId = Binder.clearCallingIdentity(); 12205 finishInstrumentationLocked(app, resultCode, results); 12206 Binder.restoreCallingIdentity(origId); 12207 } 12208 } 12209 12210 // ========================================================= 12211 // CONFIGURATION 12212 // ========================================================= 12213 12214 public ConfigurationInfo getDeviceConfigurationInfo() { 12215 ConfigurationInfo config = new ConfigurationInfo(); 12216 synchronized (this) { 12217 config.reqTouchScreen = mConfiguration.touchscreen; 12218 config.reqKeyboardType = mConfiguration.keyboard; 12219 config.reqNavigation = mConfiguration.navigation; 12220 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12221 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12222 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12223 } 12224 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12225 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12226 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12227 } 12228 config.reqGlEsVersion = GL_ES_VERSION; 12229 } 12230 return config; 12231 } 12232 12233 public Configuration getConfiguration() { 12234 Configuration ci; 12235 synchronized(this) { 12236 ci = new Configuration(mConfiguration); 12237 } 12238 return ci; 12239 } 12240 12241 public void updatePersistentConfiguration(Configuration values) { 12242 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12243 "updateConfiguration()"); 12244 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12245 "updateConfiguration()"); 12246 if (values == null) { 12247 throw new NullPointerException("Configuration must not be null"); 12248 } 12249 12250 synchronized(this) { 12251 final long origId = Binder.clearCallingIdentity(); 12252 updateConfigurationLocked(values, null, true, false); 12253 Binder.restoreCallingIdentity(origId); 12254 } 12255 } 12256 12257 public void updateConfiguration(Configuration values) { 12258 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12259 "updateConfiguration()"); 12260 12261 synchronized(this) { 12262 if (values == null && mWindowManager != null) { 12263 // sentinel: fetch the current configuration from the window manager 12264 values = mWindowManager.computeNewConfiguration(); 12265 } 12266 12267 if (mWindowManager != null) { 12268 mProcessList.applyDisplaySize(mWindowManager); 12269 } 12270 12271 final long origId = Binder.clearCallingIdentity(); 12272 if (values != null) { 12273 Settings.System.clearConfiguration(values); 12274 } 12275 updateConfigurationLocked(values, null, false, false); 12276 Binder.restoreCallingIdentity(origId); 12277 } 12278 } 12279 12280 /** 12281 * Do either or both things: (1) change the current configuration, and (2) 12282 * make sure the given activity is running with the (now) current 12283 * configuration. Returns true if the activity has been left running, or 12284 * false if <var>starting</var> is being destroyed to match the new 12285 * configuration. 12286 * @param persistent TODO 12287 */ 12288 boolean updateConfigurationLocked(Configuration values, 12289 ActivityRecord starting, boolean persistent, boolean initLocale) { 12290 // do nothing if we are headless 12291 if (mHeadless) return true; 12292 12293 int changes = 0; 12294 12295 boolean kept = true; 12296 12297 if (values != null) { 12298 Configuration newConfig = new Configuration(mConfiguration); 12299 changes = newConfig.updateFrom(values); 12300 if (changes != 0) { 12301 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12302 Slog.i(TAG, "Updating configuration to: " + values); 12303 } 12304 12305 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12306 12307 if (values.locale != null && !initLocale) { 12308 saveLocaleLocked(values.locale, 12309 !values.locale.equals(mConfiguration.locale), 12310 values.userSetLocale); 12311 } 12312 12313 mConfigurationSeq++; 12314 if (mConfigurationSeq <= 0) { 12315 mConfigurationSeq = 1; 12316 } 12317 newConfig.seq = mConfigurationSeq; 12318 mConfiguration = newConfig; 12319 Slog.i(TAG, "Config changed: " + newConfig); 12320 12321 final Configuration configCopy = new Configuration(mConfiguration); 12322 12323 // TODO: If our config changes, should we auto dismiss any currently 12324 // showing dialogs? 12325 mShowDialogs = shouldShowDialogs(newConfig); 12326 12327 AttributeCache ac = AttributeCache.instance(); 12328 if (ac != null) { 12329 ac.updateConfiguration(configCopy); 12330 } 12331 12332 // Make sure all resources in our process are updated 12333 // right now, so that anyone who is going to retrieve 12334 // resource values after we return will be sure to get 12335 // the new ones. This is especially important during 12336 // boot, where the first config change needs to guarantee 12337 // all resources have that config before following boot 12338 // code is executed. 12339 mSystemThread.applyConfigurationToResources(configCopy); 12340 12341 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12342 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12343 msg.obj = new Configuration(configCopy); 12344 mHandler.sendMessage(msg); 12345 } 12346 12347 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12348 ProcessRecord app = mLruProcesses.get(i); 12349 try { 12350 if (app.thread != null) { 12351 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12352 + app.processName + " new config " + mConfiguration); 12353 app.thread.scheduleConfigurationChanged(configCopy); 12354 } 12355 } catch (Exception e) { 12356 } 12357 } 12358 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12359 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12360 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12361 | Intent.FLAG_RECEIVER_FOREGROUND); 12362 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12363 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12364 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12365 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12366 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12367 broadcastIntentLocked(null, null, intent, 12368 null, null, 0, null, null, 12369 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12370 } 12371 } 12372 } 12373 12374 if (changes != 0 && starting == null) { 12375 // If the configuration changed, and the caller is not already 12376 // in the process of starting an activity, then find the top 12377 // activity to check if its configuration needs to change. 12378 starting = mMainStack.topRunningActivityLocked(null); 12379 } 12380 12381 if (starting != null) { 12382 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12383 // And we need to make sure at this point that all other activities 12384 // are made visible with the correct configuration. 12385 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12386 } 12387 12388 if (values != null && mWindowManager != null) { 12389 mWindowManager.setNewConfiguration(mConfiguration); 12390 } 12391 12392 return kept; 12393 } 12394 12395 /** 12396 * Decide based on the configuration whether we should shouw the ANR, 12397 * crash, etc dialogs. The idea is that if there is no affordnace to 12398 * press the on-screen buttons, we shouldn't show the dialog. 12399 * 12400 * A thought: SystemUI might also want to get told about this, the Power 12401 * dialog / global actions also might want different behaviors. 12402 */ 12403 private static final boolean shouldShowDialogs(Configuration config) { 12404 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12405 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12406 } 12407 12408 /** 12409 * Save the locale. You must be inside a synchronized (this) block. 12410 */ 12411 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12412 if(isDiff) { 12413 SystemProperties.set("user.language", l.getLanguage()); 12414 SystemProperties.set("user.region", l.getCountry()); 12415 } 12416 12417 if(isPersist) { 12418 SystemProperties.set("persist.sys.language", l.getLanguage()); 12419 SystemProperties.set("persist.sys.country", l.getCountry()); 12420 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12421 } 12422 } 12423 12424 @Override 12425 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12426 ActivityRecord srec = ActivityRecord.forToken(token); 12427 return srec != null && srec.task.affinity != null && 12428 srec.task.affinity.equals(destAffinity); 12429 } 12430 12431 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12432 Intent resultData) { 12433 ComponentName dest = destIntent.getComponent(); 12434 12435 synchronized (this) { 12436 ActivityRecord srec = ActivityRecord.forToken(token); 12437 if (srec == null) { 12438 return false; 12439 } 12440 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12441 final int start = history.indexOf(srec); 12442 if (start < 0) { 12443 // Current activity is not in history stack; do nothing. 12444 return false; 12445 } 12446 int finishTo = start - 1; 12447 ActivityRecord parent = null; 12448 boolean foundParentInTask = false; 12449 if (dest != null) { 12450 TaskRecord tr = srec.task; 12451 for (int i = start - 1; i >= 0; i--) { 12452 ActivityRecord r = history.get(i); 12453 if (tr != r.task) { 12454 // Couldn't find parent in the same task; stop at the one above this. 12455 // (Root of current task; in-app "home" behavior) 12456 // Always at least finish the current activity. 12457 finishTo = Math.min(start - 1, i + 1); 12458 parent = history.get(finishTo); 12459 break; 12460 } else if (r.info.packageName.equals(dest.getPackageName()) && 12461 r.info.name.equals(dest.getClassName())) { 12462 finishTo = i; 12463 parent = r; 12464 foundParentInTask = true; 12465 break; 12466 } 12467 } 12468 } 12469 12470 if (mController != null) { 12471 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12472 if (next != null) { 12473 // ask watcher if this is allowed 12474 boolean resumeOK = true; 12475 try { 12476 resumeOK = mController.activityResuming(next.packageName); 12477 } catch (RemoteException e) { 12478 mController = null; 12479 } 12480 12481 if (!resumeOK) { 12482 return false; 12483 } 12484 } 12485 } 12486 final long origId = Binder.clearCallingIdentity(); 12487 for (int i = start; i > finishTo; i--) { 12488 ActivityRecord r = history.get(i); 12489 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12490 "navigate-up", true); 12491 // Only return the supplied result for the first activity finished 12492 resultCode = Activity.RESULT_CANCELED; 12493 resultData = null; 12494 } 12495 12496 if (parent != null && foundParentInTask) { 12497 final int parentLaunchMode = parent.info.launchMode; 12498 final int destIntentFlags = destIntent.getFlags(); 12499 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12500 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12501 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12502 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12503 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12504 } else { 12505 try { 12506 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12507 destIntent.getComponent(), 0, srec.userId); 12508 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12509 null, aInfo, parent.appToken, null, 12510 0, -1, parent.launchedFromUid, 0, null, true, null); 12511 foundParentInTask = res == ActivityManager.START_SUCCESS; 12512 } catch (RemoteException e) { 12513 foundParentInTask = false; 12514 } 12515 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12516 resultData, "navigate-up", true); 12517 } 12518 } 12519 Binder.restoreCallingIdentity(origId); 12520 return foundParentInTask; 12521 } 12522 } 12523 12524 public int getLaunchedFromUid(IBinder activityToken) { 12525 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12526 if (srec == null) { 12527 return -1; 12528 } 12529 return srec.launchedFromUid; 12530 } 12531 12532 // ========================================================= 12533 // LIFETIME MANAGEMENT 12534 // ========================================================= 12535 12536 // Returns which broadcast queue the app is the current [or imminent] receiver 12537 // on, or 'null' if the app is not an active broadcast recipient. 12538 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12539 BroadcastRecord r = app.curReceiver; 12540 if (r != null) { 12541 return r.queue; 12542 } 12543 12544 // It's not the current receiver, but it might be starting up to become one 12545 synchronized (this) { 12546 for (BroadcastQueue queue : mBroadcastQueues) { 12547 r = queue.mPendingBroadcast; 12548 if (r != null && r.curApp == app) { 12549 // found it; report which queue it's in 12550 return queue; 12551 } 12552 } 12553 } 12554 12555 return null; 12556 } 12557 12558 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12559 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12560 if (mAdjSeq == app.adjSeq) { 12561 // This adjustment has already been computed. If we are calling 12562 // from the top, we may have already computed our adjustment with 12563 // an earlier hidden adjustment that isn't really for us... if 12564 // so, use the new hidden adjustment. 12565 if (!recursed && app.hidden) { 12566 if (app.hasActivities) { 12567 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12568 } else if (app.hasClientActivities) { 12569 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12570 } else { 12571 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12572 } 12573 } 12574 return app.curRawAdj; 12575 } 12576 12577 if (app.thread == null) { 12578 app.adjSeq = mAdjSeq; 12579 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12580 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12581 } 12582 12583 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12584 app.adjSource = null; 12585 app.adjTarget = null; 12586 app.empty = false; 12587 app.hidden = false; 12588 app.hasClientActivities = false; 12589 12590 final int activitiesSize = app.activities.size(); 12591 12592 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12593 // The max adjustment doesn't allow this app to be anything 12594 // below foreground, so it is not worth doing work for it. 12595 app.adjType = "fixed"; 12596 app.adjSeq = mAdjSeq; 12597 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12598 app.hasActivities = false; 12599 app.foregroundActivities = false; 12600 app.keeping = true; 12601 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12602 // System process can do UI, and when they do we want to have 12603 // them trim their memory after the user leaves the UI. To 12604 // facilitate this, here we need to determine whether or not it 12605 // is currently showing UI. 12606 app.systemNoUi = true; 12607 if (app == TOP_APP) { 12608 app.systemNoUi = false; 12609 app.hasActivities = true; 12610 } else if (activitiesSize > 0) { 12611 for (int j = 0; j < activitiesSize; j++) { 12612 final ActivityRecord r = app.activities.get(j); 12613 if (r.visible) { 12614 app.systemNoUi = false; 12615 } 12616 if (r.app == app) { 12617 app.hasActivities = true; 12618 } 12619 } 12620 } 12621 return (app.curAdj=app.maxAdj); 12622 } 12623 12624 app.keeping = false; 12625 app.systemNoUi = false; 12626 app.hasActivities = false; 12627 12628 // Determine the importance of the process, starting with most 12629 // important to least, and assign an appropriate OOM adjustment. 12630 int adj; 12631 int schedGroup; 12632 boolean foregroundActivities = false; 12633 boolean interesting = false; 12634 BroadcastQueue queue; 12635 if (app == TOP_APP) { 12636 // The last app on the list is the foreground app. 12637 adj = ProcessList.FOREGROUND_APP_ADJ; 12638 schedGroup = Process.THREAD_GROUP_DEFAULT; 12639 app.adjType = "top-activity"; 12640 foregroundActivities = true; 12641 interesting = true; 12642 app.hasActivities = true; 12643 } else if (app.instrumentationClass != null) { 12644 // Don't want to kill running instrumentation. 12645 adj = ProcessList.FOREGROUND_APP_ADJ; 12646 schedGroup = Process.THREAD_GROUP_DEFAULT; 12647 app.adjType = "instrumentation"; 12648 interesting = true; 12649 } else if ((queue = isReceivingBroadcast(app)) != null) { 12650 // An app that is currently receiving a broadcast also 12651 // counts as being in the foreground for OOM killer purposes. 12652 // It's placed in a sched group based on the nature of the 12653 // broadcast as reflected by which queue it's active in. 12654 adj = ProcessList.FOREGROUND_APP_ADJ; 12655 schedGroup = (queue == mFgBroadcastQueue) 12656 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12657 app.adjType = "broadcast"; 12658 } else if (app.executingServices.size() > 0) { 12659 // An app that is currently executing a service callback also 12660 // counts as being in the foreground. 12661 adj = ProcessList.FOREGROUND_APP_ADJ; 12662 schedGroup = Process.THREAD_GROUP_DEFAULT; 12663 app.adjType = "exec-service"; 12664 } else { 12665 // Assume process is hidden (has activities); we will correct 12666 // later if this is not the case. 12667 adj = hiddenAdj; 12668 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12669 app.hidden = true; 12670 app.adjType = "bg-act"; 12671 } 12672 12673 boolean hasStoppingActivities = false; 12674 12675 // Examine all activities if not already foreground. 12676 if (!foregroundActivities && activitiesSize > 0) { 12677 for (int j = 0; j < activitiesSize; j++) { 12678 final ActivityRecord r = app.activities.get(j); 12679 if (r.visible) { 12680 // App has a visible activity; only upgrade adjustment. 12681 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12682 adj = ProcessList.VISIBLE_APP_ADJ; 12683 app.adjType = "visible"; 12684 } 12685 schedGroup = Process.THREAD_GROUP_DEFAULT; 12686 app.hidden = false; 12687 app.hasActivities = true; 12688 foregroundActivities = true; 12689 break; 12690 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12691 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12692 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12693 app.adjType = "pausing"; 12694 } 12695 app.hidden = false; 12696 foregroundActivities = true; 12697 } else if (r.state == ActivityState.STOPPING) { 12698 // We will apply the actual adjustment later, because 12699 // we want to allow this process to immediately go through 12700 // any memory trimming that is in effect. 12701 app.hidden = false; 12702 foregroundActivities = true; 12703 hasStoppingActivities = true; 12704 } 12705 if (r.app == app) { 12706 app.hasActivities = true; 12707 } 12708 } 12709 } 12710 12711 if (adj == hiddenAdj && !app.hasActivities) { 12712 if (app.hasClientActivities) { 12713 adj = clientHiddenAdj; 12714 app.adjType = "bg-client-act"; 12715 } else { 12716 // Whoops, this process is completely empty as far as we know 12717 // at this point. 12718 adj = emptyAdj; 12719 app.empty = true; 12720 app.adjType = "bg-empty"; 12721 } 12722 } 12723 12724 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12725 if (app.foregroundServices) { 12726 // The user is aware of this app, so make it visible. 12727 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12728 app.hidden = false; 12729 app.adjType = "fg-service"; 12730 schedGroup = Process.THREAD_GROUP_DEFAULT; 12731 } else if (app.forcingToForeground != null) { 12732 // The user is aware of this app, so make it visible. 12733 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12734 app.hidden = false; 12735 app.adjType = "force-fg"; 12736 app.adjSource = app.forcingToForeground; 12737 schedGroup = Process.THREAD_GROUP_DEFAULT; 12738 } 12739 } 12740 12741 if (app.foregroundServices) { 12742 interesting = true; 12743 } 12744 12745 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12746 // We don't want to kill the current heavy-weight process. 12747 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12748 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12749 app.hidden = false; 12750 app.adjType = "heavy"; 12751 } 12752 12753 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12754 // This process is hosting what we currently consider to be the 12755 // home app, so we don't want to let it go into the background. 12756 adj = ProcessList.HOME_APP_ADJ; 12757 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12758 app.hidden = false; 12759 app.adjType = "home"; 12760 } 12761 12762 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12763 && app.activities.size() > 0) { 12764 // This was the previous process that showed UI to the user. 12765 // We want to try to keep it around more aggressively, to give 12766 // a good experience around switching between two apps. 12767 adj = ProcessList.PREVIOUS_APP_ADJ; 12768 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12769 app.hidden = false; 12770 app.adjType = "previous"; 12771 } 12772 12773 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12774 + " reason=" + app.adjType); 12775 12776 // By default, we use the computed adjustment. It may be changed if 12777 // there are applications dependent on our services or providers, but 12778 // this gives us a baseline and makes sure we don't get into an 12779 // infinite recursion. 12780 app.adjSeq = mAdjSeq; 12781 app.curRawAdj = app.nonStoppingAdj = adj; 12782 12783 if (mBackupTarget != null && app == mBackupTarget.app) { 12784 // If possible we want to avoid killing apps while they're being backed up 12785 if (adj > ProcessList.BACKUP_APP_ADJ) { 12786 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12787 adj = ProcessList.BACKUP_APP_ADJ; 12788 app.adjType = "backup"; 12789 app.hidden = false; 12790 } 12791 } 12792 12793 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12794 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12795 final long now = SystemClock.uptimeMillis(); 12796 // This process is more important if the top activity is 12797 // bound to the service. 12798 Iterator<ServiceRecord> jt = app.services.iterator(); 12799 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12800 ServiceRecord s = jt.next(); 12801 if (s.startRequested) { 12802 if (app.hasShownUi && app != mHomeProcess) { 12803 // If this process has shown some UI, let it immediately 12804 // go to the LRU list because it may be pretty heavy with 12805 // UI stuff. We'll tag it with a label just to help 12806 // debug and understand what is going on. 12807 if (adj > ProcessList.SERVICE_ADJ) { 12808 app.adjType = "started-bg-ui-services"; 12809 } 12810 } else { 12811 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12812 // This service has seen some activity within 12813 // recent memory, so we will keep its process ahead 12814 // of the background processes. 12815 if (adj > ProcessList.SERVICE_ADJ) { 12816 adj = ProcessList.SERVICE_ADJ; 12817 app.adjType = "started-services"; 12818 app.hidden = false; 12819 } 12820 } 12821 // If we have let the service slide into the background 12822 // state, still have some text describing what it is doing 12823 // even though the service no longer has an impact. 12824 if (adj > ProcessList.SERVICE_ADJ) { 12825 app.adjType = "started-bg-services"; 12826 } 12827 } 12828 // Don't kill this process because it is doing work; it 12829 // has said it is doing work. 12830 app.keeping = true; 12831 } 12832 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12833 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12834 Iterator<ArrayList<ConnectionRecord>> kt 12835 = s.connections.values().iterator(); 12836 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12837 ArrayList<ConnectionRecord> clist = kt.next(); 12838 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12839 // XXX should compute this based on the max of 12840 // all connected clients. 12841 ConnectionRecord cr = clist.get(i); 12842 if (cr.binding.client == app) { 12843 // Binding to ourself is not interesting. 12844 continue; 12845 } 12846 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12847 ProcessRecord client = cr.binding.client; 12848 int clientAdj = adj; 12849 int myHiddenAdj = hiddenAdj; 12850 if (myHiddenAdj > client.hiddenAdj) { 12851 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12852 myHiddenAdj = client.hiddenAdj; 12853 } else { 12854 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12855 } 12856 } 12857 int myClientHiddenAdj = clientHiddenAdj; 12858 if (myClientHiddenAdj > client.clientHiddenAdj) { 12859 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12860 myClientHiddenAdj = client.clientHiddenAdj; 12861 } else { 12862 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12863 } 12864 } 12865 int myEmptyAdj = emptyAdj; 12866 if (myEmptyAdj > client.emptyAdj) { 12867 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12868 myEmptyAdj = client.emptyAdj; 12869 } else { 12870 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12871 } 12872 } 12873 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12874 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12875 String adjType = null; 12876 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12877 // Not doing bind OOM management, so treat 12878 // this guy more like a started service. 12879 if (app.hasShownUi && app != mHomeProcess) { 12880 // If this process has shown some UI, let it immediately 12881 // go to the LRU list because it may be pretty heavy with 12882 // UI stuff. We'll tag it with a label just to help 12883 // debug and understand what is going on. 12884 if (adj > clientAdj) { 12885 adjType = "bound-bg-ui-services"; 12886 } 12887 app.hidden = false; 12888 clientAdj = adj; 12889 } else { 12890 if (now >= (s.lastActivity 12891 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12892 // This service has not seen activity within 12893 // recent memory, so allow it to drop to the 12894 // LRU list if there is no other reason to keep 12895 // it around. We'll also tag it with a label just 12896 // to help debug and undertand what is going on. 12897 if (adj > clientAdj) { 12898 adjType = "bound-bg-services"; 12899 } 12900 clientAdj = adj; 12901 } 12902 } 12903 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12904 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12905 // If this connection is keeping the service 12906 // created, then we want to try to better follow 12907 // its memory management semantics for activities. 12908 // That is, if it is sitting in the background 12909 // LRU list as a hidden process (with activities), 12910 // we don't want the service it is connected to 12911 // to go into the empty LRU and quickly get killed, 12912 // because I'll we'll do is just end up restarting 12913 // the service. 12914 app.hasClientActivities |= client.hasActivities; 12915 } 12916 } 12917 if (adj > clientAdj) { 12918 // If this process has recently shown UI, and 12919 // the process that is binding to it is less 12920 // important than being visible, then we don't 12921 // care about the binding as much as we care 12922 // about letting this process get into the LRU 12923 // list to be killed and restarted if needed for 12924 // memory. 12925 if (app.hasShownUi && app != mHomeProcess 12926 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12927 adjType = "bound-bg-ui-services"; 12928 } else { 12929 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12930 |Context.BIND_IMPORTANT)) != 0) { 12931 adj = clientAdj; 12932 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12933 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12934 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12935 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12936 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12937 adj = clientAdj; 12938 } else { 12939 app.pendingUiClean = true; 12940 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12941 adj = ProcessList.VISIBLE_APP_ADJ; 12942 } 12943 } 12944 if (!client.hidden) { 12945 app.hidden = false; 12946 } 12947 if (client.keeping) { 12948 app.keeping = true; 12949 } 12950 adjType = "service"; 12951 } 12952 } 12953 if (adjType != null) { 12954 app.adjType = adjType; 12955 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12956 .REASON_SERVICE_IN_USE; 12957 app.adjSource = cr.binding.client; 12958 app.adjSourceOom = clientAdj; 12959 app.adjTarget = s.name; 12960 } 12961 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12962 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12963 schedGroup = Process.THREAD_GROUP_DEFAULT; 12964 } 12965 } 12966 } 12967 final ActivityRecord a = cr.activity; 12968 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12969 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12970 (a.visible || a.state == ActivityState.RESUMED 12971 || a.state == ActivityState.PAUSING)) { 12972 adj = ProcessList.FOREGROUND_APP_ADJ; 12973 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12974 schedGroup = Process.THREAD_GROUP_DEFAULT; 12975 } 12976 app.hidden = false; 12977 app.adjType = "service"; 12978 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12979 .REASON_SERVICE_IN_USE; 12980 app.adjSource = a; 12981 app.adjSourceOom = adj; 12982 app.adjTarget = s.name; 12983 } 12984 } 12985 } 12986 } 12987 } 12988 } 12989 12990 // Finally, if this process has active services running in it, we 12991 // would like to avoid killing it unless it would prevent the current 12992 // application from running. By default we put the process in 12993 // with the rest of the background processes; as we scan through 12994 // its services we may bump it up from there. 12995 if (adj > hiddenAdj) { 12996 adj = hiddenAdj; 12997 app.hidden = false; 12998 app.adjType = "bg-services"; 12999 } 13000 } 13001 13002 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13003 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13004 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 13005 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 13006 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13007 ContentProviderRecord cpr = jt.next(); 13008 for (int i = cpr.connections.size()-1; 13009 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13010 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 13011 i--) { 13012 ContentProviderConnection conn = cpr.connections.get(i); 13013 ProcessRecord client = conn.client; 13014 if (client == app) { 13015 // Being our own client is not interesting. 13016 continue; 13017 } 13018 int myHiddenAdj = hiddenAdj; 13019 if (myHiddenAdj > client.hiddenAdj) { 13020 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13021 myHiddenAdj = client.hiddenAdj; 13022 } else { 13023 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13024 } 13025 } 13026 int myClientHiddenAdj = clientHiddenAdj; 13027 if (myClientHiddenAdj > client.clientHiddenAdj) { 13028 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 13029 myClientHiddenAdj = client.clientHiddenAdj; 13030 } else { 13031 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13032 } 13033 } 13034 int myEmptyAdj = emptyAdj; 13035 if (myEmptyAdj > client.emptyAdj) { 13036 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 13037 myEmptyAdj = client.emptyAdj; 13038 } else { 13039 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 13040 } 13041 } 13042 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13043 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13044 if (adj > clientAdj) { 13045 if (app.hasShownUi && app != mHomeProcess 13046 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13047 app.adjType = "bg-ui-provider"; 13048 } else { 13049 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13050 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13051 app.adjType = "provider"; 13052 } 13053 if (!client.hidden) { 13054 app.hidden = false; 13055 } 13056 if (client.keeping) { 13057 app.keeping = true; 13058 } 13059 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13060 .REASON_PROVIDER_IN_USE; 13061 app.adjSource = client; 13062 app.adjSourceOom = clientAdj; 13063 app.adjTarget = cpr.name; 13064 } 13065 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13066 schedGroup = Process.THREAD_GROUP_DEFAULT; 13067 } 13068 } 13069 // If the provider has external (non-framework) process 13070 // dependencies, ensure that its adjustment is at least 13071 // FOREGROUND_APP_ADJ. 13072 if (cpr.hasExternalProcessHandles()) { 13073 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13074 adj = ProcessList.FOREGROUND_APP_ADJ; 13075 schedGroup = Process.THREAD_GROUP_DEFAULT; 13076 app.hidden = false; 13077 app.keeping = true; 13078 app.adjType = "provider"; 13079 app.adjTarget = cpr.name; 13080 } 13081 } 13082 } 13083 } 13084 13085 if (adj == ProcessList.SERVICE_ADJ) { 13086 if (doingAll) { 13087 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13088 mNewNumServiceProcs++; 13089 } 13090 if (app.serviceb) { 13091 adj = ProcessList.SERVICE_B_ADJ; 13092 } 13093 } else { 13094 app.serviceb = false; 13095 } 13096 13097 app.nonStoppingAdj = adj; 13098 13099 if (hasStoppingActivities) { 13100 // Only upgrade adjustment. 13101 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13102 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13103 app.adjType = "stopping"; 13104 } 13105 } 13106 13107 app.curRawAdj = adj; 13108 13109 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13110 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13111 if (adj > app.maxAdj) { 13112 adj = app.maxAdj; 13113 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13114 schedGroup = Process.THREAD_GROUP_DEFAULT; 13115 } 13116 } 13117 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13118 app.keeping = true; 13119 } 13120 13121 if (app.hasAboveClient) { 13122 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13123 // then we need to drop its adjustment to be lower than the service's 13124 // in order to honor the request. We want to drop it by one adjustment 13125 // level... but there is special meaning applied to various levels so 13126 // we will skip some of them. 13127 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13128 // System process will not get dropped, ever 13129 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13130 adj = ProcessList.VISIBLE_APP_ADJ; 13131 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13132 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13133 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13134 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13135 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13136 adj++; 13137 } 13138 } 13139 13140 int importance = app.memImportance; 13141 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13142 app.curAdj = adj; 13143 app.curSchedGroup = schedGroup; 13144 if (!interesting) { 13145 // For this reporting, if there is not something explicitly 13146 // interesting in this process then we will push it to the 13147 // background importance. 13148 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13149 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13150 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13151 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13152 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13153 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13154 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13155 } else if (adj >= ProcessList.SERVICE_ADJ) { 13156 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13157 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13158 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13159 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13160 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13161 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13162 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13163 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13164 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13165 } else { 13166 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13167 } 13168 } 13169 13170 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13171 if (foregroundActivities != app.foregroundActivities) { 13172 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13173 } 13174 if (changes != 0) { 13175 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13176 app.memImportance = importance; 13177 app.foregroundActivities = foregroundActivities; 13178 int i = mPendingProcessChanges.size()-1; 13179 ProcessChangeItem item = null; 13180 while (i >= 0) { 13181 item = mPendingProcessChanges.get(i); 13182 if (item.pid == app.pid) { 13183 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13184 break; 13185 } 13186 i--; 13187 } 13188 if (i < 0) { 13189 // No existing item in pending changes; need a new one. 13190 final int NA = mAvailProcessChanges.size(); 13191 if (NA > 0) { 13192 item = mAvailProcessChanges.remove(NA-1); 13193 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13194 } else { 13195 item = new ProcessChangeItem(); 13196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13197 } 13198 item.changes = 0; 13199 item.pid = app.pid; 13200 item.uid = app.info.uid; 13201 if (mPendingProcessChanges.size() == 0) { 13202 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13203 "*** Enqueueing dispatch processes changed!"); 13204 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13205 } 13206 mPendingProcessChanges.add(item); 13207 } 13208 item.changes |= changes; 13209 item.importance = importance; 13210 item.foregroundActivities = foregroundActivities; 13211 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13212 + Integer.toHexString(System.identityHashCode(item)) 13213 + " " + app.toShortString() + ": changes=" + item.changes 13214 + " importance=" + item.importance 13215 + " foreground=" + item.foregroundActivities 13216 + " type=" + app.adjType + " source=" + app.adjSource 13217 + " target=" + app.adjTarget); 13218 } 13219 13220 return app.curRawAdj; 13221 } 13222 13223 /** 13224 * Ask a given process to GC right now. 13225 */ 13226 final void performAppGcLocked(ProcessRecord app) { 13227 try { 13228 app.lastRequestedGc = SystemClock.uptimeMillis(); 13229 if (app.thread != null) { 13230 if (app.reportLowMemory) { 13231 app.reportLowMemory = false; 13232 app.thread.scheduleLowMemory(); 13233 } else { 13234 app.thread.processInBackground(); 13235 } 13236 } 13237 } catch (Exception e) { 13238 // whatever. 13239 } 13240 } 13241 13242 /** 13243 * Returns true if things are idle enough to perform GCs. 13244 */ 13245 private final boolean canGcNowLocked() { 13246 boolean processingBroadcasts = false; 13247 for (BroadcastQueue q : mBroadcastQueues) { 13248 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13249 processingBroadcasts = true; 13250 } 13251 } 13252 return !processingBroadcasts 13253 && (mSleeping || (mMainStack.mResumedActivity != null && 13254 mMainStack.mResumedActivity.idle)); 13255 } 13256 13257 /** 13258 * Perform GCs on all processes that are waiting for it, but only 13259 * if things are idle. 13260 */ 13261 final void performAppGcsLocked() { 13262 final int N = mProcessesToGc.size(); 13263 if (N <= 0) { 13264 return; 13265 } 13266 if (canGcNowLocked()) { 13267 while (mProcessesToGc.size() > 0) { 13268 ProcessRecord proc = mProcessesToGc.remove(0); 13269 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13270 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13271 <= SystemClock.uptimeMillis()) { 13272 // To avoid spamming the system, we will GC processes one 13273 // at a time, waiting a few seconds between each. 13274 performAppGcLocked(proc); 13275 scheduleAppGcsLocked(); 13276 return; 13277 } else { 13278 // It hasn't been long enough since we last GCed this 13279 // process... put it in the list to wait for its time. 13280 addProcessToGcListLocked(proc); 13281 break; 13282 } 13283 } 13284 } 13285 13286 scheduleAppGcsLocked(); 13287 } 13288 } 13289 13290 /** 13291 * If all looks good, perform GCs on all processes waiting for them. 13292 */ 13293 final void performAppGcsIfAppropriateLocked() { 13294 if (canGcNowLocked()) { 13295 performAppGcsLocked(); 13296 return; 13297 } 13298 // Still not idle, wait some more. 13299 scheduleAppGcsLocked(); 13300 } 13301 13302 /** 13303 * Schedule the execution of all pending app GCs. 13304 */ 13305 final void scheduleAppGcsLocked() { 13306 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13307 13308 if (mProcessesToGc.size() > 0) { 13309 // Schedule a GC for the time to the next process. 13310 ProcessRecord proc = mProcessesToGc.get(0); 13311 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13312 13313 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13314 long now = SystemClock.uptimeMillis(); 13315 if (when < (now+GC_TIMEOUT)) { 13316 when = now + GC_TIMEOUT; 13317 } 13318 mHandler.sendMessageAtTime(msg, when); 13319 } 13320 } 13321 13322 /** 13323 * Add a process to the array of processes waiting to be GCed. Keeps the 13324 * list in sorted order by the last GC time. The process can't already be 13325 * on the list. 13326 */ 13327 final void addProcessToGcListLocked(ProcessRecord proc) { 13328 boolean added = false; 13329 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13330 if (mProcessesToGc.get(i).lastRequestedGc < 13331 proc.lastRequestedGc) { 13332 added = true; 13333 mProcessesToGc.add(i+1, proc); 13334 break; 13335 } 13336 } 13337 if (!added) { 13338 mProcessesToGc.add(0, proc); 13339 } 13340 } 13341 13342 /** 13343 * Set up to ask a process to GC itself. This will either do it 13344 * immediately, or put it on the list of processes to gc the next 13345 * time things are idle. 13346 */ 13347 final void scheduleAppGcLocked(ProcessRecord app) { 13348 long now = SystemClock.uptimeMillis(); 13349 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13350 return; 13351 } 13352 if (!mProcessesToGc.contains(app)) { 13353 addProcessToGcListLocked(app); 13354 scheduleAppGcsLocked(); 13355 } 13356 } 13357 13358 final void checkExcessivePowerUsageLocked(boolean doKills) { 13359 updateCpuStatsNow(); 13360 13361 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13362 boolean doWakeKills = doKills; 13363 boolean doCpuKills = doKills; 13364 if (mLastPowerCheckRealtime == 0) { 13365 doWakeKills = false; 13366 } 13367 if (mLastPowerCheckUptime == 0) { 13368 doCpuKills = false; 13369 } 13370 if (stats.isScreenOn()) { 13371 doWakeKills = false; 13372 } 13373 final long curRealtime = SystemClock.elapsedRealtime(); 13374 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13375 final long curUptime = SystemClock.uptimeMillis(); 13376 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13377 mLastPowerCheckRealtime = curRealtime; 13378 mLastPowerCheckUptime = curUptime; 13379 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13380 doWakeKills = false; 13381 } 13382 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13383 doCpuKills = false; 13384 } 13385 int i = mLruProcesses.size(); 13386 while (i > 0) { 13387 i--; 13388 ProcessRecord app = mLruProcesses.get(i); 13389 if (!app.keeping) { 13390 long wtime; 13391 synchronized (stats) { 13392 wtime = stats.getProcessWakeTime(app.info.uid, 13393 app.pid, curRealtime); 13394 } 13395 long wtimeUsed = wtime - app.lastWakeTime; 13396 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13397 if (DEBUG_POWER) { 13398 StringBuilder sb = new StringBuilder(128); 13399 sb.append("Wake for "); 13400 app.toShortString(sb); 13401 sb.append(": over "); 13402 TimeUtils.formatDuration(realtimeSince, sb); 13403 sb.append(" used "); 13404 TimeUtils.formatDuration(wtimeUsed, sb); 13405 sb.append(" ("); 13406 sb.append((wtimeUsed*100)/realtimeSince); 13407 sb.append("%)"); 13408 Slog.i(TAG, sb.toString()); 13409 sb.setLength(0); 13410 sb.append("CPU for "); 13411 app.toShortString(sb); 13412 sb.append(": over "); 13413 TimeUtils.formatDuration(uptimeSince, sb); 13414 sb.append(" used "); 13415 TimeUtils.formatDuration(cputimeUsed, sb); 13416 sb.append(" ("); 13417 sb.append((cputimeUsed*100)/uptimeSince); 13418 sb.append("%)"); 13419 Slog.i(TAG, sb.toString()); 13420 } 13421 // If a process has held a wake lock for more 13422 // than 50% of the time during this period, 13423 // that sounds bad. Kill! 13424 if (doWakeKills && realtimeSince > 0 13425 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13426 synchronized (stats) { 13427 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13428 realtimeSince, wtimeUsed); 13429 } 13430 Slog.w(TAG, "Excessive wake lock in " + app.processName 13431 + " (pid " + app.pid + "): held " + wtimeUsed 13432 + " during " + realtimeSince); 13433 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13434 app.processName, app.setAdj, "excessive wake lock"); 13435 Process.killProcessQuiet(app.pid); 13436 } else if (doCpuKills && uptimeSince > 0 13437 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13438 synchronized (stats) { 13439 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13440 uptimeSince, cputimeUsed); 13441 } 13442 Slog.w(TAG, "Excessive CPU in " + app.processName 13443 + " (pid " + app.pid + "): used " + cputimeUsed 13444 + " during " + uptimeSince); 13445 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13446 app.processName, app.setAdj, "excessive cpu"); 13447 Process.killProcessQuiet(app.pid); 13448 } else { 13449 app.lastWakeTime = wtime; 13450 app.lastCpuTime = app.curCpuTime; 13451 } 13452 } 13453 } 13454 } 13455 13456 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13457 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13458 app.hiddenAdj = hiddenAdj; 13459 app.clientHiddenAdj = clientHiddenAdj; 13460 app.emptyAdj = emptyAdj; 13461 13462 if (app.thread == null) { 13463 return false; 13464 } 13465 13466 final boolean wasKeeping = app.keeping; 13467 13468 boolean success = true; 13469 13470 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13471 13472 if (app.curRawAdj != app.setRawAdj) { 13473 if (wasKeeping && !app.keeping) { 13474 // This app is no longer something we want to keep. Note 13475 // its current wake lock time to later know to kill it if 13476 // it is not behaving well. 13477 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13478 synchronized (stats) { 13479 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13480 app.pid, SystemClock.elapsedRealtime()); 13481 } 13482 app.lastCpuTime = app.curCpuTime; 13483 } 13484 13485 app.setRawAdj = app.curRawAdj; 13486 } 13487 13488 if (app.curAdj != app.setAdj) { 13489 if (Process.setOomAdj(app.pid, app.curAdj)) { 13490 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13491 TAG, "Set " + app.pid + " " + app.processName + 13492 " adj " + app.curAdj + ": " + app.adjType); 13493 app.setAdj = app.curAdj; 13494 } else { 13495 success = false; 13496 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13497 } 13498 } 13499 if (app.setSchedGroup != app.curSchedGroup) { 13500 app.setSchedGroup = app.curSchedGroup; 13501 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13502 "Setting process group of " + app.processName 13503 + " to " + app.curSchedGroup); 13504 if (app.waitingToKill != null && 13505 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13506 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13507 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13508 app.processName, app.setAdj, app.waitingToKill); 13509 app.killedBackground = true; 13510 Process.killProcessQuiet(app.pid); 13511 success = false; 13512 } else { 13513 if (true) { 13514 long oldId = Binder.clearCallingIdentity(); 13515 try { 13516 Process.setProcessGroup(app.pid, app.curSchedGroup); 13517 } catch (Exception e) { 13518 Slog.w(TAG, "Failed setting process group of " + app.pid 13519 + " to " + app.curSchedGroup); 13520 e.printStackTrace(); 13521 } finally { 13522 Binder.restoreCallingIdentity(oldId); 13523 } 13524 } else { 13525 if (app.thread != null) { 13526 try { 13527 app.thread.setSchedulingGroup(app.curSchedGroup); 13528 } catch (RemoteException e) { 13529 } 13530 } 13531 } 13532 } 13533 } 13534 return success; 13535 } 13536 13537 private final ActivityRecord resumedAppLocked() { 13538 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13539 if (resumedActivity == null || resumedActivity.app == null) { 13540 resumedActivity = mMainStack.mPausingActivity; 13541 if (resumedActivity == null || resumedActivity.app == null) { 13542 resumedActivity = mMainStack.topRunningActivityLocked(null); 13543 } 13544 } 13545 return resumedActivity; 13546 } 13547 13548 final boolean updateOomAdjLocked(ProcessRecord app) { 13549 final ActivityRecord TOP_ACT = resumedAppLocked(); 13550 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13551 int curAdj = app.curAdj; 13552 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13553 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13554 13555 mAdjSeq++; 13556 13557 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13558 app.emptyAdj, TOP_APP, false); 13559 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13560 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13561 if (nowHidden != wasHidden) { 13562 // Changed to/from hidden state, so apps after it in the LRU 13563 // list may also be changed. 13564 updateOomAdjLocked(); 13565 } 13566 return success; 13567 } 13568 13569 final void updateOomAdjLocked() { 13570 final ActivityRecord TOP_ACT = resumedAppLocked(); 13571 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13572 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13573 13574 if (false) { 13575 RuntimeException e = new RuntimeException(); 13576 e.fillInStackTrace(); 13577 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13578 } 13579 13580 mAdjSeq++; 13581 mNewNumServiceProcs = 0; 13582 13583 final int emptyProcessLimit; 13584 final int hiddenProcessLimit; 13585 if (mProcessLimit <= 0) { 13586 emptyProcessLimit = hiddenProcessLimit = 0; 13587 } else if (mProcessLimit == 1) { 13588 emptyProcessLimit = 1; 13589 hiddenProcessLimit = 0; 13590 } else { 13591 emptyProcessLimit = (mProcessLimit*2)/3; 13592 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13593 } 13594 13595 // Let's determine how many processes we have running vs. 13596 // how many slots we have for background processes; we may want 13597 // to put multiple processes in a slot of there are enough of 13598 // them. 13599 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13600 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13601 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13602 if (numEmptyProcs > hiddenProcessLimit) { 13603 // If there are more empty processes than our limit on hidden 13604 // processes, then use the hidden process limit for the factor. 13605 // This ensures that the really old empty processes get pushed 13606 // down to the bottom, so if we are running low on memory we will 13607 // have a better chance at keeping around more hidden processes 13608 // instead of a gazillion empty processes. 13609 numEmptyProcs = hiddenProcessLimit; 13610 } 13611 int emptyFactor = numEmptyProcs/numSlots; 13612 if (emptyFactor < 1) emptyFactor = 1; 13613 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13614 if (hiddenFactor < 1) hiddenFactor = 1; 13615 int stepHidden = 0; 13616 int stepEmpty = 0; 13617 int numHidden = 0; 13618 int numEmpty = 0; 13619 int numTrimming = 0; 13620 13621 mNumNonHiddenProcs = 0; 13622 mNumHiddenProcs = 0; 13623 13624 // First update the OOM adjustment for each of the 13625 // application processes based on their current state. 13626 int i = mLruProcesses.size(); 13627 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13628 int nextHiddenAdj = curHiddenAdj+1; 13629 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13630 int nextEmptyAdj = curEmptyAdj+2; 13631 int curClientHiddenAdj = curEmptyAdj; 13632 while (i > 0) { 13633 i--; 13634 ProcessRecord app = mLruProcesses.get(i); 13635 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13636 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13637 if (!app.killedBackground) { 13638 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13639 // This process was assigned as a hidden process... step the 13640 // hidden level. 13641 mNumHiddenProcs++; 13642 if (curHiddenAdj != nextHiddenAdj) { 13643 stepHidden++; 13644 if (stepHidden >= hiddenFactor) { 13645 stepHidden = 0; 13646 curHiddenAdj = nextHiddenAdj; 13647 nextHiddenAdj += 2; 13648 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13649 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13650 } 13651 if (curClientHiddenAdj <= curHiddenAdj) { 13652 curClientHiddenAdj = curHiddenAdj + 1; 13653 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13654 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13655 } 13656 } 13657 } 13658 } 13659 numHidden++; 13660 if (numHidden > hiddenProcessLimit) { 13661 Slog.i(TAG, "No longer want " + app.processName 13662 + " (pid " + app.pid + "): hidden #" + numHidden); 13663 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13664 app.processName, app.setAdj, "too many background"); 13665 app.killedBackground = true; 13666 Process.killProcessQuiet(app.pid); 13667 } 13668 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13669 // This process has a client that has activities. We will have 13670 // given it the current hidden adj; here we will just leave it 13671 // without stepping the hidden adj. 13672 curClientHiddenAdj++; 13673 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13674 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13675 } 13676 } else { 13677 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13678 // This process was assigned as an empty process... step the 13679 // empty level. 13680 if (curEmptyAdj != nextEmptyAdj) { 13681 stepEmpty++; 13682 if (stepEmpty >= emptyFactor) { 13683 stepEmpty = 0; 13684 curEmptyAdj = nextEmptyAdj; 13685 nextEmptyAdj += 2; 13686 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13687 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13688 } 13689 } 13690 } 13691 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13692 mNumNonHiddenProcs++; 13693 } 13694 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13695 && !app.hasClientActivities) { 13696 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13697 && app.lastActivityTime < oldTime) { 13698 Slog.i(TAG, "No longer want " + app.processName 13699 + " (pid " + app.pid + "): empty for " 13700 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13701 / 1000) + "s"); 13702 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13703 app.processName, app.setAdj, "old background process"); 13704 app.killedBackground = true; 13705 Process.killProcessQuiet(app.pid); 13706 } else { 13707 numEmpty++; 13708 if (numEmpty > emptyProcessLimit) { 13709 Slog.i(TAG, "No longer want " + app.processName 13710 + " (pid " + app.pid + "): empty #" + numEmpty); 13711 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13712 app.processName, app.setAdj, "too many background"); 13713 app.killedBackground = true; 13714 Process.killProcessQuiet(app.pid); 13715 } 13716 } 13717 } 13718 } 13719 if (app.isolated && app.services.size() <= 0) { 13720 // If this is an isolated process, and there are no 13721 // services running in it, then the process is no longer 13722 // needed. We agressively kill these because we can by 13723 // definition not re-use the same process again, and it is 13724 // good to avoid having whatever code was running in them 13725 // left sitting around after no longer needed. 13726 Slog.i(TAG, "Isolated process " + app.processName 13727 + " (pid " + app.pid + ") no longer needed"); 13728 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13729 app.processName, app.setAdj, "isolated not needed"); 13730 app.killedBackground = true; 13731 Process.killProcessQuiet(app.pid); 13732 } 13733 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13734 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13735 && !app.killedBackground) { 13736 numTrimming++; 13737 } 13738 } 13739 } 13740 13741 mNumServiceProcs = mNewNumServiceProcs; 13742 13743 // Now determine the memory trimming level of background processes. 13744 // Unfortunately we need to start at the back of the list to do this 13745 // properly. We only do this if the number of background apps we 13746 // are managing to keep around is less than half the maximum we desire; 13747 // if we are keeping a good number around, we'll let them use whatever 13748 // memory they want. 13749 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13750 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13751 final int numHiddenAndEmpty = numHidden + numEmpty; 13752 final int N = mLruProcesses.size(); 13753 int factor = numTrimming/3; 13754 int minFactor = 2; 13755 if (mHomeProcess != null) minFactor++; 13756 if (mPreviousProcess != null) minFactor++; 13757 if (factor < minFactor) factor = minFactor; 13758 int step = 0; 13759 int fgTrimLevel; 13760 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13761 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13762 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13763 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13764 } else { 13765 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13766 } 13767 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13768 for (i=0; i<N; i++) { 13769 ProcessRecord app = mLruProcesses.get(i); 13770 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13771 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13772 && !app.killedBackground) { 13773 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13774 try { 13775 app.thread.scheduleTrimMemory(curLevel); 13776 } catch (RemoteException e) { 13777 } 13778 if (false) { 13779 // For now we won't do this; our memory trimming seems 13780 // to be good enough at this point that destroying 13781 // activities causes more harm than good. 13782 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13783 && app != mHomeProcess && app != mPreviousProcess) { 13784 // Need to do this on its own message because the stack may not 13785 // be in a consistent state at this point. 13786 // For these apps we will also finish their activities 13787 // to help them free memory. 13788 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13789 } 13790 } 13791 } 13792 app.trimMemoryLevel = curLevel; 13793 step++; 13794 if (step >= factor) { 13795 step = 0; 13796 switch (curLevel) { 13797 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13798 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13799 break; 13800 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13801 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13802 break; 13803 } 13804 } 13805 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13806 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13807 && app.thread != null) { 13808 try { 13809 app.thread.scheduleTrimMemory( 13810 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13811 } catch (RemoteException e) { 13812 } 13813 } 13814 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13815 } else { 13816 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13817 && app.pendingUiClean) { 13818 // If this application is now in the background and it 13819 // had done UI, then give it the special trim level to 13820 // have it free UI resources. 13821 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13822 if (app.trimMemoryLevel < level && app.thread != null) { 13823 try { 13824 app.thread.scheduleTrimMemory(level); 13825 } catch (RemoteException e) { 13826 } 13827 } 13828 app.pendingUiClean = false; 13829 } 13830 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13831 try { 13832 app.thread.scheduleTrimMemory(fgTrimLevel); 13833 } catch (RemoteException e) { 13834 } 13835 } 13836 app.trimMemoryLevel = fgTrimLevel; 13837 } 13838 } 13839 } else { 13840 final int N = mLruProcesses.size(); 13841 for (i=0; i<N; i++) { 13842 ProcessRecord app = mLruProcesses.get(i); 13843 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13844 && app.pendingUiClean) { 13845 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13846 && app.thread != null) { 13847 try { 13848 app.thread.scheduleTrimMemory( 13849 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13850 } catch (RemoteException e) { 13851 } 13852 } 13853 app.pendingUiClean = false; 13854 } 13855 app.trimMemoryLevel = 0; 13856 } 13857 } 13858 13859 if (mAlwaysFinishActivities) { 13860 // Need to do this on its own message because the stack may not 13861 // be in a consistent state at this point. 13862 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13863 } 13864 } 13865 13866 final void trimApplications() { 13867 synchronized (this) { 13868 int i; 13869 13870 // First remove any unused application processes whose package 13871 // has been removed. 13872 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13873 final ProcessRecord app = mRemovedProcesses.get(i); 13874 if (app.activities.size() == 0 13875 && app.curReceiver == null && app.services.size() == 0) { 13876 Slog.i( 13877 TAG, "Exiting empty application process " 13878 + app.processName + " (" 13879 + (app.thread != null ? app.thread.asBinder() : null) 13880 + ")\n"); 13881 if (app.pid > 0 && app.pid != MY_PID) { 13882 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13883 app.processName, app.setAdj, "empty"); 13884 Process.killProcessQuiet(app.pid); 13885 } else { 13886 try { 13887 app.thread.scheduleExit(); 13888 } catch (Exception e) { 13889 // Ignore exceptions. 13890 } 13891 } 13892 cleanUpApplicationRecordLocked(app, false, true, -1); 13893 mRemovedProcesses.remove(i); 13894 13895 if (app.persistent) { 13896 if (app.persistent) { 13897 addAppLocked(app.info, false); 13898 } 13899 } 13900 } 13901 } 13902 13903 // Now update the oom adj for all processes. 13904 updateOomAdjLocked(); 13905 } 13906 } 13907 13908 /** This method sends the specified signal to each of the persistent apps */ 13909 public void signalPersistentProcesses(int sig) throws RemoteException { 13910 if (sig != Process.SIGNAL_USR1) { 13911 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13912 } 13913 13914 synchronized (this) { 13915 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13916 != PackageManager.PERMISSION_GRANTED) { 13917 throw new SecurityException("Requires permission " 13918 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13919 } 13920 13921 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13922 ProcessRecord r = mLruProcesses.get(i); 13923 if (r.thread != null && r.persistent) { 13924 Process.sendSignal(r.pid, sig); 13925 } 13926 } 13927 } 13928 } 13929 13930 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13931 if (proc == null || proc == mProfileProc) { 13932 proc = mProfileProc; 13933 path = mProfileFile; 13934 profileType = mProfileType; 13935 clearProfilerLocked(); 13936 } 13937 if (proc == null) { 13938 return; 13939 } 13940 try { 13941 proc.thread.profilerControl(false, path, null, profileType); 13942 } catch (RemoteException e) { 13943 throw new IllegalStateException("Process disappeared"); 13944 } 13945 } 13946 13947 private void clearProfilerLocked() { 13948 if (mProfileFd != null) { 13949 try { 13950 mProfileFd.close(); 13951 } catch (IOException e) { 13952 } 13953 } 13954 mProfileApp = null; 13955 mProfileProc = null; 13956 mProfileFile = null; 13957 mProfileType = 0; 13958 mAutoStopProfiler = false; 13959 } 13960 13961 public boolean profileControl(String process, int userId, boolean start, 13962 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13963 13964 try { 13965 synchronized (this) { 13966 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13967 // its own permission. 13968 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13969 != PackageManager.PERMISSION_GRANTED) { 13970 throw new SecurityException("Requires permission " 13971 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13972 } 13973 13974 if (start && fd == null) { 13975 throw new IllegalArgumentException("null fd"); 13976 } 13977 13978 ProcessRecord proc = null; 13979 if (process != null) { 13980 proc = findProcessLocked(process, userId, "profileControl"); 13981 } 13982 13983 if (start && (proc == null || proc.thread == null)) { 13984 throw new IllegalArgumentException("Unknown process: " + process); 13985 } 13986 13987 if (start) { 13988 stopProfilerLocked(null, null, 0); 13989 setProfileApp(proc.info, proc.processName, path, fd, false); 13990 mProfileProc = proc; 13991 mProfileType = profileType; 13992 try { 13993 fd = fd.dup(); 13994 } catch (IOException e) { 13995 fd = null; 13996 } 13997 proc.thread.profilerControl(start, path, fd, profileType); 13998 fd = null; 13999 mProfileFd = null; 14000 } else { 14001 stopProfilerLocked(proc, path, profileType); 14002 if (fd != null) { 14003 try { 14004 fd.close(); 14005 } catch (IOException e) { 14006 } 14007 } 14008 } 14009 14010 return true; 14011 } 14012 } catch (RemoteException e) { 14013 throw new IllegalStateException("Process disappeared"); 14014 } finally { 14015 if (fd != null) { 14016 try { 14017 fd.close(); 14018 } catch (IOException e) { 14019 } 14020 } 14021 } 14022 } 14023 14024 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 14025 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14026 userId, true, true, callName, null); 14027 ProcessRecord proc = null; 14028 try { 14029 int pid = Integer.parseInt(process); 14030 synchronized (mPidsSelfLocked) { 14031 proc = mPidsSelfLocked.get(pid); 14032 } 14033 } catch (NumberFormatException e) { 14034 } 14035 14036 if (proc == null) { 14037 HashMap<String, SparseArray<ProcessRecord>> all 14038 = mProcessNames.getMap(); 14039 SparseArray<ProcessRecord> procs = all.get(process); 14040 if (procs != null && procs.size() > 0) { 14041 proc = procs.valueAt(0); 14042 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14043 for (int i=1; i<procs.size(); i++) { 14044 ProcessRecord thisProc = procs.valueAt(i); 14045 if (thisProc.userId == userId) { 14046 proc = thisProc; 14047 break; 14048 } 14049 } 14050 } 14051 } 14052 } 14053 14054 return proc; 14055 } 14056 14057 public boolean dumpHeap(String process, int userId, boolean managed, 14058 String path, ParcelFileDescriptor fd) throws RemoteException { 14059 14060 try { 14061 synchronized (this) { 14062 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14063 // its own permission (same as profileControl). 14064 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14065 != PackageManager.PERMISSION_GRANTED) { 14066 throw new SecurityException("Requires permission " 14067 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14068 } 14069 14070 if (fd == null) { 14071 throw new IllegalArgumentException("null fd"); 14072 } 14073 14074 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14075 if (proc == null || proc.thread == null) { 14076 throw new IllegalArgumentException("Unknown process: " + process); 14077 } 14078 14079 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14080 if (!isDebuggable) { 14081 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14082 throw new SecurityException("Process not debuggable: " + proc); 14083 } 14084 } 14085 14086 proc.thread.dumpHeap(managed, path, fd); 14087 fd = null; 14088 return true; 14089 } 14090 } catch (RemoteException e) { 14091 throw new IllegalStateException("Process disappeared"); 14092 } finally { 14093 if (fd != null) { 14094 try { 14095 fd.close(); 14096 } catch (IOException e) { 14097 } 14098 } 14099 } 14100 } 14101 14102 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14103 public void monitor() { 14104 synchronized (this) { } 14105 } 14106 14107 void onCoreSettingsChange(Bundle settings) { 14108 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14109 ProcessRecord processRecord = mLruProcesses.get(i); 14110 try { 14111 if (processRecord.thread != null) { 14112 processRecord.thread.setCoreSettings(settings); 14113 } 14114 } catch (RemoteException re) { 14115 /* ignore */ 14116 } 14117 } 14118 } 14119 14120 // Multi-user methods 14121 14122 @Override 14123 public boolean switchUser(int userId) { 14124 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14125 != PackageManager.PERMISSION_GRANTED) { 14126 String msg = "Permission Denial: switchUser() from pid=" 14127 + Binder.getCallingPid() 14128 + ", uid=" + Binder.getCallingUid() 14129 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14130 Slog.w(TAG, msg); 14131 throw new SecurityException(msg); 14132 } 14133 14134 final long ident = Binder.clearCallingIdentity(); 14135 try { 14136 synchronized (this) { 14137 final int oldUserId = mCurrentUserId; 14138 if (oldUserId == userId) { 14139 return true; 14140 } 14141 14142 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14143 if (userInfo == null) { 14144 Slog.w(TAG, "No user info for user #" + userId); 14145 return false; 14146 } 14147 14148 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14149 R.anim.screen_user_enter); 14150 14151 boolean needStart = false; 14152 14153 // If the user we are switching to is not currently started, then 14154 // we need to start it now. 14155 if (mStartedUsers.get(userId) == null) { 14156 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14157 updateStartedUserArrayLocked(); 14158 needStart = true; 14159 } 14160 14161 mCurrentUserId = userId; 14162 mCurrentUserArray = new int[] { userId }; 14163 final Integer userIdInt = Integer.valueOf(userId); 14164 mUserLru.remove(userIdInt); 14165 mUserLru.add(userIdInt); 14166 14167 mWindowManager.setCurrentUser(userId); 14168 14169 // Once the internal notion of the active user has switched, we lock the device 14170 // with the option to show the user switcher on the keyguard. 14171 mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS); 14172 14173 final UserStartedState uss = mStartedUsers.get(userId); 14174 14175 // Make sure user is in the started state. If it is currently 14176 // stopping, we need to knock that off. 14177 if (uss.mState == UserStartedState.STATE_STOPPING) { 14178 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 14179 // so we can just fairly silently bring the user back from 14180 // the almost-dead. 14181 uss.mState = UserStartedState.STATE_RUNNING; 14182 updateStartedUserArrayLocked(); 14183 needStart = true; 14184 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 14185 // This means ACTION_SHUTDOWN has been sent, so we will 14186 // need to treat this as a new boot of the user. 14187 uss.mState = UserStartedState.STATE_BOOTING; 14188 updateStartedUserArrayLocked(); 14189 needStart = true; 14190 } 14191 14192 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14193 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14194 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14195 oldUserId, userId, uss)); 14196 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14197 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14198 if (needStart) { 14199 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14200 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14201 | Intent.FLAG_RECEIVER_FOREGROUND); 14202 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14203 broadcastIntentLocked(null, null, intent, 14204 null, null, 0, null, null, null, 14205 false, false, MY_PID, Process.SYSTEM_UID, userId); 14206 } 14207 14208 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14209 if (userId != 0) { 14210 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14211 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14212 broadcastIntentLocked(null, null, intent, null, 14213 new IIntentReceiver.Stub() { 14214 public void performReceive(Intent intent, int resultCode, 14215 String data, Bundle extras, boolean ordered, 14216 boolean sticky, int sendingUser) { 14217 userInitialized(uss); 14218 } 14219 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14220 userId); 14221 uss.initializing = true; 14222 } else { 14223 getUserManagerLocked().makeInitialized(userInfo.id); 14224 } 14225 } 14226 14227 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14228 if (!haveActivities) { 14229 startHomeActivityLocked(userId); 14230 } 14231 14232 getUserManagerLocked().userForeground(userId); 14233 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14234 if (needStart) { 14235 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 14236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14237 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14238 broadcastIntentLocked(null, null, intent, 14239 null, new IIntentReceiver.Stub() { 14240 @Override 14241 public void performReceive(Intent intent, int resultCode, String data, 14242 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14243 throws RemoteException { 14244 } 14245 }, 0, null, null, 14246 android.Manifest.permission.INTERACT_ACROSS_USERS, 14247 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14248 } 14249 } 14250 } finally { 14251 Binder.restoreCallingIdentity(ident); 14252 } 14253 14254 return true; 14255 } 14256 14257 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14258 long ident = Binder.clearCallingIdentity(); 14259 try { 14260 Intent intent; 14261 if (oldUserId >= 0) { 14262 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14263 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14264 | Intent.FLAG_RECEIVER_FOREGROUND); 14265 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14266 broadcastIntentLocked(null, null, intent, 14267 null, null, 0, null, null, null, 14268 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14269 } 14270 if (newUserId >= 0) { 14271 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14272 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14273 | Intent.FLAG_RECEIVER_FOREGROUND); 14274 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14275 broadcastIntentLocked(null, null, intent, 14276 null, null, 0, null, null, null, 14277 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14278 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14279 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14280 | Intent.FLAG_RECEIVER_FOREGROUND); 14281 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14282 broadcastIntentLocked(null, null, intent, 14283 null, null, 0, null, null, 14284 android.Manifest.permission.MANAGE_USERS, 14285 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14286 } 14287 } finally { 14288 Binder.restoreCallingIdentity(ident); 14289 } 14290 } 14291 14292 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14293 final int newUserId) { 14294 final int N = mUserSwitchObservers.beginBroadcast(); 14295 if (N > 0) { 14296 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14297 int mCount = 0; 14298 @Override 14299 public void sendResult(Bundle data) throws RemoteException { 14300 synchronized (ActivityManagerService.this) { 14301 if (mCurUserSwitchCallback == this) { 14302 mCount++; 14303 if (mCount == N) { 14304 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14305 } 14306 } 14307 } 14308 } 14309 }; 14310 synchronized (this) { 14311 uss.switching = true; 14312 mCurUserSwitchCallback = callback; 14313 } 14314 for (int i=0; i<N; i++) { 14315 try { 14316 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14317 newUserId, callback); 14318 } catch (RemoteException e) { 14319 } 14320 } 14321 } else { 14322 synchronized (this) { 14323 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14324 } 14325 } 14326 mUserSwitchObservers.finishBroadcast(); 14327 } 14328 14329 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14330 synchronized (this) { 14331 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14332 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14333 } 14334 } 14335 14336 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14337 mCurUserSwitchCallback = null; 14338 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14339 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14340 oldUserId, newUserId, uss)); 14341 } 14342 14343 void userInitialized(UserStartedState uss) { 14344 synchronized (ActivityManagerService.this) { 14345 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14346 uss.initializing = false; 14347 completeSwitchAndInitalizeLocked(uss); 14348 } 14349 } 14350 14351 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14352 final int N = mUserSwitchObservers.beginBroadcast(); 14353 for (int i=0; i<N; i++) { 14354 try { 14355 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14356 } catch (RemoteException e) { 14357 } 14358 } 14359 mUserSwitchObservers.finishBroadcast(); 14360 synchronized (this) { 14361 uss.switching = false; 14362 completeSwitchAndInitalizeLocked(uss); 14363 } 14364 } 14365 14366 void completeSwitchAndInitalizeLocked(UserStartedState uss) { 14367 if (!uss.switching && !uss.initializing) { 14368 mWindowManager.stopFreezingScreen(); 14369 } 14370 } 14371 14372 void finishUserSwitch(UserStartedState uss) { 14373 synchronized (this) { 14374 if (uss.mState == UserStartedState.STATE_BOOTING 14375 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14376 uss.mState = UserStartedState.STATE_RUNNING; 14377 final int userId = uss.mHandle.getIdentifier(); 14378 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14379 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14380 broadcastIntentLocked(null, null, intent, 14381 null, null, 0, null, null, 14382 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14383 false, false, MY_PID, Process.SYSTEM_UID, userId); 14384 } 14385 int num = mUserLru.size(); 14386 int i = 0; 14387 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14388 Integer oldUserId = mUserLru.get(i); 14389 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14390 if (oldUss == null) { 14391 // Shouldn't happen, but be sane if it does. 14392 mUserLru.remove(i); 14393 num--; 14394 continue; 14395 } 14396 if (oldUss.mState == UserStartedState.STATE_STOPPING 14397 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 14398 // This user is already stopping, doesn't count. 14399 num--; 14400 i++; 14401 continue; 14402 } 14403 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14404 // Owner and current can't be stopped, but count as running. 14405 i++; 14406 continue; 14407 } 14408 // This is a user to be stopped. 14409 stopUserLocked(oldUserId, null); 14410 num--; 14411 i++; 14412 } 14413 } 14414 } 14415 14416 @Override 14417 public int stopUser(final int userId, final IStopUserCallback callback) { 14418 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14419 != PackageManager.PERMISSION_GRANTED) { 14420 String msg = "Permission Denial: switchUser() from pid=" 14421 + Binder.getCallingPid() 14422 + ", uid=" + Binder.getCallingUid() 14423 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14424 Slog.w(TAG, msg); 14425 throw new SecurityException(msg); 14426 } 14427 if (userId <= 0) { 14428 throw new IllegalArgumentException("Can't stop primary user " + userId); 14429 } 14430 synchronized (this) { 14431 return stopUserLocked(userId, callback); 14432 } 14433 } 14434 14435 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14436 if (mCurrentUserId == userId) { 14437 return ActivityManager.USER_OP_IS_CURRENT; 14438 } 14439 14440 final UserStartedState uss = mStartedUsers.get(userId); 14441 if (uss == null) { 14442 // User is not started, nothing to do... but we do need to 14443 // callback if requested. 14444 if (callback != null) { 14445 mHandler.post(new Runnable() { 14446 @Override 14447 public void run() { 14448 try { 14449 callback.userStopped(userId); 14450 } catch (RemoteException e) { 14451 } 14452 } 14453 }); 14454 } 14455 return ActivityManager.USER_OP_SUCCESS; 14456 } 14457 14458 if (callback != null) { 14459 uss.mStopCallbacks.add(callback); 14460 } 14461 14462 if (uss.mState != UserStartedState.STATE_STOPPING 14463 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14464 uss.mState = UserStartedState.STATE_STOPPING; 14465 updateStartedUserArrayLocked(); 14466 14467 long ident = Binder.clearCallingIdentity(); 14468 try { 14469 // We are going to broadcast ACTION_USER_STOPPING and then 14470 // once that is down send a final ACTION_SHUTDOWN and then 14471 // stop the user. 14472 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 14473 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14474 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14475 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 14476 // This is the result receiver for the final shutdown broadcast. 14477 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 14478 @Override 14479 public void performReceive(Intent intent, int resultCode, String data, 14480 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14481 finishUserStop(uss); 14482 } 14483 }; 14484 // This is the result receiver for the initial stopping broadcast. 14485 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 14486 @Override 14487 public void performReceive(Intent intent, int resultCode, String data, 14488 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14489 // On to the next. 14490 synchronized (ActivityManagerService.this) { 14491 if (uss.mState != UserStartedState.STATE_STOPPING) { 14492 // Whoops, we are being started back up. Abort, abort! 14493 return; 14494 } 14495 uss.mState = UserStartedState.STATE_SHUTDOWN; 14496 } 14497 broadcastIntentLocked(null, null, shutdownIntent, 14498 null, shutdownReceiver, 0, null, null, null, 14499 true, false, MY_PID, Process.SYSTEM_UID, userId); 14500 } 14501 }; 14502 // Kick things off. 14503 broadcastIntentLocked(null, null, stoppingIntent, 14504 null, stoppingReceiver, 0, null, null, 14505 android.Manifest.permission.INTERACT_ACROSS_USERS, 14506 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14507 } finally { 14508 Binder.restoreCallingIdentity(ident); 14509 } 14510 } 14511 14512 return ActivityManager.USER_OP_SUCCESS; 14513 } 14514 14515 void finishUserStop(UserStartedState uss) { 14516 final int userId = uss.mHandle.getIdentifier(); 14517 boolean stopped; 14518 ArrayList<IStopUserCallback> callbacks; 14519 synchronized (this) { 14520 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14521 if (mStartedUsers.get(userId) != uss) { 14522 stopped = false; 14523 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 14524 stopped = false; 14525 } else { 14526 stopped = true; 14527 // User can no longer run. 14528 mStartedUsers.remove(userId); 14529 mUserLru.remove(Integer.valueOf(userId)); 14530 updateStartedUserArrayLocked(); 14531 14532 // Clean up all state and processes associated with the user. 14533 // Kill all the processes for the user. 14534 forceStopUserLocked(userId); 14535 } 14536 } 14537 14538 for (int i=0; i<callbacks.size(); i++) { 14539 try { 14540 if (stopped) callbacks.get(i).userStopped(userId); 14541 else callbacks.get(i).userStopAborted(userId); 14542 } catch (RemoteException e) { 14543 } 14544 } 14545 } 14546 14547 @Override 14548 public UserInfo getCurrentUser() { 14549 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14550 != PackageManager.PERMISSION_GRANTED) && ( 14551 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14552 != PackageManager.PERMISSION_GRANTED)) { 14553 String msg = "Permission Denial: getCurrentUser() from pid=" 14554 + Binder.getCallingPid() 14555 + ", uid=" + Binder.getCallingUid() 14556 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14557 Slog.w(TAG, msg); 14558 throw new SecurityException(msg); 14559 } 14560 synchronized (this) { 14561 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14562 } 14563 } 14564 14565 int getCurrentUserIdLocked() { 14566 return mCurrentUserId; 14567 } 14568 14569 @Override 14570 public boolean isUserRunning(int userId, boolean orStopped) { 14571 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14572 != PackageManager.PERMISSION_GRANTED) { 14573 String msg = "Permission Denial: isUserRunning() from pid=" 14574 + Binder.getCallingPid() 14575 + ", uid=" + Binder.getCallingUid() 14576 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14577 Slog.w(TAG, msg); 14578 throw new SecurityException(msg); 14579 } 14580 synchronized (this) { 14581 return isUserRunningLocked(userId, orStopped); 14582 } 14583 } 14584 14585 boolean isUserRunningLocked(int userId, boolean orStopped) { 14586 UserStartedState state = mStartedUsers.get(userId); 14587 if (state == null) { 14588 return false; 14589 } 14590 if (orStopped) { 14591 return true; 14592 } 14593 return state.mState != UserStartedState.STATE_STOPPING 14594 && state.mState != UserStartedState.STATE_SHUTDOWN; 14595 } 14596 14597 @Override 14598 public int[] getRunningUserIds() { 14599 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14600 != PackageManager.PERMISSION_GRANTED) { 14601 String msg = "Permission Denial: isUserRunning() from pid=" 14602 + Binder.getCallingPid() 14603 + ", uid=" + Binder.getCallingUid() 14604 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14605 Slog.w(TAG, msg); 14606 throw new SecurityException(msg); 14607 } 14608 synchronized (this) { 14609 return mStartedUserArray; 14610 } 14611 } 14612 14613 private void updateStartedUserArrayLocked() { 14614 int num = 0; 14615 for (int i=0; i<mStartedUsers.size(); i++) { 14616 UserStartedState uss = mStartedUsers.valueAt(i); 14617 // This list does not include stopping users. 14618 if (uss.mState != UserStartedState.STATE_STOPPING 14619 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14620 num++; 14621 } 14622 } 14623 mStartedUserArray = new int[num]; 14624 num = 0; 14625 for (int i=0; i<mStartedUsers.size(); i++) { 14626 UserStartedState uss = mStartedUsers.valueAt(i); 14627 if (uss.mState != UserStartedState.STATE_STOPPING 14628 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14629 mStartedUserArray[num] = mStartedUsers.keyAt(i); 14630 num++; 14631 } 14632 } 14633 } 14634 14635 @Override 14636 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14637 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14638 != PackageManager.PERMISSION_GRANTED) { 14639 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14640 + Binder.getCallingPid() 14641 + ", uid=" + Binder.getCallingUid() 14642 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14643 Slog.w(TAG, msg); 14644 throw new SecurityException(msg); 14645 } 14646 14647 mUserSwitchObservers.register(observer); 14648 } 14649 14650 @Override 14651 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14652 mUserSwitchObservers.unregister(observer); 14653 } 14654 14655 private boolean userExists(int userId) { 14656 if (userId == 0) { 14657 return true; 14658 } 14659 UserManagerService ums = getUserManagerLocked(); 14660 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14661 } 14662 14663 int[] getUsersLocked() { 14664 UserManagerService ums = getUserManagerLocked(); 14665 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14666 } 14667 14668 UserManagerService getUserManagerLocked() { 14669 if (mUserManager == null) { 14670 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14671 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14672 } 14673 return mUserManager; 14674 } 14675 14676 private void checkValidCaller(int uid, int userId) { 14677 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14678 14679 throw new SecurityException("Caller uid=" + uid 14680 + " is not privileged to communicate with user=" + userId); 14681 } 14682 14683 private int applyUserId(int uid, int userId) { 14684 return UserHandle.getUid(userId, uid); 14685 } 14686 14687 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14688 if (info == null) return null; 14689 ApplicationInfo newInfo = new ApplicationInfo(info); 14690 newInfo.uid = applyUserId(info.uid, userId); 14691 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14692 + info.packageName; 14693 return newInfo; 14694 } 14695 14696 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14697 if (aInfo == null 14698 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14699 return aInfo; 14700 } 14701 14702 ActivityInfo info = new ActivityInfo(aInfo); 14703 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14704 return info; 14705 } 14706} 14707