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