ActivityManagerService.java revision ea7e91514ee1968d15713e82a5cca745e2c46a05
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Arrays; 151import java.util.Collections; 152import java.util.Comparator; 153import java.util.HashMap; 154import java.util.HashSet; 155import java.util.Iterator; 156import java.util.List; 157import java.util.Locale; 158import java.util.Map; 159import java.util.Set; 160import java.util.concurrent.atomic.AtomicBoolean; 161import java.util.concurrent.atomic.AtomicLong; 162 163public final class ActivityManagerService extends ActivityManagerNative 164 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 165 private static final String USER_DATA_DIR = "/data/user/"; 166 static final String TAG = "ActivityManager"; 167 static final String TAG_MU = "ActivityManagerServiceMU"; 168 static final boolean DEBUG = false; 169 static final boolean localLOGV = DEBUG; 170 static final boolean DEBUG_SWITCH = localLOGV || false; 171 static final boolean DEBUG_TASKS = localLOGV || false; 172 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 173 static final boolean DEBUG_PAUSE = localLOGV || false; 174 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 175 static final boolean DEBUG_TRANSITION = localLOGV || false; 176 static final boolean DEBUG_BROADCAST = localLOGV || false; 177 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_SERVICE = localLOGV || false; 180 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 181 static final boolean DEBUG_VISBILITY = localLOGV || false; 182 static final boolean DEBUG_PROCESSES = localLOGV || false; 183 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 184 static final boolean DEBUG_PROVIDER = localLOGV || false; 185 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 186 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 187 static final boolean DEBUG_RESULTS = localLOGV || false; 188 static final boolean DEBUG_BACKUP = localLOGV || false; 189 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 190 static final boolean DEBUG_POWER = localLOGV || false; 191 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 192 static final boolean DEBUG_MU = localLOGV || false; 193 static final boolean VALIDATE_TOKENS = false; 194 static final boolean SHOW_ACTIVITY_START_TIME = true; 195 196 // Control over CPU and battery monitoring. 197 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 198 static final boolean MONITOR_CPU_USAGE = true; 199 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 200 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 201 static final boolean MONITOR_THREAD_CPU_USAGE = false; 202 203 // The flags that are set for all calls we make to the package manager. 204 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 205 206 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 207 208 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 209 210 // Maximum number of recent tasks that we can remember. 211 static final int MAX_RECENT_TASKS = 20; 212 213 // Amount of time after a call to stopAppSwitches() during which we will 214 // prevent further untrusted switches from happening. 215 static final long APP_SWITCH_DELAY_TIME = 5*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real. 219 static final int PROC_START_TIMEOUT = 10*1000; 220 221 // How long we wait for a launched process to attach to the activity manager 222 // before we decide it's never going to come up for real, when the process was 223 // started with a wrapper for instrumentation (such as Valgrind) because it 224 // could take much longer than usual. 225 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 226 227 // How long to wait after going idle before forcing apps to GC. 228 static final int GC_TIMEOUT = 5*1000; 229 230 // The minimum amount of time between successive GC requests for a process. 231 static final int GC_MIN_INTERVAL = 60*1000; 232 233 // The rate at which we check for apps using excessive power -- 15 mins. 234 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on wake locks to start killing things. 238 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // The minimum sample duration we will allow before deciding we have 241 // enough data on CPU usage to start killing things. 242 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 243 244 // How long we allow a receiver to run before giving up on it. 245 static final int BROADCAST_FG_TIMEOUT = 10*1000; 246 static final int BROADCAST_BG_TIMEOUT = 60*1000; 247 248 // How long we wait until we timeout on key dispatching. 249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 250 251 // How long we wait until we timeout on key dispatching during instrumentation. 252 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 253 254 // Amount of time we wait for observers to handle a user switch before 255 // giving up on them and unfreezing the screen. 256 static final int USER_SWITCH_TIMEOUT = 2*1000; 257 258 // Maximum number of users we allow to be running at a time. 259 static final int MAX_RUNNING_USERS = 3; 260 261 static final int MY_PID = Process.myPid(); 262 263 static final String[] EMPTY_STRING_ARRAY = new String[0]; 264 265 public ActivityStack mMainStack; 266 267 private final boolean mHeadless; 268 269 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 270 // default actuion automatically. Important for devices without direct input 271 // devices. 272 private boolean mShowDialogs = true; 273 274 /** 275 * Description of a request to start a new activity, which has been held 276 * due to app switches being disabled. 277 */ 278 static class PendingActivityLaunch { 279 ActivityRecord r; 280 ActivityRecord sourceRecord; 281 int startFlags; 282 } 283 284 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 285 = new ArrayList<PendingActivityLaunch>(); 286 287 288 BroadcastQueue mFgBroadcastQueue; 289 BroadcastQueue mBgBroadcastQueue; 290 // Convenient for easy iteration over the queues. Foreground is first 291 // so that dispatch of foreground broadcasts gets precedence. 292 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 293 294 BroadcastQueue broadcastQueueForIntent(Intent intent) { 295 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 296 if (DEBUG_BACKGROUND_BROADCAST) { 297 Slog.i(TAG, "Broadcast intent " + intent + " on " 298 + (isFg ? "foreground" : "background") 299 + " queue"); 300 } 301 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 302 } 303 304 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 305 for (BroadcastQueue queue : mBroadcastQueues) { 306 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 307 if (r != null) { 308 return r; 309 } 310 } 311 return null; 312 } 313 314 /** 315 * Activity we have told the window manager to have key focus. 316 */ 317 ActivityRecord mFocusedActivity = null; 318 /** 319 * List of intents that were used to start the most recent tasks. 320 */ 321 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 322 323 /** 324 * Process management. 325 */ 326 final ProcessList mProcessList = new ProcessList(); 327 328 /** 329 * All of the applications we currently have running organized by name. 330 * The keys are strings of the application package name (as 331 * returned by the package manager), and the keys are ApplicationRecord 332 * objects. 333 */ 334 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 335 336 /** 337 * The currently running isolated processes. 338 */ 339 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 340 341 /** 342 * Counter for assigning isolated process uids, to avoid frequently reusing the 343 * same ones. 344 */ 345 int mNextIsolatedProcessUid = 0; 346 347 /** 348 * The currently running heavy-weight process, if any. 349 */ 350 ProcessRecord mHeavyWeightProcess = null; 351 352 /** 353 * The last time that various processes have crashed. 354 */ 355 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 356 357 /** 358 * Set of applications that we consider to be bad, and will reject 359 * incoming broadcasts from (which the user has no control over). 360 * Processes are added to this set when they have crashed twice within 361 * a minimum amount of time; they are removed from it when they are 362 * later restarted (hopefully due to some user action). The value is the 363 * time it was added to the list. 364 */ 365 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 366 367 /** 368 * All of the processes we currently have running organized by pid. 369 * The keys are the pid running the application. 370 * 371 * <p>NOTE: This object is protected by its own lock, NOT the global 372 * activity manager lock! 373 */ 374 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 375 376 /** 377 * All of the processes that have been forced to be foreground. The key 378 * is the pid of the caller who requested it (we hold a death 379 * link on it). 380 */ 381 abstract class ForegroundToken implements IBinder.DeathRecipient { 382 int pid; 383 IBinder token; 384 } 385 final SparseArray<ForegroundToken> mForegroundProcesses 386 = new SparseArray<ForegroundToken>(); 387 388 /** 389 * List of records for processes that someone had tried to start before the 390 * system was ready. We don't start them at that point, but ensure they 391 * are started by the time booting is complete. 392 */ 393 final ArrayList<ProcessRecord> mProcessesOnHold 394 = new ArrayList<ProcessRecord>(); 395 396 /** 397 * List of persistent applications that are in the process 398 * of being started. 399 */ 400 final ArrayList<ProcessRecord> mPersistentStartingProcesses 401 = new ArrayList<ProcessRecord>(); 402 403 /** 404 * Processes that are being forcibly torn down. 405 */ 406 final ArrayList<ProcessRecord> mRemovedProcesses 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * List of running applications, sorted by recent usage. 411 * The first entry in the list is the least recently used. 412 * It contains ApplicationRecord objects. This list does NOT include 413 * any persistent application records (since we never want to exit them). 414 */ 415 final ArrayList<ProcessRecord> mLruProcesses 416 = new ArrayList<ProcessRecord>(); 417 418 /** 419 * List of processes that should gc as soon as things are idle. 420 */ 421 final ArrayList<ProcessRecord> mProcessesToGc 422 = new ArrayList<ProcessRecord>(); 423 424 /** 425 * This is the process holding what we currently consider to be 426 * the "home" activity. 427 */ 428 ProcessRecord mHomeProcess; 429 430 /** 431 * This is the process holding the activity the user last visited that 432 * is in a different process from the one they are currently in. 433 */ 434 ProcessRecord mPreviousProcess; 435 436 /** 437 * The time at which the previous process was last visible. 438 */ 439 long mPreviousProcessVisibleTime; 440 441 /** 442 * Which uses have been started, so are allowed to run code. 443 */ 444 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 445 446 /** 447 * LRU list of history of current users. Most recently current is at the end. 448 */ 449 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 450 451 /** 452 * Constant array of the users that are currently started. 453 */ 454 int[] mStartedUserArray = new int[] { 0 }; 455 456 /** 457 * Registered observers of the user switching mechanics. 458 */ 459 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 460 = new RemoteCallbackList<IUserSwitchObserver>(); 461 462 /** 463 * Currently active user switch. 464 */ 465 Object mCurUserSwitchCallback; 466 467 /** 468 * Packages that the user has asked to have run in screen size 469 * compatibility mode instead of filling the screen. 470 */ 471 final CompatModePackages mCompatModePackages; 472 473 /** 474 * Set of PendingResultRecord objects that are currently active. 475 */ 476 final HashSet mPendingResultRecords = new HashSet(); 477 478 /** 479 * Set of IntentSenderRecord objects that are currently active. 480 */ 481 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 482 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 483 484 /** 485 * Fingerprints (hashCode()) of stack traces that we've 486 * already logged DropBox entries for. Guarded by itself. If 487 * something (rogue user app) forces this over 488 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 489 */ 490 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 491 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 492 493 /** 494 * Strict Mode background batched logging state. 495 * 496 * The string buffer is guarded by itself, and its lock is also 497 * used to determine if another batched write is already 498 * in-flight. 499 */ 500 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 501 502 /** 503 * Keeps track of all IIntentReceivers that have been registered for 504 * broadcasts. Hash keys are the receiver IBinder, hash value is 505 * a ReceiverList. 506 */ 507 final HashMap mRegisteredReceivers = new HashMap(); 508 509 /** 510 * Resolver for broadcast intents to registered receivers. 511 * Holds BroadcastFilter (subclass of IntentFilter). 512 */ 513 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 514 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 515 @Override 516 protected boolean allowFilterResult( 517 BroadcastFilter filter, List<BroadcastFilter> dest) { 518 IBinder target = filter.receiverList.receiver.asBinder(); 519 for (int i=dest.size()-1; i>=0; i--) { 520 if (dest.get(i).receiverList.receiver.asBinder() == target) { 521 return false; 522 } 523 } 524 return true; 525 } 526 527 @Override 528 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 529 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 530 || userId == filter.owningUserId) { 531 return super.newResult(filter, match, userId); 532 } 533 return null; 534 } 535 536 @Override 537 protected BroadcastFilter[] newArray(int size) { 538 return new BroadcastFilter[size]; 539 } 540 541 @Override 542 protected String packageForFilter(BroadcastFilter filter) { 543 return filter.packageName; 544 } 545 }; 546 547 /** 548 * State of all active sticky broadcasts per user. Keys are the action of the 549 * sticky Intent, values are an ArrayList of all broadcasted intents with 550 * that action (which should usually be one). The SparseArray is keyed 551 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 552 * for stickies that are sent to all users. 553 */ 554 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 555 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 556 557 final ActiveServices mServices; 558 559 /** 560 * Backup/restore process management 561 */ 562 String mBackupAppName = null; 563 BackupRecord mBackupTarget = null; 564 565 /** 566 * List of PendingThumbnailsRecord objects of clients who are still 567 * waiting to receive all of the thumbnails for a task. 568 */ 569 final ArrayList mPendingThumbnails = new ArrayList(); 570 571 /** 572 * List of HistoryRecord objects that have been finished and must 573 * still report back to a pending thumbnail receiver. 574 */ 575 final ArrayList mCancelledThumbnails = new ArrayList(); 576 577 final ProviderMap mProviderMap; 578 579 /** 580 * List of content providers who have clients waiting for them. The 581 * application is currently being launched and the provider will be 582 * removed from this list once it is published. 583 */ 584 final ArrayList<ContentProviderRecord> mLaunchingProviders 585 = new ArrayList<ContentProviderRecord>(); 586 587 /** 588 * Global set of specific Uri permissions that have been granted. 589 */ 590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 591 = new SparseArray<HashMap<Uri, UriPermission>>(); 592 593 CoreSettingsObserver mCoreSettingsObserver; 594 595 /** 596 * Thread-local storage used to carry caller permissions over through 597 * indirect content-provider access. 598 * @see #ActivityManagerService.openContentUri() 599 */ 600 private class Identity { 601 public int pid; 602 public int uid; 603 604 Identity(int _pid, int _uid) { 605 pid = _pid; 606 uid = _uid; 607 } 608 } 609 610 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 611 612 /** 613 * All information we have collected about the runtime performance of 614 * any user id that can impact battery performance. 615 */ 616 final BatteryStatsService mBatteryStatsService; 617 618 /** 619 * information about component usage 620 */ 621 final UsageStatsService mUsageStatsService; 622 623 /** 624 * Current configuration information. HistoryRecord objects are given 625 * a reference to this object to indicate which configuration they are 626 * currently running in, so this object must be kept immutable. 627 */ 628 Configuration mConfiguration = new Configuration(); 629 630 /** 631 * Current sequencing integer of the configuration, for skipping old 632 * configurations. 633 */ 634 int mConfigurationSeq = 0; 635 636 /** 637 * Hardware-reported OpenGLES version. 638 */ 639 final int GL_ES_VERSION; 640 641 /** 642 * List of initialization arguments to pass to all processes when binding applications to them. 643 * For example, references to the commonly used services. 644 */ 645 HashMap<String, IBinder> mAppBindArgs; 646 647 /** 648 * Temporary to avoid allocations. Protected by main lock. 649 */ 650 final StringBuilder mStringBuilder = new StringBuilder(256); 651 652 /** 653 * Used to control how we initialize the service. 654 */ 655 boolean mStartRunning = false; 656 ComponentName mTopComponent; 657 String mTopAction; 658 String mTopData; 659 boolean mProcessesReady = false; 660 boolean mSystemReady = false; 661 boolean mBooting = false; 662 boolean mWaitingUpdate = false; 663 boolean mDidUpdate = false; 664 boolean mOnBattery = false; 665 boolean mLaunchWarningShown = false; 666 667 Context mContext; 668 669 int mFactoryTest; 670 671 boolean mCheckedForSetup; 672 673 /** 674 * The time at which we will allow normal application switches again, 675 * after a call to {@link #stopAppSwitches()}. 676 */ 677 long mAppSwitchesAllowedTime; 678 679 /** 680 * This is set to true after the first switch after mAppSwitchesAllowedTime 681 * is set; any switches after that will clear the time. 682 */ 683 boolean mDidAppSwitch; 684 685 /** 686 * Last time (in realtime) at which we checked for power usage. 687 */ 688 long mLastPowerCheckRealtime; 689 690 /** 691 * Last time (in uptime) at which we checked for power usage. 692 */ 693 long mLastPowerCheckUptime; 694 695 /** 696 * Set while we are wanting to sleep, to prevent any 697 * activities from being started/resumed. 698 */ 699 boolean mSleeping = false; 700 701 /** 702 * State of external calls telling us if the device is asleep. 703 */ 704 boolean mWentToSleep = false; 705 706 /** 707 * State of external call telling us if the lock screen is shown. 708 */ 709 boolean mLockScreenShown = false; 710 711 /** 712 * Set if we are shutting down the system, similar to sleeping. 713 */ 714 boolean mShuttingDown = false; 715 716 /** 717 * Task identifier that activities are currently being started 718 * in. Incremented each time a new task is created. 719 * todo: Replace this with a TokenSpace class that generates non-repeating 720 * integers that won't wrap. 721 */ 722 int mCurTask = 1; 723 724 /** 725 * Current sequence id for oom_adj computation traversal. 726 */ 727 int mAdjSeq = 0; 728 729 /** 730 * Current sequence id for process LRU updating. 731 */ 732 int mLruSeq = 0; 733 734 /** 735 * Keep track of the non-hidden/empty process we last found, to help 736 * determine how to distribute hidden/empty processes next time. 737 */ 738 int mNumNonHiddenProcs = 0; 739 740 /** 741 * Keep track of the number of hidden procs, to balance oom adj 742 * distribution between those and empty procs. 743 */ 744 int mNumHiddenProcs = 0; 745 746 /** 747 * Keep track of the number of service processes we last found, to 748 * determine on the next iteration which should be B services. 749 */ 750 int mNumServiceProcs = 0; 751 int mNewNumServiceProcs = 0; 752 753 /** 754 * System monitoring: number of processes that died since the last 755 * N procs were started. 756 */ 757 int[] mProcDeaths = new int[20]; 758 759 /** 760 * This is set if we had to do a delayed dexopt of an app before launching 761 * it, to increasing the ANR timeouts in that case. 762 */ 763 boolean mDidDexOpt; 764 765 String mDebugApp = null; 766 boolean mWaitForDebugger = false; 767 boolean mDebugTransient = false; 768 String mOrigDebugApp = null; 769 boolean mOrigWaitForDebugger = false; 770 boolean mAlwaysFinishActivities = false; 771 IActivityController mController = null; 772 String mProfileApp = null; 773 ProcessRecord mProfileProc = null; 774 String mProfileFile; 775 ParcelFileDescriptor mProfileFd; 776 int mProfileType = 0; 777 boolean mAutoStopProfiler = false; 778 String mOpenGlTraceApp = null; 779 780 static class ProcessChangeItem { 781 static final int CHANGE_ACTIVITIES = 1<<0; 782 static final int CHANGE_IMPORTANCE= 1<<1; 783 int changes; 784 int uid; 785 int pid; 786 int importance; 787 boolean foregroundActivities; 788 } 789 790 final RemoteCallbackList<IProcessObserver> mProcessObservers 791 = new RemoteCallbackList<IProcessObserver>(); 792 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 793 794 final ArrayList<ProcessChangeItem> mPendingProcessChanges 795 = new ArrayList<ProcessChangeItem>(); 796 final ArrayList<ProcessChangeItem> mAvailProcessChanges 797 = new ArrayList<ProcessChangeItem>(); 798 799 /** 800 * Callback of last caller to {@link #requestPss}. 801 */ 802 Runnable mRequestPssCallback; 803 804 /** 805 * Remaining processes for which we are waiting results from the last 806 * call to {@link #requestPss}. 807 */ 808 final ArrayList<ProcessRecord> mRequestPssList 809 = new ArrayList<ProcessRecord>(); 810 811 /** 812 * Runtime statistics collection thread. This object's lock is used to 813 * protect all related state. 814 */ 815 final Thread mProcessStatsThread; 816 817 /** 818 * Used to collect process stats when showing not responding dialog. 819 * Protected by mProcessStatsThread. 820 */ 821 final ProcessStats mProcessStats = new ProcessStats( 822 MONITOR_THREAD_CPU_USAGE); 823 final AtomicLong mLastCpuTime = new AtomicLong(0); 824 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 825 826 long mLastWriteTime = 0; 827 828 /** 829 * Set to true after the system has finished booting. 830 */ 831 boolean mBooted = false; 832 833 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 834 int mProcessLimitOverride = -1; 835 836 WindowManagerService mWindowManager; 837 838 static ActivityManagerService mSelf; 839 static ActivityThread mSystemThread; 840 841 private int mCurrentUserId = 0; 842 private int[] mCurrentUserArray = new int[] { 0 }; 843 private UserManagerService mUserManager; 844 845 private final class AppDeathRecipient implements IBinder.DeathRecipient { 846 final ProcessRecord mApp; 847 final int mPid; 848 final IApplicationThread mAppThread; 849 850 AppDeathRecipient(ProcessRecord app, int pid, 851 IApplicationThread thread) { 852 if (localLOGV) Slog.v( 853 TAG, "New death recipient " + this 854 + " for thread " + thread.asBinder()); 855 mApp = app; 856 mPid = pid; 857 mAppThread = thread; 858 } 859 860 public void binderDied() { 861 if (localLOGV) Slog.v( 862 TAG, "Death received in " + this 863 + " for thread " + mAppThread.asBinder()); 864 synchronized(ActivityManagerService.this) { 865 appDiedLocked(mApp, mPid, mAppThread); 866 } 867 } 868 } 869 870 static final int SHOW_ERROR_MSG = 1; 871 static final int SHOW_NOT_RESPONDING_MSG = 2; 872 static final int SHOW_FACTORY_ERROR_MSG = 3; 873 static final int UPDATE_CONFIGURATION_MSG = 4; 874 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 875 static final int WAIT_FOR_DEBUGGER_MSG = 6; 876 static final int SERVICE_TIMEOUT_MSG = 12; 877 static final int UPDATE_TIME_ZONE = 13; 878 static final int SHOW_UID_ERROR_MSG = 14; 879 static final int IM_FEELING_LUCKY_MSG = 15; 880 static final int PROC_START_TIMEOUT_MSG = 20; 881 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 882 static final int KILL_APPLICATION_MSG = 22; 883 static final int FINALIZE_PENDING_INTENT_MSG = 23; 884 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 885 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 886 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 887 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 888 static final int CLEAR_DNS_CACHE = 28; 889 static final int UPDATE_HTTP_PROXY = 29; 890 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 891 static final int DISPATCH_PROCESSES_CHANGED = 31; 892 static final int DISPATCH_PROCESS_DIED = 32; 893 static final int REPORT_MEM_USAGE = 33; 894 static final int REPORT_USER_SWITCH_MSG = 34; 895 static final int CONTINUE_USER_SWITCH_MSG = 35; 896 static final int USER_SWITCH_TIMEOUT_MSG = 36; 897 898 static final int FIRST_ACTIVITY_STACK_MSG = 100; 899 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 900 static final int FIRST_COMPAT_MODE_MSG = 300; 901 902 AlertDialog mUidAlert; 903 CompatModeDialog mCompatModeDialog; 904 long mLastMemUsageReportTime = 0; 905 906 final Handler mHandler = new Handler() { 907 //public Handler() { 908 // if (localLOGV) Slog.v(TAG, "Handler started!"); 909 //} 910 911 public void handleMessage(Message msg) { 912 switch (msg.what) { 913 case SHOW_ERROR_MSG: { 914 HashMap data = (HashMap) msg.obj; 915 synchronized (ActivityManagerService.this) { 916 ProcessRecord proc = (ProcessRecord)data.get("app"); 917 if (proc != null && proc.crashDialog != null) { 918 Slog.e(TAG, "App already has crash dialog: " + proc); 919 return; 920 } 921 AppErrorResult res = (AppErrorResult) data.get("result"); 922 if (mShowDialogs && !mSleeping && !mShuttingDown) { 923 Dialog d = new AppErrorDialog(mContext, res, proc); 924 d.show(); 925 proc.crashDialog = d; 926 } else { 927 // The device is asleep, so just pretend that the user 928 // saw a crash dialog and hit "force quit". 929 res.set(0); 930 } 931 } 932 933 ensureBootCompleted(); 934 } break; 935 case SHOW_NOT_RESPONDING_MSG: { 936 synchronized (ActivityManagerService.this) { 937 HashMap data = (HashMap) msg.obj; 938 ProcessRecord proc = (ProcessRecord)data.get("app"); 939 if (proc != null && proc.anrDialog != null) { 940 Slog.e(TAG, "App already has anr dialog: " + proc); 941 return; 942 } 943 944 Intent intent = new Intent("android.intent.action.ANR"); 945 if (!mProcessesReady) { 946 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 947 | Intent.FLAG_RECEIVER_FOREGROUND); 948 } 949 broadcastIntentLocked(null, null, intent, 950 null, null, 0, null, null, null, 951 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 952 953 if (mShowDialogs) { 954 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 955 mContext, proc, (ActivityRecord)data.get("activity")); 956 d.show(); 957 proc.anrDialog = d; 958 } else { 959 // Just kill the app if there is no dialog to be shown. 960 killAppAtUsersRequest(proc, null); 961 } 962 } 963 964 ensureBootCompleted(); 965 } break; 966 case SHOW_STRICT_MODE_VIOLATION_MSG: { 967 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 968 synchronized (ActivityManagerService.this) { 969 ProcessRecord proc = (ProcessRecord) data.get("app"); 970 if (proc == null) { 971 Slog.e(TAG, "App not found when showing strict mode dialog."); 972 break; 973 } 974 if (proc.crashDialog != null) { 975 Slog.e(TAG, "App already has strict mode dialog: " + proc); 976 return; 977 } 978 AppErrorResult res = (AppErrorResult) data.get("result"); 979 if (mShowDialogs && !mSleeping && !mShuttingDown) { 980 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 981 d.show(); 982 proc.crashDialog = d; 983 } else { 984 // The device is asleep, so just pretend that the user 985 // saw a crash dialog and hit "force quit". 986 res.set(0); 987 } 988 } 989 ensureBootCompleted(); 990 } break; 991 case SHOW_FACTORY_ERROR_MSG: { 992 Dialog d = new FactoryErrorDialog( 993 mContext, msg.getData().getCharSequence("msg")); 994 d.show(); 995 ensureBootCompleted(); 996 } break; 997 case UPDATE_CONFIGURATION_MSG: { 998 final ContentResolver resolver = mContext.getContentResolver(); 999 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1000 } break; 1001 case GC_BACKGROUND_PROCESSES_MSG: { 1002 synchronized (ActivityManagerService.this) { 1003 performAppGcsIfAppropriateLocked(); 1004 } 1005 } break; 1006 case WAIT_FOR_DEBUGGER_MSG: { 1007 synchronized (ActivityManagerService.this) { 1008 ProcessRecord app = (ProcessRecord)msg.obj; 1009 if (msg.arg1 != 0) { 1010 if (!app.waitedForDebugger) { 1011 Dialog d = new AppWaitingForDebuggerDialog( 1012 ActivityManagerService.this, 1013 mContext, app); 1014 app.waitDialog = d; 1015 app.waitedForDebugger = true; 1016 d.show(); 1017 } 1018 } else { 1019 if (app.waitDialog != null) { 1020 app.waitDialog.dismiss(); 1021 app.waitDialog = null; 1022 } 1023 } 1024 } 1025 } break; 1026 case SERVICE_TIMEOUT_MSG: { 1027 if (mDidDexOpt) { 1028 mDidDexOpt = false; 1029 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1030 nmsg.obj = msg.obj; 1031 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1032 return; 1033 } 1034 mServices.serviceTimeout((ProcessRecord)msg.obj); 1035 } break; 1036 case UPDATE_TIME_ZONE: { 1037 synchronized (ActivityManagerService.this) { 1038 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1039 ProcessRecord r = mLruProcesses.get(i); 1040 if (r.thread != null) { 1041 try { 1042 r.thread.updateTimeZone(); 1043 } catch (RemoteException ex) { 1044 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1045 } 1046 } 1047 } 1048 } 1049 } break; 1050 case CLEAR_DNS_CACHE: { 1051 synchronized (ActivityManagerService.this) { 1052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1053 ProcessRecord r = mLruProcesses.get(i); 1054 if (r.thread != null) { 1055 try { 1056 r.thread.clearDnsCache(); 1057 } catch (RemoteException ex) { 1058 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1059 } 1060 } 1061 } 1062 } 1063 } break; 1064 case UPDATE_HTTP_PROXY: { 1065 ProxyProperties proxy = (ProxyProperties)msg.obj; 1066 String host = ""; 1067 String port = ""; 1068 String exclList = ""; 1069 if (proxy != null) { 1070 host = proxy.getHost(); 1071 port = Integer.toString(proxy.getPort()); 1072 exclList = proxy.getExclusionList(); 1073 } 1074 synchronized (ActivityManagerService.this) { 1075 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1076 ProcessRecord r = mLruProcesses.get(i); 1077 if (r.thread != null) { 1078 try { 1079 r.thread.setHttpProxy(host, port, exclList); 1080 } catch (RemoteException ex) { 1081 Slog.w(TAG, "Failed to update http proxy for: " + 1082 r.info.processName); 1083 } 1084 } 1085 } 1086 } 1087 } break; 1088 case SHOW_UID_ERROR_MSG: { 1089 String title = "System UIDs Inconsistent"; 1090 String text = "UIDs on the system are inconsistent, you need to wipe your" 1091 + " data partition or your device will be unstable."; 1092 Log.e(TAG, title + ": " + text); 1093 if (mShowDialogs) { 1094 // XXX This is a temporary dialog, no need to localize. 1095 AlertDialog d = new BaseErrorDialog(mContext); 1096 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1097 d.setCancelable(false); 1098 d.setTitle(title); 1099 d.setMessage(text); 1100 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1101 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1102 mUidAlert = d; 1103 d.show(); 1104 } 1105 } break; 1106 case IM_FEELING_LUCKY_MSG: { 1107 if (mUidAlert != null) { 1108 mUidAlert.dismiss(); 1109 mUidAlert = null; 1110 } 1111 } break; 1112 case PROC_START_TIMEOUT_MSG: { 1113 if (mDidDexOpt) { 1114 mDidDexOpt = false; 1115 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1116 nmsg.obj = msg.obj; 1117 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1118 return; 1119 } 1120 ProcessRecord app = (ProcessRecord)msg.obj; 1121 synchronized (ActivityManagerService.this) { 1122 processStartTimedOutLocked(app); 1123 } 1124 } break; 1125 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1126 synchronized (ActivityManagerService.this) { 1127 doPendingActivityLaunchesLocked(true); 1128 } 1129 } break; 1130 case KILL_APPLICATION_MSG: { 1131 synchronized (ActivityManagerService.this) { 1132 int appid = msg.arg1; 1133 boolean restart = (msg.arg2 == 1); 1134 String pkg = (String) msg.obj; 1135 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1136 UserHandle.USER_ALL); 1137 } 1138 } break; 1139 case FINALIZE_PENDING_INTENT_MSG: { 1140 ((PendingIntentRecord)msg.obj).completeFinalize(); 1141 } break; 1142 case POST_HEAVY_NOTIFICATION_MSG: { 1143 INotificationManager inm = NotificationManager.getService(); 1144 if (inm == null) { 1145 return; 1146 } 1147 1148 ActivityRecord root = (ActivityRecord)msg.obj; 1149 ProcessRecord process = root.app; 1150 if (process == null) { 1151 return; 1152 } 1153 1154 try { 1155 Context context = mContext.createPackageContext(process.info.packageName, 0); 1156 String text = mContext.getString(R.string.heavy_weight_notification, 1157 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1158 Notification notification = new Notification(); 1159 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1160 notification.when = 0; 1161 notification.flags = Notification.FLAG_ONGOING_EVENT; 1162 notification.tickerText = text; 1163 notification.defaults = 0; // please be quiet 1164 notification.sound = null; 1165 notification.vibrate = null; 1166 notification.setLatestEventInfo(context, text, 1167 mContext.getText(R.string.heavy_weight_notification_detail), 1168 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1169 PendingIntent.FLAG_CANCEL_CURRENT, null, 1170 new UserHandle(root.userId))); 1171 1172 try { 1173 int[] outId = new int[1]; 1174 inm.enqueueNotificationWithTag("android", null, 1175 R.string.heavy_weight_notification, 1176 notification, outId, root.userId); 1177 } catch (RuntimeException e) { 1178 Slog.w(ActivityManagerService.TAG, 1179 "Error showing notification for heavy-weight app", e); 1180 } catch (RemoteException e) { 1181 } 1182 } catch (NameNotFoundException e) { 1183 Slog.w(TAG, "Unable to create context for heavy notification", e); 1184 } 1185 } break; 1186 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1187 INotificationManager inm = NotificationManager.getService(); 1188 if (inm == null) { 1189 return; 1190 } 1191 try { 1192 inm.cancelNotificationWithTag("android", null, 1193 R.string.heavy_weight_notification, msg.arg1); 1194 } catch (RuntimeException e) { 1195 Slog.w(ActivityManagerService.TAG, 1196 "Error canceling notification for service", e); 1197 } catch (RemoteException e) { 1198 } 1199 } break; 1200 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1201 synchronized (ActivityManagerService.this) { 1202 checkExcessivePowerUsageLocked(true); 1203 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1204 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1205 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1206 } 1207 } break; 1208 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1209 synchronized (ActivityManagerService.this) { 1210 ActivityRecord ar = (ActivityRecord)msg.obj; 1211 if (mCompatModeDialog != null) { 1212 if (mCompatModeDialog.mAppInfo.packageName.equals( 1213 ar.info.applicationInfo.packageName)) { 1214 return; 1215 } 1216 mCompatModeDialog.dismiss(); 1217 mCompatModeDialog = null; 1218 } 1219 if (ar != null && false) { 1220 if (mCompatModePackages.getPackageAskCompatModeLocked( 1221 ar.packageName)) { 1222 int mode = mCompatModePackages.computeCompatModeLocked( 1223 ar.info.applicationInfo); 1224 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1225 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1226 mCompatModeDialog = new CompatModeDialog( 1227 ActivityManagerService.this, mContext, 1228 ar.info.applicationInfo); 1229 mCompatModeDialog.show(); 1230 } 1231 } 1232 } 1233 } 1234 break; 1235 } 1236 case DISPATCH_PROCESSES_CHANGED: { 1237 dispatchProcessesChanged(); 1238 break; 1239 } 1240 case DISPATCH_PROCESS_DIED: { 1241 final int pid = msg.arg1; 1242 final int uid = msg.arg2; 1243 dispatchProcessDied(pid, uid); 1244 break; 1245 } 1246 case REPORT_MEM_USAGE: { 1247 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1248 if (!isDebuggable) { 1249 return; 1250 } 1251 synchronized (ActivityManagerService.this) { 1252 long now = SystemClock.uptimeMillis(); 1253 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1254 // Don't report more than every 5 minutes to somewhat 1255 // avoid spamming. 1256 return; 1257 } 1258 mLastMemUsageReportTime = now; 1259 } 1260 Thread thread = new Thread() { 1261 @Override public void run() { 1262 StringBuilder dropBuilder = new StringBuilder(1024); 1263 StringBuilder logBuilder = new StringBuilder(1024); 1264 StringWriter oomSw = new StringWriter(); 1265 PrintWriter oomPw = new PrintWriter(oomSw); 1266 StringWriter catSw = new StringWriter(); 1267 PrintWriter catPw = new PrintWriter(catSw); 1268 String[] emptyArgs = new String[] { }; 1269 StringBuilder tag = new StringBuilder(128); 1270 StringBuilder stack = new StringBuilder(128); 1271 tag.append("Low on memory -- "); 1272 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1273 tag, stack); 1274 dropBuilder.append(stack); 1275 dropBuilder.append('\n'); 1276 dropBuilder.append('\n'); 1277 String oomString = oomSw.toString(); 1278 dropBuilder.append(oomString); 1279 dropBuilder.append('\n'); 1280 logBuilder.append(oomString); 1281 try { 1282 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1283 "procrank", }); 1284 final InputStreamReader converter = new InputStreamReader( 1285 proc.getInputStream()); 1286 BufferedReader in = new BufferedReader(converter); 1287 String line; 1288 while (true) { 1289 line = in.readLine(); 1290 if (line == null) { 1291 break; 1292 } 1293 if (line.length() > 0) { 1294 logBuilder.append(line); 1295 logBuilder.append('\n'); 1296 } 1297 dropBuilder.append(line); 1298 dropBuilder.append('\n'); 1299 } 1300 converter.close(); 1301 } catch (IOException e) { 1302 } 1303 synchronized (ActivityManagerService.this) { 1304 catPw.println(); 1305 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1306 catPw.println(); 1307 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1308 false, false, null); 1309 catPw.println(); 1310 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1311 } 1312 dropBuilder.append(catSw.toString()); 1313 addErrorToDropBox("lowmem", null, "system_server", null, 1314 null, tag.toString(), dropBuilder.toString(), null, null); 1315 Slog.i(TAG, logBuilder.toString()); 1316 synchronized (ActivityManagerService.this) { 1317 long now = SystemClock.uptimeMillis(); 1318 if (mLastMemUsageReportTime < now) { 1319 mLastMemUsageReportTime = now; 1320 } 1321 } 1322 } 1323 }; 1324 thread.start(); 1325 break; 1326 } 1327 case REPORT_USER_SWITCH_MSG: { 1328 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1329 break; 1330 } 1331 case CONTINUE_USER_SWITCH_MSG: { 1332 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1333 break; 1334 } 1335 case USER_SWITCH_TIMEOUT_MSG: { 1336 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1337 break; 1338 } 1339 } 1340 } 1341 }; 1342 1343 public static void setSystemProcess() { 1344 try { 1345 ActivityManagerService m = mSelf; 1346 1347 ServiceManager.addService("activity", m, true); 1348 ServiceManager.addService("meminfo", new MemBinder(m)); 1349 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1350 ServiceManager.addService("dbinfo", new DbBinder(m)); 1351 if (MONITOR_CPU_USAGE) { 1352 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1353 } 1354 ServiceManager.addService("permission", new PermissionController(m)); 1355 1356 ApplicationInfo info = 1357 mSelf.mContext.getPackageManager().getApplicationInfo( 1358 "android", STOCK_PM_FLAGS); 1359 mSystemThread.installSystemApplicationInfo(info); 1360 1361 synchronized (mSelf) { 1362 ProcessRecord app = mSelf.newProcessRecordLocked( 1363 mSystemThread.getApplicationThread(), info, 1364 info.processName, false); 1365 app.persistent = true; 1366 app.pid = MY_PID; 1367 app.maxAdj = ProcessList.SYSTEM_ADJ; 1368 mSelf.mProcessNames.put(app.processName, app.uid, app); 1369 synchronized (mSelf.mPidsSelfLocked) { 1370 mSelf.mPidsSelfLocked.put(app.pid, app); 1371 } 1372 mSelf.updateLruProcessLocked(app, true, true); 1373 } 1374 } catch (PackageManager.NameNotFoundException e) { 1375 throw new RuntimeException( 1376 "Unable to find android system package", e); 1377 } 1378 } 1379 1380 public void setWindowManager(WindowManagerService wm) { 1381 mWindowManager = wm; 1382 } 1383 1384 public static final Context main(int factoryTest) { 1385 AThread thr = new AThread(); 1386 thr.start(); 1387 1388 synchronized (thr) { 1389 while (thr.mService == null) { 1390 try { 1391 thr.wait(); 1392 } catch (InterruptedException e) { 1393 } 1394 } 1395 } 1396 1397 ActivityManagerService m = thr.mService; 1398 mSelf = m; 1399 ActivityThread at = ActivityThread.systemMain(); 1400 mSystemThread = at; 1401 Context context = at.getSystemContext(); 1402 context.setTheme(android.R.style.Theme_Holo); 1403 m.mContext = context; 1404 m.mFactoryTest = factoryTest; 1405 m.mMainStack = new ActivityStack(m, context, true); 1406 1407 m.mBatteryStatsService.publish(context); 1408 m.mUsageStatsService.publish(context); 1409 1410 synchronized (thr) { 1411 thr.mReady = true; 1412 thr.notifyAll(); 1413 } 1414 1415 m.startRunning(null, null, null, null); 1416 1417 return context; 1418 } 1419 1420 public static ActivityManagerService self() { 1421 return mSelf; 1422 } 1423 1424 static class AThread extends Thread { 1425 ActivityManagerService mService; 1426 boolean mReady = false; 1427 1428 public AThread() { 1429 super("ActivityManager"); 1430 } 1431 1432 public void run() { 1433 Looper.prepare(); 1434 1435 android.os.Process.setThreadPriority( 1436 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1437 android.os.Process.setCanSelfBackground(false); 1438 1439 ActivityManagerService m = new ActivityManagerService(); 1440 1441 synchronized (this) { 1442 mService = m; 1443 notifyAll(); 1444 } 1445 1446 synchronized (this) { 1447 while (!mReady) { 1448 try { 1449 wait(); 1450 } catch (InterruptedException e) { 1451 } 1452 } 1453 } 1454 1455 // For debug builds, log event loop stalls to dropbox for analysis. 1456 if (StrictMode.conditionallyEnableDebugLogging()) { 1457 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1458 } 1459 1460 Looper.loop(); 1461 } 1462 } 1463 1464 static class MemBinder extends Binder { 1465 ActivityManagerService mActivityManagerService; 1466 MemBinder(ActivityManagerService activityManagerService) { 1467 mActivityManagerService = activityManagerService; 1468 } 1469 1470 @Override 1471 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1472 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1473 != PackageManager.PERMISSION_GRANTED) { 1474 pw.println("Permission Denial: can't dump meminfo from from pid=" 1475 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1476 + " without permission " + android.Manifest.permission.DUMP); 1477 return; 1478 } 1479 1480 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1481 false, null, null, null); 1482 } 1483 } 1484 1485 static class GraphicsBinder extends Binder { 1486 ActivityManagerService mActivityManagerService; 1487 GraphicsBinder(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 gfxinfo from from pid=" 1496 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1497 + " without permission " + android.Manifest.permission.DUMP); 1498 return; 1499 } 1500 1501 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1502 } 1503 } 1504 1505 static class DbBinder extends Binder { 1506 ActivityManagerService mActivityManagerService; 1507 DbBinder(ActivityManagerService activityManagerService) { 1508 mActivityManagerService = activityManagerService; 1509 } 1510 1511 @Override 1512 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1513 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1514 != PackageManager.PERMISSION_GRANTED) { 1515 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1516 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1517 + " without permission " + android.Manifest.permission.DUMP); 1518 return; 1519 } 1520 1521 mActivityManagerService.dumpDbInfo(fd, pw, args); 1522 } 1523 } 1524 1525 static class CpuBinder extends Binder { 1526 ActivityManagerService mActivityManagerService; 1527 CpuBinder(ActivityManagerService activityManagerService) { 1528 mActivityManagerService = activityManagerService; 1529 } 1530 1531 @Override 1532 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1533 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1534 != PackageManager.PERMISSION_GRANTED) { 1535 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1536 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1537 + " without permission " + android.Manifest.permission.DUMP); 1538 return; 1539 } 1540 1541 synchronized (mActivityManagerService.mProcessStatsThread) { 1542 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1543 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1544 SystemClock.uptimeMillis())); 1545 } 1546 } 1547 } 1548 1549 private ActivityManagerService() { 1550 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1551 1552 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1553 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1554 mBroadcastQueues[0] = mFgBroadcastQueue; 1555 mBroadcastQueues[1] = mBgBroadcastQueue; 1556 1557 mServices = new ActiveServices(this); 1558 mProviderMap = new ProviderMap(this); 1559 1560 File dataDir = Environment.getDataDirectory(); 1561 File systemDir = new File(dataDir, "system"); 1562 systemDir.mkdirs(); 1563 mBatteryStatsService = new BatteryStatsService(new File( 1564 systemDir, "batterystats.bin").toString()); 1565 mBatteryStatsService.getActiveStatistics().readLocked(); 1566 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1567 mOnBattery = DEBUG_POWER ? true 1568 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1569 mBatteryStatsService.getActiveStatistics().setCallback(this); 1570 1571 mUsageStatsService = new UsageStatsService(new File( 1572 systemDir, "usagestats").toString()); 1573 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1574 1575 // User 0 is the first and only user that runs at boot. 1576 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1577 mUserLru.add(Integer.valueOf(0)); 1578 updateStartedUserArrayLocked(); 1579 1580 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1581 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1582 1583 mConfiguration.setToDefaults(); 1584 mConfiguration.setLocale(Locale.getDefault()); 1585 1586 mConfigurationSeq = mConfiguration.seq = 1; 1587 mProcessStats.init(); 1588 1589 mCompatModePackages = new CompatModePackages(this, systemDir); 1590 1591 // Add ourself to the Watchdog monitors. 1592 Watchdog.getInstance().addMonitor(this); 1593 1594 mProcessStatsThread = new Thread("ProcessStats") { 1595 public void run() { 1596 while (true) { 1597 try { 1598 try { 1599 synchronized(this) { 1600 final long now = SystemClock.uptimeMillis(); 1601 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1602 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1603 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1604 // + ", write delay=" + nextWriteDelay); 1605 if (nextWriteDelay < nextCpuDelay) { 1606 nextCpuDelay = nextWriteDelay; 1607 } 1608 if (nextCpuDelay > 0) { 1609 mProcessStatsMutexFree.set(true); 1610 this.wait(nextCpuDelay); 1611 } 1612 } 1613 } catch (InterruptedException e) { 1614 } 1615 updateCpuStatsNow(); 1616 } catch (Exception e) { 1617 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1618 } 1619 } 1620 } 1621 }; 1622 mProcessStatsThread.start(); 1623 } 1624 1625 @Override 1626 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1627 throws RemoteException { 1628 if (code == SYSPROPS_TRANSACTION) { 1629 // We need to tell all apps about the system property change. 1630 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1631 synchronized(this) { 1632 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1633 final int NA = apps.size(); 1634 for (int ia=0; ia<NA; ia++) { 1635 ProcessRecord app = apps.valueAt(ia); 1636 if (app.thread != null) { 1637 procs.add(app.thread.asBinder()); 1638 } 1639 } 1640 } 1641 } 1642 1643 int N = procs.size(); 1644 for (int i=0; i<N; i++) { 1645 Parcel data2 = Parcel.obtain(); 1646 try { 1647 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1648 } catch (RemoteException e) { 1649 } 1650 data2.recycle(); 1651 } 1652 } 1653 try { 1654 return super.onTransact(code, data, reply, flags); 1655 } catch (RuntimeException e) { 1656 // The activity manager only throws security exceptions, so let's 1657 // log all others. 1658 if (!(e instanceof SecurityException)) { 1659 Slog.e(TAG, "Activity Manager Crash", e); 1660 } 1661 throw e; 1662 } 1663 } 1664 1665 void updateCpuStats() { 1666 final long now = SystemClock.uptimeMillis(); 1667 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1668 return; 1669 } 1670 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1671 synchronized (mProcessStatsThread) { 1672 mProcessStatsThread.notify(); 1673 } 1674 } 1675 } 1676 1677 void updateCpuStatsNow() { 1678 synchronized (mProcessStatsThread) { 1679 mProcessStatsMutexFree.set(false); 1680 final long now = SystemClock.uptimeMillis(); 1681 boolean haveNewCpuStats = false; 1682 1683 if (MONITOR_CPU_USAGE && 1684 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1685 mLastCpuTime.set(now); 1686 haveNewCpuStats = true; 1687 mProcessStats.update(); 1688 //Slog.i(TAG, mProcessStats.printCurrentState()); 1689 //Slog.i(TAG, "Total CPU usage: " 1690 // + mProcessStats.getTotalCpuPercent() + "%"); 1691 1692 // Slog the cpu usage if the property is set. 1693 if ("true".equals(SystemProperties.get("events.cpu"))) { 1694 int user = mProcessStats.getLastUserTime(); 1695 int system = mProcessStats.getLastSystemTime(); 1696 int iowait = mProcessStats.getLastIoWaitTime(); 1697 int irq = mProcessStats.getLastIrqTime(); 1698 int softIrq = mProcessStats.getLastSoftIrqTime(); 1699 int idle = mProcessStats.getLastIdleTime(); 1700 1701 int total = user + system + iowait + irq + softIrq + idle; 1702 if (total == 0) total = 1; 1703 1704 EventLog.writeEvent(EventLogTags.CPU, 1705 ((user+system+iowait+irq+softIrq) * 100) / total, 1706 (user * 100) / total, 1707 (system * 100) / total, 1708 (iowait * 100) / total, 1709 (irq * 100) / total, 1710 (softIrq * 100) / total); 1711 } 1712 } 1713 1714 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1715 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1716 synchronized(bstats) { 1717 synchronized(mPidsSelfLocked) { 1718 if (haveNewCpuStats) { 1719 if (mOnBattery) { 1720 int perc = bstats.startAddingCpuLocked(); 1721 int totalUTime = 0; 1722 int totalSTime = 0; 1723 final int N = mProcessStats.countStats(); 1724 for (int i=0; i<N; i++) { 1725 ProcessStats.Stats st = mProcessStats.getStats(i); 1726 if (!st.working) { 1727 continue; 1728 } 1729 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1730 int otherUTime = (st.rel_utime*perc)/100; 1731 int otherSTime = (st.rel_stime*perc)/100; 1732 totalUTime += otherUTime; 1733 totalSTime += otherSTime; 1734 if (pr != null) { 1735 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1736 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1737 st.rel_stime-otherSTime); 1738 ps.addSpeedStepTimes(cpuSpeedTimes); 1739 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1740 } else { 1741 BatteryStatsImpl.Uid.Proc ps = 1742 bstats.getProcessStatsLocked(st.name, st.pid); 1743 if (ps != null) { 1744 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1745 st.rel_stime-otherSTime); 1746 ps.addSpeedStepTimes(cpuSpeedTimes); 1747 } 1748 } 1749 } 1750 bstats.finishAddingCpuLocked(perc, totalUTime, 1751 totalSTime, cpuSpeedTimes); 1752 } 1753 } 1754 } 1755 1756 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1757 mLastWriteTime = now; 1758 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1759 } 1760 } 1761 } 1762 } 1763 1764 @Override 1765 public void batteryNeedsCpuUpdate() { 1766 updateCpuStatsNow(); 1767 } 1768 1769 @Override 1770 public void batteryPowerChanged(boolean onBattery) { 1771 // When plugging in, update the CPU stats first before changing 1772 // the plug state. 1773 updateCpuStatsNow(); 1774 synchronized (this) { 1775 synchronized(mPidsSelfLocked) { 1776 mOnBattery = DEBUG_POWER ? true : onBattery; 1777 } 1778 } 1779 } 1780 1781 /** 1782 * Initialize the application bind args. These are passed to each 1783 * process when the bindApplication() IPC is sent to the process. They're 1784 * lazily setup to make sure the services are running when they're asked for. 1785 */ 1786 private HashMap<String, IBinder> getCommonServicesLocked() { 1787 if (mAppBindArgs == null) { 1788 mAppBindArgs = new HashMap<String, IBinder>(); 1789 1790 // Setup the application init args 1791 mAppBindArgs.put("package", ServiceManager.getService("package")); 1792 mAppBindArgs.put("window", ServiceManager.getService("window")); 1793 mAppBindArgs.put(Context.ALARM_SERVICE, 1794 ServiceManager.getService(Context.ALARM_SERVICE)); 1795 } 1796 return mAppBindArgs; 1797 } 1798 1799 final void setFocusedActivityLocked(ActivityRecord r) { 1800 if (mFocusedActivity != r) { 1801 mFocusedActivity = r; 1802 if (r != null) { 1803 mWindowManager.setFocusedApp(r.appToken, true); 1804 } 1805 } 1806 } 1807 1808 private final void updateLruProcessInternalLocked(ProcessRecord app, 1809 boolean updateActivityTime, int bestPos) { 1810 // put it on the LRU to keep track of when it should be exited. 1811 int lrui = mLruProcesses.indexOf(app); 1812 if (lrui >= 0) mLruProcesses.remove(lrui); 1813 1814 int i = mLruProcesses.size()-1; 1815 int skipTop = 0; 1816 1817 app.lruSeq = mLruSeq; 1818 1819 // compute the new weight for this process. 1820 if (updateActivityTime) { 1821 app.lastActivityTime = SystemClock.uptimeMillis(); 1822 } 1823 if (app.activities.size() > 0) { 1824 // If this process has activities, we more strongly want to keep 1825 // it around. 1826 app.lruWeight = app.lastActivityTime; 1827 } else if (app.pubProviders.size() > 0) { 1828 // If this process contains content providers, we want to keep 1829 // it a little more strongly. 1830 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1831 // Also don't let it kick out the first few "real" hidden processes. 1832 skipTop = ProcessList.MIN_HIDDEN_APPS; 1833 } else { 1834 // If this process doesn't have activities, we less strongly 1835 // want to keep it around, and generally want to avoid getting 1836 // in front of any very recently used activities. 1837 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1838 // Also don't let it kick out the first few "real" hidden processes. 1839 skipTop = ProcessList.MIN_HIDDEN_APPS; 1840 } 1841 1842 while (i >= 0) { 1843 ProcessRecord p = mLruProcesses.get(i); 1844 // If this app shouldn't be in front of the first N background 1845 // apps, then skip over that many that are currently hidden. 1846 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1847 skipTop--; 1848 } 1849 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1850 mLruProcesses.add(i+1, app); 1851 break; 1852 } 1853 i--; 1854 } 1855 if (i < 0) { 1856 mLruProcesses.add(0, app); 1857 } 1858 1859 // If the app is currently using a content provider or service, 1860 // bump those processes as well. 1861 if (app.connections.size() > 0) { 1862 for (ConnectionRecord cr : app.connections) { 1863 if (cr.binding != null && cr.binding.service != null 1864 && cr.binding.service.app != null 1865 && cr.binding.service.app.lruSeq != mLruSeq) { 1866 updateLruProcessInternalLocked(cr.binding.service.app, 1867 updateActivityTime, i+1); 1868 } 1869 } 1870 } 1871 for (int j=app.conProviders.size()-1; j>=0; j--) { 1872 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1873 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1874 updateLruProcessInternalLocked(cpr.proc, 1875 updateActivityTime, i+1); 1876 } 1877 } 1878 } 1879 1880 final void updateLruProcessLocked(ProcessRecord app, 1881 boolean oomAdj, boolean updateActivityTime) { 1882 mLruSeq++; 1883 updateLruProcessInternalLocked(app, updateActivityTime, 0); 1884 1885 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1886 if (oomAdj) { 1887 updateOomAdjLocked(); 1888 } 1889 } 1890 1891 final ProcessRecord getProcessRecordLocked( 1892 String processName, int uid) { 1893 if (uid == Process.SYSTEM_UID) { 1894 // The system gets to run in any process. If there are multiple 1895 // processes with the same uid, just pick the first (this 1896 // should never happen). 1897 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1898 processName); 1899 if (procs == null) return null; 1900 final int N = procs.size(); 1901 for (int i = 0; i < N; i++) { 1902 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1903 } 1904 } 1905 ProcessRecord proc = mProcessNames.get(processName, uid); 1906 return proc; 1907 } 1908 1909 void ensurePackageDexOpt(String packageName) { 1910 IPackageManager pm = AppGlobals.getPackageManager(); 1911 try { 1912 if (pm.performDexOpt(packageName)) { 1913 mDidDexOpt = true; 1914 } 1915 } catch (RemoteException e) { 1916 } 1917 } 1918 1919 boolean isNextTransitionForward() { 1920 int transit = mWindowManager.getPendingAppTransition(); 1921 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1922 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1923 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1924 } 1925 1926 final ProcessRecord startProcessLocked(String processName, 1927 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1928 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1929 boolean isolated) { 1930 ProcessRecord app; 1931 if (!isolated) { 1932 app = getProcessRecordLocked(processName, info.uid); 1933 } else { 1934 // If this is an isolated process, it can't re-use an existing process. 1935 app = null; 1936 } 1937 // We don't have to do anything more if: 1938 // (1) There is an existing application record; and 1939 // (2) The caller doesn't think it is dead, OR there is no thread 1940 // object attached to it so we know it couldn't have crashed; and 1941 // (3) There is a pid assigned to it, so it is either starting or 1942 // already running. 1943 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1944 + " app=" + app + " knownToBeDead=" + knownToBeDead 1945 + " thread=" + (app != null ? app.thread : null) 1946 + " pid=" + (app != null ? app.pid : -1)); 1947 if (app != null && app.pid > 0) { 1948 if (!knownToBeDead || app.thread == null) { 1949 // We already have the app running, or are waiting for it to 1950 // come up (we have a pid but not yet its thread), so keep it. 1951 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1952 // If this is a new package in the process, add the package to the list 1953 app.addPackage(info.packageName); 1954 return app; 1955 } else { 1956 // An application record is attached to a previous process, 1957 // clean it up now. 1958 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1959 handleAppDiedLocked(app, true, true); 1960 } 1961 } 1962 1963 String hostingNameStr = hostingName != null 1964 ? hostingName.flattenToShortString() : null; 1965 1966 if (!isolated) { 1967 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1968 // If we are in the background, then check to see if this process 1969 // is bad. If so, we will just silently fail. 1970 if (mBadProcesses.get(info.processName, info.uid) != null) { 1971 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1972 + "/" + info.processName); 1973 return null; 1974 } 1975 } else { 1976 // When the user is explicitly starting a process, then clear its 1977 // crash count so that we won't make it bad until they see at 1978 // least one crash dialog again, and make the process good again 1979 // if it had been bad. 1980 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1981 + "/" + info.processName); 1982 mProcessCrashTimes.remove(info.processName, info.uid); 1983 if (mBadProcesses.get(info.processName, info.uid) != null) { 1984 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1985 info.processName); 1986 mBadProcesses.remove(info.processName, info.uid); 1987 if (app != null) { 1988 app.bad = false; 1989 } 1990 } 1991 } 1992 } 1993 1994 if (app == null) { 1995 app = newProcessRecordLocked(null, info, processName, isolated); 1996 if (app == null) { 1997 Slog.w(TAG, "Failed making new process record for " 1998 + processName + "/" + info.uid + " isolated=" + isolated); 1999 return null; 2000 } 2001 mProcessNames.put(processName, app.uid, app); 2002 if (isolated) { 2003 mIsolatedProcesses.put(app.uid, app); 2004 } 2005 } else { 2006 // If this is a new package in the process, add the package to the list 2007 app.addPackage(info.packageName); 2008 } 2009 2010 // If the system is not ready yet, then hold off on starting this 2011 // process until it is. 2012 if (!mProcessesReady 2013 && !isAllowedWhileBooting(info) 2014 && !allowWhileBooting) { 2015 if (!mProcessesOnHold.contains(app)) { 2016 mProcessesOnHold.add(app); 2017 } 2018 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2019 return app; 2020 } 2021 2022 startProcessLocked(app, hostingType, hostingNameStr); 2023 return (app.pid != 0) ? app : null; 2024 } 2025 2026 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2027 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2028 } 2029 2030 private final void startProcessLocked(ProcessRecord app, 2031 String hostingType, String hostingNameStr) { 2032 if (app.pid > 0 && app.pid != MY_PID) { 2033 synchronized (mPidsSelfLocked) { 2034 mPidsSelfLocked.remove(app.pid); 2035 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2036 } 2037 app.setPid(0); 2038 } 2039 2040 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2041 "startProcessLocked removing on hold: " + app); 2042 mProcessesOnHold.remove(app); 2043 2044 updateCpuStats(); 2045 2046 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2047 mProcDeaths[0] = 0; 2048 2049 try { 2050 int uid = app.uid; 2051 2052 int[] gids = null; 2053 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2054 if (!app.isolated) { 2055 int[] permGids = null; 2056 try { 2057 final PackageManager pm = mContext.getPackageManager(); 2058 permGids = pm.getPackageGids(app.info.packageName); 2059 2060 if (Environment.isExternalStorageEmulated()) { 2061 if (pm.checkPermission( 2062 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2063 app.info.packageName) == PERMISSION_GRANTED) { 2064 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2065 } else { 2066 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2067 } 2068 } 2069 } catch (PackageManager.NameNotFoundException e) { 2070 Slog.w(TAG, "Unable to retrieve gids", e); 2071 } 2072 2073 /* 2074 * Add shared application GID so applications can share some 2075 * resources like shared libraries 2076 */ 2077 if (permGids == null) { 2078 gids = new int[1]; 2079 } else { 2080 gids = new int[permGids.length + 1]; 2081 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2082 } 2083 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2084 } 2085 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2086 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2087 && mTopComponent != null 2088 && app.processName.equals(mTopComponent.getPackageName())) { 2089 uid = 0; 2090 } 2091 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2092 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2093 uid = 0; 2094 } 2095 } 2096 int debugFlags = 0; 2097 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2098 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2099 // Also turn on CheckJNI for debuggable apps. It's quite 2100 // awkward to turn on otherwise. 2101 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2102 } 2103 // Run the app in safe mode if its manifest requests so or the 2104 // system is booted in safe mode. 2105 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2106 Zygote.systemInSafeMode == true) { 2107 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2108 } 2109 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2110 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2111 } 2112 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2113 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2114 } 2115 if ("1".equals(SystemProperties.get("debug.assert"))) { 2116 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2117 } 2118 2119 // Start the process. It will either succeed and return a result containing 2120 // the PID of the new process, or else throw a RuntimeException. 2121 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2122 app.processName, uid, uid, gids, debugFlags, mountExternal, 2123 app.info.targetSdkVersion, null, null); 2124 2125 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2126 synchronized (bs) { 2127 if (bs.isOnBattery()) { 2128 app.batteryStats.incStartsLocked(); 2129 } 2130 } 2131 2132 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2133 app.processName, hostingType, 2134 hostingNameStr != null ? hostingNameStr : ""); 2135 2136 if (app.persistent) { 2137 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2138 } 2139 2140 StringBuilder buf = mStringBuilder; 2141 buf.setLength(0); 2142 buf.append("Start proc "); 2143 buf.append(app.processName); 2144 buf.append(" for "); 2145 buf.append(hostingType); 2146 if (hostingNameStr != null) { 2147 buf.append(" "); 2148 buf.append(hostingNameStr); 2149 } 2150 buf.append(": pid="); 2151 buf.append(startResult.pid); 2152 buf.append(" uid="); 2153 buf.append(uid); 2154 buf.append(" gids={"); 2155 if (gids != null) { 2156 for (int gi=0; gi<gids.length; gi++) { 2157 if (gi != 0) buf.append(", "); 2158 buf.append(gids[gi]); 2159 2160 } 2161 } 2162 buf.append("}"); 2163 Slog.i(TAG, buf.toString()); 2164 app.setPid(startResult.pid); 2165 app.usingWrapper = startResult.usingWrapper; 2166 app.removed = false; 2167 synchronized (mPidsSelfLocked) { 2168 this.mPidsSelfLocked.put(startResult.pid, app); 2169 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2170 msg.obj = app; 2171 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2172 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2173 } 2174 } catch (RuntimeException e) { 2175 // XXX do better error recovery. 2176 app.setPid(0); 2177 Slog.e(TAG, "Failure starting process " + app.processName, e); 2178 } 2179 } 2180 2181 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2182 if (resumed) { 2183 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2184 } else { 2185 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2186 } 2187 } 2188 2189 boolean startHomeActivityLocked(int userId) { 2190 if (mHeadless) { 2191 // Added because none of the other calls to ensureBootCompleted seem to fire 2192 // when running headless. 2193 ensureBootCompleted(); 2194 return false; 2195 } 2196 2197 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2198 && mTopAction == null) { 2199 // We are running in factory test mode, but unable to find 2200 // the factory test app, so just sit around displaying the 2201 // error message and don't try to start anything. 2202 return false; 2203 } 2204 Intent intent = new Intent( 2205 mTopAction, 2206 mTopData != null ? Uri.parse(mTopData) : null); 2207 intent.setComponent(mTopComponent); 2208 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2209 intent.addCategory(Intent.CATEGORY_HOME); 2210 } 2211 ActivityInfo aInfo = 2212 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2213 if (aInfo != null) { 2214 intent.setComponent(new ComponentName( 2215 aInfo.applicationInfo.packageName, aInfo.name)); 2216 // Don't do this if the home app is currently being 2217 // instrumented. 2218 aInfo = new ActivityInfo(aInfo); 2219 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2220 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2221 aInfo.applicationInfo.uid); 2222 if (app == null || app.instrumentationClass == null) { 2223 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2224 mMainStack.startActivityLocked(null, intent, null, aInfo, 2225 null, null, 0, 0, 0, 0, null, false, null); 2226 } 2227 } 2228 2229 return true; 2230 } 2231 2232 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2233 ActivityInfo ai = null; 2234 ComponentName comp = intent.getComponent(); 2235 try { 2236 if (comp != null) { 2237 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2238 } else { 2239 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2240 intent, 2241 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2242 flags, userId); 2243 2244 if (info != null) { 2245 ai = info.activityInfo; 2246 } 2247 } 2248 } catch (RemoteException e) { 2249 // ignore 2250 } 2251 2252 return ai; 2253 } 2254 2255 /** 2256 * Starts the "new version setup screen" if appropriate. 2257 */ 2258 void startSetupActivityLocked() { 2259 // Only do this once per boot. 2260 if (mCheckedForSetup) { 2261 return; 2262 } 2263 2264 // We will show this screen if the current one is a different 2265 // version than the last one shown, and we are not running in 2266 // low-level factory test mode. 2267 final ContentResolver resolver = mContext.getContentResolver(); 2268 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2269 Settings.Secure.getInt(resolver, 2270 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2271 mCheckedForSetup = true; 2272 2273 // See if we should be showing the platform update setup UI. 2274 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2275 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2276 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2277 2278 // We don't allow third party apps to replace this. 2279 ResolveInfo ri = null; 2280 for (int i=0; ris != null && i<ris.size(); i++) { 2281 if ((ris.get(i).activityInfo.applicationInfo.flags 2282 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2283 ri = ris.get(i); 2284 break; 2285 } 2286 } 2287 2288 if (ri != null) { 2289 String vers = ri.activityInfo.metaData != null 2290 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2291 : null; 2292 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2293 vers = ri.activityInfo.applicationInfo.metaData.getString( 2294 Intent.METADATA_SETUP_VERSION); 2295 } 2296 String lastVers = Settings.Secure.getString( 2297 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2298 if (vers != null && !vers.equals(lastVers)) { 2299 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2300 intent.setComponent(new ComponentName( 2301 ri.activityInfo.packageName, ri.activityInfo.name)); 2302 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2303 null, null, 0, 0, 0, 0, null, false, null); 2304 } 2305 } 2306 } 2307 } 2308 2309 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2310 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2311 } 2312 2313 void enforceNotIsolatedCaller(String caller) { 2314 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2315 throw new SecurityException("Isolated process not allowed to call " + caller); 2316 } 2317 } 2318 2319 public int getFrontActivityScreenCompatMode() { 2320 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2321 synchronized (this) { 2322 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2323 } 2324 } 2325 2326 public void setFrontActivityScreenCompatMode(int mode) { 2327 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2328 "setFrontActivityScreenCompatMode"); 2329 synchronized (this) { 2330 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2331 } 2332 } 2333 2334 public int getPackageScreenCompatMode(String packageName) { 2335 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2336 synchronized (this) { 2337 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2338 } 2339 } 2340 2341 public void setPackageScreenCompatMode(String packageName, int mode) { 2342 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2343 "setPackageScreenCompatMode"); 2344 synchronized (this) { 2345 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2346 } 2347 } 2348 2349 public boolean getPackageAskScreenCompat(String packageName) { 2350 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2351 synchronized (this) { 2352 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2353 } 2354 } 2355 2356 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2357 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2358 "setPackageAskScreenCompat"); 2359 synchronized (this) { 2360 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2361 } 2362 } 2363 2364 void reportResumedActivityLocked(ActivityRecord r) { 2365 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2366 updateUsageStats(r, true); 2367 } 2368 2369 private void dispatchProcessesChanged() { 2370 int N; 2371 synchronized (this) { 2372 N = mPendingProcessChanges.size(); 2373 if (mActiveProcessChanges.length < N) { 2374 mActiveProcessChanges = new ProcessChangeItem[N]; 2375 } 2376 mPendingProcessChanges.toArray(mActiveProcessChanges); 2377 mAvailProcessChanges.addAll(mPendingProcessChanges); 2378 mPendingProcessChanges.clear(); 2379 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2380 } 2381 int i = mProcessObservers.beginBroadcast(); 2382 while (i > 0) { 2383 i--; 2384 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2385 if (observer != null) { 2386 try { 2387 for (int j=0; j<N; j++) { 2388 ProcessChangeItem item = mActiveProcessChanges[j]; 2389 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2390 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2391 + item.pid + " uid=" + item.uid + ": " 2392 + item.foregroundActivities); 2393 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2394 item.foregroundActivities); 2395 } 2396 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2398 + item.pid + " uid=" + item.uid + ": " + item.importance); 2399 observer.onImportanceChanged(item.pid, item.uid, 2400 item.importance); 2401 } 2402 } 2403 } catch (RemoteException e) { 2404 } 2405 } 2406 } 2407 mProcessObservers.finishBroadcast(); 2408 } 2409 2410 private void dispatchProcessDied(int pid, int uid) { 2411 int i = mProcessObservers.beginBroadcast(); 2412 while (i > 0) { 2413 i--; 2414 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2415 if (observer != null) { 2416 try { 2417 observer.onProcessDied(pid, uid); 2418 } catch (RemoteException e) { 2419 } 2420 } 2421 } 2422 mProcessObservers.finishBroadcast(); 2423 } 2424 2425 final void doPendingActivityLaunchesLocked(boolean doResume) { 2426 final int N = mPendingActivityLaunches.size(); 2427 if (N <= 0) { 2428 return; 2429 } 2430 for (int i=0; i<N; i++) { 2431 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2432 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2433 pal.startFlags, doResume && i == (N-1), null); 2434 } 2435 mPendingActivityLaunches.clear(); 2436 } 2437 2438 public final int startActivity(IApplicationThread caller, 2439 Intent intent, String resolvedType, IBinder resultTo, 2440 String resultWho, int requestCode, int startFlags, 2441 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2442 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2443 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2444 } 2445 2446 public final int startActivityAsUser(IApplicationThread caller, 2447 Intent intent, String resolvedType, IBinder resultTo, 2448 String resultWho, int requestCode, int startFlags, 2449 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2450 enforceNotIsolatedCaller("startActivity"); 2451 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2452 false, true, "startActivity", null); 2453 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2454 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2455 null, null, options, userId); 2456 } 2457 2458 public final WaitResult startActivityAndWait(IApplicationThread caller, 2459 Intent intent, String resolvedType, IBinder resultTo, 2460 String resultWho, int requestCode, int startFlags, String profileFile, 2461 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2462 enforceNotIsolatedCaller("startActivityAndWait"); 2463 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2464 false, true, "startActivityAndWait", null); 2465 WaitResult res = new WaitResult(); 2466 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2467 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2468 res, null, options, UserHandle.getCallingUserId()); 2469 return res; 2470 } 2471 2472 public final int startActivityWithConfig(IApplicationThread caller, 2473 Intent intent, String resolvedType, IBinder resultTo, 2474 String resultWho, int requestCode, int startFlags, Configuration config, 2475 Bundle options, int userId) { 2476 enforceNotIsolatedCaller("startActivityWithConfig"); 2477 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2478 false, true, "startActivityWithConfig", null); 2479 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2480 resultTo, resultWho, requestCode, startFlags, 2481 null, null, null, config, options, userId); 2482 return ret; 2483 } 2484 2485 public int startActivityIntentSender(IApplicationThread caller, 2486 IntentSender intent, Intent fillInIntent, String resolvedType, 2487 IBinder resultTo, String resultWho, int requestCode, 2488 int flagsMask, int flagsValues, Bundle options) { 2489 enforceNotIsolatedCaller("startActivityIntentSender"); 2490 // Refuse possible leaked file descriptors 2491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2492 throw new IllegalArgumentException("File descriptors passed in Intent"); 2493 } 2494 2495 IIntentSender sender = intent.getTarget(); 2496 if (!(sender instanceof PendingIntentRecord)) { 2497 throw new IllegalArgumentException("Bad PendingIntent object"); 2498 } 2499 2500 PendingIntentRecord pir = (PendingIntentRecord)sender; 2501 2502 synchronized (this) { 2503 // If this is coming from the currently resumed activity, it is 2504 // effectively saying that app switches are allowed at this point. 2505 if (mMainStack.mResumedActivity != null 2506 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2507 Binder.getCallingUid()) { 2508 mAppSwitchesAllowedTime = 0; 2509 } 2510 } 2511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2512 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2513 return ret; 2514 } 2515 2516 public boolean startNextMatchingActivity(IBinder callingActivity, 2517 Intent intent, Bundle options) { 2518 // Refuse possible leaked file descriptors 2519 if (intent != null && intent.hasFileDescriptors() == true) { 2520 throw new IllegalArgumentException("File descriptors passed in Intent"); 2521 } 2522 2523 synchronized (this) { 2524 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2525 if (r == null) { 2526 ActivityOptions.abort(options); 2527 return false; 2528 } 2529 if (r.app == null || r.app.thread == null) { 2530 // The caller is not running... d'oh! 2531 ActivityOptions.abort(options); 2532 return false; 2533 } 2534 intent = new Intent(intent); 2535 // The caller is not allowed to change the data. 2536 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2537 // And we are resetting to find the next component... 2538 intent.setComponent(null); 2539 2540 ActivityInfo aInfo = null; 2541 try { 2542 List<ResolveInfo> resolves = 2543 AppGlobals.getPackageManager().queryIntentActivities( 2544 intent, r.resolvedType, 2545 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2546 UserHandle.getCallingUserId()); 2547 2548 // Look for the original activity in the list... 2549 final int N = resolves != null ? resolves.size() : 0; 2550 for (int i=0; i<N; i++) { 2551 ResolveInfo rInfo = resolves.get(i); 2552 if (rInfo.activityInfo.packageName.equals(r.packageName) 2553 && rInfo.activityInfo.name.equals(r.info.name)) { 2554 // We found the current one... the next matching is 2555 // after it. 2556 i++; 2557 if (i<N) { 2558 aInfo = resolves.get(i).activityInfo; 2559 } 2560 break; 2561 } 2562 } 2563 } catch (RemoteException e) { 2564 } 2565 2566 if (aInfo == null) { 2567 // Nobody who is next! 2568 ActivityOptions.abort(options); 2569 return false; 2570 } 2571 2572 intent.setComponent(new ComponentName( 2573 aInfo.applicationInfo.packageName, aInfo.name)); 2574 intent.setFlags(intent.getFlags()&~( 2575 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2576 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2577 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2578 Intent.FLAG_ACTIVITY_NEW_TASK)); 2579 2580 // Okay now we need to start the new activity, replacing the 2581 // currently running activity. This is a little tricky because 2582 // we want to start the new one as if the current one is finished, 2583 // but not finish the current one first so that there is no flicker. 2584 // And thus... 2585 final boolean wasFinishing = r.finishing; 2586 r.finishing = true; 2587 2588 // Propagate reply information over to the new activity. 2589 final ActivityRecord resultTo = r.resultTo; 2590 final String resultWho = r.resultWho; 2591 final int requestCode = r.requestCode; 2592 r.resultTo = null; 2593 if (resultTo != null) { 2594 resultTo.removeResultsLocked(r, resultWho, requestCode); 2595 } 2596 2597 final long origId = Binder.clearCallingIdentity(); 2598 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2599 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2600 resultWho, requestCode, -1, r.launchedFromUid, 0, 2601 options, false, null); 2602 Binder.restoreCallingIdentity(origId); 2603 2604 r.finishing = wasFinishing; 2605 if (res != ActivityManager.START_SUCCESS) { 2606 return false; 2607 } 2608 return true; 2609 } 2610 } 2611 2612 final int startActivityInPackage(int uid, 2613 Intent intent, String resolvedType, IBinder resultTo, 2614 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2615 2616 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2617 false, true, "startActivityInPackage", null); 2618 2619 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2620 resultTo, resultWho, requestCode, startFlags, 2621 null, null, null, null, options, userId); 2622 return ret; 2623 } 2624 2625 public final int startActivities(IApplicationThread caller, 2626 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2627 int userId) { 2628 enforceNotIsolatedCaller("startActivities"); 2629 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2630 false, true, "startActivity", null); 2631 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2632 options, userId); 2633 return ret; 2634 } 2635 2636 final int startActivitiesInPackage(int uid, 2637 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2638 Bundle options, int userId) { 2639 2640 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2641 false, true, "startActivityInPackage", null); 2642 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2643 options, userId); 2644 return ret; 2645 } 2646 2647 final void addRecentTaskLocked(TaskRecord task) { 2648 int N = mRecentTasks.size(); 2649 // Quick case: check if the top-most recent task is the same. 2650 if (N > 0 && mRecentTasks.get(0) == task) { 2651 return; 2652 } 2653 // Remove any existing entries that are the same kind of task. 2654 for (int i=0; i<N; i++) { 2655 TaskRecord tr = mRecentTasks.get(i); 2656 if (task.userId == tr.userId 2657 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2658 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2659 mRecentTasks.remove(i); 2660 i--; 2661 N--; 2662 if (task.intent == null) { 2663 // If the new recent task we are adding is not fully 2664 // specified, then replace it with the existing recent task. 2665 task = tr; 2666 } 2667 } 2668 } 2669 if (N >= MAX_RECENT_TASKS) { 2670 mRecentTasks.remove(N-1); 2671 } 2672 mRecentTasks.add(0, task); 2673 } 2674 2675 public void setRequestedOrientation(IBinder token, 2676 int requestedOrientation) { 2677 synchronized (this) { 2678 ActivityRecord r = mMainStack.isInStackLocked(token); 2679 if (r == null) { 2680 return; 2681 } 2682 final long origId = Binder.clearCallingIdentity(); 2683 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2684 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2685 mConfiguration, 2686 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2687 if (config != null) { 2688 r.frozenBeforeDestroy = true; 2689 if (!updateConfigurationLocked(config, r, false, false)) { 2690 mMainStack.resumeTopActivityLocked(null); 2691 } 2692 } 2693 Binder.restoreCallingIdentity(origId); 2694 } 2695 } 2696 2697 public int getRequestedOrientation(IBinder token) { 2698 synchronized (this) { 2699 ActivityRecord r = mMainStack.isInStackLocked(token); 2700 if (r == null) { 2701 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2702 } 2703 return mWindowManager.getAppOrientation(r.appToken); 2704 } 2705 } 2706 2707 /** 2708 * This is the internal entry point for handling Activity.finish(). 2709 * 2710 * @param token The Binder token referencing the Activity we want to finish. 2711 * @param resultCode Result code, if any, from this Activity. 2712 * @param resultData Result data (Intent), if any, from this Activity. 2713 * 2714 * @return Returns true if the activity successfully finished, or false if it is still running. 2715 */ 2716 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2717 // Refuse possible leaked file descriptors 2718 if (resultData != null && resultData.hasFileDescriptors() == true) { 2719 throw new IllegalArgumentException("File descriptors passed in Intent"); 2720 } 2721 2722 synchronized(this) { 2723 if (mController != null) { 2724 // Find the first activity that is not finishing. 2725 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2726 if (next != null) { 2727 // ask watcher if this is allowed 2728 boolean resumeOK = true; 2729 try { 2730 resumeOK = mController.activityResuming(next.packageName); 2731 } catch (RemoteException e) { 2732 mController = null; 2733 } 2734 2735 if (!resumeOK) { 2736 return false; 2737 } 2738 } 2739 } 2740 final long origId = Binder.clearCallingIdentity(); 2741 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2742 resultData, "app-request", true); 2743 Binder.restoreCallingIdentity(origId); 2744 return res; 2745 } 2746 } 2747 2748 public final void finishHeavyWeightApp() { 2749 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2750 != PackageManager.PERMISSION_GRANTED) { 2751 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2752 + Binder.getCallingPid() 2753 + ", uid=" + Binder.getCallingUid() 2754 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2755 Slog.w(TAG, msg); 2756 throw new SecurityException(msg); 2757 } 2758 2759 synchronized(this) { 2760 if (mHeavyWeightProcess == null) { 2761 return; 2762 } 2763 2764 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2765 mHeavyWeightProcess.activities); 2766 for (int i=0; i<activities.size(); i++) { 2767 ActivityRecord r = activities.get(i); 2768 if (!r.finishing) { 2769 int index = mMainStack.indexOfTokenLocked(r.appToken); 2770 if (index >= 0) { 2771 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2772 null, "finish-heavy", true); 2773 } 2774 } 2775 } 2776 2777 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2778 mHeavyWeightProcess.userId, 0)); 2779 mHeavyWeightProcess = null; 2780 } 2781 } 2782 2783 public void crashApplication(int uid, int initialPid, String packageName, 2784 String message) { 2785 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2786 != PackageManager.PERMISSION_GRANTED) { 2787 String msg = "Permission Denial: crashApplication() from pid=" 2788 + Binder.getCallingPid() 2789 + ", uid=" + Binder.getCallingUid() 2790 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2791 Slog.w(TAG, msg); 2792 throw new SecurityException(msg); 2793 } 2794 2795 synchronized(this) { 2796 ProcessRecord proc = null; 2797 2798 // Figure out which process to kill. We don't trust that initialPid 2799 // still has any relation to current pids, so must scan through the 2800 // list. 2801 synchronized (mPidsSelfLocked) { 2802 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2803 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2804 if (p.uid != uid) { 2805 continue; 2806 } 2807 if (p.pid == initialPid) { 2808 proc = p; 2809 break; 2810 } 2811 for (String str : p.pkgList) { 2812 if (str.equals(packageName)) { 2813 proc = p; 2814 } 2815 } 2816 } 2817 } 2818 2819 if (proc == null) { 2820 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2821 + " initialPid=" + initialPid 2822 + " packageName=" + packageName); 2823 return; 2824 } 2825 2826 if (proc.thread != null) { 2827 if (proc.pid == Process.myPid()) { 2828 Log.w(TAG, "crashApplication: trying to crash self!"); 2829 return; 2830 } 2831 long ident = Binder.clearCallingIdentity(); 2832 try { 2833 proc.thread.scheduleCrash(message); 2834 } catch (RemoteException e) { 2835 } 2836 Binder.restoreCallingIdentity(ident); 2837 } 2838 } 2839 } 2840 2841 public final void finishSubActivity(IBinder token, String resultWho, 2842 int requestCode) { 2843 synchronized(this) { 2844 final long origId = Binder.clearCallingIdentity(); 2845 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2846 Binder.restoreCallingIdentity(origId); 2847 } 2848 } 2849 2850 public boolean finishActivityAffinity(IBinder token) { 2851 synchronized(this) { 2852 final long origId = Binder.clearCallingIdentity(); 2853 boolean res = mMainStack.finishActivityAffinityLocked(token); 2854 Binder.restoreCallingIdentity(origId); 2855 return res; 2856 } 2857 } 2858 2859 public boolean willActivityBeVisible(IBinder token) { 2860 synchronized(this) { 2861 int i; 2862 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2863 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2864 if (r.appToken == token) { 2865 return true; 2866 } 2867 if (r.fullscreen && !r.finishing) { 2868 return false; 2869 } 2870 } 2871 return true; 2872 } 2873 } 2874 2875 public void overridePendingTransition(IBinder token, String packageName, 2876 int enterAnim, int exitAnim) { 2877 synchronized(this) { 2878 ActivityRecord self = mMainStack.isInStackLocked(token); 2879 if (self == null) { 2880 return; 2881 } 2882 2883 final long origId = Binder.clearCallingIdentity(); 2884 2885 if (self.state == ActivityState.RESUMED 2886 || self.state == ActivityState.PAUSING) { 2887 mWindowManager.overridePendingAppTransition(packageName, 2888 enterAnim, exitAnim, null); 2889 } 2890 2891 Binder.restoreCallingIdentity(origId); 2892 } 2893 } 2894 2895 /** 2896 * Main function for removing an existing process from the activity manager 2897 * as a result of that process going away. Clears out all connections 2898 * to the process. 2899 */ 2900 private final void handleAppDiedLocked(ProcessRecord app, 2901 boolean restarting, boolean allowRestart) { 2902 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2903 if (!restarting) { 2904 mLruProcesses.remove(app); 2905 } 2906 2907 if (mProfileProc == app) { 2908 clearProfilerLocked(); 2909 } 2910 2911 // Just in case... 2912 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2913 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2914 mMainStack.mPausingActivity = null; 2915 } 2916 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2917 mMainStack.mLastPausedActivity = null; 2918 } 2919 2920 // Remove this application's activities from active lists. 2921 mMainStack.removeHistoryRecordsForAppLocked(app); 2922 2923 boolean atTop = true; 2924 boolean hasVisibleActivities = false; 2925 2926 // Clean out the history list. 2927 int i = mMainStack.mHistory.size(); 2928 if (localLOGV) Slog.v( 2929 TAG, "Removing app " + app + " from history with " + i + " entries"); 2930 while (i > 0) { 2931 i--; 2932 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2933 if (localLOGV) Slog.v( 2934 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2935 if (r.app == app) { 2936 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2937 if (ActivityStack.DEBUG_ADD_REMOVE) { 2938 RuntimeException here = new RuntimeException("here"); 2939 here.fillInStackTrace(); 2940 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2941 + ": haveState=" + r.haveState 2942 + " stateNotNeeded=" + r.stateNotNeeded 2943 + " finishing=" + r.finishing 2944 + " state=" + r.state, here); 2945 } 2946 if (!r.finishing) { 2947 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2948 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2949 System.identityHashCode(r), 2950 r.task.taskId, r.shortComponentName, 2951 "proc died without state saved"); 2952 } 2953 mMainStack.removeActivityFromHistoryLocked(r); 2954 2955 } else { 2956 // We have the current state for this activity, so 2957 // it can be restarted later when needed. 2958 if (localLOGV) Slog.v( 2959 TAG, "Keeping entry, setting app to null"); 2960 if (r.visible) { 2961 hasVisibleActivities = true; 2962 } 2963 r.app = null; 2964 r.nowVisible = false; 2965 if (!r.haveState) { 2966 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2967 "App died, clearing saved state of " + r); 2968 r.icicle = null; 2969 } 2970 } 2971 2972 r.stack.cleanUpActivityLocked(r, true, true); 2973 } 2974 atTop = false; 2975 } 2976 2977 app.activities.clear(); 2978 2979 if (app.instrumentationClass != null) { 2980 Slog.w(TAG, "Crash of app " + app.processName 2981 + " running instrumentation " + app.instrumentationClass); 2982 Bundle info = new Bundle(); 2983 info.putString("shortMsg", "Process crashed."); 2984 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2985 } 2986 2987 if (!restarting) { 2988 if (!mMainStack.resumeTopActivityLocked(null)) { 2989 // If there was nothing to resume, and we are not already 2990 // restarting this process, but there is a visible activity that 2991 // is hosted by the process... then make sure all visible 2992 // activities are running, taking care of restarting this 2993 // process. 2994 if (hasVisibleActivities) { 2995 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2996 } 2997 } 2998 } 2999 } 3000 3001 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3002 IBinder threadBinder = thread.asBinder(); 3003 // Find the application record. 3004 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3005 ProcessRecord rec = mLruProcesses.get(i); 3006 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3007 return i; 3008 } 3009 } 3010 return -1; 3011 } 3012 3013 final ProcessRecord getRecordForAppLocked( 3014 IApplicationThread thread) { 3015 if (thread == null) { 3016 return null; 3017 } 3018 3019 int appIndex = getLRURecordIndexForAppLocked(thread); 3020 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3021 } 3022 3023 final void appDiedLocked(ProcessRecord app, int pid, 3024 IApplicationThread thread) { 3025 3026 mProcDeaths[0]++; 3027 3028 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3029 synchronized (stats) { 3030 stats.noteProcessDiedLocked(app.info.uid, pid); 3031 } 3032 3033 // Clean up already done if the process has been re-started. 3034 if (app.pid == pid && app.thread != null && 3035 app.thread.asBinder() == thread.asBinder()) { 3036 if (!app.killedBackground) { 3037 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3038 + ") has died."); 3039 } 3040 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3041 if (localLOGV) Slog.v( 3042 TAG, "Dying app: " + app + ", pid: " + pid 3043 + ", thread: " + thread.asBinder()); 3044 boolean doLowMem = app.instrumentationClass == null; 3045 handleAppDiedLocked(app, false, true); 3046 3047 if (doLowMem) { 3048 // If there are no longer any background processes running, 3049 // and the app that died was not running instrumentation, 3050 // then tell everyone we are now low on memory. 3051 boolean haveBg = false; 3052 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3053 ProcessRecord rec = mLruProcesses.get(i); 3054 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3055 haveBg = true; 3056 break; 3057 } 3058 } 3059 3060 if (!haveBg) { 3061 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3062 long now = SystemClock.uptimeMillis(); 3063 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3064 ProcessRecord rec = mLruProcesses.get(i); 3065 if (rec != app && rec.thread != null && 3066 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3067 // The low memory report is overriding any current 3068 // state for a GC request. Make sure to do 3069 // heavy/important/visible/foreground processes first. 3070 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3071 rec.lastRequestedGc = 0; 3072 } else { 3073 rec.lastRequestedGc = rec.lastLowMemory; 3074 } 3075 rec.reportLowMemory = true; 3076 rec.lastLowMemory = now; 3077 mProcessesToGc.remove(rec); 3078 addProcessToGcListLocked(rec); 3079 } 3080 } 3081 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3082 scheduleAppGcsLocked(); 3083 } 3084 } 3085 } else if (app.pid != pid) { 3086 // A new process has already been started. 3087 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3088 + ") has died and restarted (pid " + app.pid + ")."); 3089 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3090 } else if (DEBUG_PROCESSES) { 3091 Slog.d(TAG, "Received spurious death notification for thread " 3092 + thread.asBinder()); 3093 } 3094 } 3095 3096 /** 3097 * If a stack trace dump file is configured, dump process stack traces. 3098 * @param clearTraces causes the dump file to be erased prior to the new 3099 * traces being written, if true; when false, the new traces will be 3100 * appended to any existing file content. 3101 * @param firstPids of dalvik VM processes to dump stack traces for first 3102 * @param lastPids of dalvik VM processes to dump stack traces for last 3103 * @param nativeProcs optional list of native process names to dump stack crawls 3104 * @return file containing stack traces, or null if no dump file is configured 3105 */ 3106 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3107 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3108 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3109 if (tracesPath == null || tracesPath.length() == 0) { 3110 return null; 3111 } 3112 3113 File tracesFile = new File(tracesPath); 3114 try { 3115 File tracesDir = tracesFile.getParentFile(); 3116 if (!tracesDir.exists()) { 3117 tracesFile.mkdirs(); 3118 if (!SELinux.restorecon(tracesDir)) { 3119 return null; 3120 } 3121 } 3122 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3123 3124 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3125 tracesFile.createNewFile(); 3126 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3127 } catch (IOException e) { 3128 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3129 return null; 3130 } 3131 3132 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3133 return tracesFile; 3134 } 3135 3136 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3137 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3138 // Use a FileObserver to detect when traces finish writing. 3139 // The order of traces is considered important to maintain for legibility. 3140 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3141 public synchronized void onEvent(int event, String path) { notify(); } 3142 }; 3143 3144 try { 3145 observer.startWatching(); 3146 3147 // First collect all of the stacks of the most important pids. 3148 if (firstPids != null) { 3149 try { 3150 int num = firstPids.size(); 3151 for (int i = 0; i < num; i++) { 3152 synchronized (observer) { 3153 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3154 observer.wait(200); // Wait for write-close, give up after 200msec 3155 } 3156 } 3157 } catch (InterruptedException e) { 3158 Log.wtf(TAG, e); 3159 } 3160 } 3161 3162 // Next measure CPU usage. 3163 if (processStats != null) { 3164 processStats.init(); 3165 System.gc(); 3166 processStats.update(); 3167 try { 3168 synchronized (processStats) { 3169 processStats.wait(500); // measure over 1/2 second. 3170 } 3171 } catch (InterruptedException e) { 3172 } 3173 processStats.update(); 3174 3175 // We'll take the stack crawls of just the top apps using CPU. 3176 final int N = processStats.countWorkingStats(); 3177 int numProcs = 0; 3178 for (int i=0; i<N && numProcs<5; i++) { 3179 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3180 if (lastPids.indexOfKey(stats.pid) >= 0) { 3181 numProcs++; 3182 try { 3183 synchronized (observer) { 3184 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3185 observer.wait(200); // Wait for write-close, give up after 200msec 3186 } 3187 } catch (InterruptedException e) { 3188 Log.wtf(TAG, e); 3189 } 3190 3191 } 3192 } 3193 } 3194 3195 } finally { 3196 observer.stopWatching(); 3197 } 3198 3199 if (nativeProcs != null) { 3200 int[] pids = Process.getPidsForCommands(nativeProcs); 3201 if (pids != null) { 3202 for (int pid : pids) { 3203 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3204 } 3205 } 3206 } 3207 } 3208 3209 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3210 if (true || IS_USER_BUILD) { 3211 return; 3212 } 3213 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3214 if (tracesPath == null || tracesPath.length() == 0) { 3215 return; 3216 } 3217 3218 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3219 StrictMode.allowThreadDiskWrites(); 3220 try { 3221 final File tracesFile = new File(tracesPath); 3222 final File tracesDir = tracesFile.getParentFile(); 3223 final File tracesTmp = new File(tracesDir, "__tmp__"); 3224 try { 3225 if (!tracesDir.exists()) { 3226 tracesFile.mkdirs(); 3227 if (!SELinux.restorecon(tracesDir.getPath())) { 3228 return; 3229 } 3230 } 3231 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3232 3233 if (tracesFile.exists()) { 3234 tracesTmp.delete(); 3235 tracesFile.renameTo(tracesTmp); 3236 } 3237 StringBuilder sb = new StringBuilder(); 3238 Time tobj = new Time(); 3239 tobj.set(System.currentTimeMillis()); 3240 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3241 sb.append(": "); 3242 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3243 sb.append(" since "); 3244 sb.append(msg); 3245 FileOutputStream fos = new FileOutputStream(tracesFile); 3246 fos.write(sb.toString().getBytes()); 3247 if (app == null) { 3248 fos.write("\n*** No application process!".getBytes()); 3249 } 3250 fos.close(); 3251 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3252 } catch (IOException e) { 3253 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3254 return; 3255 } 3256 3257 if (app != null) { 3258 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3259 firstPids.add(app.pid); 3260 dumpStackTraces(tracesPath, firstPids, null, null, null); 3261 } 3262 3263 File lastTracesFile = null; 3264 File curTracesFile = null; 3265 for (int i=9; i>=0; i--) { 3266 String name = String.format("slow%02d.txt", i); 3267 curTracesFile = new File(tracesDir, name); 3268 if (curTracesFile.exists()) { 3269 if (lastTracesFile != null) { 3270 curTracesFile.renameTo(lastTracesFile); 3271 } else { 3272 curTracesFile.delete(); 3273 } 3274 } 3275 lastTracesFile = curTracesFile; 3276 } 3277 tracesFile.renameTo(curTracesFile); 3278 if (tracesTmp.exists()) { 3279 tracesTmp.renameTo(tracesFile); 3280 } 3281 } finally { 3282 StrictMode.setThreadPolicy(oldPolicy); 3283 } 3284 } 3285 3286 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3287 ActivityRecord parent, final String annotation) { 3288 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3289 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3290 3291 if (mController != null) { 3292 try { 3293 // 0 == continue, -1 = kill process immediately 3294 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3295 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3296 } catch (RemoteException e) { 3297 mController = null; 3298 } 3299 } 3300 3301 long anrTime = SystemClock.uptimeMillis(); 3302 if (MONITOR_CPU_USAGE) { 3303 updateCpuStatsNow(); 3304 } 3305 3306 synchronized (this) { 3307 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3308 if (mShuttingDown) { 3309 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3310 return; 3311 } else if (app.notResponding) { 3312 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3313 return; 3314 } else if (app.crashing) { 3315 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3316 return; 3317 } 3318 3319 // In case we come through here for the same app before completing 3320 // this one, mark as anring now so we will bail out. 3321 app.notResponding = true; 3322 3323 // Log the ANR to the event log. 3324 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3325 annotation); 3326 3327 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3328 firstPids.add(app.pid); 3329 3330 int parentPid = app.pid; 3331 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3332 if (parentPid != app.pid) firstPids.add(parentPid); 3333 3334 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3335 3336 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3337 ProcessRecord r = mLruProcesses.get(i); 3338 if (r != null && r.thread != null) { 3339 int pid = r.pid; 3340 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3341 if (r.persistent) { 3342 firstPids.add(pid); 3343 } else { 3344 lastPids.put(pid, Boolean.TRUE); 3345 } 3346 } 3347 } 3348 } 3349 } 3350 3351 // Log the ANR to the main log. 3352 StringBuilder info = new StringBuilder(); 3353 info.setLength(0); 3354 info.append("ANR in ").append(app.processName); 3355 if (activity != null && activity.shortComponentName != null) { 3356 info.append(" (").append(activity.shortComponentName).append(")"); 3357 } 3358 info.append("\n"); 3359 if (annotation != null) { 3360 info.append("Reason: ").append(annotation).append("\n"); 3361 } 3362 if (parent != null && parent != activity) { 3363 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3364 } 3365 3366 final ProcessStats processStats = new ProcessStats(true); 3367 3368 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3369 3370 String cpuInfo = null; 3371 if (MONITOR_CPU_USAGE) { 3372 updateCpuStatsNow(); 3373 synchronized (mProcessStatsThread) { 3374 cpuInfo = mProcessStats.printCurrentState(anrTime); 3375 } 3376 info.append(processStats.printCurrentLoad()); 3377 info.append(cpuInfo); 3378 } 3379 3380 info.append(processStats.printCurrentState(anrTime)); 3381 3382 Slog.e(TAG, info.toString()); 3383 if (tracesFile == null) { 3384 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3385 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3386 } 3387 3388 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3389 cpuInfo, tracesFile, null); 3390 3391 if (mController != null) { 3392 try { 3393 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3394 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3395 if (res != 0) { 3396 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3397 return; 3398 } 3399 } catch (RemoteException e) { 3400 mController = null; 3401 } 3402 } 3403 3404 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3405 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3406 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3407 3408 synchronized (this) { 3409 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3410 Slog.w(TAG, "Killing " + app + ": background ANR"); 3411 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3412 app.processName, app.setAdj, "background ANR"); 3413 Process.killProcessQuiet(app.pid); 3414 return; 3415 } 3416 3417 // Set the app's notResponding state, and look up the errorReportReceiver 3418 makeAppNotRespondingLocked(app, 3419 activity != null ? activity.shortComponentName : null, 3420 annotation != null ? "ANR " + annotation : "ANR", 3421 info.toString()); 3422 3423 // Bring up the infamous App Not Responding dialog 3424 Message msg = Message.obtain(); 3425 HashMap map = new HashMap(); 3426 msg.what = SHOW_NOT_RESPONDING_MSG; 3427 msg.obj = map; 3428 map.put("app", app); 3429 if (activity != null) { 3430 map.put("activity", activity); 3431 } 3432 3433 mHandler.sendMessage(msg); 3434 } 3435 } 3436 3437 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3438 if (!mLaunchWarningShown) { 3439 mLaunchWarningShown = true; 3440 mHandler.post(new Runnable() { 3441 @Override 3442 public void run() { 3443 synchronized (ActivityManagerService.this) { 3444 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3445 d.show(); 3446 mHandler.postDelayed(new Runnable() { 3447 @Override 3448 public void run() { 3449 synchronized (ActivityManagerService.this) { 3450 d.dismiss(); 3451 mLaunchWarningShown = false; 3452 } 3453 } 3454 }, 4000); 3455 } 3456 } 3457 }); 3458 } 3459 } 3460 3461 public boolean clearApplicationUserData(final String packageName, 3462 final IPackageDataObserver observer, int userId) { 3463 enforceNotIsolatedCaller("clearApplicationUserData"); 3464 int uid = Binder.getCallingUid(); 3465 int pid = Binder.getCallingPid(); 3466 userId = handleIncomingUserLocked(pid, uid, 3467 userId, false, true, "clearApplicationUserData", null); 3468 long callingId = Binder.clearCallingIdentity(); 3469 try { 3470 IPackageManager pm = AppGlobals.getPackageManager(); 3471 int pkgUid = -1; 3472 synchronized(this) { 3473 try { 3474 pkgUid = pm.getPackageUid(packageName, userId); 3475 } catch (RemoteException e) { 3476 } 3477 if (pkgUid == -1) { 3478 Slog.w(TAG, "Invalid packageName:" + packageName); 3479 return false; 3480 } 3481 if (uid == pkgUid || checkComponentPermission( 3482 android.Manifest.permission.CLEAR_APP_USER_DATA, 3483 pid, uid, -1, true) 3484 == PackageManager.PERMISSION_GRANTED) { 3485 forceStopPackageLocked(packageName, pkgUid); 3486 } else { 3487 throw new SecurityException(pid+" does not have permission:"+ 3488 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3489 "for process:"+packageName); 3490 } 3491 } 3492 3493 try { 3494 //clear application user data 3495 pm.clearApplicationUserData(packageName, observer, userId); 3496 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3497 Uri.fromParts("package", packageName, null)); 3498 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3499 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3500 null, null, 0, null, null, null, false, false, userId); 3501 } catch (RemoteException e) { 3502 } 3503 } finally { 3504 Binder.restoreCallingIdentity(callingId); 3505 } 3506 return true; 3507 } 3508 3509 public void killBackgroundProcesses(final String packageName, int userId) { 3510 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3511 != PackageManager.PERMISSION_GRANTED && 3512 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3513 != PackageManager.PERMISSION_GRANTED) { 3514 String msg = "Permission Denial: killBackgroundProcesses() 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 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3523 userId, true, true, "killBackgroundProcesses", null); 3524 long callingId = Binder.clearCallingIdentity(); 3525 try { 3526 IPackageManager pm = AppGlobals.getPackageManager(); 3527 synchronized(this) { 3528 int appId = -1; 3529 try { 3530 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3531 } catch (RemoteException e) { 3532 } 3533 if (appId == -1) { 3534 Slog.w(TAG, "Invalid packageName: " + packageName); 3535 return; 3536 } 3537 killPackageProcessesLocked(packageName, appId, userId, 3538 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3539 } 3540 } finally { 3541 Binder.restoreCallingIdentity(callingId); 3542 } 3543 } 3544 3545 public void killAllBackgroundProcesses() { 3546 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3547 != PackageManager.PERMISSION_GRANTED) { 3548 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3549 + Binder.getCallingPid() 3550 + ", uid=" + Binder.getCallingUid() 3551 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3552 Slog.w(TAG, msg); 3553 throw new SecurityException(msg); 3554 } 3555 3556 long callingId = Binder.clearCallingIdentity(); 3557 try { 3558 synchronized(this) { 3559 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3560 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3561 final int NA = apps.size(); 3562 for (int ia=0; ia<NA; ia++) { 3563 ProcessRecord app = apps.valueAt(ia); 3564 if (app.persistent) { 3565 // we don't kill persistent processes 3566 continue; 3567 } 3568 if (app.removed) { 3569 procs.add(app); 3570 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3571 app.removed = true; 3572 procs.add(app); 3573 } 3574 } 3575 } 3576 3577 int N = procs.size(); 3578 for (int i=0; i<N; i++) { 3579 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3580 } 3581 } 3582 } finally { 3583 Binder.restoreCallingIdentity(callingId); 3584 } 3585 } 3586 3587 public void forceStopPackage(final String packageName, int userId) { 3588 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3589 != PackageManager.PERMISSION_GRANTED) { 3590 String msg = "Permission Denial: forceStopPackage() from pid=" 3591 + Binder.getCallingPid() 3592 + ", uid=" + Binder.getCallingUid() 3593 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3594 Slog.w(TAG, msg); 3595 throw new SecurityException(msg); 3596 } 3597 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3598 userId, true, true, "forceStopPackage", null); 3599 long callingId = Binder.clearCallingIdentity(); 3600 try { 3601 IPackageManager pm = AppGlobals.getPackageManager(); 3602 synchronized(this) { 3603 int[] users = userId == UserHandle.USER_ALL 3604 ? getUsersLocked() : new int[] { userId }; 3605 for (int user : users) { 3606 int pkgUid = -1; 3607 try { 3608 pkgUid = pm.getPackageUid(packageName, user); 3609 } catch (RemoteException e) { 3610 } 3611 if (pkgUid == -1) { 3612 Slog.w(TAG, "Invalid packageName: " + packageName); 3613 continue; 3614 } 3615 try { 3616 pm.setPackageStoppedState(packageName, true, user); 3617 } catch (RemoteException e) { 3618 } catch (IllegalArgumentException e) { 3619 Slog.w(TAG, "Failed trying to unstop package " 3620 + packageName + ": " + e); 3621 } 3622 if (isUserRunningLocked(user)) { 3623 forceStopPackageLocked(packageName, pkgUid); 3624 } 3625 } 3626 } 3627 } finally { 3628 Binder.restoreCallingIdentity(callingId); 3629 } 3630 } 3631 3632 /* 3633 * The pkg name and app id have to be specified. 3634 */ 3635 public void killApplicationWithAppId(String pkg, int appid) { 3636 if (pkg == null) { 3637 return; 3638 } 3639 // Make sure the uid is valid. 3640 if (appid < 0) { 3641 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3642 return; 3643 } 3644 int callerUid = Binder.getCallingUid(); 3645 // Only the system server can kill an application 3646 if (callerUid == Process.SYSTEM_UID) { 3647 // Post an aysnc message to kill the application 3648 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3649 msg.arg1 = appid; 3650 msg.arg2 = 0; 3651 msg.obj = pkg; 3652 mHandler.sendMessage(msg); 3653 } else { 3654 throw new SecurityException(callerUid + " cannot kill pkg: " + 3655 pkg); 3656 } 3657 } 3658 3659 public void closeSystemDialogs(String reason) { 3660 enforceNotIsolatedCaller("closeSystemDialogs"); 3661 3662 final int pid = Binder.getCallingPid(); 3663 final int uid = Binder.getCallingUid(); 3664 final long origId = Binder.clearCallingIdentity(); 3665 try { 3666 synchronized (this) { 3667 // Only allow this from foreground processes, so that background 3668 // applications can't abuse it to prevent system UI from being shown. 3669 if (uid >= Process.FIRST_APPLICATION_UID) { 3670 ProcessRecord proc; 3671 synchronized (mPidsSelfLocked) { 3672 proc = mPidsSelfLocked.get(pid); 3673 } 3674 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3675 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3676 + " from background process " + proc); 3677 return; 3678 } 3679 } 3680 closeSystemDialogsLocked(reason); 3681 } 3682 } finally { 3683 Binder.restoreCallingIdentity(origId); 3684 } 3685 } 3686 3687 void closeSystemDialogsLocked(String reason) { 3688 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3689 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3690 if (reason != null) { 3691 intent.putExtra("reason", reason); 3692 } 3693 mWindowManager.closeSystemDialogs(reason); 3694 3695 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3696 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3697 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3698 r.stack.finishActivityLocked(r, i, 3699 Activity.RESULT_CANCELED, null, "close-sys", true); 3700 } 3701 } 3702 3703 broadcastIntentLocked(null, null, intent, null, 3704 null, 0, null, null, null, false, false, -1, 3705 Process.SYSTEM_UID, UserHandle.USER_ALL); 3706 } 3707 3708 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3709 throws RemoteException { 3710 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3711 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3712 for (int i=pids.length-1; i>=0; i--) { 3713 infos[i] = new Debug.MemoryInfo(); 3714 Debug.getMemoryInfo(pids[i], infos[i]); 3715 } 3716 return infos; 3717 } 3718 3719 public long[] getProcessPss(int[] pids) throws RemoteException { 3720 enforceNotIsolatedCaller("getProcessPss"); 3721 long[] pss = new long[pids.length]; 3722 for (int i=pids.length-1; i>=0; i--) { 3723 pss[i] = Debug.getPss(pids[i]); 3724 } 3725 return pss; 3726 } 3727 3728 public void killApplicationProcess(String processName, int uid) { 3729 if (processName == null) { 3730 return; 3731 } 3732 3733 int callerUid = Binder.getCallingUid(); 3734 // Only the system server can kill an application 3735 if (callerUid == Process.SYSTEM_UID) { 3736 synchronized (this) { 3737 ProcessRecord app = getProcessRecordLocked(processName, uid); 3738 if (app != null && app.thread != null) { 3739 try { 3740 app.thread.scheduleSuicide(); 3741 } catch (RemoteException e) { 3742 // If the other end already died, then our work here is done. 3743 } 3744 } else { 3745 Slog.w(TAG, "Process/uid not found attempting kill of " 3746 + processName + " / " + uid); 3747 } 3748 } 3749 } else { 3750 throw new SecurityException(callerUid + " cannot kill app process: " + 3751 processName); 3752 } 3753 } 3754 3755 private void forceStopPackageLocked(final String packageName, int uid) { 3756 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3757 false, true, false, UserHandle.getUserId(uid)); 3758 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3759 Uri.fromParts("package", packageName, null)); 3760 if (!mProcessesReady) { 3761 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3762 } 3763 intent.putExtra(Intent.EXTRA_UID, uid); 3764 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3765 broadcastIntentLocked(null, null, intent, 3766 null, null, 0, null, null, null, 3767 false, false, 3768 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3769 } 3770 3771 private void forceStopUserLocked(int userId) { 3772 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3773 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3774 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3775 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3776 broadcastIntentLocked(null, null, intent, 3777 null, null, 0, null, null, null, 3778 false, false, 3779 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3780 } 3781 3782 private final boolean killPackageProcessesLocked(String packageName, int appId, 3783 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3784 boolean doit, boolean evenPersistent, String reason) { 3785 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3786 3787 // Remove all processes this package may have touched: all with the 3788 // same UID (except for the system or root user), and all whose name 3789 // matches the package name. 3790 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3791 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3792 final int NA = apps.size(); 3793 for (int ia=0; ia<NA; ia++) { 3794 ProcessRecord app = apps.valueAt(ia); 3795 if (app.persistent && !evenPersistent) { 3796 // we don't kill persistent processes 3797 continue; 3798 } 3799 if (app.removed) { 3800 if (doit) { 3801 procs.add(app); 3802 } 3803 continue; 3804 } 3805 3806 // Skip process if it doesn't meet our oom adj requirement. 3807 if (app.setAdj < minOomAdj) { 3808 continue; 3809 } 3810 3811 // If no package is specified, we call all processes under the 3812 // give user id. 3813 if (packageName == null) { 3814 if (app.userId != userId) { 3815 continue; 3816 } 3817 // Package has been specified, we want to hit all processes 3818 // that match it. We need to qualify this by the processes 3819 // that are running under the specified app and user ID. 3820 } else { 3821 if (UserHandle.getAppId(app.uid) != appId) { 3822 continue; 3823 } 3824 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3825 continue; 3826 } 3827 if (!app.pkgList.contains(packageName)) { 3828 continue; 3829 } 3830 } 3831 3832 // Process has passed all conditions, kill it! 3833 if (!doit) { 3834 return true; 3835 } 3836 app.removed = true; 3837 procs.add(app); 3838 } 3839 } 3840 3841 int N = procs.size(); 3842 for (int i=0; i<N; i++) { 3843 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3844 } 3845 return N > 0; 3846 } 3847 3848 private final boolean forceStopPackageLocked(String name, int appId, 3849 boolean callerWillRestart, boolean purgeCache, boolean doit, 3850 boolean evenPersistent, int userId) { 3851 int i; 3852 int N; 3853 3854 if (userId == UserHandle.USER_ALL && name == null) { 3855 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3856 } 3857 3858 if (appId < 0 && name != null) { 3859 try { 3860 appId = UserHandle.getAppId( 3861 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3862 } catch (RemoteException e) { 3863 } 3864 } 3865 3866 if (doit) { 3867 if (name != null) { 3868 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3869 + " user=" + userId); 3870 } else { 3871 Slog.i(TAG, "Force stopping user " + userId); 3872 } 3873 3874 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3875 while (badApps.hasNext()) { 3876 SparseArray<Long> ba = badApps.next(); 3877 for (i=ba.size()-1; i>=0; i--) { 3878 boolean remove = false; 3879 final int entUid = ba.keyAt(i); 3880 if (name != null) { 3881 if (userId == UserHandle.USER_ALL) { 3882 if (UserHandle.getAppId(entUid) == appId) { 3883 remove = true; 3884 } 3885 } else { 3886 if (entUid == UserHandle.getUid(userId, appId)) { 3887 remove = true; 3888 } 3889 } 3890 } else if (UserHandle.getUserId(entUid) == userId) { 3891 remove = true; 3892 } 3893 if (remove) { 3894 ba.removeAt(i); 3895 } 3896 } 3897 if (ba.size() == 0) { 3898 badApps.remove(); 3899 } 3900 } 3901 } 3902 3903 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3904 -100, callerWillRestart, false, doit, evenPersistent, 3905 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3906 3907 TaskRecord lastTask = null; 3908 for (i=0; i<mMainStack.mHistory.size(); i++) { 3909 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3910 final boolean samePackage = r.packageName.equals(name) 3911 || (name == null && r.userId == userId); 3912 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3913 && (samePackage || r.task == lastTask) 3914 && (r.app == null || evenPersistent || !r.app.persistent)) { 3915 if (!doit) { 3916 if (r.finishing) { 3917 // If this activity is just finishing, then it is not 3918 // interesting as far as something to stop. 3919 continue; 3920 } 3921 return true; 3922 } 3923 didSomething = true; 3924 Slog.i(TAG, " Force finishing activity " + r); 3925 if (samePackage) { 3926 if (r.app != null) { 3927 r.app.removed = true; 3928 } 3929 r.app = null; 3930 } 3931 lastTask = r.task; 3932 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3933 null, "force-stop", true)) { 3934 i--; 3935 } 3936 } 3937 } 3938 3939 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3940 if (!doit) { 3941 return true; 3942 } 3943 didSomething = true; 3944 } 3945 3946 if (name == null) { 3947 // Remove all sticky broadcasts from this user. 3948 mStickyBroadcasts.remove(userId); 3949 } 3950 3951 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3952 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3953 userId, providers)) { 3954 if (!doit) { 3955 return true; 3956 } 3957 didSomething = true; 3958 } 3959 N = providers.size(); 3960 for (i=0; i<N; i++) { 3961 removeDyingProviderLocked(null, providers.get(i), true); 3962 } 3963 3964 if (mIntentSenderRecords.size() > 0) { 3965 Iterator<WeakReference<PendingIntentRecord>> it 3966 = mIntentSenderRecords.values().iterator(); 3967 while (it.hasNext()) { 3968 WeakReference<PendingIntentRecord> wpir = it.next(); 3969 if (wpir == null) { 3970 it.remove(); 3971 continue; 3972 } 3973 PendingIntentRecord pir = wpir.get(); 3974 if (pir == null) { 3975 it.remove(); 3976 continue; 3977 } 3978 if (name == null) { 3979 // Stopping user, remove all objects for the user. 3980 if (pir.key.userId != userId) { 3981 // Not the same user, skip it. 3982 continue; 3983 } 3984 } else { 3985 if (UserHandle.getAppId(pir.uid) != appId) { 3986 // Different app id, skip it. 3987 continue; 3988 } 3989 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3990 // Different user, skip it. 3991 continue; 3992 } 3993 if (!pir.key.packageName.equals(name)) { 3994 // Different package, skip it. 3995 continue; 3996 } 3997 } 3998 if (!doit) { 3999 return true; 4000 } 4001 didSomething = true; 4002 it.remove(); 4003 pir.canceled = true; 4004 if (pir.key.activity != null) { 4005 pir.key.activity.pendingResults.remove(pir.ref); 4006 } 4007 } 4008 } 4009 4010 if (doit) { 4011 if (purgeCache && name != null) { 4012 AttributeCache ac = AttributeCache.instance(); 4013 if (ac != null) { 4014 ac.removePackage(name); 4015 } 4016 } 4017 if (mBooted) { 4018 mMainStack.resumeTopActivityLocked(null); 4019 mMainStack.scheduleIdleLocked(); 4020 } 4021 } 4022 4023 return didSomething; 4024 } 4025 4026 private final boolean removeProcessLocked(ProcessRecord app, 4027 boolean callerWillRestart, boolean allowRestart, String reason) { 4028 final String name = app.processName; 4029 final int uid = app.uid; 4030 if (DEBUG_PROCESSES) Slog.d( 4031 TAG, "Force removing proc " + app.toShortString() + " (" + name 4032 + "/" + uid + ")"); 4033 4034 mProcessNames.remove(name, uid); 4035 mIsolatedProcesses.remove(app.uid); 4036 if (mHeavyWeightProcess == app) { 4037 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4038 mHeavyWeightProcess.userId, 0)); 4039 mHeavyWeightProcess = null; 4040 } 4041 boolean needRestart = false; 4042 if (app.pid > 0 && app.pid != MY_PID) { 4043 int pid = app.pid; 4044 synchronized (mPidsSelfLocked) { 4045 mPidsSelfLocked.remove(pid); 4046 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4047 } 4048 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4049 handleAppDiedLocked(app, true, allowRestart); 4050 mLruProcesses.remove(app); 4051 Process.killProcessQuiet(pid); 4052 4053 if (app.persistent && !app.isolated) { 4054 if (!callerWillRestart) { 4055 addAppLocked(app.info, false); 4056 } else { 4057 needRestart = true; 4058 } 4059 } 4060 } else { 4061 mRemovedProcesses.add(app); 4062 } 4063 4064 return needRestart; 4065 } 4066 4067 private final void processStartTimedOutLocked(ProcessRecord app) { 4068 final int pid = app.pid; 4069 boolean gone = false; 4070 synchronized (mPidsSelfLocked) { 4071 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4072 if (knownApp != null && knownApp.thread == null) { 4073 mPidsSelfLocked.remove(pid); 4074 gone = true; 4075 } 4076 } 4077 4078 if (gone) { 4079 Slog.w(TAG, "Process " + app + " failed to attach"); 4080 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4081 app.processName); 4082 mProcessNames.remove(app.processName, app.uid); 4083 mIsolatedProcesses.remove(app.uid); 4084 if (mHeavyWeightProcess == app) { 4085 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4086 mHeavyWeightProcess.userId, 0)); 4087 mHeavyWeightProcess = null; 4088 } 4089 // Take care of any launching providers waiting for this process. 4090 checkAppInLaunchingProvidersLocked(app, true); 4091 // Take care of any services that are waiting for the process. 4092 mServices.processStartTimedOutLocked(app); 4093 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4094 app.processName, app.setAdj, "start timeout"); 4095 Process.killProcessQuiet(pid); 4096 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4097 Slog.w(TAG, "Unattached app died before backup, skipping"); 4098 try { 4099 IBackupManager bm = IBackupManager.Stub.asInterface( 4100 ServiceManager.getService(Context.BACKUP_SERVICE)); 4101 bm.agentDisconnected(app.info.packageName); 4102 } catch (RemoteException e) { 4103 // Can't happen; the backup manager is local 4104 } 4105 } 4106 if (isPendingBroadcastProcessLocked(pid)) { 4107 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4108 skipPendingBroadcastLocked(pid); 4109 } 4110 } else { 4111 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4112 } 4113 } 4114 4115 private final boolean attachApplicationLocked(IApplicationThread thread, 4116 int pid) { 4117 4118 // Find the application record that is being attached... either via 4119 // the pid if we are running in multiple processes, or just pull the 4120 // next app record if we are emulating process with anonymous threads. 4121 ProcessRecord app; 4122 if (pid != MY_PID && pid >= 0) { 4123 synchronized (mPidsSelfLocked) { 4124 app = mPidsSelfLocked.get(pid); 4125 } 4126 } else { 4127 app = null; 4128 } 4129 4130 if (app == null) { 4131 Slog.w(TAG, "No pending application record for pid " + pid 4132 + " (IApplicationThread " + thread + "); dropping process"); 4133 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4134 if (pid > 0 && pid != MY_PID) { 4135 Process.killProcessQuiet(pid); 4136 } else { 4137 try { 4138 thread.scheduleExit(); 4139 } catch (Exception e) { 4140 // Ignore exceptions. 4141 } 4142 } 4143 return false; 4144 } 4145 4146 // If this application record is still attached to a previous 4147 // process, clean it up now. 4148 if (app.thread != null) { 4149 handleAppDiedLocked(app, true, true); 4150 } 4151 4152 // Tell the process all about itself. 4153 4154 if (localLOGV) Slog.v( 4155 TAG, "Binding process pid " + pid + " to record " + app); 4156 4157 String processName = app.processName; 4158 try { 4159 AppDeathRecipient adr = new AppDeathRecipient( 4160 app, pid, thread); 4161 thread.asBinder().linkToDeath(adr, 0); 4162 app.deathRecipient = adr; 4163 } catch (RemoteException e) { 4164 app.resetPackageList(); 4165 startProcessLocked(app, "link fail", processName); 4166 return false; 4167 } 4168 4169 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4170 4171 app.thread = thread; 4172 app.curAdj = app.setAdj = -100; 4173 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4174 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4175 app.forcingToForeground = null; 4176 app.foregroundServices = false; 4177 app.hasShownUi = false; 4178 app.debugging = false; 4179 4180 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4181 4182 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4183 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4184 4185 if (!normalMode) { 4186 Slog.i(TAG, "Launching preboot mode app: " + app); 4187 } 4188 4189 if (localLOGV) Slog.v( 4190 TAG, "New app record " + app 4191 + " thread=" + thread.asBinder() + " pid=" + pid); 4192 try { 4193 int testMode = IApplicationThread.DEBUG_OFF; 4194 if (mDebugApp != null && mDebugApp.equals(processName)) { 4195 testMode = mWaitForDebugger 4196 ? IApplicationThread.DEBUG_WAIT 4197 : IApplicationThread.DEBUG_ON; 4198 app.debugging = true; 4199 if (mDebugTransient) { 4200 mDebugApp = mOrigDebugApp; 4201 mWaitForDebugger = mOrigWaitForDebugger; 4202 } 4203 } 4204 String profileFile = app.instrumentationProfileFile; 4205 ParcelFileDescriptor profileFd = null; 4206 boolean profileAutoStop = false; 4207 if (mProfileApp != null && mProfileApp.equals(processName)) { 4208 mProfileProc = app; 4209 profileFile = mProfileFile; 4210 profileFd = mProfileFd; 4211 profileAutoStop = mAutoStopProfiler; 4212 } 4213 boolean enableOpenGlTrace = false; 4214 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4215 enableOpenGlTrace = true; 4216 mOpenGlTraceApp = null; 4217 } 4218 4219 // If the app is being launched for restore or full backup, set it up specially 4220 boolean isRestrictedBackupMode = false; 4221 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4222 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4223 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4224 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4225 } 4226 4227 ensurePackageDexOpt(app.instrumentationInfo != null 4228 ? app.instrumentationInfo.packageName 4229 : app.info.packageName); 4230 if (app.instrumentationClass != null) { 4231 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4232 } 4233 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4234 + processName + " with config " + mConfiguration); 4235 ApplicationInfo appInfo = app.instrumentationInfo != null 4236 ? app.instrumentationInfo : app.info; 4237 app.compat = compatibilityInfoForPackageLocked(appInfo); 4238 if (profileFd != null) { 4239 profileFd = profileFd.dup(); 4240 } 4241 thread.bindApplication(processName, appInfo, providers, 4242 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4243 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4244 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4245 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4246 mCoreSettingsObserver.getCoreSettingsLocked()); 4247 updateLruProcessLocked(app, false, true); 4248 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4249 } catch (Exception e) { 4250 // todo: Yikes! What should we do? For now we will try to 4251 // start another process, but that could easily get us in 4252 // an infinite loop of restarting processes... 4253 Slog.w(TAG, "Exception thrown during bind!", e); 4254 4255 app.resetPackageList(); 4256 app.unlinkDeathRecipient(); 4257 startProcessLocked(app, "bind fail", processName); 4258 return false; 4259 } 4260 4261 // Remove this record from the list of starting applications. 4262 mPersistentStartingProcesses.remove(app); 4263 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4264 "Attach application locked removing on hold: " + app); 4265 mProcessesOnHold.remove(app); 4266 4267 boolean badApp = false; 4268 boolean didSomething = false; 4269 4270 // See if the top visible activity is waiting to run in this process... 4271 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4272 if (hr != null && normalMode) { 4273 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4274 && processName.equals(hr.processName)) { 4275 try { 4276 if (mHeadless) { 4277 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4278 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4279 didSomething = true; 4280 } 4281 } catch (Exception e) { 4282 Slog.w(TAG, "Exception in new application when starting activity " 4283 + hr.intent.getComponent().flattenToShortString(), e); 4284 badApp = true; 4285 } 4286 } else { 4287 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4288 } 4289 } 4290 4291 // Find any services that should be running in this process... 4292 if (!badApp) { 4293 try { 4294 didSomething |= mServices.attachApplicationLocked(app, processName); 4295 } catch (Exception e) { 4296 badApp = true; 4297 } 4298 } 4299 4300 // Check if a next-broadcast receiver is in this process... 4301 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4302 try { 4303 didSomething = sendPendingBroadcastsLocked(app); 4304 } catch (Exception e) { 4305 // If the app died trying to launch the receiver we declare it 'bad' 4306 badApp = true; 4307 } 4308 } 4309 4310 // Check whether the next backup agent is in this process... 4311 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4312 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4313 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4314 try { 4315 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4316 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4317 mBackupTarget.backupMode); 4318 } catch (Exception e) { 4319 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4320 e.printStackTrace(); 4321 } 4322 } 4323 4324 if (badApp) { 4325 // todo: Also need to kill application to deal with all 4326 // kinds of exceptions. 4327 handleAppDiedLocked(app, false, true); 4328 return false; 4329 } 4330 4331 if (!didSomething) { 4332 updateOomAdjLocked(); 4333 } 4334 4335 return true; 4336 } 4337 4338 public final void attachApplication(IApplicationThread thread) { 4339 synchronized (this) { 4340 int callingPid = Binder.getCallingPid(); 4341 final long origId = Binder.clearCallingIdentity(); 4342 attachApplicationLocked(thread, callingPid); 4343 Binder.restoreCallingIdentity(origId); 4344 } 4345 } 4346 4347 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4348 final long origId = Binder.clearCallingIdentity(); 4349 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4350 if (stopProfiling) { 4351 synchronized (this) { 4352 if (mProfileProc == r.app) { 4353 if (mProfileFd != null) { 4354 try { 4355 mProfileFd.close(); 4356 } catch (IOException e) { 4357 } 4358 clearProfilerLocked(); 4359 } 4360 } 4361 } 4362 } 4363 Binder.restoreCallingIdentity(origId); 4364 } 4365 4366 void enableScreenAfterBoot() { 4367 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4368 SystemClock.uptimeMillis()); 4369 mWindowManager.enableScreenAfterBoot(); 4370 4371 synchronized (this) { 4372 updateEventDispatchingLocked(); 4373 } 4374 } 4375 4376 public void showBootMessage(final CharSequence msg, final boolean always) { 4377 enforceNotIsolatedCaller("showBootMessage"); 4378 mWindowManager.showBootMessage(msg, always); 4379 } 4380 4381 public void dismissKeyguardOnNextActivity() { 4382 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4383 final long token = Binder.clearCallingIdentity(); 4384 try { 4385 synchronized (this) { 4386 if (mLockScreenShown) { 4387 mLockScreenShown = false; 4388 comeOutOfSleepIfNeededLocked(); 4389 } 4390 mMainStack.dismissKeyguardOnNextActivityLocked(); 4391 } 4392 } finally { 4393 Binder.restoreCallingIdentity(token); 4394 } 4395 } 4396 4397 final void finishBooting() { 4398 IntentFilter pkgFilter = new IntentFilter(); 4399 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4400 pkgFilter.addDataScheme("package"); 4401 mContext.registerReceiver(new BroadcastReceiver() { 4402 @Override 4403 public void onReceive(Context context, Intent intent) { 4404 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4405 if (pkgs != null) { 4406 for (String pkg : pkgs) { 4407 synchronized (ActivityManagerService.this) { 4408 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4409 setResultCode(Activity.RESULT_OK); 4410 return; 4411 } 4412 } 4413 } 4414 } 4415 } 4416 }, pkgFilter); 4417 4418 synchronized (this) { 4419 // Ensure that any processes we had put on hold are now started 4420 // up. 4421 final int NP = mProcessesOnHold.size(); 4422 if (NP > 0) { 4423 ArrayList<ProcessRecord> procs = 4424 new ArrayList<ProcessRecord>(mProcessesOnHold); 4425 for (int ip=0; ip<NP; ip++) { 4426 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4427 + procs.get(ip)); 4428 startProcessLocked(procs.get(ip), "on-hold", null); 4429 } 4430 } 4431 4432 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4433 // Start looking for apps that are abusing wake locks. 4434 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4435 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4436 // Tell anyone interested that we are done booting! 4437 SystemProperties.set("sys.boot_completed", "1"); 4438 SystemProperties.set("dev.bootcomplete", "1"); 4439 for (int i=0; i<mStartedUsers.size(); i++) { 4440 UserStartedState uss = mStartedUsers.valueAt(i); 4441 if (uss.mState == UserStartedState.STATE_BOOTING) { 4442 uss.mState = UserStartedState.STATE_RUNNING; 4443 final int userId = mStartedUsers.keyAt(i); 4444 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4445 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4446 broadcastIntentLocked(null, null, intent, 4447 null, null, 0, null, null, 4448 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4449 false, false, MY_PID, Process.SYSTEM_UID, userId); 4450 } 4451 } 4452 } 4453 } 4454 } 4455 4456 final void ensureBootCompleted() { 4457 boolean booting; 4458 boolean enableScreen; 4459 synchronized (this) { 4460 booting = mBooting; 4461 mBooting = false; 4462 enableScreen = !mBooted; 4463 mBooted = true; 4464 } 4465 4466 if (booting) { 4467 finishBooting(); 4468 } 4469 4470 if (enableScreen) { 4471 enableScreenAfterBoot(); 4472 } 4473 } 4474 4475 public final void activityResumed(IBinder token) { 4476 final long origId = Binder.clearCallingIdentity(); 4477 mMainStack.activityResumed(token); 4478 Binder.restoreCallingIdentity(origId); 4479 } 4480 4481 public final void activityPaused(IBinder token) { 4482 final long origId = Binder.clearCallingIdentity(); 4483 mMainStack.activityPaused(token, false); 4484 Binder.restoreCallingIdentity(origId); 4485 } 4486 4487 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4488 CharSequence description) { 4489 if (localLOGV) Slog.v( 4490 TAG, "Activity stopped: token=" + token); 4491 4492 // Refuse possible leaked file descriptors 4493 if (icicle != null && icicle.hasFileDescriptors()) { 4494 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4495 } 4496 4497 ActivityRecord r = null; 4498 4499 final long origId = Binder.clearCallingIdentity(); 4500 4501 synchronized (this) { 4502 r = mMainStack.isInStackLocked(token); 4503 if (r != null) { 4504 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4505 } 4506 } 4507 4508 if (r != null) { 4509 sendPendingThumbnail(r, null, null, null, false); 4510 } 4511 4512 trimApplications(); 4513 4514 Binder.restoreCallingIdentity(origId); 4515 } 4516 4517 public final void activityDestroyed(IBinder token) { 4518 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4519 mMainStack.activityDestroyed(token); 4520 } 4521 4522 public String getCallingPackage(IBinder token) { 4523 synchronized (this) { 4524 ActivityRecord r = getCallingRecordLocked(token); 4525 return r != null && r.app != null ? r.info.packageName : null; 4526 } 4527 } 4528 4529 public ComponentName getCallingActivity(IBinder token) { 4530 synchronized (this) { 4531 ActivityRecord r = getCallingRecordLocked(token); 4532 return r != null ? r.intent.getComponent() : null; 4533 } 4534 } 4535 4536 private ActivityRecord getCallingRecordLocked(IBinder token) { 4537 ActivityRecord r = mMainStack.isInStackLocked(token); 4538 if (r == null) { 4539 return null; 4540 } 4541 return r.resultTo; 4542 } 4543 4544 public ComponentName getActivityClassForToken(IBinder token) { 4545 synchronized(this) { 4546 ActivityRecord r = mMainStack.isInStackLocked(token); 4547 if (r == null) { 4548 return null; 4549 } 4550 return r.intent.getComponent(); 4551 } 4552 } 4553 4554 public String getPackageForToken(IBinder token) { 4555 synchronized(this) { 4556 ActivityRecord r = mMainStack.isInStackLocked(token); 4557 if (r == null) { 4558 return null; 4559 } 4560 return r.packageName; 4561 } 4562 } 4563 4564 public IIntentSender getIntentSender(int type, 4565 String packageName, IBinder token, String resultWho, 4566 int requestCode, Intent[] intents, String[] resolvedTypes, 4567 int flags, Bundle options, int userId) { 4568 enforceNotIsolatedCaller("getIntentSender"); 4569 // Refuse possible leaked file descriptors 4570 if (intents != null) { 4571 if (intents.length < 1) { 4572 throw new IllegalArgumentException("Intents array length must be >= 1"); 4573 } 4574 for (int i=0; i<intents.length; i++) { 4575 Intent intent = intents[i]; 4576 if (intent != null) { 4577 if (intent.hasFileDescriptors()) { 4578 throw new IllegalArgumentException("File descriptors passed in Intent"); 4579 } 4580 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4581 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4582 throw new IllegalArgumentException( 4583 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4584 } 4585 intents[i] = new Intent(intent); 4586 } 4587 } 4588 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4589 throw new IllegalArgumentException( 4590 "Intent array length does not match resolvedTypes length"); 4591 } 4592 } 4593 if (options != null) { 4594 if (options.hasFileDescriptors()) { 4595 throw new IllegalArgumentException("File descriptors passed in options"); 4596 } 4597 } 4598 4599 synchronized(this) { 4600 int callingUid = Binder.getCallingUid(); 4601 int origUserId = userId; 4602 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4603 type == ActivityManager.INTENT_SENDER_BROADCAST, true, 4604 "getIntentSender", null); 4605 if (origUserId == UserHandle.USER_CURRENT) { 4606 // We don't want to evaluate this until the pending intent is 4607 // actually executed. However, we do want to always do the 4608 // security checking for it above. 4609 userId = UserHandle.USER_CURRENT; 4610 } 4611 try { 4612 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4613 int uid = AppGlobals.getPackageManager() 4614 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4615 if (!UserHandle.isSameApp(callingUid, uid)) { 4616 String msg = "Permission Denial: getIntentSender() from pid=" 4617 + Binder.getCallingPid() 4618 + ", uid=" + Binder.getCallingUid() 4619 + ", (need uid=" + uid + ")" 4620 + " is not allowed to send as package " + packageName; 4621 Slog.w(TAG, msg); 4622 throw new SecurityException(msg); 4623 } 4624 } 4625 4626 return getIntentSenderLocked(type, packageName, callingUid, userId, 4627 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4628 4629 } catch (RemoteException e) { 4630 throw new SecurityException(e); 4631 } 4632 } 4633 } 4634 4635 IIntentSender getIntentSenderLocked(int type, String packageName, 4636 int callingUid, int userId, IBinder token, String resultWho, 4637 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4638 Bundle options) { 4639 if (DEBUG_MU) 4640 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4641 ActivityRecord activity = null; 4642 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4643 activity = mMainStack.isInStackLocked(token); 4644 if (activity == null) { 4645 return null; 4646 } 4647 if (activity.finishing) { 4648 return null; 4649 } 4650 } 4651 4652 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4653 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4654 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4655 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4656 |PendingIntent.FLAG_UPDATE_CURRENT); 4657 4658 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4659 type, packageName, activity, resultWho, 4660 requestCode, intents, resolvedTypes, flags, options, userId); 4661 WeakReference<PendingIntentRecord> ref; 4662 ref = mIntentSenderRecords.get(key); 4663 PendingIntentRecord rec = ref != null ? ref.get() : null; 4664 if (rec != null) { 4665 if (!cancelCurrent) { 4666 if (updateCurrent) { 4667 if (rec.key.requestIntent != null) { 4668 rec.key.requestIntent.replaceExtras(intents != null ? 4669 intents[intents.length - 1] : null); 4670 } 4671 if (intents != null) { 4672 intents[intents.length-1] = rec.key.requestIntent; 4673 rec.key.allIntents = intents; 4674 rec.key.allResolvedTypes = resolvedTypes; 4675 } else { 4676 rec.key.allIntents = null; 4677 rec.key.allResolvedTypes = null; 4678 } 4679 } 4680 return rec; 4681 } 4682 rec.canceled = true; 4683 mIntentSenderRecords.remove(key); 4684 } 4685 if (noCreate) { 4686 return rec; 4687 } 4688 rec = new PendingIntentRecord(this, key, callingUid); 4689 mIntentSenderRecords.put(key, rec.ref); 4690 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4691 if (activity.pendingResults == null) { 4692 activity.pendingResults 4693 = new HashSet<WeakReference<PendingIntentRecord>>(); 4694 } 4695 activity.pendingResults.add(rec.ref); 4696 } 4697 return rec; 4698 } 4699 4700 public void cancelIntentSender(IIntentSender sender) { 4701 if (!(sender instanceof PendingIntentRecord)) { 4702 return; 4703 } 4704 synchronized(this) { 4705 PendingIntentRecord rec = (PendingIntentRecord)sender; 4706 try { 4707 int uid = AppGlobals.getPackageManager() 4708 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4709 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4710 String msg = "Permission Denial: cancelIntentSender() from pid=" 4711 + Binder.getCallingPid() 4712 + ", uid=" + Binder.getCallingUid() 4713 + " is not allowed to cancel packges " 4714 + rec.key.packageName; 4715 Slog.w(TAG, msg); 4716 throw new SecurityException(msg); 4717 } 4718 } catch (RemoteException e) { 4719 throw new SecurityException(e); 4720 } 4721 cancelIntentSenderLocked(rec, true); 4722 } 4723 } 4724 4725 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4726 rec.canceled = true; 4727 mIntentSenderRecords.remove(rec.key); 4728 if (cleanActivity && rec.key.activity != null) { 4729 rec.key.activity.pendingResults.remove(rec.ref); 4730 } 4731 } 4732 4733 public String getPackageForIntentSender(IIntentSender pendingResult) { 4734 if (!(pendingResult instanceof PendingIntentRecord)) { 4735 return null; 4736 } 4737 try { 4738 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4739 return res.key.packageName; 4740 } catch (ClassCastException e) { 4741 } 4742 return null; 4743 } 4744 4745 public int getUidForIntentSender(IIntentSender sender) { 4746 if (sender instanceof PendingIntentRecord) { 4747 try { 4748 PendingIntentRecord res = (PendingIntentRecord)sender; 4749 return res.uid; 4750 } catch (ClassCastException e) { 4751 } 4752 } 4753 return -1; 4754 } 4755 4756 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4757 if (!(pendingResult instanceof PendingIntentRecord)) { 4758 return false; 4759 } 4760 try { 4761 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4762 if (res.key.allIntents == null) { 4763 return false; 4764 } 4765 for (int i=0; i<res.key.allIntents.length; i++) { 4766 Intent intent = res.key.allIntents[i]; 4767 if (intent.getPackage() != null && intent.getComponent() != null) { 4768 return false; 4769 } 4770 } 4771 return true; 4772 } catch (ClassCastException e) { 4773 } 4774 return false; 4775 } 4776 4777 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4778 if (!(pendingResult instanceof PendingIntentRecord)) { 4779 return false; 4780 } 4781 try { 4782 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4783 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4784 return true; 4785 } 4786 return false; 4787 } catch (ClassCastException e) { 4788 } 4789 return false; 4790 } 4791 4792 public void setProcessLimit(int max) { 4793 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4794 "setProcessLimit()"); 4795 synchronized (this) { 4796 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4797 mProcessLimitOverride = max; 4798 } 4799 trimApplications(); 4800 } 4801 4802 public int getProcessLimit() { 4803 synchronized (this) { 4804 return mProcessLimitOverride; 4805 } 4806 } 4807 4808 void foregroundTokenDied(ForegroundToken token) { 4809 synchronized (ActivityManagerService.this) { 4810 synchronized (mPidsSelfLocked) { 4811 ForegroundToken cur 4812 = mForegroundProcesses.get(token.pid); 4813 if (cur != token) { 4814 return; 4815 } 4816 mForegroundProcesses.remove(token.pid); 4817 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4818 if (pr == null) { 4819 return; 4820 } 4821 pr.forcingToForeground = null; 4822 pr.foregroundServices = false; 4823 } 4824 updateOomAdjLocked(); 4825 } 4826 } 4827 4828 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4829 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4830 "setProcessForeground()"); 4831 synchronized(this) { 4832 boolean changed = false; 4833 4834 synchronized (mPidsSelfLocked) { 4835 ProcessRecord pr = mPidsSelfLocked.get(pid); 4836 if (pr == null && isForeground) { 4837 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4838 return; 4839 } 4840 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4841 if (oldToken != null) { 4842 oldToken.token.unlinkToDeath(oldToken, 0); 4843 mForegroundProcesses.remove(pid); 4844 if (pr != null) { 4845 pr.forcingToForeground = null; 4846 } 4847 changed = true; 4848 } 4849 if (isForeground && token != null) { 4850 ForegroundToken newToken = new ForegroundToken() { 4851 public void binderDied() { 4852 foregroundTokenDied(this); 4853 } 4854 }; 4855 newToken.pid = pid; 4856 newToken.token = token; 4857 try { 4858 token.linkToDeath(newToken, 0); 4859 mForegroundProcesses.put(pid, newToken); 4860 pr.forcingToForeground = token; 4861 changed = true; 4862 } catch (RemoteException e) { 4863 // If the process died while doing this, we will later 4864 // do the cleanup with the process death link. 4865 } 4866 } 4867 } 4868 4869 if (changed) { 4870 updateOomAdjLocked(); 4871 } 4872 } 4873 } 4874 4875 // ========================================================= 4876 // PERMISSIONS 4877 // ========================================================= 4878 4879 static class PermissionController extends IPermissionController.Stub { 4880 ActivityManagerService mActivityManagerService; 4881 PermissionController(ActivityManagerService activityManagerService) { 4882 mActivityManagerService = activityManagerService; 4883 } 4884 4885 public boolean checkPermission(String permission, int pid, int uid) { 4886 return mActivityManagerService.checkPermission(permission, pid, 4887 uid) == PackageManager.PERMISSION_GRANTED; 4888 } 4889 } 4890 4891 /** 4892 * This can be called with or without the global lock held. 4893 */ 4894 int checkComponentPermission(String permission, int pid, int uid, 4895 int owningUid, boolean exported) { 4896 // We might be performing an operation on behalf of an indirect binder 4897 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4898 // client identity accordingly before proceeding. 4899 Identity tlsIdentity = sCallerIdentity.get(); 4900 if (tlsIdentity != null) { 4901 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4902 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4903 uid = tlsIdentity.uid; 4904 pid = tlsIdentity.pid; 4905 } 4906 4907 if (pid == MY_PID) { 4908 return PackageManager.PERMISSION_GRANTED; 4909 } 4910 4911 return ActivityManager.checkComponentPermission(permission, uid, 4912 owningUid, exported); 4913 } 4914 4915 /** 4916 * As the only public entry point for permissions checking, this method 4917 * can enforce the semantic that requesting a check on a null global 4918 * permission is automatically denied. (Internally a null permission 4919 * string is used when calling {@link #checkComponentPermission} in cases 4920 * when only uid-based security is needed.) 4921 * 4922 * This can be called with or without the global lock held. 4923 */ 4924 public int checkPermission(String permission, int pid, int uid) { 4925 if (permission == null) { 4926 return PackageManager.PERMISSION_DENIED; 4927 } 4928 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4929 } 4930 4931 /** 4932 * Binder IPC calls go through the public entry point. 4933 * This can be called with or without the global lock held. 4934 */ 4935 int checkCallingPermission(String permission) { 4936 return checkPermission(permission, 4937 Binder.getCallingPid(), 4938 UserHandle.getAppId(Binder.getCallingUid())); 4939 } 4940 4941 /** 4942 * This can be called with or without the global lock held. 4943 */ 4944 void enforceCallingPermission(String permission, String func) { 4945 if (checkCallingPermission(permission) 4946 == PackageManager.PERMISSION_GRANTED) { 4947 return; 4948 } 4949 4950 String msg = "Permission Denial: " + func + " from pid=" 4951 + Binder.getCallingPid() 4952 + ", uid=" + Binder.getCallingUid() 4953 + " requires " + permission; 4954 Slog.w(TAG, msg); 4955 throw new SecurityException(msg); 4956 } 4957 4958 /** 4959 * Determine if UID is holding permissions required to access {@link Uri} in 4960 * the given {@link ProviderInfo}. Final permission checking is always done 4961 * in {@link ContentProvider}. 4962 */ 4963 private final boolean checkHoldingPermissionsLocked( 4964 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4965 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4966 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4967 4968 if (pi.applicationInfo.uid == uid) { 4969 return true; 4970 } else if (!pi.exported) { 4971 return false; 4972 } 4973 4974 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4975 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4976 try { 4977 // check if target holds top-level <provider> permissions 4978 if (!readMet && pi.readPermission != null 4979 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4980 readMet = true; 4981 } 4982 if (!writeMet && pi.writePermission != null 4983 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4984 writeMet = true; 4985 } 4986 4987 // track if unprotected read/write is allowed; any denied 4988 // <path-permission> below removes this ability 4989 boolean allowDefaultRead = pi.readPermission == null; 4990 boolean allowDefaultWrite = pi.writePermission == null; 4991 4992 // check if target holds any <path-permission> that match uri 4993 final PathPermission[] pps = pi.pathPermissions; 4994 if (pps != null) { 4995 final String path = uri.getPath(); 4996 int i = pps.length; 4997 while (i > 0 && (!readMet || !writeMet)) { 4998 i--; 4999 PathPermission pp = pps[i]; 5000 if (pp.match(path)) { 5001 if (!readMet) { 5002 final String pprperm = pp.getReadPermission(); 5003 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5004 + pprperm + " for " + pp.getPath() 5005 + ": match=" + pp.match(path) 5006 + " check=" + pm.checkUidPermission(pprperm, uid)); 5007 if (pprperm != null) { 5008 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5009 readMet = true; 5010 } else { 5011 allowDefaultRead = false; 5012 } 5013 } 5014 } 5015 if (!writeMet) { 5016 final String ppwperm = pp.getWritePermission(); 5017 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5018 + ppwperm + " for " + pp.getPath() 5019 + ": match=" + pp.match(path) 5020 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5021 if (ppwperm != null) { 5022 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5023 writeMet = true; 5024 } else { 5025 allowDefaultWrite = false; 5026 } 5027 } 5028 } 5029 } 5030 } 5031 } 5032 5033 // grant unprotected <provider> read/write, if not blocked by 5034 // <path-permission> above 5035 if (allowDefaultRead) readMet = true; 5036 if (allowDefaultWrite) writeMet = true; 5037 5038 } catch (RemoteException e) { 5039 return false; 5040 } 5041 5042 return readMet && writeMet; 5043 } 5044 5045 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5046 int modeFlags) { 5047 // Root gets to do everything. 5048 if (uid == 0) { 5049 return true; 5050 } 5051 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5052 if (perms == null) return false; 5053 UriPermission perm = perms.get(uri); 5054 if (perm == null) return false; 5055 return (modeFlags&perm.modeFlags) == modeFlags; 5056 } 5057 5058 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5059 enforceNotIsolatedCaller("checkUriPermission"); 5060 5061 // Another redirected-binder-call permissions check as in 5062 // {@link checkComponentPermission}. 5063 Identity tlsIdentity = sCallerIdentity.get(); 5064 if (tlsIdentity != null) { 5065 uid = tlsIdentity.uid; 5066 pid = tlsIdentity.pid; 5067 } 5068 5069 // Our own process gets to do everything. 5070 if (pid == MY_PID) { 5071 return PackageManager.PERMISSION_GRANTED; 5072 } 5073 synchronized(this) { 5074 return checkUriPermissionLocked(uri, uid, modeFlags) 5075 ? PackageManager.PERMISSION_GRANTED 5076 : PackageManager.PERMISSION_DENIED; 5077 } 5078 } 5079 5080 /** 5081 * Check if the targetPkg can be granted permission to access uri by 5082 * the callingUid using the given modeFlags. Throws a security exception 5083 * if callingUid is not allowed to do this. Returns the uid of the target 5084 * if the URI permission grant should be performed; returns -1 if it is not 5085 * needed (for example targetPkg already has permission to access the URI). 5086 * If you already know the uid of the target, you can supply it in 5087 * lastTargetUid else set that to -1. 5088 */ 5089 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5090 Uri uri, int modeFlags, int lastTargetUid) { 5091 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5092 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5093 if (modeFlags == 0) { 5094 return -1; 5095 } 5096 5097 if (targetPkg != null) { 5098 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5099 "Checking grant " + targetPkg + " permission to " + uri); 5100 } 5101 5102 final IPackageManager pm = AppGlobals.getPackageManager(); 5103 5104 // If this is not a content: uri, we can't do anything with it. 5105 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5106 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5107 "Can't grant URI permission for non-content URI: " + uri); 5108 return -1; 5109 } 5110 5111 String name = uri.getAuthority(); 5112 ProviderInfo pi = null; 5113 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5114 UserHandle.getUserId(callingUid)); 5115 if (cpr != null) { 5116 pi = cpr.info; 5117 } else { 5118 try { 5119 pi = pm.resolveContentProvider(name, 5120 PackageManager.GET_URI_PERMISSION_PATTERNS, 5121 UserHandle.getUserId(callingUid)); 5122 } catch (RemoteException ex) { 5123 } 5124 } 5125 if (pi == null) { 5126 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5127 return -1; 5128 } 5129 5130 int targetUid = lastTargetUid; 5131 if (targetUid < 0 && targetPkg != null) { 5132 try { 5133 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5134 if (targetUid < 0) { 5135 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5136 "Can't grant URI permission no uid for: " + targetPkg); 5137 return -1; 5138 } 5139 } catch (RemoteException ex) { 5140 return -1; 5141 } 5142 } 5143 5144 if (targetUid >= 0) { 5145 // First... does the target actually need this permission? 5146 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5147 // No need to grant the target this permission. 5148 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5149 "Target " + targetPkg + " already has full permission to " + uri); 5150 return -1; 5151 } 5152 } else { 5153 // First... there is no target package, so can anyone access it? 5154 boolean allowed = pi.exported; 5155 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5156 if (pi.readPermission != null) { 5157 allowed = false; 5158 } 5159 } 5160 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5161 if (pi.writePermission != null) { 5162 allowed = false; 5163 } 5164 } 5165 if (allowed) { 5166 return -1; 5167 } 5168 } 5169 5170 // Second... is the provider allowing granting of URI permissions? 5171 if (!pi.grantUriPermissions) { 5172 throw new SecurityException("Provider " + pi.packageName 5173 + "/" + pi.name 5174 + " does not allow granting of Uri permissions (uri " 5175 + uri + ")"); 5176 } 5177 if (pi.uriPermissionPatterns != null) { 5178 final int N = pi.uriPermissionPatterns.length; 5179 boolean allowed = false; 5180 for (int i=0; i<N; i++) { 5181 if (pi.uriPermissionPatterns[i] != null 5182 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5183 allowed = true; 5184 break; 5185 } 5186 } 5187 if (!allowed) { 5188 throw new SecurityException("Provider " + pi.packageName 5189 + "/" + pi.name 5190 + " does not allow granting of permission to path of Uri " 5191 + uri); 5192 } 5193 } 5194 5195 // Third... does the caller itself have permission to access 5196 // this uri? 5197 if (callingUid != Process.myUid()) { 5198 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5199 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5200 throw new SecurityException("Uid " + callingUid 5201 + " does not have permission to uri " + uri); 5202 } 5203 } 5204 } 5205 5206 return targetUid; 5207 } 5208 5209 public int checkGrantUriPermission(int callingUid, String targetPkg, 5210 Uri uri, int modeFlags) { 5211 enforceNotIsolatedCaller("checkGrantUriPermission"); 5212 synchronized(this) { 5213 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5214 } 5215 } 5216 5217 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5218 Uri uri, int modeFlags, UriPermissionOwner owner) { 5219 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5220 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5221 if (modeFlags == 0) { 5222 return; 5223 } 5224 5225 // So here we are: the caller has the assumed permission 5226 // to the uri, and the target doesn't. Let's now give this to 5227 // the target. 5228 5229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5230 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5231 5232 HashMap<Uri, UriPermission> targetUris 5233 = mGrantedUriPermissions.get(targetUid); 5234 if (targetUris == null) { 5235 targetUris = new HashMap<Uri, UriPermission>(); 5236 mGrantedUriPermissions.put(targetUid, targetUris); 5237 } 5238 5239 UriPermission perm = targetUris.get(uri); 5240 if (perm == null) { 5241 perm = new UriPermission(targetUid, uri); 5242 targetUris.put(uri, perm); 5243 } 5244 5245 perm.modeFlags |= modeFlags; 5246 if (owner == null) { 5247 perm.globalModeFlags |= modeFlags; 5248 } else { 5249 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5250 perm.readOwners.add(owner); 5251 owner.addReadPermission(perm); 5252 } 5253 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5254 perm.writeOwners.add(owner); 5255 owner.addWritePermission(perm); 5256 } 5257 } 5258 } 5259 5260 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5261 int modeFlags, UriPermissionOwner owner) { 5262 if (targetPkg == null) { 5263 throw new NullPointerException("targetPkg"); 5264 } 5265 5266 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5267 if (targetUid < 0) { 5268 return; 5269 } 5270 5271 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5272 } 5273 5274 static class NeededUriGrants extends ArrayList<Uri> { 5275 final String targetPkg; 5276 final int targetUid; 5277 final int flags; 5278 5279 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5280 targetPkg = _targetPkg; 5281 targetUid = _targetUid; 5282 flags = _flags; 5283 } 5284 } 5285 5286 /** 5287 * Like checkGrantUriPermissionLocked, but takes an Intent. 5288 */ 5289 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5290 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5291 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5292 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5293 + " clip=" + (intent != null ? intent.getClipData() : null) 5294 + " from " + intent + "; flags=0x" 5295 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5296 5297 if (targetPkg == null) { 5298 throw new NullPointerException("targetPkg"); 5299 } 5300 5301 if (intent == null) { 5302 return null; 5303 } 5304 Uri data = intent.getData(); 5305 ClipData clip = intent.getClipData(); 5306 if (data == null && clip == null) { 5307 return null; 5308 } 5309 if (data != null) { 5310 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5311 mode, needed != null ? needed.targetUid : -1); 5312 if (target > 0) { 5313 if (needed == null) { 5314 needed = new NeededUriGrants(targetPkg, target, mode); 5315 } 5316 needed.add(data); 5317 } 5318 } 5319 if (clip != null) { 5320 for (int i=0; i<clip.getItemCount(); i++) { 5321 Uri uri = clip.getItemAt(i).getUri(); 5322 if (uri != null) { 5323 int target = -1; 5324 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5325 mode, needed != null ? needed.targetUid : -1); 5326 if (target > 0) { 5327 if (needed == null) { 5328 needed = new NeededUriGrants(targetPkg, target, mode); 5329 } 5330 needed.add(uri); 5331 } 5332 } else { 5333 Intent clipIntent = clip.getItemAt(i).getIntent(); 5334 if (clipIntent != null) { 5335 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5336 callingUid, targetPkg, clipIntent, mode, needed); 5337 if (newNeeded != null) { 5338 needed = newNeeded; 5339 } 5340 } 5341 } 5342 } 5343 } 5344 5345 return needed; 5346 } 5347 5348 /** 5349 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5350 */ 5351 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5352 UriPermissionOwner owner) { 5353 if (needed != null) { 5354 for (int i=0; i<needed.size(); i++) { 5355 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5356 needed.get(i), needed.flags, owner); 5357 } 5358 } 5359 } 5360 5361 void grantUriPermissionFromIntentLocked(int callingUid, 5362 String targetPkg, Intent intent, UriPermissionOwner owner) { 5363 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5364 intent, intent != null ? intent.getFlags() : 0, null); 5365 if (needed == null) { 5366 return; 5367 } 5368 5369 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5370 } 5371 5372 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5373 Uri uri, int modeFlags) { 5374 enforceNotIsolatedCaller("grantUriPermission"); 5375 synchronized(this) { 5376 final ProcessRecord r = getRecordForAppLocked(caller); 5377 if (r == null) { 5378 throw new SecurityException("Unable to find app for caller " 5379 + caller 5380 + " when granting permission to uri " + uri); 5381 } 5382 if (targetPkg == null) { 5383 throw new IllegalArgumentException("null target"); 5384 } 5385 if (uri == null) { 5386 throw new IllegalArgumentException("null uri"); 5387 } 5388 5389 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5390 null); 5391 } 5392 } 5393 5394 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5395 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5396 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5397 HashMap<Uri, UriPermission> perms 5398 = mGrantedUriPermissions.get(perm.uid); 5399 if (perms != null) { 5400 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5401 "Removing " + perm.uid + " permission to " + perm.uri); 5402 perms.remove(perm.uri); 5403 if (perms.size() == 0) { 5404 mGrantedUriPermissions.remove(perm.uid); 5405 } 5406 } 5407 } 5408 } 5409 5410 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5411 int modeFlags) { 5412 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5413 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5414 if (modeFlags == 0) { 5415 return; 5416 } 5417 5418 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5419 "Revoking all granted permissions to " + uri); 5420 5421 final IPackageManager pm = AppGlobals.getPackageManager(); 5422 5423 final String authority = uri.getAuthority(); 5424 ProviderInfo pi = null; 5425 int userId = UserHandle.getUserId(callingUid); 5426 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5427 if (cpr != null) { 5428 pi = cpr.info; 5429 } else { 5430 try { 5431 pi = pm.resolveContentProvider(authority, 5432 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5433 } catch (RemoteException ex) { 5434 } 5435 } 5436 if (pi == null) { 5437 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5438 return; 5439 } 5440 5441 // Does the caller have this permission on the URI? 5442 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5443 // Right now, if you are not the original owner of the permission, 5444 // you are not allowed to revoke it. 5445 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5446 throw new SecurityException("Uid " + callingUid 5447 + " does not have permission to uri " + uri); 5448 //} 5449 } 5450 5451 // Go through all of the permissions and remove any that match. 5452 final List<String> SEGMENTS = uri.getPathSegments(); 5453 if (SEGMENTS != null) { 5454 final int NS = SEGMENTS.size(); 5455 int N = mGrantedUriPermissions.size(); 5456 for (int i=0; i<N; i++) { 5457 HashMap<Uri, UriPermission> perms 5458 = mGrantedUriPermissions.valueAt(i); 5459 Iterator<UriPermission> it = perms.values().iterator(); 5460 toploop: 5461 while (it.hasNext()) { 5462 UriPermission perm = it.next(); 5463 Uri targetUri = perm.uri; 5464 if (!authority.equals(targetUri.getAuthority())) { 5465 continue; 5466 } 5467 List<String> targetSegments = targetUri.getPathSegments(); 5468 if (targetSegments == null) { 5469 continue; 5470 } 5471 if (targetSegments.size() < NS) { 5472 continue; 5473 } 5474 for (int j=0; j<NS; j++) { 5475 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5476 continue toploop; 5477 } 5478 } 5479 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5480 "Revoking " + perm.uid + " permission to " + perm.uri); 5481 perm.clearModes(modeFlags); 5482 if (perm.modeFlags == 0) { 5483 it.remove(); 5484 } 5485 } 5486 if (perms.size() == 0) { 5487 mGrantedUriPermissions.remove( 5488 mGrantedUriPermissions.keyAt(i)); 5489 N--; 5490 i--; 5491 } 5492 } 5493 } 5494 } 5495 5496 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5497 int modeFlags) { 5498 enforceNotIsolatedCaller("revokeUriPermission"); 5499 synchronized(this) { 5500 final ProcessRecord r = getRecordForAppLocked(caller); 5501 if (r == null) { 5502 throw new SecurityException("Unable to find app for caller " 5503 + caller 5504 + " when revoking permission to uri " + uri); 5505 } 5506 if (uri == null) { 5507 Slog.w(TAG, "revokeUriPermission: null uri"); 5508 return; 5509 } 5510 5511 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5512 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5513 if (modeFlags == 0) { 5514 return; 5515 } 5516 5517 final IPackageManager pm = AppGlobals.getPackageManager(); 5518 5519 final String authority = uri.getAuthority(); 5520 ProviderInfo pi = null; 5521 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5522 if (cpr != null) { 5523 pi = cpr.info; 5524 } else { 5525 try { 5526 pi = pm.resolveContentProvider(authority, 5527 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5528 } catch (RemoteException ex) { 5529 } 5530 } 5531 if (pi == null) { 5532 Slog.w(TAG, "No content provider found for permission revoke: " 5533 + uri.toSafeString()); 5534 return; 5535 } 5536 5537 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5538 } 5539 } 5540 5541 @Override 5542 public IBinder newUriPermissionOwner(String name) { 5543 enforceNotIsolatedCaller("newUriPermissionOwner"); 5544 synchronized(this) { 5545 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5546 return owner.getExternalTokenLocked(); 5547 } 5548 } 5549 5550 @Override 5551 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5552 Uri uri, int modeFlags) { 5553 synchronized(this) { 5554 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5555 if (owner == null) { 5556 throw new IllegalArgumentException("Unknown owner: " + token); 5557 } 5558 if (fromUid != Binder.getCallingUid()) { 5559 if (Binder.getCallingUid() != Process.myUid()) { 5560 // Only system code can grant URI permissions on behalf 5561 // of other users. 5562 throw new SecurityException("nice try"); 5563 } 5564 } 5565 if (targetPkg == null) { 5566 throw new IllegalArgumentException("null target"); 5567 } 5568 if (uri == null) { 5569 throw new IllegalArgumentException("null uri"); 5570 } 5571 5572 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5573 } 5574 } 5575 5576 @Override 5577 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5578 synchronized(this) { 5579 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5580 if (owner == null) { 5581 throw new IllegalArgumentException("Unknown owner: " + token); 5582 } 5583 5584 if (uri == null) { 5585 owner.removeUriPermissionsLocked(mode); 5586 } else { 5587 owner.removeUriPermissionLocked(uri, mode); 5588 } 5589 } 5590 } 5591 5592 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5593 synchronized (this) { 5594 ProcessRecord app = 5595 who != null ? getRecordForAppLocked(who) : null; 5596 if (app == null) return; 5597 5598 Message msg = Message.obtain(); 5599 msg.what = WAIT_FOR_DEBUGGER_MSG; 5600 msg.obj = app; 5601 msg.arg1 = waiting ? 1 : 0; 5602 mHandler.sendMessage(msg); 5603 } 5604 } 5605 5606 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5607 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5608 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5609 outInfo.availMem = Process.getFreeMemory(); 5610 outInfo.totalMem = Process.getTotalMemory(); 5611 outInfo.threshold = homeAppMem; 5612 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5613 outInfo.hiddenAppThreshold = hiddenAppMem; 5614 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5615 ProcessList.SERVICE_ADJ); 5616 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5617 ProcessList.VISIBLE_APP_ADJ); 5618 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5619 ProcessList.FOREGROUND_APP_ADJ); 5620 } 5621 5622 // ========================================================= 5623 // TASK MANAGEMENT 5624 // ========================================================= 5625 5626 public List getTasks(int maxNum, int flags, 5627 IThumbnailReceiver receiver) { 5628 ArrayList list = new ArrayList(); 5629 5630 PendingThumbnailsRecord pending = null; 5631 IApplicationThread topThumbnail = null; 5632 ActivityRecord topRecord = null; 5633 5634 synchronized(this) { 5635 if (localLOGV) Slog.v( 5636 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5637 + ", receiver=" + receiver); 5638 5639 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5640 != PackageManager.PERMISSION_GRANTED) { 5641 if (receiver != null) { 5642 // If the caller wants to wait for pending thumbnails, 5643 // it ain't gonna get them. 5644 try { 5645 receiver.finished(); 5646 } catch (RemoteException ex) { 5647 } 5648 } 5649 String msg = "Permission Denial: getTasks() from pid=" 5650 + Binder.getCallingPid() 5651 + ", uid=" + Binder.getCallingUid() 5652 + " requires " + android.Manifest.permission.GET_TASKS; 5653 Slog.w(TAG, msg); 5654 throw new SecurityException(msg); 5655 } 5656 5657 int pos = mMainStack.mHistory.size()-1; 5658 ActivityRecord next = 5659 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5660 ActivityRecord top = null; 5661 TaskRecord curTask = null; 5662 int numActivities = 0; 5663 int numRunning = 0; 5664 while (pos >= 0 && maxNum > 0) { 5665 final ActivityRecord r = next; 5666 pos--; 5667 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5668 5669 // Initialize state for next task if needed. 5670 if (top == null || 5671 (top.state == ActivityState.INITIALIZING 5672 && top.task == r.task)) { 5673 top = r; 5674 curTask = r.task; 5675 numActivities = numRunning = 0; 5676 } 5677 5678 // Add 'r' into the current task. 5679 numActivities++; 5680 if (r.app != null && r.app.thread != null) { 5681 numRunning++; 5682 } 5683 5684 if (localLOGV) Slog.v( 5685 TAG, r.intent.getComponent().flattenToShortString() 5686 + ": task=" + r.task); 5687 5688 // If the next one is a different task, generate a new 5689 // TaskInfo entry for what we have. 5690 if (next == null || next.task != curTask) { 5691 ActivityManager.RunningTaskInfo ci 5692 = new ActivityManager.RunningTaskInfo(); 5693 ci.id = curTask.taskId; 5694 ci.baseActivity = r.intent.getComponent(); 5695 ci.topActivity = top.intent.getComponent(); 5696 if (top.thumbHolder != null) { 5697 ci.description = top.thumbHolder.lastDescription; 5698 } 5699 ci.numActivities = numActivities; 5700 ci.numRunning = numRunning; 5701 //System.out.println( 5702 // "#" + maxNum + ": " + " descr=" + ci.description); 5703 if (ci.thumbnail == null && receiver != null) { 5704 if (localLOGV) Slog.v( 5705 TAG, "State=" + top.state + "Idle=" + top.idle 5706 + " app=" + top.app 5707 + " thr=" + (top.app != null ? top.app.thread : null)); 5708 if (top.state == ActivityState.RESUMED 5709 || top.state == ActivityState.PAUSING) { 5710 if (top.idle && top.app != null 5711 && top.app.thread != null) { 5712 topRecord = top; 5713 topThumbnail = top.app.thread; 5714 } else { 5715 top.thumbnailNeeded = true; 5716 } 5717 } 5718 if (pending == null) { 5719 pending = new PendingThumbnailsRecord(receiver); 5720 } 5721 pending.pendingRecords.add(top); 5722 } 5723 list.add(ci); 5724 maxNum--; 5725 top = null; 5726 } 5727 } 5728 5729 if (pending != null) { 5730 mPendingThumbnails.add(pending); 5731 } 5732 } 5733 5734 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5735 5736 if (topThumbnail != null) { 5737 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5738 try { 5739 topThumbnail.requestThumbnail(topRecord.appToken); 5740 } catch (Exception e) { 5741 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5742 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5743 } 5744 } 5745 5746 if (pending == null && receiver != null) { 5747 // In this case all thumbnails were available and the client 5748 // is being asked to be told when the remaining ones come in... 5749 // which is unusually, since the top-most currently running 5750 // activity should never have a canned thumbnail! Oh well. 5751 try { 5752 receiver.finished(); 5753 } catch (RemoteException ex) { 5754 } 5755 } 5756 5757 return list; 5758 } 5759 5760 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5761 int flags, int userId) { 5762 final int callingUid = Binder.getCallingUid(); 5763 if (userId != UserHandle.getCallingUserId()) { 5764 // Check if the caller is holding permissions for cross-user requests. 5765 if (checkComponentPermission( 5766 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5767 Binder.getCallingPid(), callingUid, -1, true) 5768 != PackageManager.PERMISSION_GRANTED) { 5769 String msg = "Permission Denial: " 5770 + "Request to get recent tasks for user " + userId 5771 + " but is calling from user " + UserHandle.getUserId(callingUid) 5772 + "; this requires " 5773 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5774 Slog.w(TAG, msg); 5775 throw new SecurityException(msg); 5776 } else { 5777 if (userId == UserHandle.USER_CURRENT) { 5778 userId = mCurrentUserId; 5779 } 5780 } 5781 } 5782 5783 synchronized (this) { 5784 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5785 "getRecentTasks()"); 5786 final boolean detailed = checkCallingPermission( 5787 android.Manifest.permission.GET_DETAILED_TASKS) 5788 == PackageManager.PERMISSION_GRANTED; 5789 5790 IPackageManager pm = AppGlobals.getPackageManager(); 5791 5792 final int N = mRecentTasks.size(); 5793 ArrayList<ActivityManager.RecentTaskInfo> res 5794 = new ArrayList<ActivityManager.RecentTaskInfo>( 5795 maxNum < N ? maxNum : N); 5796 for (int i=0; i<N && maxNum > 0; i++) { 5797 TaskRecord tr = mRecentTasks.get(i); 5798 // Only add calling user's recent tasks 5799 if (tr.userId != userId) continue; 5800 // Return the entry if desired by the caller. We always return 5801 // the first entry, because callers always expect this to be the 5802 // foreground app. We may filter others if the caller has 5803 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5804 // we should exclude the entry. 5805 5806 if (i == 0 5807 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5808 || (tr.intent == null) 5809 || ((tr.intent.getFlags() 5810 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5811 ActivityManager.RecentTaskInfo rti 5812 = new ActivityManager.RecentTaskInfo(); 5813 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5814 rti.persistentId = tr.taskId; 5815 rti.baseIntent = new Intent( 5816 tr.intent != null ? tr.intent : tr.affinityIntent); 5817 if (!detailed) { 5818 rti.baseIntent.replaceExtras((Bundle)null); 5819 } 5820 rti.origActivity = tr.origActivity; 5821 rti.description = tr.lastDescription; 5822 5823 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5824 // Check whether this activity is currently available. 5825 try { 5826 if (rti.origActivity != null) { 5827 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5828 == null) { 5829 continue; 5830 } 5831 } else if (rti.baseIntent != null) { 5832 if (pm.queryIntentActivities(rti.baseIntent, 5833 null, 0, userId) == null) { 5834 continue; 5835 } 5836 } 5837 } catch (RemoteException e) { 5838 // Will never happen. 5839 } 5840 } 5841 5842 res.add(rti); 5843 maxNum--; 5844 } 5845 } 5846 return res; 5847 } 5848 } 5849 5850 private TaskRecord taskForIdLocked(int id) { 5851 final int N = mRecentTasks.size(); 5852 for (int i=0; i<N; i++) { 5853 TaskRecord tr = mRecentTasks.get(i); 5854 if (tr.taskId == id) { 5855 return tr; 5856 } 5857 } 5858 return null; 5859 } 5860 5861 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5862 synchronized (this) { 5863 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5864 "getTaskThumbnails()"); 5865 TaskRecord tr = taskForIdLocked(id); 5866 if (tr != null) { 5867 return mMainStack.getTaskThumbnailsLocked(tr); 5868 } 5869 } 5870 return null; 5871 } 5872 5873 public Bitmap getTaskTopThumbnail(int id) { 5874 synchronized (this) { 5875 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5876 "getTaskTopThumbnail()"); 5877 TaskRecord tr = taskForIdLocked(id); 5878 if (tr != null) { 5879 return mMainStack.getTaskTopThumbnailLocked(tr); 5880 } 5881 } 5882 return null; 5883 } 5884 5885 public boolean removeSubTask(int taskId, int subTaskIndex) { 5886 synchronized (this) { 5887 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5888 "removeSubTask()"); 5889 long ident = Binder.clearCallingIdentity(); 5890 try { 5891 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5892 true) != null; 5893 } finally { 5894 Binder.restoreCallingIdentity(ident); 5895 } 5896 } 5897 } 5898 5899 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5900 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5901 Intent baseIntent = new Intent( 5902 tr.intent != null ? tr.intent : tr.affinityIntent); 5903 ComponentName component = baseIntent.getComponent(); 5904 if (component == null) { 5905 Slog.w(TAG, "Now component for base intent of task: " + tr); 5906 return; 5907 } 5908 5909 // Find any running services associated with this app. 5910 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5911 5912 if (killProcesses) { 5913 // Find any running processes associated with this app. 5914 final String pkg = component.getPackageName(); 5915 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5916 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5917 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5918 for (int i=0; i<uids.size(); i++) { 5919 ProcessRecord proc = uids.valueAt(i); 5920 if (proc.userId != tr.userId) { 5921 continue; 5922 } 5923 if (!proc.pkgList.contains(pkg)) { 5924 continue; 5925 } 5926 procs.add(proc); 5927 } 5928 } 5929 5930 // Kill the running processes. 5931 for (int i=0; i<procs.size(); i++) { 5932 ProcessRecord pr = procs.get(i); 5933 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5934 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5935 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5936 pr.processName, pr.setAdj, "remove task"); 5937 pr.killedBackground = true; 5938 Process.killProcessQuiet(pr.pid); 5939 } else { 5940 pr.waitingToKill = "remove task"; 5941 } 5942 } 5943 } 5944 } 5945 5946 public boolean removeTask(int taskId, int flags) { 5947 synchronized (this) { 5948 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5949 "removeTask()"); 5950 long ident = Binder.clearCallingIdentity(); 5951 try { 5952 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5953 false); 5954 if (r != null) { 5955 mRecentTasks.remove(r.task); 5956 cleanUpRemovedTaskLocked(r.task, flags); 5957 return true; 5958 } else { 5959 TaskRecord tr = null; 5960 int i=0; 5961 while (i < mRecentTasks.size()) { 5962 TaskRecord t = mRecentTasks.get(i); 5963 if (t.taskId == taskId) { 5964 tr = t; 5965 break; 5966 } 5967 i++; 5968 } 5969 if (tr != null) { 5970 if (tr.numActivities <= 0) { 5971 // Caller is just removing a recent task that is 5972 // not actively running. That is easy! 5973 mRecentTasks.remove(i); 5974 cleanUpRemovedTaskLocked(tr, flags); 5975 return true; 5976 } else { 5977 Slog.w(TAG, "removeTask: task " + taskId 5978 + " does not have activities to remove, " 5979 + " but numActivities=" + tr.numActivities 5980 + ": " + tr); 5981 } 5982 } 5983 } 5984 } finally { 5985 Binder.restoreCallingIdentity(ident); 5986 } 5987 } 5988 return false; 5989 } 5990 5991 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5992 int j; 5993 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5994 TaskRecord jt = startTask; 5995 5996 // First look backwards 5997 for (j=startIndex-1; j>=0; j--) { 5998 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5999 if (r.task != jt) { 6000 jt = r.task; 6001 if (affinity.equals(jt.affinity)) { 6002 return j; 6003 } 6004 } 6005 } 6006 6007 // Now look forwards 6008 final int N = mMainStack.mHistory.size(); 6009 jt = startTask; 6010 for (j=startIndex+1; j<N; j++) { 6011 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 6012 if (r.task != jt) { 6013 if (affinity.equals(jt.affinity)) { 6014 return j; 6015 } 6016 jt = r.task; 6017 } 6018 } 6019 6020 // Might it be at the top? 6021 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 6022 return N-1; 6023 } 6024 6025 return -1; 6026 } 6027 6028 /** 6029 * TODO: Add mController hook 6030 */ 6031 public void moveTaskToFront(int task, int flags, Bundle options) { 6032 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6033 "moveTaskToFront()"); 6034 6035 synchronized(this) { 6036 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6037 Binder.getCallingUid(), "Task to front")) { 6038 ActivityOptions.abort(options); 6039 return; 6040 } 6041 final long origId = Binder.clearCallingIdentity(); 6042 try { 6043 TaskRecord tr = taskForIdLocked(task); 6044 if (tr != null) { 6045 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6046 mMainStack.mUserLeaving = true; 6047 } 6048 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6049 // Caller wants the home activity moved with it. To accomplish this, 6050 // we'll just move the home task to the top first. 6051 mMainStack.moveHomeToFrontLocked(); 6052 } 6053 mMainStack.moveTaskToFrontLocked(tr, null, options); 6054 return; 6055 } 6056 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6057 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6058 if (hr.task.taskId == task) { 6059 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6060 mMainStack.mUserLeaving = true; 6061 } 6062 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6063 // Caller wants the home activity moved with it. To accomplish this, 6064 // we'll just move the home task to the top first. 6065 mMainStack.moveHomeToFrontLocked(); 6066 } 6067 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6068 return; 6069 } 6070 } 6071 } finally { 6072 Binder.restoreCallingIdentity(origId); 6073 } 6074 ActivityOptions.abort(options); 6075 } 6076 } 6077 6078 public void moveTaskToBack(int task) { 6079 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6080 "moveTaskToBack()"); 6081 6082 synchronized(this) { 6083 if (mMainStack.mResumedActivity != null 6084 && mMainStack.mResumedActivity.task.taskId == task) { 6085 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6086 Binder.getCallingUid(), "Task to back")) { 6087 return; 6088 } 6089 } 6090 final long origId = Binder.clearCallingIdentity(); 6091 mMainStack.moveTaskToBackLocked(task, null); 6092 Binder.restoreCallingIdentity(origId); 6093 } 6094 } 6095 6096 /** 6097 * Moves an activity, and all of the other activities within the same task, to the bottom 6098 * of the history stack. The activity's order within the task is unchanged. 6099 * 6100 * @param token A reference to the activity we wish to move 6101 * @param nonRoot If false then this only works if the activity is the root 6102 * of a task; if true it will work for any activity in a task. 6103 * @return Returns true if the move completed, false if not. 6104 */ 6105 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6106 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6107 synchronized(this) { 6108 final long origId = Binder.clearCallingIdentity(); 6109 int taskId = getTaskForActivityLocked(token, !nonRoot); 6110 if (taskId >= 0) { 6111 return mMainStack.moveTaskToBackLocked(taskId, null); 6112 } 6113 Binder.restoreCallingIdentity(origId); 6114 } 6115 return false; 6116 } 6117 6118 public void moveTaskBackwards(int task) { 6119 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6120 "moveTaskBackwards()"); 6121 6122 synchronized(this) { 6123 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6124 Binder.getCallingUid(), "Task backwards")) { 6125 return; 6126 } 6127 final long origId = Binder.clearCallingIdentity(); 6128 moveTaskBackwardsLocked(task); 6129 Binder.restoreCallingIdentity(origId); 6130 } 6131 } 6132 6133 private final void moveTaskBackwardsLocked(int task) { 6134 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6135 } 6136 6137 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6138 synchronized(this) { 6139 return getTaskForActivityLocked(token, onlyRoot); 6140 } 6141 } 6142 6143 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6144 final int N = mMainStack.mHistory.size(); 6145 TaskRecord lastTask = null; 6146 for (int i=0; i<N; i++) { 6147 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6148 if (r.appToken == token) { 6149 if (!onlyRoot || lastTask != r.task) { 6150 return r.task.taskId; 6151 } 6152 return -1; 6153 } 6154 lastTask = r.task; 6155 } 6156 6157 return -1; 6158 } 6159 6160 // ========================================================= 6161 // THUMBNAILS 6162 // ========================================================= 6163 6164 public void reportThumbnail(IBinder token, 6165 Bitmap thumbnail, CharSequence description) { 6166 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6167 final long origId = Binder.clearCallingIdentity(); 6168 sendPendingThumbnail(null, token, thumbnail, description, true); 6169 Binder.restoreCallingIdentity(origId); 6170 } 6171 6172 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6173 Bitmap thumbnail, CharSequence description, boolean always) { 6174 TaskRecord task = null; 6175 ArrayList receivers = null; 6176 6177 //System.out.println("Send pending thumbnail: " + r); 6178 6179 synchronized(this) { 6180 if (r == null) { 6181 r = mMainStack.isInStackLocked(token); 6182 if (r == null) { 6183 return; 6184 } 6185 } 6186 if (thumbnail == null && r.thumbHolder != null) { 6187 thumbnail = r.thumbHolder.lastThumbnail; 6188 description = r.thumbHolder.lastDescription; 6189 } 6190 if (thumbnail == null && !always) { 6191 // If there is no thumbnail, and this entry is not actually 6192 // going away, then abort for now and pick up the next 6193 // thumbnail we get. 6194 return; 6195 } 6196 task = r.task; 6197 6198 int N = mPendingThumbnails.size(); 6199 int i=0; 6200 while (i<N) { 6201 PendingThumbnailsRecord pr = 6202 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6203 //System.out.println("Looking in " + pr.pendingRecords); 6204 if (pr.pendingRecords.remove(r)) { 6205 if (receivers == null) { 6206 receivers = new ArrayList(); 6207 } 6208 receivers.add(pr); 6209 if (pr.pendingRecords.size() == 0) { 6210 pr.finished = true; 6211 mPendingThumbnails.remove(i); 6212 N--; 6213 continue; 6214 } 6215 } 6216 i++; 6217 } 6218 } 6219 6220 if (receivers != null) { 6221 final int N = receivers.size(); 6222 for (int i=0; i<N; i++) { 6223 try { 6224 PendingThumbnailsRecord pr = 6225 (PendingThumbnailsRecord)receivers.get(i); 6226 pr.receiver.newThumbnail( 6227 task != null ? task.taskId : -1, thumbnail, description); 6228 if (pr.finished) { 6229 pr.receiver.finished(); 6230 } 6231 } catch (Exception e) { 6232 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6233 } 6234 } 6235 } 6236 } 6237 6238 // ========================================================= 6239 // CONTENT PROVIDERS 6240 // ========================================================= 6241 6242 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6243 List<ProviderInfo> providers = null; 6244 try { 6245 providers = AppGlobals.getPackageManager(). 6246 queryContentProviders(app.processName, app.uid, 6247 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6248 } catch (RemoteException ex) { 6249 } 6250 if (DEBUG_MU) 6251 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6252 int userId = app.userId; 6253 if (providers != null) { 6254 int N = providers.size(); 6255 for (int i=0; i<N; i++) { 6256 ProviderInfo cpi = 6257 (ProviderInfo)providers.get(i); 6258 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6259 cpi.name, cpi.flags); 6260 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6261 // This is a singleton provider, but a user besides the 6262 // default user is asking to initialize a process it runs 6263 // in... well, no, it doesn't actually run in this process, 6264 // it runs in the process of the default user. Get rid of it. 6265 providers.remove(i); 6266 N--; 6267 continue; 6268 } 6269 6270 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6271 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6272 if (cpr == null) { 6273 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6274 mProviderMap.putProviderByClass(comp, cpr); 6275 } 6276 if (DEBUG_MU) 6277 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6278 app.pubProviders.put(cpi.name, cpr); 6279 app.addPackage(cpi.applicationInfo.packageName); 6280 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6281 } 6282 } 6283 return providers; 6284 } 6285 6286 /** 6287 * Check if {@link ProcessRecord} has a possible chance at accessing the 6288 * given {@link ProviderInfo}. Final permission checking is always done 6289 * in {@link ContentProvider}. 6290 */ 6291 private final String checkContentProviderPermissionLocked( 6292 ProviderInfo cpi, ProcessRecord r) { 6293 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6294 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6295 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6296 cpi.applicationInfo.uid, cpi.exported) 6297 == PackageManager.PERMISSION_GRANTED) { 6298 return null; 6299 } 6300 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6301 cpi.applicationInfo.uid, cpi.exported) 6302 == PackageManager.PERMISSION_GRANTED) { 6303 return null; 6304 } 6305 6306 PathPermission[] pps = cpi.pathPermissions; 6307 if (pps != null) { 6308 int i = pps.length; 6309 while (i > 0) { 6310 i--; 6311 PathPermission pp = pps[i]; 6312 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6313 cpi.applicationInfo.uid, cpi.exported) 6314 == PackageManager.PERMISSION_GRANTED) { 6315 return null; 6316 } 6317 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6318 cpi.applicationInfo.uid, cpi.exported) 6319 == PackageManager.PERMISSION_GRANTED) { 6320 return null; 6321 } 6322 } 6323 } 6324 6325 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6326 if (perms != null) { 6327 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6328 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6329 return null; 6330 } 6331 } 6332 } 6333 6334 String msg; 6335 if (!cpi.exported) { 6336 msg = "Permission Denial: opening provider " + cpi.name 6337 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6338 + ", uid=" + callingUid + ") that is not exported from uid " 6339 + cpi.applicationInfo.uid; 6340 } else { 6341 msg = "Permission Denial: opening provider " + cpi.name 6342 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6343 + ", uid=" + callingUid + ") requires " 6344 + cpi.readPermission + " or " + cpi.writePermission; 6345 } 6346 Slog.w(TAG, msg); 6347 return msg; 6348 } 6349 6350 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6351 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6352 if (r != null) { 6353 for (int i=0; i<r.conProviders.size(); i++) { 6354 ContentProviderConnection conn = r.conProviders.get(i); 6355 if (conn.provider == cpr) { 6356 if (DEBUG_PROVIDER) Slog.v(TAG, 6357 "Adding provider requested by " 6358 + r.processName + " from process " 6359 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6360 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6361 if (stable) { 6362 conn.stableCount++; 6363 conn.numStableIncs++; 6364 } else { 6365 conn.unstableCount++; 6366 conn.numUnstableIncs++; 6367 } 6368 return conn; 6369 } 6370 } 6371 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6372 if (stable) { 6373 conn.stableCount = 1; 6374 conn.numStableIncs = 1; 6375 } else { 6376 conn.unstableCount = 1; 6377 conn.numUnstableIncs = 1; 6378 } 6379 cpr.connections.add(conn); 6380 r.conProviders.add(conn); 6381 return conn; 6382 } 6383 cpr.addExternalProcessHandleLocked(externalProcessToken); 6384 return null; 6385 } 6386 6387 boolean decProviderCountLocked(ContentProviderConnection conn, 6388 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6389 if (conn != null) { 6390 cpr = conn.provider; 6391 if (DEBUG_PROVIDER) Slog.v(TAG, 6392 "Removing provider requested by " 6393 + conn.client.processName + " from process " 6394 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6395 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6396 if (stable) { 6397 conn.stableCount--; 6398 } else { 6399 conn.unstableCount--; 6400 } 6401 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6402 cpr.connections.remove(conn); 6403 conn.client.conProviders.remove(conn); 6404 return true; 6405 } 6406 return false; 6407 } 6408 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6409 return false; 6410 } 6411 6412 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6413 String name, IBinder token, boolean stable, int userId) { 6414 ContentProviderRecord cpr; 6415 ContentProviderConnection conn = null; 6416 ProviderInfo cpi = null; 6417 6418 synchronized(this) { 6419 ProcessRecord r = null; 6420 if (caller != null) { 6421 r = getRecordForAppLocked(caller); 6422 if (r == null) { 6423 throw new SecurityException( 6424 "Unable to find app for caller " + caller 6425 + " (pid=" + Binder.getCallingPid() 6426 + ") when getting content provider " + name); 6427 } 6428 } 6429 6430 // First check if this content provider has been published... 6431 cpr = mProviderMap.getProviderByName(name, userId); 6432 boolean providerRunning = cpr != null; 6433 if (providerRunning) { 6434 cpi = cpr.info; 6435 String msg; 6436 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6437 throw new SecurityException(msg); 6438 } 6439 6440 if (r != null && cpr.canRunHere(r)) { 6441 // This provider has been published or is in the process 6442 // of being published... but it is also allowed to run 6443 // in the caller's process, so don't make a connection 6444 // and just let the caller instantiate its own instance. 6445 ContentProviderHolder holder = cpr.newHolder(null); 6446 // don't give caller the provider object, it needs 6447 // to make its own. 6448 holder.provider = null; 6449 return holder; 6450 } 6451 6452 final long origId = Binder.clearCallingIdentity(); 6453 6454 // In this case the provider instance already exists, so we can 6455 // return it right away. 6456 conn = incProviderCountLocked(r, cpr, token, stable); 6457 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6458 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6459 // If this is a perceptible app accessing the provider, 6460 // make sure to count it as being accessed and thus 6461 // back up on the LRU list. This is good because 6462 // content providers are often expensive to start. 6463 updateLruProcessLocked(cpr.proc, false, true); 6464 } 6465 } 6466 6467 if (cpr.proc != null) { 6468 if (false) { 6469 if (cpr.name.flattenToShortString().equals( 6470 "com.android.providers.calendar/.CalendarProvider2")) { 6471 Slog.v(TAG, "****************** KILLING " 6472 + cpr.name.flattenToShortString()); 6473 Process.killProcess(cpr.proc.pid); 6474 } 6475 } 6476 boolean success = updateOomAdjLocked(cpr.proc); 6477 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6478 // NOTE: there is still a race here where a signal could be 6479 // pending on the process even though we managed to update its 6480 // adj level. Not sure what to do about this, but at least 6481 // the race is now smaller. 6482 if (!success) { 6483 // Uh oh... it looks like the provider's process 6484 // has been killed on us. We need to wait for a new 6485 // process to be started, and make sure its death 6486 // doesn't kill our process. 6487 Slog.i(TAG, 6488 "Existing provider " + cpr.name.flattenToShortString() 6489 + " is crashing; detaching " + r); 6490 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6491 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6492 if (!lastRef) { 6493 // This wasn't the last ref our process had on 6494 // the provider... we have now been killed, bail. 6495 return null; 6496 } 6497 providerRunning = false; 6498 conn = null; 6499 } 6500 } 6501 6502 Binder.restoreCallingIdentity(origId); 6503 } 6504 6505 boolean singleton; 6506 if (!providerRunning) { 6507 try { 6508 cpi = AppGlobals.getPackageManager(). 6509 resolveContentProvider(name, 6510 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6511 } catch (RemoteException ex) { 6512 } 6513 if (cpi == null) { 6514 return null; 6515 } 6516 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6517 cpi.name, cpi.flags); 6518 if (singleton) { 6519 userId = 0; 6520 } 6521 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6522 6523 String msg; 6524 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6525 throw new SecurityException(msg); 6526 } 6527 6528 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6529 && !cpi.processName.equals("system")) { 6530 // If this content provider does not run in the system 6531 // process, and the system is not yet ready to run other 6532 // processes, then fail fast instead of hanging. 6533 throw new IllegalArgumentException( 6534 "Attempt to launch content provider before system ready"); 6535 } 6536 6537 // Make sure that the user who owns this provider is started. If not, 6538 // we don't want to allow it to run. 6539 if (mStartedUsers.get(userId) == null) { 6540 Slog.w(TAG, "Unable to launch app " 6541 + cpi.applicationInfo.packageName + "/" 6542 + cpi.applicationInfo.uid + " for provider " 6543 + name + ": user " + userId + " is stopped"); 6544 return null; 6545 } 6546 6547 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6548 cpr = mProviderMap.getProviderByClass(comp, userId); 6549 final boolean firstClass = cpr == null; 6550 if (firstClass) { 6551 try { 6552 ApplicationInfo ai = 6553 AppGlobals.getPackageManager(). 6554 getApplicationInfo( 6555 cpi.applicationInfo.packageName, 6556 STOCK_PM_FLAGS, userId); 6557 if (ai == null) { 6558 Slog.w(TAG, "No package info for content provider " 6559 + cpi.name); 6560 return null; 6561 } 6562 ai = getAppInfoForUser(ai, userId); 6563 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6564 } catch (RemoteException ex) { 6565 // pm is in same process, this will never happen. 6566 } 6567 } 6568 6569 if (r != null && cpr.canRunHere(r)) { 6570 // If this is a multiprocess provider, then just return its 6571 // info and allow the caller to instantiate it. Only do 6572 // this if the provider is the same user as the caller's 6573 // process, or can run as root (so can be in any process). 6574 return cpr.newHolder(null); 6575 } 6576 6577 if (DEBUG_PROVIDER) { 6578 RuntimeException e = new RuntimeException("here"); 6579 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6580 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6581 } 6582 6583 // This is single process, and our app is now connecting to it. 6584 // See if we are already in the process of launching this 6585 // provider. 6586 final int N = mLaunchingProviders.size(); 6587 int i; 6588 for (i=0; i<N; i++) { 6589 if (mLaunchingProviders.get(i) == cpr) { 6590 break; 6591 } 6592 } 6593 6594 // If the provider is not already being launched, then get it 6595 // started. 6596 if (i >= N) { 6597 final long origId = Binder.clearCallingIdentity(); 6598 6599 try { 6600 // Content provider is now in use, its package can't be stopped. 6601 try { 6602 AppGlobals.getPackageManager().setPackageStoppedState( 6603 cpr.appInfo.packageName, false, userId); 6604 } catch (RemoteException e) { 6605 } catch (IllegalArgumentException e) { 6606 Slog.w(TAG, "Failed trying to unstop package " 6607 + cpr.appInfo.packageName + ": " + e); 6608 } 6609 6610 ProcessRecord proc = startProcessLocked(cpi.processName, 6611 cpr.appInfo, false, 0, "content provider", 6612 new ComponentName(cpi.applicationInfo.packageName, 6613 cpi.name), false, false); 6614 if (proc == null) { 6615 Slog.w(TAG, "Unable to launch app " 6616 + cpi.applicationInfo.packageName + "/" 6617 + cpi.applicationInfo.uid + " for provider " 6618 + name + ": process is bad"); 6619 return null; 6620 } 6621 cpr.launchingApp = proc; 6622 mLaunchingProviders.add(cpr); 6623 } finally { 6624 Binder.restoreCallingIdentity(origId); 6625 } 6626 } 6627 6628 // Make sure the provider is published (the same provider class 6629 // may be published under multiple names). 6630 if (firstClass) { 6631 mProviderMap.putProviderByClass(comp, cpr); 6632 } 6633 6634 mProviderMap.putProviderByName(name, cpr); 6635 conn = incProviderCountLocked(r, cpr, token, stable); 6636 if (conn != null) { 6637 conn.waiting = true; 6638 } 6639 } 6640 } 6641 6642 // Wait for the provider to be published... 6643 synchronized (cpr) { 6644 while (cpr.provider == null) { 6645 if (cpr.launchingApp == null) { 6646 Slog.w(TAG, "Unable to launch app " 6647 + cpi.applicationInfo.packageName + "/" 6648 + cpi.applicationInfo.uid + " for provider " 6649 + name + ": launching app became null"); 6650 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6651 cpi.applicationInfo.packageName, 6652 cpi.applicationInfo.uid, name); 6653 return null; 6654 } 6655 try { 6656 if (DEBUG_MU) { 6657 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6658 + cpr.launchingApp); 6659 } 6660 if (conn != null) { 6661 conn.waiting = true; 6662 } 6663 cpr.wait(); 6664 } catch (InterruptedException ex) { 6665 } finally { 6666 if (conn != null) { 6667 conn.waiting = false; 6668 } 6669 } 6670 } 6671 } 6672 return cpr != null ? cpr.newHolder(conn) : null; 6673 } 6674 6675 public final ContentProviderHolder getContentProvider( 6676 IApplicationThread caller, String name, int userId, boolean stable) { 6677 enforceNotIsolatedCaller("getContentProvider"); 6678 if (caller == null) { 6679 String msg = "null IApplicationThread when getting content provider " 6680 + name; 6681 Slog.w(TAG, msg); 6682 throw new SecurityException(msg); 6683 } 6684 6685 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6686 false, true, "getContentProvider", null); 6687 return getContentProviderImpl(caller, name, null, stable, userId); 6688 } 6689 6690 public ContentProviderHolder getContentProviderExternal( 6691 String name, int userId, IBinder token) { 6692 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6693 "Do not have permission in call getContentProviderExternal()"); 6694 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6695 false, true, "getContentProvider", null); 6696 return getContentProviderExternalUnchecked(name, token, userId); 6697 } 6698 6699 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6700 IBinder token, int userId) { 6701 return getContentProviderImpl(null, name, token, true, userId); 6702 } 6703 6704 /** 6705 * Drop a content provider from a ProcessRecord's bookkeeping 6706 * @param cpr 6707 */ 6708 public void removeContentProvider(IBinder connection, boolean stable) { 6709 enforceNotIsolatedCaller("removeContentProvider"); 6710 synchronized (this) { 6711 ContentProviderConnection conn; 6712 try { 6713 conn = (ContentProviderConnection)connection; 6714 } catch (ClassCastException e) { 6715 String msg ="removeContentProvider: " + connection 6716 + " not a ContentProviderConnection"; 6717 Slog.w(TAG, msg); 6718 throw new IllegalArgumentException(msg); 6719 } 6720 if (conn == null) { 6721 throw new NullPointerException("connection is null"); 6722 } 6723 if (decProviderCountLocked(conn, null, null, stable)) { 6724 updateOomAdjLocked(); 6725 } 6726 } 6727 } 6728 6729 public void removeContentProviderExternal(String name, IBinder token) { 6730 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6731 "Do not have permission in call removeContentProviderExternal()"); 6732 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6733 } 6734 6735 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6736 synchronized (this) { 6737 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6738 if(cpr == null) { 6739 //remove from mProvidersByClass 6740 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6741 return; 6742 } 6743 6744 //update content provider record entry info 6745 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6746 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6747 if (localCpr.hasExternalProcessHandles()) { 6748 if (localCpr.removeExternalProcessHandleLocked(token)) { 6749 updateOomAdjLocked(); 6750 } else { 6751 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6752 + " with no external reference for token: " 6753 + token + "."); 6754 } 6755 } else { 6756 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6757 + " with no external references."); 6758 } 6759 } 6760 } 6761 6762 public final void publishContentProviders(IApplicationThread caller, 6763 List<ContentProviderHolder> providers) { 6764 if (providers == null) { 6765 return; 6766 } 6767 6768 enforceNotIsolatedCaller("publishContentProviders"); 6769 synchronized (this) { 6770 final ProcessRecord r = getRecordForAppLocked(caller); 6771 if (DEBUG_MU) 6772 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6773 if (r == null) { 6774 throw new SecurityException( 6775 "Unable to find app for caller " + caller 6776 + " (pid=" + Binder.getCallingPid() 6777 + ") when publishing content providers"); 6778 } 6779 6780 final long origId = Binder.clearCallingIdentity(); 6781 6782 final int N = providers.size(); 6783 for (int i=0; i<N; i++) { 6784 ContentProviderHolder src = providers.get(i); 6785 if (src == null || src.info == null || src.provider == null) { 6786 continue; 6787 } 6788 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6789 if (DEBUG_MU) 6790 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6791 if (dst != null) { 6792 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6793 mProviderMap.putProviderByClass(comp, dst); 6794 String names[] = dst.info.authority.split(";"); 6795 for (int j = 0; j < names.length; j++) { 6796 mProviderMap.putProviderByName(names[j], dst); 6797 } 6798 6799 int NL = mLaunchingProviders.size(); 6800 int j; 6801 for (j=0; j<NL; j++) { 6802 if (mLaunchingProviders.get(j) == dst) { 6803 mLaunchingProviders.remove(j); 6804 j--; 6805 NL--; 6806 } 6807 } 6808 synchronized (dst) { 6809 dst.provider = src.provider; 6810 dst.proc = r; 6811 dst.notifyAll(); 6812 } 6813 updateOomAdjLocked(r); 6814 } 6815 } 6816 6817 Binder.restoreCallingIdentity(origId); 6818 } 6819 } 6820 6821 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6822 ContentProviderConnection conn; 6823 try { 6824 conn = (ContentProviderConnection)connection; 6825 } catch (ClassCastException e) { 6826 String msg ="refContentProvider: " + connection 6827 + " not a ContentProviderConnection"; 6828 Slog.w(TAG, msg); 6829 throw new IllegalArgumentException(msg); 6830 } 6831 if (conn == null) { 6832 throw new NullPointerException("connection is null"); 6833 } 6834 6835 synchronized (this) { 6836 if (stable > 0) { 6837 conn.numStableIncs += stable; 6838 } 6839 stable = conn.stableCount + stable; 6840 if (stable < 0) { 6841 throw new IllegalStateException("stableCount < 0: " + stable); 6842 } 6843 6844 if (unstable > 0) { 6845 conn.numUnstableIncs += unstable; 6846 } 6847 unstable = conn.unstableCount + unstable; 6848 if (unstable < 0) { 6849 throw new IllegalStateException("unstableCount < 0: " + unstable); 6850 } 6851 6852 if ((stable+unstable) <= 0) { 6853 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6854 + stable + " unstable=" + unstable); 6855 } 6856 conn.stableCount = stable; 6857 conn.unstableCount = unstable; 6858 return !conn.dead; 6859 } 6860 } 6861 6862 public void unstableProviderDied(IBinder connection) { 6863 ContentProviderConnection conn; 6864 try { 6865 conn = (ContentProviderConnection)connection; 6866 } catch (ClassCastException e) { 6867 String msg ="refContentProvider: " + connection 6868 + " not a ContentProviderConnection"; 6869 Slog.w(TAG, msg); 6870 throw new IllegalArgumentException(msg); 6871 } 6872 if (conn == null) { 6873 throw new NullPointerException("connection is null"); 6874 } 6875 6876 // Safely retrieve the content provider associated with the connection. 6877 IContentProvider provider; 6878 synchronized (this) { 6879 provider = conn.provider.provider; 6880 } 6881 6882 if (provider == null) { 6883 // Um, yeah, we're way ahead of you. 6884 return; 6885 } 6886 6887 // Make sure the caller is being honest with us. 6888 if (provider.asBinder().pingBinder()) { 6889 // Er, no, still looks good to us. 6890 synchronized (this) { 6891 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6892 + " says " + conn + " died, but we don't agree"); 6893 return; 6894 } 6895 } 6896 6897 // Well look at that! It's dead! 6898 synchronized (this) { 6899 if (conn.provider.provider != provider) { 6900 // But something changed... good enough. 6901 return; 6902 } 6903 6904 ProcessRecord proc = conn.provider.proc; 6905 if (proc == null || proc.thread == null) { 6906 // Seems like the process is already cleaned up. 6907 return; 6908 } 6909 6910 // As far as we're concerned, this is just like receiving a 6911 // death notification... just a bit prematurely. 6912 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6913 + ") early provider death"); 6914 final long ident = Binder.clearCallingIdentity(); 6915 try { 6916 appDiedLocked(proc, proc.pid, proc.thread); 6917 } finally { 6918 Binder.restoreCallingIdentity(ident); 6919 } 6920 } 6921 } 6922 6923 public static final void installSystemProviders() { 6924 List<ProviderInfo> providers; 6925 synchronized (mSelf) { 6926 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6927 providers = mSelf.generateApplicationProvidersLocked(app); 6928 if (providers != null) { 6929 for (int i=providers.size()-1; i>=0; i--) { 6930 ProviderInfo pi = (ProviderInfo)providers.get(i); 6931 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6932 Slog.w(TAG, "Not installing system proc provider " + pi.name 6933 + ": not system .apk"); 6934 providers.remove(i); 6935 } 6936 } 6937 } 6938 } 6939 if (providers != null) { 6940 mSystemThread.installSystemProviders(providers); 6941 } 6942 6943 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6944 6945 mSelf.mUsageStatsService.monitorPackages(); 6946 } 6947 6948 /** 6949 * Allows app to retrieve the MIME type of a URI without having permission 6950 * to access its content provider. 6951 * 6952 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6953 * 6954 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6955 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6956 */ 6957 public String getProviderMimeType(Uri uri, int userId) { 6958 enforceNotIsolatedCaller("getProviderMimeType"); 6959 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6960 userId, false, true, "getProviderMimeType", null); 6961 final String name = uri.getAuthority(); 6962 final long ident = Binder.clearCallingIdentity(); 6963 ContentProviderHolder holder = null; 6964 6965 try { 6966 holder = getContentProviderExternalUnchecked(name, null, userId); 6967 if (holder != null) { 6968 return holder.provider.getType(uri); 6969 } 6970 } catch (RemoteException e) { 6971 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6972 return null; 6973 } finally { 6974 if (holder != null) { 6975 removeContentProviderExternalUnchecked(name, null, userId); 6976 } 6977 Binder.restoreCallingIdentity(ident); 6978 } 6979 6980 return null; 6981 } 6982 6983 // ========================================================= 6984 // GLOBAL MANAGEMENT 6985 // ========================================================= 6986 6987 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6988 ApplicationInfo info, String customProcess, boolean isolated) { 6989 String proc = customProcess != null ? customProcess : info.processName; 6990 BatteryStatsImpl.Uid.Proc ps = null; 6991 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6992 int uid = info.uid; 6993 if (isolated) { 6994 int userId = UserHandle.getUserId(uid); 6995 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6996 uid = 0; 6997 while (true) { 6998 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6999 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 7000 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 7001 } 7002 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 7003 mNextIsolatedProcessUid++; 7004 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 7005 // No process for this uid, use it. 7006 break; 7007 } 7008 stepsLeft--; 7009 if (stepsLeft <= 0) { 7010 return null; 7011 } 7012 } 7013 } 7014 synchronized (stats) { 7015 ps = stats.getProcessStatsLocked(info.uid, proc); 7016 } 7017 return new ProcessRecord(ps, thread, info, proc, uid); 7018 } 7019 7020 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 7021 ProcessRecord app; 7022 if (!isolated) { 7023 app = getProcessRecordLocked(info.processName, info.uid); 7024 } else { 7025 app = null; 7026 } 7027 7028 if (app == null) { 7029 app = newProcessRecordLocked(null, info, null, isolated); 7030 mProcessNames.put(info.processName, app.uid, app); 7031 if (isolated) { 7032 mIsolatedProcesses.put(app.uid, app); 7033 } 7034 updateLruProcessLocked(app, true, true); 7035 } 7036 7037 // This package really, really can not be stopped. 7038 try { 7039 AppGlobals.getPackageManager().setPackageStoppedState( 7040 info.packageName, false, UserHandle.getUserId(app.uid)); 7041 } catch (RemoteException e) { 7042 } catch (IllegalArgumentException e) { 7043 Slog.w(TAG, "Failed trying to unstop package " 7044 + info.packageName + ": " + e); 7045 } 7046 7047 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7048 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7049 app.persistent = true; 7050 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7051 } 7052 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7053 mPersistentStartingProcesses.add(app); 7054 startProcessLocked(app, "added application", app.processName); 7055 } 7056 7057 return app; 7058 } 7059 7060 public void unhandledBack() { 7061 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7062 "unhandledBack()"); 7063 7064 synchronized(this) { 7065 int count = mMainStack.mHistory.size(); 7066 if (DEBUG_SWITCH) Slog.d( 7067 TAG, "Performing unhandledBack(): stack size = " + count); 7068 if (count > 1) { 7069 final long origId = Binder.clearCallingIdentity(); 7070 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7071 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7072 Binder.restoreCallingIdentity(origId); 7073 } 7074 } 7075 } 7076 7077 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7078 enforceNotIsolatedCaller("openContentUri"); 7079 final int userId = UserHandle.getCallingUserId(); 7080 String name = uri.getAuthority(); 7081 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7082 ParcelFileDescriptor pfd = null; 7083 if (cph != null) { 7084 // We record the binder invoker's uid in thread-local storage before 7085 // going to the content provider to open the file. Later, in the code 7086 // that handles all permissions checks, we look for this uid and use 7087 // that rather than the Activity Manager's own uid. The effect is that 7088 // we do the check against the caller's permissions even though it looks 7089 // to the content provider like the Activity Manager itself is making 7090 // the request. 7091 sCallerIdentity.set(new Identity( 7092 Binder.getCallingPid(), Binder.getCallingUid())); 7093 try { 7094 pfd = cph.provider.openFile(uri, "r"); 7095 } catch (FileNotFoundException e) { 7096 // do nothing; pfd will be returned null 7097 } finally { 7098 // Ensure that whatever happens, we clean up the identity state 7099 sCallerIdentity.remove(); 7100 } 7101 7102 // We've got the fd now, so we're done with the provider. 7103 removeContentProviderExternalUnchecked(name, null, userId); 7104 } else { 7105 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7106 } 7107 return pfd; 7108 } 7109 7110 // Actually is sleeping or shutting down or whatever else in the future 7111 // is an inactive state. 7112 public boolean isSleeping() { 7113 return mSleeping || mShuttingDown; 7114 } 7115 7116 public void goingToSleep() { 7117 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7118 != PackageManager.PERMISSION_GRANTED) { 7119 throw new SecurityException("Requires permission " 7120 + android.Manifest.permission.DEVICE_POWER); 7121 } 7122 7123 synchronized(this) { 7124 mWentToSleep = true; 7125 updateEventDispatchingLocked(); 7126 7127 if (!mSleeping) { 7128 mSleeping = true; 7129 mMainStack.stopIfSleepingLocked(); 7130 7131 // Initialize the wake times of all processes. 7132 checkExcessivePowerUsageLocked(false); 7133 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7134 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7135 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7136 } 7137 } 7138 } 7139 7140 public boolean shutdown(int timeout) { 7141 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7142 != PackageManager.PERMISSION_GRANTED) { 7143 throw new SecurityException("Requires permission " 7144 + android.Manifest.permission.SHUTDOWN); 7145 } 7146 7147 boolean timedout = false; 7148 7149 synchronized(this) { 7150 mShuttingDown = true; 7151 updateEventDispatchingLocked(); 7152 7153 if (mMainStack.mResumedActivity != null) { 7154 mMainStack.stopIfSleepingLocked(); 7155 final long endTime = System.currentTimeMillis() + timeout; 7156 while (mMainStack.mResumedActivity != null 7157 || mMainStack.mPausingActivity != null) { 7158 long delay = endTime - System.currentTimeMillis(); 7159 if (delay <= 0) { 7160 Slog.w(TAG, "Activity manager shutdown timed out"); 7161 timedout = true; 7162 break; 7163 } 7164 try { 7165 this.wait(); 7166 } catch (InterruptedException e) { 7167 } 7168 } 7169 } 7170 } 7171 7172 mUsageStatsService.shutdown(); 7173 mBatteryStatsService.shutdown(); 7174 7175 return timedout; 7176 } 7177 7178 public final void activitySlept(IBinder token) { 7179 if (localLOGV) Slog.v( 7180 TAG, "Activity slept: token=" + token); 7181 7182 ActivityRecord r = null; 7183 7184 final long origId = Binder.clearCallingIdentity(); 7185 7186 synchronized (this) { 7187 r = mMainStack.isInStackLocked(token); 7188 if (r != null) { 7189 mMainStack.activitySleptLocked(r); 7190 } 7191 } 7192 7193 Binder.restoreCallingIdentity(origId); 7194 } 7195 7196 private void comeOutOfSleepIfNeededLocked() { 7197 if (!mWentToSleep && !mLockScreenShown) { 7198 if (mSleeping) { 7199 mSleeping = false; 7200 mMainStack.awakeFromSleepingLocked(); 7201 mMainStack.resumeTopActivityLocked(null); 7202 } 7203 } 7204 } 7205 7206 public void wakingUp() { 7207 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7208 != PackageManager.PERMISSION_GRANTED) { 7209 throw new SecurityException("Requires permission " 7210 + android.Manifest.permission.DEVICE_POWER); 7211 } 7212 7213 synchronized(this) { 7214 mWentToSleep = false; 7215 updateEventDispatchingLocked(); 7216 comeOutOfSleepIfNeededLocked(); 7217 } 7218 } 7219 7220 private void updateEventDispatchingLocked() { 7221 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7222 } 7223 7224 public void setLockScreenShown(boolean shown) { 7225 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7226 != PackageManager.PERMISSION_GRANTED) { 7227 throw new SecurityException("Requires permission " 7228 + android.Manifest.permission.DEVICE_POWER); 7229 } 7230 7231 synchronized(this) { 7232 mLockScreenShown = shown; 7233 comeOutOfSleepIfNeededLocked(); 7234 } 7235 } 7236 7237 public void stopAppSwitches() { 7238 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7239 != PackageManager.PERMISSION_GRANTED) { 7240 throw new SecurityException("Requires permission " 7241 + android.Manifest.permission.STOP_APP_SWITCHES); 7242 } 7243 7244 synchronized(this) { 7245 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7246 + APP_SWITCH_DELAY_TIME; 7247 mDidAppSwitch = false; 7248 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7249 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7250 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7251 } 7252 } 7253 7254 public void resumeAppSwitches() { 7255 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7256 != PackageManager.PERMISSION_GRANTED) { 7257 throw new SecurityException("Requires permission " 7258 + android.Manifest.permission.STOP_APP_SWITCHES); 7259 } 7260 7261 synchronized(this) { 7262 // Note that we don't execute any pending app switches... we will 7263 // let those wait until either the timeout, or the next start 7264 // activity request. 7265 mAppSwitchesAllowedTime = 0; 7266 } 7267 } 7268 7269 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7270 String name) { 7271 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7272 return true; 7273 } 7274 7275 final int perm = checkComponentPermission( 7276 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7277 callingUid, -1, true); 7278 if (perm == PackageManager.PERMISSION_GRANTED) { 7279 return true; 7280 } 7281 7282 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7283 return false; 7284 } 7285 7286 public void setDebugApp(String packageName, boolean waitForDebugger, 7287 boolean persistent) { 7288 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7289 "setDebugApp()"); 7290 7291 // Note that this is not really thread safe if there are multiple 7292 // callers into it at the same time, but that's not a situation we 7293 // care about. 7294 if (persistent) { 7295 final ContentResolver resolver = mContext.getContentResolver(); 7296 Settings.System.putString( 7297 resolver, Settings.System.DEBUG_APP, 7298 packageName); 7299 Settings.System.putInt( 7300 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7301 waitForDebugger ? 1 : 0); 7302 } 7303 7304 synchronized (this) { 7305 if (!persistent) { 7306 mOrigDebugApp = mDebugApp; 7307 mOrigWaitForDebugger = mWaitForDebugger; 7308 } 7309 mDebugApp = packageName; 7310 mWaitForDebugger = waitForDebugger; 7311 mDebugTransient = !persistent; 7312 if (packageName != null) { 7313 final long origId = Binder.clearCallingIdentity(); 7314 forceStopPackageLocked(packageName, -1, false, false, true, true, 7315 UserHandle.USER_ALL); 7316 Binder.restoreCallingIdentity(origId); 7317 } 7318 } 7319 } 7320 7321 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7322 synchronized (this) { 7323 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7324 if (!isDebuggable) { 7325 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7326 throw new SecurityException("Process not debuggable: " + app.packageName); 7327 } 7328 } 7329 7330 mOpenGlTraceApp = processName; 7331 } 7332 } 7333 7334 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7335 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7336 synchronized (this) { 7337 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7338 if (!isDebuggable) { 7339 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7340 throw new SecurityException("Process not debuggable: " + app.packageName); 7341 } 7342 } 7343 mProfileApp = processName; 7344 mProfileFile = profileFile; 7345 if (mProfileFd != null) { 7346 try { 7347 mProfileFd.close(); 7348 } catch (IOException e) { 7349 } 7350 mProfileFd = null; 7351 } 7352 mProfileFd = profileFd; 7353 mProfileType = 0; 7354 mAutoStopProfiler = autoStopProfiler; 7355 } 7356 } 7357 7358 public void setAlwaysFinish(boolean enabled) { 7359 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7360 "setAlwaysFinish()"); 7361 7362 Settings.System.putInt( 7363 mContext.getContentResolver(), 7364 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7365 7366 synchronized (this) { 7367 mAlwaysFinishActivities = enabled; 7368 } 7369 } 7370 7371 public void setActivityController(IActivityController controller) { 7372 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7373 "setActivityController()"); 7374 synchronized (this) { 7375 mController = controller; 7376 } 7377 } 7378 7379 public boolean isUserAMonkey() { 7380 // For now the fact that there is a controller implies 7381 // we have a monkey. 7382 synchronized (this) { 7383 return mController != null; 7384 } 7385 } 7386 7387 public void registerProcessObserver(IProcessObserver observer) { 7388 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7389 "registerProcessObserver()"); 7390 synchronized (this) { 7391 mProcessObservers.register(observer); 7392 } 7393 } 7394 7395 public void unregisterProcessObserver(IProcessObserver observer) { 7396 synchronized (this) { 7397 mProcessObservers.unregister(observer); 7398 } 7399 } 7400 7401 public void setImmersive(IBinder token, boolean immersive) { 7402 synchronized(this) { 7403 ActivityRecord r = mMainStack.isInStackLocked(token); 7404 if (r == null) { 7405 throw new IllegalArgumentException(); 7406 } 7407 r.immersive = immersive; 7408 } 7409 } 7410 7411 public boolean isImmersive(IBinder token) { 7412 synchronized (this) { 7413 ActivityRecord r = mMainStack.isInStackLocked(token); 7414 if (r == null) { 7415 throw new IllegalArgumentException(); 7416 } 7417 return r.immersive; 7418 } 7419 } 7420 7421 public boolean isTopActivityImmersive() { 7422 enforceNotIsolatedCaller("startActivity"); 7423 synchronized (this) { 7424 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7425 return (r != null) ? r.immersive : false; 7426 } 7427 } 7428 7429 public final void enterSafeMode() { 7430 synchronized(this) { 7431 // It only makes sense to do this before the system is ready 7432 // and started launching other packages. 7433 if (!mSystemReady) { 7434 try { 7435 AppGlobals.getPackageManager().enterSafeMode(); 7436 } catch (RemoteException e) { 7437 } 7438 } 7439 } 7440 } 7441 7442 public final void showSafeModeOverlay() { 7443 View v = LayoutInflater.from(mContext).inflate( 7444 com.android.internal.R.layout.safe_mode, null); 7445 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7446 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7447 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7448 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7449 lp.gravity = Gravity.BOTTOM | Gravity.START; 7450 lp.format = v.getBackground().getOpacity(); 7451 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7452 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7453 ((WindowManager)mContext.getSystemService( 7454 Context.WINDOW_SERVICE)).addView(v, lp); 7455 } 7456 7457 public void noteWakeupAlarm(IIntentSender sender) { 7458 if (!(sender instanceof PendingIntentRecord)) { 7459 return; 7460 } 7461 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7462 synchronized (stats) { 7463 if (mBatteryStatsService.isOnBattery()) { 7464 mBatteryStatsService.enforceCallingPermission(); 7465 PendingIntentRecord rec = (PendingIntentRecord)sender; 7466 int MY_UID = Binder.getCallingUid(); 7467 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7468 BatteryStatsImpl.Uid.Pkg pkg = 7469 stats.getPackageStatsLocked(uid, rec.key.packageName); 7470 pkg.incWakeupsLocked(); 7471 } 7472 } 7473 } 7474 7475 public boolean killPids(int[] pids, String pReason, boolean secure) { 7476 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7477 throw new SecurityException("killPids only available to the system"); 7478 } 7479 String reason = (pReason == null) ? "Unknown" : pReason; 7480 // XXX Note: don't acquire main activity lock here, because the window 7481 // manager calls in with its locks held. 7482 7483 boolean killed = false; 7484 synchronized (mPidsSelfLocked) { 7485 int[] types = new int[pids.length]; 7486 int worstType = 0; 7487 for (int i=0; i<pids.length; i++) { 7488 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7489 if (proc != null) { 7490 int type = proc.setAdj; 7491 types[i] = type; 7492 if (type > worstType) { 7493 worstType = type; 7494 } 7495 } 7496 } 7497 7498 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7499 // then constrain it so we will kill all hidden procs. 7500 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7501 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7502 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7503 } 7504 7505 // If this is not a secure call, don't let it kill processes that 7506 // are important. 7507 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7508 worstType = ProcessList.SERVICE_ADJ; 7509 } 7510 7511 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7512 for (int i=0; i<pids.length; i++) { 7513 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7514 if (proc == null) { 7515 continue; 7516 } 7517 int adj = proc.setAdj; 7518 if (adj >= worstType && !proc.killedBackground) { 7519 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7520 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7521 proc.processName, adj, reason); 7522 killed = true; 7523 proc.killedBackground = true; 7524 Process.killProcessQuiet(pids[i]); 7525 } 7526 } 7527 } 7528 return killed; 7529 } 7530 7531 @Override 7532 public boolean killProcessesBelowForeground(String reason) { 7533 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7534 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7535 } 7536 7537 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7538 } 7539 7540 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7541 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7542 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7543 } 7544 7545 boolean killed = false; 7546 synchronized (mPidsSelfLocked) { 7547 final int size = mPidsSelfLocked.size(); 7548 for (int i = 0; i < size; i++) { 7549 final int pid = mPidsSelfLocked.keyAt(i); 7550 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7551 if (proc == null) continue; 7552 7553 final int adj = proc.setAdj; 7554 if (adj > belowAdj && !proc.killedBackground) { 7555 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7556 EventLog.writeEvent( 7557 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7558 killed = true; 7559 proc.killedBackground = true; 7560 Process.killProcessQuiet(pid); 7561 } 7562 } 7563 } 7564 return killed; 7565 } 7566 7567 public final void startRunning(String pkg, String cls, String action, 7568 String data) { 7569 synchronized(this) { 7570 if (mStartRunning) { 7571 return; 7572 } 7573 mStartRunning = true; 7574 mTopComponent = pkg != null && cls != null 7575 ? new ComponentName(pkg, cls) : null; 7576 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7577 mTopData = data; 7578 if (!mSystemReady) { 7579 return; 7580 } 7581 } 7582 7583 systemReady(null); 7584 } 7585 7586 private void retrieveSettings() { 7587 final ContentResolver resolver = mContext.getContentResolver(); 7588 String debugApp = Settings.System.getString( 7589 resolver, Settings.System.DEBUG_APP); 7590 boolean waitForDebugger = Settings.System.getInt( 7591 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7592 boolean alwaysFinishActivities = Settings.System.getInt( 7593 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7594 7595 Configuration configuration = new Configuration(); 7596 Settings.System.getConfiguration(resolver, configuration); 7597 7598 synchronized (this) { 7599 mDebugApp = mOrigDebugApp = debugApp; 7600 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7601 mAlwaysFinishActivities = alwaysFinishActivities; 7602 // This happens before any activities are started, so we can 7603 // change mConfiguration in-place. 7604 updateConfigurationLocked(configuration, null, false, true); 7605 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7606 } 7607 } 7608 7609 public boolean testIsSystemReady() { 7610 // no need to synchronize(this) just to read & return the value 7611 return mSystemReady; 7612 } 7613 7614 private static File getCalledPreBootReceiversFile() { 7615 File dataDir = Environment.getDataDirectory(); 7616 File systemDir = new File(dataDir, "system"); 7617 File fname = new File(systemDir, "called_pre_boots.dat"); 7618 return fname; 7619 } 7620 7621 static final int LAST_DONE_VERSION = 10000; 7622 7623 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7624 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7625 File file = getCalledPreBootReceiversFile(); 7626 FileInputStream fis = null; 7627 try { 7628 fis = new FileInputStream(file); 7629 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7630 int fvers = dis.readInt(); 7631 if (fvers == LAST_DONE_VERSION) { 7632 String vers = dis.readUTF(); 7633 String codename = dis.readUTF(); 7634 String build = dis.readUTF(); 7635 if (android.os.Build.VERSION.RELEASE.equals(vers) 7636 && android.os.Build.VERSION.CODENAME.equals(codename) 7637 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7638 int num = dis.readInt(); 7639 while (num > 0) { 7640 num--; 7641 String pkg = dis.readUTF(); 7642 String cls = dis.readUTF(); 7643 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7644 } 7645 } 7646 } 7647 } catch (FileNotFoundException e) { 7648 } catch (IOException e) { 7649 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7650 } finally { 7651 if (fis != null) { 7652 try { 7653 fis.close(); 7654 } catch (IOException e) { 7655 } 7656 } 7657 } 7658 return lastDoneReceivers; 7659 } 7660 7661 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7662 File file = getCalledPreBootReceiversFile(); 7663 FileOutputStream fos = null; 7664 DataOutputStream dos = null; 7665 try { 7666 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7667 fos = new FileOutputStream(file); 7668 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7669 dos.writeInt(LAST_DONE_VERSION); 7670 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7671 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7672 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7673 dos.writeInt(list.size()); 7674 for (int i=0; i<list.size(); i++) { 7675 dos.writeUTF(list.get(i).getPackageName()); 7676 dos.writeUTF(list.get(i).getClassName()); 7677 } 7678 } catch (IOException e) { 7679 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7680 file.delete(); 7681 } finally { 7682 FileUtils.sync(fos); 7683 if (dos != null) { 7684 try { 7685 dos.close(); 7686 } catch (IOException e) { 7687 // TODO Auto-generated catch block 7688 e.printStackTrace(); 7689 } 7690 } 7691 } 7692 } 7693 7694 public void systemReady(final Runnable goingCallback) { 7695 synchronized(this) { 7696 if (mSystemReady) { 7697 if (goingCallback != null) goingCallback.run(); 7698 return; 7699 } 7700 7701 // Check to see if there are any update receivers to run. 7702 if (!mDidUpdate) { 7703 if (mWaitingUpdate) { 7704 return; 7705 } 7706 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7707 List<ResolveInfo> ris = null; 7708 try { 7709 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7710 intent, null, 0, 0); 7711 } catch (RemoteException e) { 7712 } 7713 if (ris != null) { 7714 for (int i=ris.size()-1; i>=0; i--) { 7715 if ((ris.get(i).activityInfo.applicationInfo.flags 7716 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7717 ris.remove(i); 7718 } 7719 } 7720 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7721 7722 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7723 7724 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7725 for (int i=0; i<ris.size(); i++) { 7726 ActivityInfo ai = ris.get(i).activityInfo; 7727 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7728 if (lastDoneReceivers.contains(comp)) { 7729 ris.remove(i); 7730 i--; 7731 } 7732 } 7733 7734 final int[] users = getUsersLocked(); 7735 for (int i=0; i<ris.size(); i++) { 7736 ActivityInfo ai = ris.get(i).activityInfo; 7737 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7738 doneReceivers.add(comp); 7739 intent.setComponent(comp); 7740 for (int j=0; j<users.length; j++) { 7741 IIntentReceiver finisher = null; 7742 if (i == ris.size()-1 && j == users.length-1) { 7743 finisher = new IIntentReceiver.Stub() { 7744 public void performReceive(Intent intent, int resultCode, 7745 String data, Bundle extras, boolean ordered, 7746 boolean sticky, int sendingUser) { 7747 // The raw IIntentReceiver interface is called 7748 // with the AM lock held, so redispatch to 7749 // execute our code without the lock. 7750 mHandler.post(new Runnable() { 7751 public void run() { 7752 synchronized (ActivityManagerService.this) { 7753 mDidUpdate = true; 7754 } 7755 writeLastDonePreBootReceivers(doneReceivers); 7756 showBootMessage(mContext.getText( 7757 R.string.android_upgrading_complete), 7758 false); 7759 systemReady(goingCallback); 7760 } 7761 }); 7762 } 7763 }; 7764 } 7765 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7766 + " for user " + users[j]); 7767 broadcastIntentLocked(null, null, intent, null, finisher, 7768 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7769 users[j]); 7770 if (finisher != null) { 7771 mWaitingUpdate = true; 7772 } 7773 } 7774 } 7775 } 7776 if (mWaitingUpdate) { 7777 return; 7778 } 7779 mDidUpdate = true; 7780 } 7781 7782 mSystemReady = true; 7783 if (!mStartRunning) { 7784 return; 7785 } 7786 } 7787 7788 ArrayList<ProcessRecord> procsToKill = null; 7789 synchronized(mPidsSelfLocked) { 7790 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7791 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7792 if (!isAllowedWhileBooting(proc.info)){ 7793 if (procsToKill == null) { 7794 procsToKill = new ArrayList<ProcessRecord>(); 7795 } 7796 procsToKill.add(proc); 7797 } 7798 } 7799 } 7800 7801 synchronized(this) { 7802 if (procsToKill != null) { 7803 for (int i=procsToKill.size()-1; i>=0; i--) { 7804 ProcessRecord proc = procsToKill.get(i); 7805 Slog.i(TAG, "Removing system update proc: " + proc); 7806 removeProcessLocked(proc, true, false, "system update done"); 7807 } 7808 } 7809 7810 // Now that we have cleaned up any update processes, we 7811 // are ready to start launching real processes and know that 7812 // we won't trample on them any more. 7813 mProcessesReady = true; 7814 } 7815 7816 Slog.i(TAG, "System now ready"); 7817 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7818 SystemClock.uptimeMillis()); 7819 7820 synchronized(this) { 7821 // Make sure we have no pre-ready processes sitting around. 7822 7823 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7824 ResolveInfo ri = mContext.getPackageManager() 7825 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7826 STOCK_PM_FLAGS); 7827 CharSequence errorMsg = null; 7828 if (ri != null) { 7829 ActivityInfo ai = ri.activityInfo; 7830 ApplicationInfo app = ai.applicationInfo; 7831 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7832 mTopAction = Intent.ACTION_FACTORY_TEST; 7833 mTopData = null; 7834 mTopComponent = new ComponentName(app.packageName, 7835 ai.name); 7836 } else { 7837 errorMsg = mContext.getResources().getText( 7838 com.android.internal.R.string.factorytest_not_system); 7839 } 7840 } else { 7841 errorMsg = mContext.getResources().getText( 7842 com.android.internal.R.string.factorytest_no_action); 7843 } 7844 if (errorMsg != null) { 7845 mTopAction = null; 7846 mTopData = null; 7847 mTopComponent = null; 7848 Message msg = Message.obtain(); 7849 msg.what = SHOW_FACTORY_ERROR_MSG; 7850 msg.getData().putCharSequence("msg", errorMsg); 7851 mHandler.sendMessage(msg); 7852 } 7853 } 7854 } 7855 7856 retrieveSettings(); 7857 7858 if (goingCallback != null) goingCallback.run(); 7859 7860 synchronized (this) { 7861 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7862 try { 7863 List apps = AppGlobals.getPackageManager(). 7864 getPersistentApplications(STOCK_PM_FLAGS); 7865 if (apps != null) { 7866 int N = apps.size(); 7867 int i; 7868 for (i=0; i<N; i++) { 7869 ApplicationInfo info 7870 = (ApplicationInfo)apps.get(i); 7871 if (info != null && 7872 !info.packageName.equals("android")) { 7873 addAppLocked(info, false); 7874 } 7875 } 7876 } 7877 } catch (RemoteException ex) { 7878 // pm is in same process, this will never happen. 7879 } 7880 } 7881 7882 // Start up initial activity. 7883 mBooting = true; 7884 7885 try { 7886 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7887 Message msg = Message.obtain(); 7888 msg.what = SHOW_UID_ERROR_MSG; 7889 mHandler.sendMessage(msg); 7890 } 7891 } catch (RemoteException e) { 7892 } 7893 7894 long ident = Binder.clearCallingIdentity(); 7895 try { 7896 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7897 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7898 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7899 broadcastIntentLocked(null, null, intent, 7900 null, null, 0, null, null, null, 7901 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7902 } finally { 7903 Binder.restoreCallingIdentity(ident); 7904 } 7905 mMainStack.resumeTopActivityLocked(null); 7906 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7907 } 7908 } 7909 7910 private boolean makeAppCrashingLocked(ProcessRecord app, 7911 String shortMsg, String longMsg, String stackTrace) { 7912 app.crashing = true; 7913 app.crashingReport = generateProcessError(app, 7914 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7915 startAppProblemLocked(app); 7916 app.stopFreezingAllLocked(); 7917 return handleAppCrashLocked(app); 7918 } 7919 7920 private void makeAppNotRespondingLocked(ProcessRecord app, 7921 String activity, String shortMsg, String longMsg) { 7922 app.notResponding = true; 7923 app.notRespondingReport = generateProcessError(app, 7924 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7925 activity, shortMsg, longMsg, null); 7926 startAppProblemLocked(app); 7927 app.stopFreezingAllLocked(); 7928 } 7929 7930 /** 7931 * Generate a process error record, suitable for attachment to a ProcessRecord. 7932 * 7933 * @param app The ProcessRecord in which the error occurred. 7934 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7935 * ActivityManager.AppErrorStateInfo 7936 * @param activity The activity associated with the crash, if known. 7937 * @param shortMsg Short message describing the crash. 7938 * @param longMsg Long message describing the crash. 7939 * @param stackTrace Full crash stack trace, may be null. 7940 * 7941 * @return Returns a fully-formed AppErrorStateInfo record. 7942 */ 7943 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7944 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7945 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7946 7947 report.condition = condition; 7948 report.processName = app.processName; 7949 report.pid = app.pid; 7950 report.uid = app.info.uid; 7951 report.tag = activity; 7952 report.shortMsg = shortMsg; 7953 report.longMsg = longMsg; 7954 report.stackTrace = stackTrace; 7955 7956 return report; 7957 } 7958 7959 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7960 synchronized (this) { 7961 app.crashing = false; 7962 app.crashingReport = null; 7963 app.notResponding = false; 7964 app.notRespondingReport = null; 7965 if (app.anrDialog == fromDialog) { 7966 app.anrDialog = null; 7967 } 7968 if (app.waitDialog == fromDialog) { 7969 app.waitDialog = null; 7970 } 7971 if (app.pid > 0 && app.pid != MY_PID) { 7972 handleAppCrashLocked(app); 7973 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7974 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7975 app.processName, app.setAdj, "user's request after error"); 7976 Process.killProcessQuiet(app.pid); 7977 } 7978 } 7979 } 7980 7981 private boolean handleAppCrashLocked(ProcessRecord app) { 7982 if (mHeadless) { 7983 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7984 return false; 7985 } 7986 long now = SystemClock.uptimeMillis(); 7987 7988 Long crashTime; 7989 if (!app.isolated) { 7990 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7991 } else { 7992 crashTime = null; 7993 } 7994 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7995 // This process loses! 7996 Slog.w(TAG, "Process " + app.info.processName 7997 + " has crashed too many times: killing!"); 7998 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7999 app.info.processName, app.uid); 8000 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8001 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8002 if (r.app == app) { 8003 Slog.w(TAG, " Force finishing activity " 8004 + r.intent.getComponent().flattenToShortString()); 8005 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8006 null, "crashed", false); 8007 } 8008 } 8009 if (!app.persistent) { 8010 // We don't want to start this process again until the user 8011 // explicitly does so... but for persistent process, we really 8012 // need to keep it running. If a persistent process is actually 8013 // repeatedly crashing, then badness for everyone. 8014 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 8015 app.info.processName); 8016 if (!app.isolated) { 8017 // XXX We don't have a way to mark isolated processes 8018 // as bad, since they don't have a peristent identity. 8019 mBadProcesses.put(app.info.processName, app.uid, now); 8020 mProcessCrashTimes.remove(app.info.processName, app.uid); 8021 } 8022 app.bad = true; 8023 app.removed = true; 8024 // Don't let services in this process be restarted and potentially 8025 // annoy the user repeatedly. Unless it is persistent, since those 8026 // processes run critical code. 8027 removeProcessLocked(app, false, false, "crash"); 8028 mMainStack.resumeTopActivityLocked(null); 8029 return false; 8030 } 8031 mMainStack.resumeTopActivityLocked(null); 8032 } else { 8033 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8034 if (r != null && r.app == app) { 8035 // If the top running activity is from this crashing 8036 // process, then terminate it to avoid getting in a loop. 8037 Slog.w(TAG, " Force finishing activity " 8038 + r.intent.getComponent().flattenToShortString()); 8039 int index = mMainStack.indexOfActivityLocked(r); 8040 r.stack.finishActivityLocked(r, index, 8041 Activity.RESULT_CANCELED, null, "crashed", false); 8042 // Also terminate any activities below it that aren't yet 8043 // stopped, to avoid a situation where one will get 8044 // re-start our crashing activity once it gets resumed again. 8045 index--; 8046 if (index >= 0) { 8047 r = (ActivityRecord)mMainStack.mHistory.get(index); 8048 if (r.state == ActivityState.RESUMED 8049 || r.state == ActivityState.PAUSING 8050 || r.state == ActivityState.PAUSED) { 8051 if (!r.isHomeActivity || mHomeProcess != r.app) { 8052 Slog.w(TAG, " Force finishing activity " 8053 + r.intent.getComponent().flattenToShortString()); 8054 r.stack.finishActivityLocked(r, index, 8055 Activity.RESULT_CANCELED, null, "crashed", false); 8056 } 8057 } 8058 } 8059 } 8060 } 8061 8062 // Bump up the crash count of any services currently running in the proc. 8063 if (app.services.size() != 0) { 8064 // Any services running in the application need to be placed 8065 // back in the pending list. 8066 Iterator<ServiceRecord> it = app.services.iterator(); 8067 while (it.hasNext()) { 8068 ServiceRecord sr = it.next(); 8069 sr.crashCount++; 8070 } 8071 } 8072 8073 // If the crashing process is what we consider to be the "home process" and it has been 8074 // replaced by a third-party app, clear the package preferred activities from packages 8075 // with a home activity running in the process to prevent a repeatedly crashing app 8076 // from blocking the user to manually clear the list. 8077 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8078 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8079 Iterator it = mHomeProcess.activities.iterator(); 8080 while (it.hasNext()) { 8081 ActivityRecord r = (ActivityRecord)it.next(); 8082 if (r.isHomeActivity) { 8083 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8084 try { 8085 ActivityThread.getPackageManager() 8086 .clearPackagePreferredActivities(r.packageName); 8087 } catch (RemoteException c) { 8088 // pm is in same process, this will never happen. 8089 } 8090 } 8091 } 8092 } 8093 8094 if (!app.isolated) { 8095 // XXX Can't keep track of crash times for isolated processes, 8096 // because they don't have a perisistent identity. 8097 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8098 } 8099 8100 return true; 8101 } 8102 8103 void startAppProblemLocked(ProcessRecord app) { 8104 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8105 mContext, app.info.packageName, app.info.flags); 8106 skipCurrentReceiverLocked(app); 8107 } 8108 8109 void skipCurrentReceiverLocked(ProcessRecord app) { 8110 for (BroadcastQueue queue : mBroadcastQueues) { 8111 queue.skipCurrentReceiverLocked(app); 8112 } 8113 } 8114 8115 /** 8116 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8117 * The application process will exit immediately after this call returns. 8118 * @param app object of the crashing app, null for the system server 8119 * @param crashInfo describing the exception 8120 */ 8121 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8122 ProcessRecord r = findAppProcess(app, "Crash"); 8123 final String processName = app == null ? "system_server" 8124 : (r == null ? "unknown" : r.processName); 8125 8126 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8127 processName, 8128 r == null ? -1 : r.info.flags, 8129 crashInfo.exceptionClassName, 8130 crashInfo.exceptionMessage, 8131 crashInfo.throwFileName, 8132 crashInfo.throwLineNumber); 8133 8134 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8135 8136 crashApplication(r, crashInfo); 8137 } 8138 8139 public void handleApplicationStrictModeViolation( 8140 IBinder app, 8141 int violationMask, 8142 StrictMode.ViolationInfo info) { 8143 ProcessRecord r = findAppProcess(app, "StrictMode"); 8144 if (r == null) { 8145 return; 8146 } 8147 8148 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8149 Integer stackFingerprint = info.hashCode(); 8150 boolean logIt = true; 8151 synchronized (mAlreadyLoggedViolatedStacks) { 8152 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8153 logIt = false; 8154 // TODO: sub-sample into EventLog for these, with 8155 // the info.durationMillis? Then we'd get 8156 // the relative pain numbers, without logging all 8157 // the stack traces repeatedly. We'd want to do 8158 // likewise in the client code, which also does 8159 // dup suppression, before the Binder call. 8160 } else { 8161 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8162 mAlreadyLoggedViolatedStacks.clear(); 8163 } 8164 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8165 } 8166 } 8167 if (logIt) { 8168 logStrictModeViolationToDropBox(r, info); 8169 } 8170 } 8171 8172 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8173 AppErrorResult result = new AppErrorResult(); 8174 synchronized (this) { 8175 final long origId = Binder.clearCallingIdentity(); 8176 8177 Message msg = Message.obtain(); 8178 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8179 HashMap<String, Object> data = new HashMap<String, Object>(); 8180 data.put("result", result); 8181 data.put("app", r); 8182 data.put("violationMask", violationMask); 8183 data.put("info", info); 8184 msg.obj = data; 8185 mHandler.sendMessage(msg); 8186 8187 Binder.restoreCallingIdentity(origId); 8188 } 8189 int res = result.get(); 8190 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8191 } 8192 } 8193 8194 // Depending on the policy in effect, there could be a bunch of 8195 // these in quick succession so we try to batch these together to 8196 // minimize disk writes, number of dropbox entries, and maximize 8197 // compression, by having more fewer, larger records. 8198 private void logStrictModeViolationToDropBox( 8199 ProcessRecord process, 8200 StrictMode.ViolationInfo info) { 8201 if (info == null) { 8202 return; 8203 } 8204 final boolean isSystemApp = process == null || 8205 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8206 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8207 final String processName = process == null ? "unknown" : process.processName; 8208 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8209 final DropBoxManager dbox = (DropBoxManager) 8210 mContext.getSystemService(Context.DROPBOX_SERVICE); 8211 8212 // Exit early if the dropbox isn't configured to accept this report type. 8213 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8214 8215 boolean bufferWasEmpty; 8216 boolean needsFlush; 8217 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8218 synchronized (sb) { 8219 bufferWasEmpty = sb.length() == 0; 8220 appendDropBoxProcessHeaders(process, processName, sb); 8221 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8222 sb.append("System-App: ").append(isSystemApp).append("\n"); 8223 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8224 if (info.violationNumThisLoop != 0) { 8225 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8226 } 8227 if (info.numAnimationsRunning != 0) { 8228 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8229 } 8230 if (info.broadcastIntentAction != null) { 8231 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8232 } 8233 if (info.durationMillis != -1) { 8234 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8235 } 8236 if (info.numInstances != -1) { 8237 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8238 } 8239 if (info.tags != null) { 8240 for (String tag : info.tags) { 8241 sb.append("Span-Tag: ").append(tag).append("\n"); 8242 } 8243 } 8244 sb.append("\n"); 8245 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8246 sb.append(info.crashInfo.stackTrace); 8247 } 8248 sb.append("\n"); 8249 8250 // Only buffer up to ~64k. Various logging bits truncate 8251 // things at 128k. 8252 needsFlush = (sb.length() > 64 * 1024); 8253 } 8254 8255 // Flush immediately if the buffer's grown too large, or this 8256 // is a non-system app. Non-system apps are isolated with a 8257 // different tag & policy and not batched. 8258 // 8259 // Batching is useful during internal testing with 8260 // StrictMode settings turned up high. Without batching, 8261 // thousands of separate files could be created on boot. 8262 if (!isSystemApp || needsFlush) { 8263 new Thread("Error dump: " + dropboxTag) { 8264 @Override 8265 public void run() { 8266 String report; 8267 synchronized (sb) { 8268 report = sb.toString(); 8269 sb.delete(0, sb.length()); 8270 sb.trimToSize(); 8271 } 8272 if (report.length() != 0) { 8273 dbox.addText(dropboxTag, report); 8274 } 8275 } 8276 }.start(); 8277 return; 8278 } 8279 8280 // System app batching: 8281 if (!bufferWasEmpty) { 8282 // An existing dropbox-writing thread is outstanding, so 8283 // we don't need to start it up. The existing thread will 8284 // catch the buffer appends we just did. 8285 return; 8286 } 8287 8288 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8289 // (After this point, we shouldn't access AMS internal data structures.) 8290 new Thread("Error dump: " + dropboxTag) { 8291 @Override 8292 public void run() { 8293 // 5 second sleep to let stacks arrive and be batched together 8294 try { 8295 Thread.sleep(5000); // 5 seconds 8296 } catch (InterruptedException e) {} 8297 8298 String errorReport; 8299 synchronized (mStrictModeBuffer) { 8300 errorReport = mStrictModeBuffer.toString(); 8301 if (errorReport.length() == 0) { 8302 return; 8303 } 8304 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8305 mStrictModeBuffer.trimToSize(); 8306 } 8307 dbox.addText(dropboxTag, errorReport); 8308 } 8309 }.start(); 8310 } 8311 8312 /** 8313 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8314 * @param app object of the crashing app, null for the system server 8315 * @param tag reported by the caller 8316 * @param crashInfo describing the context of the error 8317 * @return true if the process should exit immediately (WTF is fatal) 8318 */ 8319 public boolean handleApplicationWtf(IBinder app, String tag, 8320 ApplicationErrorReport.CrashInfo crashInfo) { 8321 ProcessRecord r = findAppProcess(app, "WTF"); 8322 final String processName = app == null ? "system_server" 8323 : (r == null ? "unknown" : r.processName); 8324 8325 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8326 processName, 8327 r == null ? -1 : r.info.flags, 8328 tag, crashInfo.exceptionMessage); 8329 8330 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8331 8332 if (r != null && r.pid != Process.myPid() && 8333 Settings.Secure.getInt(mContext.getContentResolver(), 8334 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8335 crashApplication(r, crashInfo); 8336 return true; 8337 } else { 8338 return false; 8339 } 8340 } 8341 8342 /** 8343 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8344 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8345 */ 8346 private ProcessRecord findAppProcess(IBinder app, String reason) { 8347 if (app == null) { 8348 return null; 8349 } 8350 8351 synchronized (this) { 8352 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8353 final int NA = apps.size(); 8354 for (int ia=0; ia<NA; ia++) { 8355 ProcessRecord p = apps.valueAt(ia); 8356 if (p.thread != null && p.thread.asBinder() == app) { 8357 return p; 8358 } 8359 } 8360 } 8361 8362 Slog.w(TAG, "Can't find mystery application for " + reason 8363 + " from pid=" + Binder.getCallingPid() 8364 + " uid=" + Binder.getCallingUid() + ": " + app); 8365 return null; 8366 } 8367 } 8368 8369 /** 8370 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8371 * to append various headers to the dropbox log text. 8372 */ 8373 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8374 StringBuilder sb) { 8375 // Watchdog thread ends up invoking this function (with 8376 // a null ProcessRecord) to add the stack file to dropbox. 8377 // Do not acquire a lock on this (am) in such cases, as it 8378 // could cause a potential deadlock, if and when watchdog 8379 // is invoked due to unavailability of lock on am and it 8380 // would prevent watchdog from killing system_server. 8381 if (process == null) { 8382 sb.append("Process: ").append(processName).append("\n"); 8383 return; 8384 } 8385 // Note: ProcessRecord 'process' is guarded by the service 8386 // instance. (notably process.pkgList, which could otherwise change 8387 // concurrently during execution of this method) 8388 synchronized (this) { 8389 sb.append("Process: ").append(processName).append("\n"); 8390 int flags = process.info.flags; 8391 IPackageManager pm = AppGlobals.getPackageManager(); 8392 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8393 for (String pkg : process.pkgList) { 8394 sb.append("Package: ").append(pkg); 8395 try { 8396 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8397 if (pi != null) { 8398 sb.append(" v").append(pi.versionCode); 8399 if (pi.versionName != null) { 8400 sb.append(" (").append(pi.versionName).append(")"); 8401 } 8402 } 8403 } catch (RemoteException e) { 8404 Slog.e(TAG, "Error getting package info: " + pkg, e); 8405 } 8406 sb.append("\n"); 8407 } 8408 } 8409 } 8410 8411 private static String processClass(ProcessRecord process) { 8412 if (process == null || process.pid == MY_PID) { 8413 return "system_server"; 8414 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8415 return "system_app"; 8416 } else { 8417 return "data_app"; 8418 } 8419 } 8420 8421 /** 8422 * Write a description of an error (crash, WTF, ANR) to the drop box. 8423 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8424 * @param process which caused the error, null means the system server 8425 * @param activity which triggered the error, null if unknown 8426 * @param parent activity related to the error, null if unknown 8427 * @param subject line related to the error, null if absent 8428 * @param report in long form describing the error, null if absent 8429 * @param logFile to include in the report, null if none 8430 * @param crashInfo giving an application stack trace, null if absent 8431 */ 8432 public void addErrorToDropBox(String eventType, 8433 ProcessRecord process, String processName, ActivityRecord activity, 8434 ActivityRecord parent, String subject, 8435 final String report, final File logFile, 8436 final ApplicationErrorReport.CrashInfo crashInfo) { 8437 // NOTE -- this must never acquire the ActivityManagerService lock, 8438 // otherwise the watchdog may be prevented from resetting the system. 8439 8440 final String dropboxTag = processClass(process) + "_" + eventType; 8441 final DropBoxManager dbox = (DropBoxManager) 8442 mContext.getSystemService(Context.DROPBOX_SERVICE); 8443 8444 // Exit early if the dropbox isn't configured to accept this report type. 8445 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8446 8447 final StringBuilder sb = new StringBuilder(1024); 8448 appendDropBoxProcessHeaders(process, processName, sb); 8449 if (activity != null) { 8450 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8451 } 8452 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8453 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8454 } 8455 if (parent != null && parent != activity) { 8456 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8457 } 8458 if (subject != null) { 8459 sb.append("Subject: ").append(subject).append("\n"); 8460 } 8461 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8462 if (Debug.isDebuggerConnected()) { 8463 sb.append("Debugger: Connected\n"); 8464 } 8465 sb.append("\n"); 8466 8467 // Do the rest in a worker thread to avoid blocking the caller on I/O 8468 // (After this point, we shouldn't access AMS internal data structures.) 8469 Thread worker = new Thread("Error dump: " + dropboxTag) { 8470 @Override 8471 public void run() { 8472 if (report != null) { 8473 sb.append(report); 8474 } 8475 if (logFile != null) { 8476 try { 8477 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8478 } catch (IOException e) { 8479 Slog.e(TAG, "Error reading " + logFile, e); 8480 } 8481 } 8482 if (crashInfo != null && crashInfo.stackTrace != null) { 8483 sb.append(crashInfo.stackTrace); 8484 } 8485 8486 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8487 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8488 if (lines > 0) { 8489 sb.append("\n"); 8490 8491 // Merge several logcat streams, and take the last N lines 8492 InputStreamReader input = null; 8493 try { 8494 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8495 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8496 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8497 8498 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8499 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8500 input = new InputStreamReader(logcat.getInputStream()); 8501 8502 int num; 8503 char[] buf = new char[8192]; 8504 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8505 } catch (IOException e) { 8506 Slog.e(TAG, "Error running logcat", e); 8507 } finally { 8508 if (input != null) try { input.close(); } catch (IOException e) {} 8509 } 8510 } 8511 8512 dbox.addText(dropboxTag, sb.toString()); 8513 } 8514 }; 8515 8516 if (process == null) { 8517 // If process is null, we are being called from some internal code 8518 // and may be about to die -- run this synchronously. 8519 worker.run(); 8520 } else { 8521 worker.start(); 8522 } 8523 } 8524 8525 /** 8526 * Bring up the "unexpected error" dialog box for a crashing app. 8527 * Deal with edge cases (intercepts from instrumented applications, 8528 * ActivityController, error intent receivers, that sort of thing). 8529 * @param r the application crashing 8530 * @param crashInfo describing the failure 8531 */ 8532 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8533 long timeMillis = System.currentTimeMillis(); 8534 String shortMsg = crashInfo.exceptionClassName; 8535 String longMsg = crashInfo.exceptionMessage; 8536 String stackTrace = crashInfo.stackTrace; 8537 if (shortMsg != null && longMsg != null) { 8538 longMsg = shortMsg + ": " + longMsg; 8539 } else if (shortMsg != null) { 8540 longMsg = shortMsg; 8541 } 8542 8543 AppErrorResult result = new AppErrorResult(); 8544 synchronized (this) { 8545 if (mController != null) { 8546 try { 8547 String name = r != null ? r.processName : null; 8548 int pid = r != null ? r.pid : Binder.getCallingPid(); 8549 if (!mController.appCrashed(name, pid, 8550 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8551 Slog.w(TAG, "Force-killing crashed app " + name 8552 + " at watcher's request"); 8553 Process.killProcess(pid); 8554 return; 8555 } 8556 } catch (RemoteException e) { 8557 mController = null; 8558 } 8559 } 8560 8561 final long origId = Binder.clearCallingIdentity(); 8562 8563 // If this process is running instrumentation, finish it. 8564 if (r != null && r.instrumentationClass != null) { 8565 Slog.w(TAG, "Error in app " + r.processName 8566 + " running instrumentation " + r.instrumentationClass + ":"); 8567 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8568 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8569 Bundle info = new Bundle(); 8570 info.putString("shortMsg", shortMsg); 8571 info.putString("longMsg", longMsg); 8572 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8573 Binder.restoreCallingIdentity(origId); 8574 return; 8575 } 8576 8577 // If we can't identify the process or it's already exceeded its crash quota, 8578 // quit right away without showing a crash dialog. 8579 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8580 Binder.restoreCallingIdentity(origId); 8581 return; 8582 } 8583 8584 Message msg = Message.obtain(); 8585 msg.what = SHOW_ERROR_MSG; 8586 HashMap data = new HashMap(); 8587 data.put("result", result); 8588 data.put("app", r); 8589 msg.obj = data; 8590 mHandler.sendMessage(msg); 8591 8592 Binder.restoreCallingIdentity(origId); 8593 } 8594 8595 int res = result.get(); 8596 8597 Intent appErrorIntent = null; 8598 synchronized (this) { 8599 if (r != null && !r.isolated) { 8600 // XXX Can't keep track of crash time for isolated processes, 8601 // since they don't have a persistent identity. 8602 mProcessCrashTimes.put(r.info.processName, r.uid, 8603 SystemClock.uptimeMillis()); 8604 } 8605 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8606 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8607 } 8608 } 8609 8610 if (appErrorIntent != null) { 8611 try { 8612 mContext.startActivity(appErrorIntent); 8613 } catch (ActivityNotFoundException e) { 8614 Slog.w(TAG, "bug report receiver dissappeared", e); 8615 } 8616 } 8617 } 8618 8619 Intent createAppErrorIntentLocked(ProcessRecord r, 8620 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8621 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8622 if (report == null) { 8623 return null; 8624 } 8625 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8626 result.setComponent(r.errorReportReceiver); 8627 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8628 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8629 return result; 8630 } 8631 8632 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8633 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8634 if (r.errorReportReceiver == null) { 8635 return null; 8636 } 8637 8638 if (!r.crashing && !r.notResponding) { 8639 return null; 8640 } 8641 8642 ApplicationErrorReport report = new ApplicationErrorReport(); 8643 report.packageName = r.info.packageName; 8644 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8645 report.processName = r.processName; 8646 report.time = timeMillis; 8647 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8648 8649 if (r.crashing) { 8650 report.type = ApplicationErrorReport.TYPE_CRASH; 8651 report.crashInfo = crashInfo; 8652 } else if (r.notResponding) { 8653 report.type = ApplicationErrorReport.TYPE_ANR; 8654 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8655 8656 report.anrInfo.activity = r.notRespondingReport.tag; 8657 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8658 report.anrInfo.info = r.notRespondingReport.longMsg; 8659 } 8660 8661 return report; 8662 } 8663 8664 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8665 enforceNotIsolatedCaller("getProcessesInErrorState"); 8666 // assume our apps are happy - lazy create the list 8667 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8668 8669 final boolean allUsers = ActivityManager.checkUidPermission( 8670 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8671 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8672 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8673 8674 synchronized (this) { 8675 8676 // iterate across all processes 8677 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8678 ProcessRecord app = mLruProcesses.get(i); 8679 if (!allUsers && app.userId != userId) { 8680 continue; 8681 } 8682 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8683 // This one's in trouble, so we'll generate a report for it 8684 // crashes are higher priority (in case there's a crash *and* an anr) 8685 ActivityManager.ProcessErrorStateInfo report = null; 8686 if (app.crashing) { 8687 report = app.crashingReport; 8688 } else if (app.notResponding) { 8689 report = app.notRespondingReport; 8690 } 8691 8692 if (report != null) { 8693 if (errList == null) { 8694 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8695 } 8696 errList.add(report); 8697 } else { 8698 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8699 " crashing = " + app.crashing + 8700 " notResponding = " + app.notResponding); 8701 } 8702 } 8703 } 8704 } 8705 8706 return errList; 8707 } 8708 8709 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8710 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8711 if (currApp != null) { 8712 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8713 } 8714 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8715 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8716 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8717 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8718 if (currApp != null) { 8719 currApp.lru = 0; 8720 } 8721 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8722 } else if (adj >= ProcessList.SERVICE_ADJ) { 8723 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8724 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8725 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8726 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8727 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8728 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8729 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8730 } else { 8731 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8732 } 8733 } 8734 8735 private void fillInProcMemInfo(ProcessRecord app, 8736 ActivityManager.RunningAppProcessInfo outInfo) { 8737 outInfo.pid = app.pid; 8738 outInfo.uid = app.info.uid; 8739 if (mHeavyWeightProcess == app) { 8740 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8741 } 8742 if (app.persistent) { 8743 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8744 } 8745 if (app.hasActivities) { 8746 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8747 } 8748 outInfo.lastTrimLevel = app.trimMemoryLevel; 8749 int adj = app.curAdj; 8750 outInfo.importance = oomAdjToImportance(adj, outInfo); 8751 outInfo.importanceReasonCode = app.adjTypeCode; 8752 } 8753 8754 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8755 enforceNotIsolatedCaller("getRunningAppProcesses"); 8756 // Lazy instantiation of list 8757 List<ActivityManager.RunningAppProcessInfo> runList = null; 8758 final boolean allUsers = ActivityManager.checkUidPermission( 8759 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8760 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8761 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8762 synchronized (this) { 8763 // Iterate across all processes 8764 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8765 ProcessRecord app = mLruProcesses.get(i); 8766 if (!allUsers && app.userId != userId) { 8767 continue; 8768 } 8769 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8770 // Generate process state info for running application 8771 ActivityManager.RunningAppProcessInfo currApp = 8772 new ActivityManager.RunningAppProcessInfo(app.processName, 8773 app.pid, app.getPackageList()); 8774 fillInProcMemInfo(app, currApp); 8775 if (app.adjSource instanceof ProcessRecord) { 8776 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8777 currApp.importanceReasonImportance = oomAdjToImportance( 8778 app.adjSourceOom, null); 8779 } else if (app.adjSource instanceof ActivityRecord) { 8780 ActivityRecord r = (ActivityRecord)app.adjSource; 8781 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8782 } 8783 if (app.adjTarget instanceof ComponentName) { 8784 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8785 } 8786 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8787 // + " lru=" + currApp.lru); 8788 if (runList == null) { 8789 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8790 } 8791 runList.add(currApp); 8792 } 8793 } 8794 } 8795 return runList; 8796 } 8797 8798 public List<ApplicationInfo> getRunningExternalApplications() { 8799 enforceNotIsolatedCaller("getRunningExternalApplications"); 8800 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8801 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8802 if (runningApps != null && runningApps.size() > 0) { 8803 Set<String> extList = new HashSet<String>(); 8804 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8805 if (app.pkgList != null) { 8806 for (String pkg : app.pkgList) { 8807 extList.add(pkg); 8808 } 8809 } 8810 } 8811 IPackageManager pm = AppGlobals.getPackageManager(); 8812 for (String pkg : extList) { 8813 try { 8814 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8815 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8816 retList.add(info); 8817 } 8818 } catch (RemoteException e) { 8819 } 8820 } 8821 } 8822 return retList; 8823 } 8824 8825 @Override 8826 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8827 enforceNotIsolatedCaller("getMyMemoryState"); 8828 synchronized (this) { 8829 ProcessRecord proc; 8830 synchronized (mPidsSelfLocked) { 8831 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8832 } 8833 fillInProcMemInfo(proc, outInfo); 8834 } 8835 } 8836 8837 @Override 8838 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8839 if (checkCallingPermission(android.Manifest.permission.DUMP) 8840 != PackageManager.PERMISSION_GRANTED) { 8841 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8842 + Binder.getCallingPid() 8843 + ", uid=" + Binder.getCallingUid() 8844 + " without permission " 8845 + android.Manifest.permission.DUMP); 8846 return; 8847 } 8848 8849 boolean dumpAll = false; 8850 boolean dumpClient = false; 8851 String dumpPackage = null; 8852 8853 int opti = 0; 8854 while (opti < args.length) { 8855 String opt = args[opti]; 8856 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8857 break; 8858 } 8859 opti++; 8860 if ("-a".equals(opt)) { 8861 dumpAll = true; 8862 } else if ("-c".equals(opt)) { 8863 dumpClient = true; 8864 } else if ("-h".equals(opt)) { 8865 pw.println("Activity manager dump options:"); 8866 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8867 pw.println(" cmd may be one of:"); 8868 pw.println(" a[ctivities]: activity stack state"); 8869 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8870 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8871 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8872 pw.println(" o[om]: out of memory management"); 8873 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8874 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8875 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8876 pw.println(" service [COMP_SPEC]: service client-side state"); 8877 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8878 pw.println(" all: dump all activities"); 8879 pw.println(" top: dump the top activity"); 8880 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8881 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8882 pw.println(" a partial substring in a component name, a"); 8883 pw.println(" hex object identifier."); 8884 pw.println(" -a: include all available server state."); 8885 pw.println(" -c: include client state."); 8886 return; 8887 } else { 8888 pw.println("Unknown argument: " + opt + "; use -h for help"); 8889 } 8890 } 8891 8892 long origId = Binder.clearCallingIdentity(); 8893 boolean more = false; 8894 // Is the caller requesting to dump a particular piece of data? 8895 if (opti < args.length) { 8896 String cmd = args[opti]; 8897 opti++; 8898 if ("activities".equals(cmd) || "a".equals(cmd)) { 8899 synchronized (this) { 8900 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8901 } 8902 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8903 String[] newArgs; 8904 String name; 8905 if (opti >= args.length) { 8906 name = null; 8907 newArgs = EMPTY_STRING_ARRAY; 8908 } else { 8909 name = args[opti]; 8910 opti++; 8911 newArgs = new String[args.length - opti]; 8912 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8913 args.length - opti); 8914 } 8915 synchronized (this) { 8916 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8917 } 8918 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8919 String[] newArgs; 8920 String name; 8921 if (opti >= args.length) { 8922 name = null; 8923 newArgs = EMPTY_STRING_ARRAY; 8924 } else { 8925 name = args[opti]; 8926 opti++; 8927 newArgs = new String[args.length - opti]; 8928 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8929 args.length - opti); 8930 } 8931 synchronized (this) { 8932 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8933 } 8934 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8935 String[] newArgs; 8936 String name; 8937 if (opti >= args.length) { 8938 name = null; 8939 newArgs = EMPTY_STRING_ARRAY; 8940 } else { 8941 name = args[opti]; 8942 opti++; 8943 newArgs = new String[args.length - opti]; 8944 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8945 args.length - opti); 8946 } 8947 synchronized (this) { 8948 dumpProcessesLocked(fd, pw, args, opti, true, name); 8949 } 8950 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8951 synchronized (this) { 8952 dumpOomLocked(fd, pw, args, opti, true); 8953 } 8954 } else if ("provider".equals(cmd)) { 8955 String[] newArgs; 8956 String name; 8957 if (opti >= args.length) { 8958 name = null; 8959 newArgs = EMPTY_STRING_ARRAY; 8960 } else { 8961 name = args[opti]; 8962 opti++; 8963 newArgs = new String[args.length - opti]; 8964 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8965 } 8966 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8967 pw.println("No providers match: " + name); 8968 pw.println("Use -h for help."); 8969 } 8970 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8971 synchronized (this) { 8972 dumpProvidersLocked(fd, pw, args, opti, true, null); 8973 } 8974 } else if ("service".equals(cmd)) { 8975 String[] newArgs; 8976 String name; 8977 if (opti >= args.length) { 8978 name = null; 8979 newArgs = EMPTY_STRING_ARRAY; 8980 } else { 8981 name = args[opti]; 8982 opti++; 8983 newArgs = new String[args.length - opti]; 8984 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8985 args.length - opti); 8986 } 8987 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8988 pw.println("No services match: " + name); 8989 pw.println("Use -h for help."); 8990 } 8991 } else if ("package".equals(cmd)) { 8992 String[] newArgs; 8993 if (opti >= args.length) { 8994 pw.println("package: no package name specified"); 8995 pw.println("Use -h for help."); 8996 } else { 8997 dumpPackage = args[opti]; 8998 opti++; 8999 newArgs = new String[args.length - opti]; 9000 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9001 args.length - opti); 9002 args = newArgs; 9003 opti = 0; 9004 more = true; 9005 } 9006 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9007 synchronized (this) { 9008 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9009 } 9010 } else { 9011 // Dumping a single activity? 9012 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9013 pw.println("Bad activity command, or no activities match: " + cmd); 9014 pw.println("Use -h for help."); 9015 } 9016 } 9017 if (!more) { 9018 Binder.restoreCallingIdentity(origId); 9019 return; 9020 } 9021 } 9022 9023 // No piece of data specified, dump everything. 9024 synchronized (this) { 9025 boolean needSep; 9026 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9027 if (needSep) { 9028 pw.println(" "); 9029 } 9030 if (dumpAll) { 9031 pw.println("-------------------------------------------------------------------------------"); 9032 } 9033 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9034 if (needSep) { 9035 pw.println(" "); 9036 } 9037 if (dumpAll) { 9038 pw.println("-------------------------------------------------------------------------------"); 9039 } 9040 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9041 if (needSep) { 9042 pw.println(" "); 9043 } 9044 if (dumpAll) { 9045 pw.println("-------------------------------------------------------------------------------"); 9046 } 9047 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9048 if (needSep) { 9049 pw.println(" "); 9050 } 9051 if (dumpAll) { 9052 pw.println("-------------------------------------------------------------------------------"); 9053 } 9054 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9055 if (needSep) { 9056 pw.println(" "); 9057 } 9058 if (dumpAll) { 9059 pw.println("-------------------------------------------------------------------------------"); 9060 } 9061 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9062 } 9063 Binder.restoreCallingIdentity(origId); 9064 } 9065 9066 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9067 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9068 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9069 pw.println(" Main stack:"); 9070 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9071 dumpPackage); 9072 pw.println(" "); 9073 pw.println(" Running activities (most recent first):"); 9074 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9075 dumpPackage); 9076 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9077 pw.println(" "); 9078 pw.println(" Activities waiting for another to become visible:"); 9079 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9080 !dumpAll, false, dumpPackage); 9081 } 9082 if (mMainStack.mStoppingActivities.size() > 0) { 9083 pw.println(" "); 9084 pw.println(" Activities waiting to stop:"); 9085 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9086 !dumpAll, false, dumpPackage); 9087 } 9088 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9089 pw.println(" "); 9090 pw.println(" Activities waiting to sleep:"); 9091 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9092 !dumpAll, false, dumpPackage); 9093 } 9094 if (mMainStack.mFinishingActivities.size() > 0) { 9095 pw.println(" "); 9096 pw.println(" Activities waiting to finish:"); 9097 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9098 !dumpAll, false, dumpPackage); 9099 } 9100 9101 pw.println(" "); 9102 if (mMainStack.mPausingActivity != null) { 9103 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9104 } 9105 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9106 pw.println(" mFocusedActivity: " + mFocusedActivity); 9107 if (dumpAll) { 9108 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9109 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9110 pw.println(" mDismissKeyguardOnNextActivity: " 9111 + mMainStack.mDismissKeyguardOnNextActivity); 9112 } 9113 9114 if (mRecentTasks.size() > 0) { 9115 pw.println(); 9116 pw.println(" Recent tasks:"); 9117 9118 final int N = mRecentTasks.size(); 9119 for (int i=0; i<N; i++) { 9120 TaskRecord tr = mRecentTasks.get(i); 9121 if (dumpPackage != null) { 9122 if (tr.realActivity == null || 9123 !dumpPackage.equals(tr.realActivity)) { 9124 continue; 9125 } 9126 } 9127 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9128 pw.println(tr); 9129 if (dumpAll) { 9130 mRecentTasks.get(i).dump(pw, " "); 9131 } 9132 } 9133 } 9134 9135 if (dumpAll) { 9136 pw.println(" "); 9137 pw.println(" mCurTask: " + mCurTask); 9138 } 9139 9140 return true; 9141 } 9142 9143 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9144 int opti, boolean dumpAll, String dumpPackage) { 9145 boolean needSep = false; 9146 int numPers = 0; 9147 9148 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9149 9150 if (dumpAll) { 9151 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9152 final int NA = procs.size(); 9153 for (int ia=0; ia<NA; ia++) { 9154 ProcessRecord r = procs.valueAt(ia); 9155 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9156 continue; 9157 } 9158 if (!needSep) { 9159 pw.println(" All known processes:"); 9160 needSep = true; 9161 } 9162 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9163 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9164 pw.print(" "); pw.println(r); 9165 r.dump(pw, " "); 9166 if (r.persistent) { 9167 numPers++; 9168 } 9169 } 9170 } 9171 } 9172 9173 if (mIsolatedProcesses.size() > 0) { 9174 if (needSep) pw.println(" "); 9175 needSep = true; 9176 pw.println(" Isolated process list (sorted by uid):"); 9177 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9178 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9179 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9180 continue; 9181 } 9182 pw.println(String.format("%sIsolated #%2d: %s", 9183 " ", i, r.toString())); 9184 } 9185 } 9186 9187 if (mLruProcesses.size() > 0) { 9188 if (needSep) pw.println(" "); 9189 needSep = true; 9190 pw.println(" Process LRU list (sorted by oom_adj):"); 9191 dumpProcessOomList(pw, this, mLruProcesses, " ", 9192 "Proc", "PERS", false, dumpPackage); 9193 needSep = true; 9194 } 9195 9196 if (dumpAll) { 9197 synchronized (mPidsSelfLocked) { 9198 boolean printed = false; 9199 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9200 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9201 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9202 continue; 9203 } 9204 if (!printed) { 9205 if (needSep) pw.println(" "); 9206 needSep = true; 9207 pw.println(" PID mappings:"); 9208 printed = true; 9209 } 9210 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9211 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9212 } 9213 } 9214 } 9215 9216 if (mForegroundProcesses.size() > 0) { 9217 synchronized (mPidsSelfLocked) { 9218 boolean printed = false; 9219 for (int i=0; i<mForegroundProcesses.size(); i++) { 9220 ProcessRecord r = mPidsSelfLocked.get( 9221 mForegroundProcesses.valueAt(i).pid); 9222 if (dumpPackage != null && (r == null 9223 || !dumpPackage.equals(r.info.packageName))) { 9224 continue; 9225 } 9226 if (!printed) { 9227 if (needSep) pw.println(" "); 9228 needSep = true; 9229 pw.println(" Foreground Processes:"); 9230 printed = true; 9231 } 9232 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9233 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9234 } 9235 } 9236 } 9237 9238 if (mPersistentStartingProcesses.size() > 0) { 9239 if (needSep) pw.println(" "); 9240 needSep = true; 9241 pw.println(" Persisent processes that are starting:"); 9242 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9243 "Starting Norm", "Restarting PERS", dumpPackage); 9244 } 9245 9246 if (mRemovedProcesses.size() > 0) { 9247 if (needSep) pw.println(" "); 9248 needSep = true; 9249 pw.println(" Processes that are being removed:"); 9250 dumpProcessList(pw, this, mRemovedProcesses, " ", 9251 "Removed Norm", "Removed PERS", dumpPackage); 9252 } 9253 9254 if (mProcessesOnHold.size() > 0) { 9255 if (needSep) pw.println(" "); 9256 needSep = true; 9257 pw.println(" Processes that are on old until the system is ready:"); 9258 dumpProcessList(pw, this, mProcessesOnHold, " ", 9259 "OnHold Norm", "OnHold PERS", dumpPackage); 9260 } 9261 9262 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9263 9264 if (mProcessCrashTimes.getMap().size() > 0) { 9265 boolean printed = false; 9266 long now = SystemClock.uptimeMillis(); 9267 for (Map.Entry<String, SparseArray<Long>> procs 9268 : mProcessCrashTimes.getMap().entrySet()) { 9269 String pname = procs.getKey(); 9270 SparseArray<Long> uids = procs.getValue(); 9271 final int N = uids.size(); 9272 for (int i=0; i<N; i++) { 9273 int puid = uids.keyAt(i); 9274 ProcessRecord r = mProcessNames.get(pname, puid); 9275 if (dumpPackage != null && (r == null 9276 || !dumpPackage.equals(r.info.packageName))) { 9277 continue; 9278 } 9279 if (!printed) { 9280 if (needSep) pw.println(" "); 9281 needSep = true; 9282 pw.println(" Time since processes crashed:"); 9283 printed = true; 9284 } 9285 pw.print(" Process "); pw.print(pname); 9286 pw.print(" uid "); pw.print(puid); 9287 pw.print(": last crashed "); 9288 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9289 pw.println(" ago"); 9290 } 9291 } 9292 } 9293 9294 if (mBadProcesses.getMap().size() > 0) { 9295 boolean printed = false; 9296 for (Map.Entry<String, SparseArray<Long>> procs 9297 : mBadProcesses.getMap().entrySet()) { 9298 String pname = procs.getKey(); 9299 SparseArray<Long> uids = procs.getValue(); 9300 final int N = uids.size(); 9301 for (int i=0; i<N; i++) { 9302 int puid = uids.keyAt(i); 9303 ProcessRecord r = mProcessNames.get(pname, puid); 9304 if (dumpPackage != null && (r == null 9305 || !dumpPackage.equals(r.info.packageName))) { 9306 continue; 9307 } 9308 if (!printed) { 9309 if (needSep) pw.println(" "); 9310 needSep = true; 9311 pw.println(" Bad processes:"); 9312 } 9313 pw.print(" Bad process "); pw.print(pname); 9314 pw.print(" uid "); pw.print(puid); 9315 pw.print(": crashed at time "); 9316 pw.println(uids.valueAt(i)); 9317 } 9318 } 9319 } 9320 9321 pw.println(); 9322 pw.println(" mStartedUsers:"); 9323 for (int i=0; i<mStartedUsers.size(); i++) { 9324 UserStartedState uss = mStartedUsers.valueAt(i); 9325 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9326 pw.print(": "); uss.dump("", pw); 9327 } 9328 pw.print(" mUserLru: ["); 9329 for (int i=0; i<mUserLru.size(); i++) { 9330 if (i > 0) pw.print(", "); 9331 pw.print(mUserLru.get(i)); 9332 } 9333 pw.println("]"); 9334 if (dumpAll) { 9335 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9336 } 9337 pw.println(" mHomeProcess: " + mHomeProcess); 9338 pw.println(" mPreviousProcess: " + mPreviousProcess); 9339 if (dumpAll) { 9340 StringBuilder sb = new StringBuilder(128); 9341 sb.append(" mPreviousProcessVisibleTime: "); 9342 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9343 pw.println(sb); 9344 } 9345 if (mHeavyWeightProcess != null) { 9346 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9347 } 9348 pw.println(" mConfiguration: " + mConfiguration); 9349 if (dumpAll) { 9350 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9351 if (mCompatModePackages.getPackages().size() > 0) { 9352 boolean printed = false; 9353 for (Map.Entry<String, Integer> entry 9354 : mCompatModePackages.getPackages().entrySet()) { 9355 String pkg = entry.getKey(); 9356 int mode = entry.getValue(); 9357 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9358 continue; 9359 } 9360 if (!printed) { 9361 pw.println(" mScreenCompatPackages:"); 9362 printed = true; 9363 } 9364 pw.print(" "); pw.print(pkg); pw.print(": "); 9365 pw.print(mode); pw.println(); 9366 } 9367 } 9368 } 9369 if (mSleeping || mWentToSleep || mLockScreenShown) { 9370 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9371 + " mLockScreenShown " + mLockScreenShown); 9372 } 9373 if (mShuttingDown) { 9374 pw.println(" mShuttingDown=" + mShuttingDown); 9375 } 9376 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9377 || mOrigWaitForDebugger) { 9378 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9379 + " mDebugTransient=" + mDebugTransient 9380 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9381 } 9382 if (mOpenGlTraceApp != null) { 9383 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9384 } 9385 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9386 || mProfileFd != null) { 9387 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9388 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9389 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9390 + mAutoStopProfiler); 9391 } 9392 if (mAlwaysFinishActivities || mController != null) { 9393 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9394 + " mController=" + mController); 9395 } 9396 if (dumpAll) { 9397 pw.println(" Total persistent processes: " + numPers); 9398 pw.println(" mStartRunning=" + mStartRunning 9399 + " mProcessesReady=" + mProcessesReady 9400 + " mSystemReady=" + mSystemReady); 9401 pw.println(" mBooting=" + mBooting 9402 + " mBooted=" + mBooted 9403 + " mFactoryTest=" + mFactoryTest); 9404 pw.print(" mLastPowerCheckRealtime="); 9405 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9406 pw.println(""); 9407 pw.print(" mLastPowerCheckUptime="); 9408 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9409 pw.println(""); 9410 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9411 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9412 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9413 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9414 + " mNumHiddenProcs=" + mNumHiddenProcs 9415 + " mNumServiceProcs=" + mNumServiceProcs 9416 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9417 } 9418 9419 return true; 9420 } 9421 9422 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9423 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9424 if (mProcessesToGc.size() > 0) { 9425 boolean printed = false; 9426 long now = SystemClock.uptimeMillis(); 9427 for (int i=0; i<mProcessesToGc.size(); i++) { 9428 ProcessRecord proc = mProcessesToGc.get(i); 9429 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9430 continue; 9431 } 9432 if (!printed) { 9433 if (needSep) pw.println(" "); 9434 needSep = true; 9435 pw.println(" Processes that are waiting to GC:"); 9436 printed = true; 9437 } 9438 pw.print(" Process "); pw.println(proc); 9439 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9440 pw.print(", last gced="); 9441 pw.print(now-proc.lastRequestedGc); 9442 pw.print(" ms ago, last lowMem="); 9443 pw.print(now-proc.lastLowMemory); 9444 pw.println(" ms ago"); 9445 9446 } 9447 } 9448 return needSep; 9449 } 9450 9451 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9452 int opti, boolean dumpAll) { 9453 boolean needSep = false; 9454 9455 if (mLruProcesses.size() > 0) { 9456 if (needSep) pw.println(" "); 9457 needSep = true; 9458 pw.println(" OOM levels:"); 9459 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9460 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9461 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9462 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9463 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9464 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9465 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9466 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9467 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9468 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9469 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9470 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9471 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9472 9473 if (needSep) pw.println(" "); 9474 needSep = true; 9475 pw.println(" Process OOM control:"); 9476 dumpProcessOomList(pw, this, mLruProcesses, " ", 9477 "Proc", "PERS", true, null); 9478 needSep = true; 9479 } 9480 9481 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9482 9483 pw.println(); 9484 pw.println(" mHomeProcess: " + mHomeProcess); 9485 pw.println(" mPreviousProcess: " + mPreviousProcess); 9486 if (mHeavyWeightProcess != null) { 9487 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9488 } 9489 9490 return true; 9491 } 9492 9493 /** 9494 * There are three ways to call this: 9495 * - no provider specified: dump all the providers 9496 * - a flattened component name that matched an existing provider was specified as the 9497 * first arg: dump that one provider 9498 * - the first arg isn't the flattened component name of an existing provider: 9499 * dump all providers whose component contains the first arg as a substring 9500 */ 9501 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9502 int opti, boolean dumpAll) { 9503 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9504 } 9505 9506 static class ItemMatcher { 9507 ArrayList<ComponentName> components; 9508 ArrayList<String> strings; 9509 ArrayList<Integer> objects; 9510 boolean all; 9511 9512 ItemMatcher() { 9513 all = true; 9514 } 9515 9516 void build(String name) { 9517 ComponentName componentName = ComponentName.unflattenFromString(name); 9518 if (componentName != null) { 9519 if (components == null) { 9520 components = new ArrayList<ComponentName>(); 9521 } 9522 components.add(componentName); 9523 all = false; 9524 } else { 9525 int objectId = 0; 9526 // Not a '/' separated full component name; maybe an object ID? 9527 try { 9528 objectId = Integer.parseInt(name, 16); 9529 if (objects == null) { 9530 objects = new ArrayList<Integer>(); 9531 } 9532 objects.add(objectId); 9533 all = false; 9534 } catch (RuntimeException e) { 9535 // Not an integer; just do string match. 9536 if (strings == null) { 9537 strings = new ArrayList<String>(); 9538 } 9539 strings.add(name); 9540 all = false; 9541 } 9542 } 9543 } 9544 9545 int build(String[] args, int opti) { 9546 for (; opti<args.length; opti++) { 9547 String name = args[opti]; 9548 if ("--".equals(name)) { 9549 return opti+1; 9550 } 9551 build(name); 9552 } 9553 return opti; 9554 } 9555 9556 boolean match(Object object, ComponentName comp) { 9557 if (all) { 9558 return true; 9559 } 9560 if (components != null) { 9561 for (int i=0; i<components.size(); i++) { 9562 if (components.get(i).equals(comp)) { 9563 return true; 9564 } 9565 } 9566 } 9567 if (objects != null) { 9568 for (int i=0; i<objects.size(); i++) { 9569 if (System.identityHashCode(object) == objects.get(i)) { 9570 return true; 9571 } 9572 } 9573 } 9574 if (strings != null) { 9575 String flat = comp.flattenToString(); 9576 for (int i=0; i<strings.size(); i++) { 9577 if (flat.contains(strings.get(i))) { 9578 return true; 9579 } 9580 } 9581 } 9582 return false; 9583 } 9584 } 9585 9586 /** 9587 * There are three things that cmd can be: 9588 * - a flattened component name that matches an existing activity 9589 * - the cmd arg isn't the flattened component name of an existing activity: 9590 * dump all activity whose component contains the cmd as a substring 9591 * - A hex number of the ActivityRecord object instance. 9592 */ 9593 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9594 int opti, boolean dumpAll) { 9595 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9596 9597 if ("all".equals(name)) { 9598 synchronized (this) { 9599 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9600 activities.add(r1); 9601 } 9602 } 9603 } else if ("top".equals(name)) { 9604 synchronized (this) { 9605 final int N = mMainStack.mHistory.size(); 9606 if (N > 0) { 9607 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9608 } 9609 } 9610 } else { 9611 ItemMatcher matcher = new ItemMatcher(); 9612 matcher.build(name); 9613 9614 synchronized (this) { 9615 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9616 if (matcher.match(r1, r1.intent.getComponent())) { 9617 activities.add(r1); 9618 } 9619 } 9620 } 9621 } 9622 9623 if (activities.size() <= 0) { 9624 return false; 9625 } 9626 9627 String[] newArgs = new String[args.length - opti]; 9628 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9629 9630 TaskRecord lastTask = null; 9631 boolean needSep = false; 9632 for (int i=activities.size()-1; i>=0; i--) { 9633 ActivityRecord r = (ActivityRecord)activities.get(i); 9634 if (needSep) { 9635 pw.println(); 9636 } 9637 needSep = true; 9638 synchronized (this) { 9639 if (lastTask != r.task) { 9640 lastTask = r.task; 9641 pw.print("TASK "); pw.print(lastTask.affinity); 9642 pw.print(" id="); pw.println(lastTask.taskId); 9643 if (dumpAll) { 9644 lastTask.dump(pw, " "); 9645 } 9646 } 9647 } 9648 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9649 } 9650 return true; 9651 } 9652 9653 /** 9654 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9655 * there is a thread associated with the activity. 9656 */ 9657 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9658 final ActivityRecord r, String[] args, boolean dumpAll) { 9659 String innerPrefix = prefix + " "; 9660 synchronized (this) { 9661 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9662 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9663 pw.print(" pid="); 9664 if (r.app != null) pw.println(r.app.pid); 9665 else pw.println("(not running)"); 9666 if (dumpAll) { 9667 r.dump(pw, innerPrefix); 9668 } 9669 } 9670 if (r.app != null && r.app.thread != null) { 9671 // flush anything that is already in the PrintWriter since the thread is going 9672 // to write to the file descriptor directly 9673 pw.flush(); 9674 try { 9675 TransferPipe tp = new TransferPipe(); 9676 try { 9677 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9678 r.appToken, innerPrefix, args); 9679 tp.go(fd); 9680 } finally { 9681 tp.kill(); 9682 } 9683 } catch (IOException e) { 9684 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9685 } catch (RemoteException e) { 9686 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9687 } 9688 } 9689 } 9690 9691 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9692 int opti, boolean dumpAll, String dumpPackage) { 9693 boolean needSep = false; 9694 boolean onlyHistory = false; 9695 9696 if ("history".equals(dumpPackage)) { 9697 onlyHistory = true; 9698 dumpPackage = null; 9699 } 9700 9701 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9702 if (!onlyHistory && dumpAll) { 9703 if (mRegisteredReceivers.size() > 0) { 9704 boolean printed = false; 9705 Iterator it = mRegisteredReceivers.values().iterator(); 9706 while (it.hasNext()) { 9707 ReceiverList r = (ReceiverList)it.next(); 9708 if (dumpPackage != null && (r.app == null || 9709 !dumpPackage.equals(r.app.info.packageName))) { 9710 continue; 9711 } 9712 if (!printed) { 9713 pw.println(" Registered Receivers:"); 9714 needSep = true; 9715 printed = true; 9716 } 9717 pw.print(" * "); pw.println(r); 9718 r.dump(pw, " "); 9719 } 9720 } 9721 9722 if (mReceiverResolver.dump(pw, needSep ? 9723 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9724 " ", dumpPackage, false)) { 9725 needSep = true; 9726 } 9727 } 9728 9729 for (BroadcastQueue q : mBroadcastQueues) { 9730 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9731 } 9732 9733 needSep = true; 9734 9735 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9736 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9737 if (needSep) { 9738 pw.println(); 9739 } 9740 needSep = true; 9741 pw.print(" Sticky broadcasts for user "); 9742 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9743 StringBuilder sb = new StringBuilder(128); 9744 for (Map.Entry<String, ArrayList<Intent>> ent 9745 : mStickyBroadcasts.valueAt(user).entrySet()) { 9746 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9747 if (dumpAll) { 9748 pw.println(":"); 9749 ArrayList<Intent> intents = ent.getValue(); 9750 final int N = intents.size(); 9751 for (int i=0; i<N; i++) { 9752 sb.setLength(0); 9753 sb.append(" Intent: "); 9754 intents.get(i).toShortString(sb, false, true, false, false); 9755 pw.println(sb.toString()); 9756 Bundle bundle = intents.get(i).getExtras(); 9757 if (bundle != null) { 9758 pw.print(" "); 9759 pw.println(bundle.toString()); 9760 } 9761 } 9762 } else { 9763 pw.println(""); 9764 } 9765 } 9766 } 9767 } 9768 9769 if (!onlyHistory && dumpAll) { 9770 pw.println(); 9771 for (BroadcastQueue queue : mBroadcastQueues) { 9772 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9773 + queue.mBroadcastsScheduled); 9774 } 9775 pw.println(" mHandler:"); 9776 mHandler.dump(new PrintWriterPrinter(pw), " "); 9777 needSep = true; 9778 } 9779 9780 return needSep; 9781 } 9782 9783 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9784 int opti, boolean dumpAll, String dumpPackage) { 9785 boolean needSep = true; 9786 9787 ItemMatcher matcher = new ItemMatcher(); 9788 matcher.build(args, opti); 9789 9790 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9791 9792 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9793 9794 if (mLaunchingProviders.size() > 0) { 9795 boolean printed = false; 9796 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9797 ContentProviderRecord r = mLaunchingProviders.get(i); 9798 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9799 continue; 9800 } 9801 if (!printed) { 9802 if (needSep) pw.println(" "); 9803 needSep = true; 9804 pw.println(" Launching content providers:"); 9805 printed = true; 9806 } 9807 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9808 pw.println(r); 9809 } 9810 } 9811 9812 if (mGrantedUriPermissions.size() > 0) { 9813 if (needSep) pw.println(); 9814 needSep = true; 9815 pw.println("Granted Uri Permissions:"); 9816 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9817 int uid = mGrantedUriPermissions.keyAt(i); 9818 HashMap<Uri, UriPermission> perms 9819 = mGrantedUriPermissions.valueAt(i); 9820 pw.print(" * UID "); pw.print(uid); 9821 pw.println(" holds:"); 9822 for (UriPermission perm : perms.values()) { 9823 pw.print(" "); pw.println(perm); 9824 if (dumpAll) { 9825 perm.dump(pw, " "); 9826 } 9827 } 9828 } 9829 needSep = true; 9830 } 9831 9832 return needSep; 9833 } 9834 9835 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9836 int opti, boolean dumpAll, String dumpPackage) { 9837 boolean needSep = false; 9838 9839 if (mIntentSenderRecords.size() > 0) { 9840 boolean printed = false; 9841 Iterator<WeakReference<PendingIntentRecord>> it 9842 = mIntentSenderRecords.values().iterator(); 9843 while (it.hasNext()) { 9844 WeakReference<PendingIntentRecord> ref = it.next(); 9845 PendingIntentRecord rec = ref != null ? ref.get(): null; 9846 if (dumpPackage != null && (rec == null 9847 || !dumpPackage.equals(rec.key.packageName))) { 9848 continue; 9849 } 9850 if (!printed) { 9851 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9852 printed = true; 9853 } 9854 needSep = true; 9855 if (rec != null) { 9856 pw.print(" * "); pw.println(rec); 9857 if (dumpAll) { 9858 rec.dump(pw, " "); 9859 } 9860 } else { 9861 pw.print(" * "); pw.println(ref); 9862 } 9863 } 9864 } 9865 9866 return needSep; 9867 } 9868 9869 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9870 String prefix, String label, boolean complete, boolean brief, boolean client, 9871 String dumpPackage) { 9872 TaskRecord lastTask = null; 9873 boolean needNL = false; 9874 final String innerPrefix = prefix + " "; 9875 final String[] args = new String[0]; 9876 for (int i=list.size()-1; i>=0; i--) { 9877 final ActivityRecord r = (ActivityRecord)list.get(i); 9878 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9879 continue; 9880 } 9881 final boolean full = !brief && (complete || !r.isInHistory()); 9882 if (needNL) { 9883 pw.println(" "); 9884 needNL = false; 9885 } 9886 if (lastTask != r.task) { 9887 lastTask = r.task; 9888 pw.print(prefix); 9889 pw.print(full ? "* " : " "); 9890 pw.println(lastTask); 9891 if (full) { 9892 lastTask.dump(pw, prefix + " "); 9893 } else if (complete) { 9894 // Complete + brief == give a summary. Isn't that obvious?!? 9895 if (lastTask.intent != null) { 9896 pw.print(prefix); pw.print(" "); 9897 pw.println(lastTask.intent.toInsecureStringWithClip()); 9898 } 9899 } 9900 } 9901 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9902 pw.print(" #"); pw.print(i); pw.print(": "); 9903 pw.println(r); 9904 if (full) { 9905 r.dump(pw, innerPrefix); 9906 } else if (complete) { 9907 // Complete + brief == give a summary. Isn't that obvious?!? 9908 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9909 if (r.app != null) { 9910 pw.print(innerPrefix); pw.println(r.app); 9911 } 9912 } 9913 if (client && r.app != null && r.app.thread != null) { 9914 // flush anything that is already in the PrintWriter since the thread is going 9915 // to write to the file descriptor directly 9916 pw.flush(); 9917 try { 9918 TransferPipe tp = new TransferPipe(); 9919 try { 9920 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9921 r.appToken, innerPrefix, args); 9922 // Short timeout, since blocking here can 9923 // deadlock with the application. 9924 tp.go(fd, 2000); 9925 } finally { 9926 tp.kill(); 9927 } 9928 } catch (IOException e) { 9929 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9930 } catch (RemoteException e) { 9931 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9932 } 9933 needNL = true; 9934 } 9935 } 9936 } 9937 9938 private static String buildOomTag(String prefix, String space, int val, int base) { 9939 if (val == base) { 9940 if (space == null) return prefix; 9941 return prefix + " "; 9942 } 9943 return prefix + "+" + Integer.toString(val-base); 9944 } 9945 9946 private static final int dumpProcessList(PrintWriter pw, 9947 ActivityManagerService service, List list, 9948 String prefix, String normalLabel, String persistentLabel, 9949 String dumpPackage) { 9950 int numPers = 0; 9951 final int N = list.size()-1; 9952 for (int i=N; i>=0; i--) { 9953 ProcessRecord r = (ProcessRecord)list.get(i); 9954 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9955 continue; 9956 } 9957 pw.println(String.format("%s%s #%2d: %s", 9958 prefix, (r.persistent ? persistentLabel : normalLabel), 9959 i, r.toString())); 9960 if (r.persistent) { 9961 numPers++; 9962 } 9963 } 9964 return numPers; 9965 } 9966 9967 private static final boolean dumpProcessOomList(PrintWriter pw, 9968 ActivityManagerService service, List<ProcessRecord> origList, 9969 String prefix, String normalLabel, String persistentLabel, 9970 boolean inclDetails, String dumpPackage) { 9971 9972 ArrayList<Pair<ProcessRecord, Integer>> list 9973 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9974 for (int i=0; i<origList.size(); i++) { 9975 ProcessRecord r = origList.get(i); 9976 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9977 continue; 9978 } 9979 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9980 } 9981 9982 if (list.size() <= 0) { 9983 return false; 9984 } 9985 9986 Comparator<Pair<ProcessRecord, Integer>> comparator 9987 = new Comparator<Pair<ProcessRecord, Integer>>() { 9988 @Override 9989 public int compare(Pair<ProcessRecord, Integer> object1, 9990 Pair<ProcessRecord, Integer> object2) { 9991 if (object1.first.setAdj != object2.first.setAdj) { 9992 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9993 } 9994 if (object1.second.intValue() != object2.second.intValue()) { 9995 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9996 } 9997 return 0; 9998 } 9999 }; 10000 10001 Collections.sort(list, comparator); 10002 10003 final long curRealtime = SystemClock.elapsedRealtime(); 10004 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10005 final long curUptime = SystemClock.uptimeMillis(); 10006 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10007 10008 for (int i=list.size()-1; i>=0; i--) { 10009 ProcessRecord r = list.get(i).first; 10010 String oomAdj; 10011 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10012 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10013 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10014 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10015 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10016 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10017 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10018 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10019 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10020 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10021 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10022 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10023 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10024 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10025 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10026 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10027 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10028 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10029 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10030 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10031 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10032 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10033 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10034 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10035 } else { 10036 oomAdj = Integer.toString(r.setAdj); 10037 } 10038 String schedGroup; 10039 switch (r.setSchedGroup) { 10040 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10041 schedGroup = "B"; 10042 break; 10043 case Process.THREAD_GROUP_DEFAULT: 10044 schedGroup = "F"; 10045 break; 10046 default: 10047 schedGroup = Integer.toString(r.setSchedGroup); 10048 break; 10049 } 10050 String foreground; 10051 if (r.foregroundActivities) { 10052 foreground = "A"; 10053 } else if (r.foregroundServices) { 10054 foreground = "S"; 10055 } else { 10056 foreground = " "; 10057 } 10058 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10059 prefix, (r.persistent ? persistentLabel : normalLabel), 10060 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10061 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10062 if (r.adjSource != null || r.adjTarget != null) { 10063 pw.print(prefix); 10064 pw.print(" "); 10065 if (r.adjTarget instanceof ComponentName) { 10066 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10067 } else if (r.adjTarget != null) { 10068 pw.print(r.adjTarget.toString()); 10069 } else { 10070 pw.print("{null}"); 10071 } 10072 pw.print("<="); 10073 if (r.adjSource instanceof ProcessRecord) { 10074 pw.print("Proc{"); 10075 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10076 pw.println("}"); 10077 } else if (r.adjSource != null) { 10078 pw.println(r.adjSource.toString()); 10079 } else { 10080 pw.println("{null}"); 10081 } 10082 } 10083 if (inclDetails) { 10084 pw.print(prefix); 10085 pw.print(" "); 10086 pw.print("oom: max="); pw.print(r.maxAdj); 10087 pw.print(" hidden="); pw.print(r.hiddenAdj); 10088 pw.print(" empty="); pw.print(r.emptyAdj); 10089 pw.print(" curRaw="); pw.print(r.curRawAdj); 10090 pw.print(" setRaw="); pw.print(r.setRawAdj); 10091 pw.print(" cur="); pw.print(r.curAdj); 10092 pw.print(" set="); pw.println(r.setAdj); 10093 pw.print(prefix); 10094 pw.print(" "); 10095 pw.print("keeping="); pw.print(r.keeping); 10096 pw.print(" hidden="); pw.print(r.hidden); 10097 pw.print(" empty="); pw.print(r.empty); 10098 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10099 10100 if (!r.keeping) { 10101 if (r.lastWakeTime != 0) { 10102 long wtime; 10103 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10104 synchronized (stats) { 10105 wtime = stats.getProcessWakeTime(r.info.uid, 10106 r.pid, curRealtime); 10107 } 10108 long timeUsed = wtime - r.lastWakeTime; 10109 pw.print(prefix); 10110 pw.print(" "); 10111 pw.print("keep awake over "); 10112 TimeUtils.formatDuration(realtimeSince, pw); 10113 pw.print(" used "); 10114 TimeUtils.formatDuration(timeUsed, pw); 10115 pw.print(" ("); 10116 pw.print((timeUsed*100)/realtimeSince); 10117 pw.println("%)"); 10118 } 10119 if (r.lastCpuTime != 0) { 10120 long timeUsed = r.curCpuTime - r.lastCpuTime; 10121 pw.print(prefix); 10122 pw.print(" "); 10123 pw.print("run cpu over "); 10124 TimeUtils.formatDuration(uptimeSince, pw); 10125 pw.print(" used "); 10126 TimeUtils.formatDuration(timeUsed, pw); 10127 pw.print(" ("); 10128 pw.print((timeUsed*100)/uptimeSince); 10129 pw.println("%)"); 10130 } 10131 } 10132 } 10133 } 10134 return true; 10135 } 10136 10137 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10138 ArrayList<ProcessRecord> procs; 10139 synchronized (this) { 10140 if (args != null && args.length > start 10141 && args[start].charAt(0) != '-') { 10142 procs = new ArrayList<ProcessRecord>(); 10143 int pid = -1; 10144 try { 10145 pid = Integer.parseInt(args[start]); 10146 } catch (NumberFormatException e) { 10147 10148 } 10149 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10150 ProcessRecord proc = mLruProcesses.get(i); 10151 if (proc.pid == pid) { 10152 procs.add(proc); 10153 } else if (proc.processName.equals(args[start])) { 10154 procs.add(proc); 10155 } 10156 } 10157 if (procs.size() <= 0) { 10158 pw.println("No process found for: " + args[start]); 10159 return null; 10160 } 10161 } else { 10162 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10163 } 10164 } 10165 return procs; 10166 } 10167 10168 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10169 PrintWriter pw, String[] args) { 10170 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10171 if (procs == null) { 10172 return; 10173 } 10174 10175 long uptime = SystemClock.uptimeMillis(); 10176 long realtime = SystemClock.elapsedRealtime(); 10177 pw.println("Applications Graphics Acceleration Info:"); 10178 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10179 10180 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10181 ProcessRecord r = procs.get(i); 10182 if (r.thread != null) { 10183 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10184 pw.flush(); 10185 try { 10186 TransferPipe tp = new TransferPipe(); 10187 try { 10188 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10189 tp.go(fd); 10190 } finally { 10191 tp.kill(); 10192 } 10193 } catch (IOException e) { 10194 pw.println("Failure while dumping the app: " + r); 10195 pw.flush(); 10196 } catch (RemoteException e) { 10197 pw.println("Got a RemoteException while dumping the app " + r); 10198 pw.flush(); 10199 } 10200 } 10201 } 10202 } 10203 10204 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10205 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10206 if (procs == null) { 10207 return; 10208 } 10209 10210 pw.println("Applications Database Info:"); 10211 10212 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10213 ProcessRecord r = procs.get(i); 10214 if (r.thread != null) { 10215 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10216 pw.flush(); 10217 try { 10218 TransferPipe tp = new TransferPipe(); 10219 try { 10220 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10221 tp.go(fd); 10222 } finally { 10223 tp.kill(); 10224 } 10225 } catch (IOException e) { 10226 pw.println("Failure while dumping the app: " + r); 10227 pw.flush(); 10228 } catch (RemoteException e) { 10229 pw.println("Got a RemoteException while dumping the app " + r); 10230 pw.flush(); 10231 } 10232 } 10233 } 10234 } 10235 10236 final static class MemItem { 10237 final String label; 10238 final String shortLabel; 10239 final long pss; 10240 final int id; 10241 ArrayList<MemItem> subitems; 10242 10243 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10244 label = _label; 10245 shortLabel = _shortLabel; 10246 pss = _pss; 10247 id = _id; 10248 } 10249 } 10250 10251 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10252 boolean sort) { 10253 if (sort) { 10254 Collections.sort(items, new Comparator<MemItem>() { 10255 @Override 10256 public int compare(MemItem lhs, MemItem rhs) { 10257 if (lhs.pss < rhs.pss) { 10258 return 1; 10259 } else if (lhs.pss > rhs.pss) { 10260 return -1; 10261 } 10262 return 0; 10263 } 10264 }); 10265 } 10266 10267 for (int i=0; i<items.size(); i++) { 10268 MemItem mi = items.get(i); 10269 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10270 if (mi.subitems != null) { 10271 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10272 } 10273 } 10274 } 10275 10276 // These are in KB. 10277 static final long[] DUMP_MEM_BUCKETS = new long[] { 10278 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10279 120*1024, 160*1024, 200*1024, 10280 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10281 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10282 }; 10283 10284 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10285 boolean stackLike) { 10286 int start = label.lastIndexOf('.'); 10287 if (start >= 0) start++; 10288 else start = 0; 10289 int end = label.length(); 10290 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10291 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10292 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10293 out.append(bucket); 10294 out.append(stackLike ? "MB." : "MB "); 10295 out.append(label, start, end); 10296 return; 10297 } 10298 } 10299 out.append(memKB/1024); 10300 out.append(stackLike ? "MB." : "MB "); 10301 out.append(label, start, end); 10302 } 10303 10304 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10305 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10306 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10307 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10308 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10309 }; 10310 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10311 "System", "Persistent", "Foreground", 10312 "Visible", "Perceptible", "Heavy Weight", 10313 "Backup", "A Services", "Home", "Previous", 10314 "B Services", "Background" 10315 }; 10316 10317 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10318 PrintWriter pw, String prefix, String[] args, boolean brief, 10319 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10320 boolean dumpAll = false; 10321 boolean oomOnly = false; 10322 10323 int opti = 0; 10324 while (opti < args.length) { 10325 String opt = args[opti]; 10326 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10327 break; 10328 } 10329 opti++; 10330 if ("-a".equals(opt)) { 10331 dumpAll = true; 10332 } else if ("--oom".equals(opt)) { 10333 oomOnly = true; 10334 } else if ("-h".equals(opt)) { 10335 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10336 pw.println(" -a: include all available information for each process."); 10337 pw.println(" --oom: only show processes organized by oom adj."); 10338 pw.println("If [process] is specified it can be the name or "); 10339 pw.println("pid of a specific process to dump."); 10340 return; 10341 } else { 10342 pw.println("Unknown argument: " + opt + "; use -h for help"); 10343 } 10344 } 10345 10346 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10347 if (procs == null) { 10348 return; 10349 } 10350 10351 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10352 long uptime = SystemClock.uptimeMillis(); 10353 long realtime = SystemClock.elapsedRealtime(); 10354 10355 if (procs.size() == 1 || isCheckinRequest) { 10356 dumpAll = true; 10357 } 10358 10359 if (isCheckinRequest) { 10360 // short checkin version 10361 pw.println(uptime + "," + realtime); 10362 pw.flush(); 10363 } else { 10364 pw.println("Applications Memory Usage (kB):"); 10365 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10366 } 10367 10368 String[] innerArgs = new String[args.length-opti]; 10369 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10370 10371 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10372 long nativePss=0, dalvikPss=0, otherPss=0; 10373 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10374 10375 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10376 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10377 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10378 10379 long totalPss = 0; 10380 10381 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10382 ProcessRecord r = procs.get(i); 10383 if (r.thread != null) { 10384 if (!isCheckinRequest && dumpAll) { 10385 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10386 pw.flush(); 10387 } 10388 Debug.MemoryInfo mi = null; 10389 if (dumpAll) { 10390 try { 10391 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10392 } catch (RemoteException e) { 10393 if (!isCheckinRequest) { 10394 pw.println("Got RemoteException!"); 10395 pw.flush(); 10396 } 10397 } 10398 } else { 10399 mi = new Debug.MemoryInfo(); 10400 Debug.getMemoryInfo(r.pid, mi); 10401 } 10402 10403 if (!isCheckinRequest && mi != null) { 10404 long myTotalPss = mi.getTotalPss(); 10405 totalPss += myTotalPss; 10406 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10407 r.processName, myTotalPss, 0); 10408 procMems.add(pssItem); 10409 10410 nativePss += mi.nativePss; 10411 dalvikPss += mi.dalvikPss; 10412 otherPss += mi.otherPss; 10413 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10414 long mem = mi.getOtherPss(j); 10415 miscPss[j] += mem; 10416 otherPss -= mem; 10417 } 10418 10419 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10420 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10421 || oomIndex == (oomPss.length-1)) { 10422 oomPss[oomIndex] += myTotalPss; 10423 if (oomProcs[oomIndex] == null) { 10424 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10425 } 10426 oomProcs[oomIndex].add(pssItem); 10427 break; 10428 } 10429 } 10430 } 10431 } 10432 } 10433 10434 if (!isCheckinRequest && procs.size() > 1) { 10435 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10436 10437 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10438 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10439 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10440 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10441 String label = Debug.MemoryInfo.getOtherLabel(j); 10442 catMems.add(new MemItem(label, label, miscPss[j], j)); 10443 } 10444 10445 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10446 for (int j=0; j<oomPss.length; j++) { 10447 if (oomPss[j] != 0) { 10448 String label = DUMP_MEM_OOM_LABEL[j]; 10449 MemItem item = new MemItem(label, label, oomPss[j], 10450 DUMP_MEM_OOM_ADJ[j]); 10451 item.subitems = oomProcs[j]; 10452 oomMems.add(item); 10453 } 10454 } 10455 10456 if (outTag != null || outStack != null) { 10457 if (outTag != null) { 10458 appendMemBucket(outTag, totalPss, "total", false); 10459 } 10460 if (outStack != null) { 10461 appendMemBucket(outStack, totalPss, "total", true); 10462 } 10463 boolean firstLine = true; 10464 for (int i=0; i<oomMems.size(); i++) { 10465 MemItem miCat = oomMems.get(i); 10466 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10467 continue; 10468 } 10469 if (miCat.id < ProcessList.SERVICE_ADJ 10470 || miCat.id == ProcessList.HOME_APP_ADJ 10471 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10472 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10473 outTag.append(" / "); 10474 } 10475 if (outStack != null) { 10476 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10477 if (firstLine) { 10478 outStack.append(":"); 10479 firstLine = false; 10480 } 10481 outStack.append("\n\t at "); 10482 } else { 10483 outStack.append("$"); 10484 } 10485 } 10486 for (int j=0; j<miCat.subitems.size(); j++) { 10487 MemItem mi = miCat.subitems.get(j); 10488 if (j > 0) { 10489 if (outTag != null) { 10490 outTag.append(" "); 10491 } 10492 if (outStack != null) { 10493 outStack.append("$"); 10494 } 10495 } 10496 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10497 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10498 } 10499 if (outStack != null) { 10500 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10501 } 10502 } 10503 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10504 outStack.append("("); 10505 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10506 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10507 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10508 outStack.append(":"); 10509 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10510 } 10511 } 10512 outStack.append(")"); 10513 } 10514 } 10515 } 10516 } 10517 10518 if (!brief && !oomOnly) { 10519 pw.println(); 10520 pw.println("Total PSS by process:"); 10521 dumpMemItems(pw, " ", procMems, true); 10522 pw.println(); 10523 } 10524 pw.println("Total PSS by OOM adjustment:"); 10525 dumpMemItems(pw, " ", oomMems, false); 10526 if (!oomOnly) { 10527 PrintWriter out = categoryPw != null ? categoryPw : pw; 10528 out.println(); 10529 out.println("Total PSS by category:"); 10530 dumpMemItems(out, " ", catMems, true); 10531 } 10532 pw.println(); 10533 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10534 final int[] SINGLE_LONG_FORMAT = new int[] { 10535 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10536 }; 10537 long[] longOut = new long[1]; 10538 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10539 SINGLE_LONG_FORMAT, null, longOut, null); 10540 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10541 longOut[0] = 0; 10542 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10543 SINGLE_LONG_FORMAT, null, longOut, null); 10544 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10545 longOut[0] = 0; 10546 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10547 SINGLE_LONG_FORMAT, null, longOut, null); 10548 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10549 longOut[0] = 0; 10550 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10551 SINGLE_LONG_FORMAT, null, longOut, null); 10552 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10553 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10554 pw.print(shared); pw.println(" kB"); 10555 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10556 pw.print(voltile); pw.println(" kB volatile"); 10557 } 10558 } 10559 10560 /** 10561 * Searches array of arguments for the specified string 10562 * @param args array of argument strings 10563 * @param value value to search for 10564 * @return true if the value is contained in the array 10565 */ 10566 private static boolean scanArgs(String[] args, String value) { 10567 if (args != null) { 10568 for (String arg : args) { 10569 if (value.equals(arg)) { 10570 return true; 10571 } 10572 } 10573 } 10574 return false; 10575 } 10576 10577 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10578 ContentProviderRecord cpr, boolean always) { 10579 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10580 10581 if (!inLaunching || always) { 10582 synchronized (cpr) { 10583 cpr.launchingApp = null; 10584 cpr.notifyAll(); 10585 } 10586 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10587 String names[] = cpr.info.authority.split(";"); 10588 for (int j = 0; j < names.length; j++) { 10589 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10590 } 10591 } 10592 10593 for (int i=0; i<cpr.connections.size(); i++) { 10594 ContentProviderConnection conn = cpr.connections.get(i); 10595 if (conn.waiting) { 10596 // If this connection is waiting for the provider, then we don't 10597 // need to mess with its process unless we are always removing 10598 // or for some reason the provider is not currently launching. 10599 if (inLaunching && !always) { 10600 continue; 10601 } 10602 } 10603 ProcessRecord capp = conn.client; 10604 conn.dead = true; 10605 if (conn.stableCount > 0) { 10606 if (!capp.persistent && capp.thread != null 10607 && capp.pid != 0 10608 && capp.pid != MY_PID) { 10609 Slog.i(TAG, "Kill " + capp.processName 10610 + " (pid " + capp.pid + "): provider " + cpr.info.name 10611 + " in dying process " + (proc != null ? proc.processName : "??")); 10612 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10613 capp.processName, capp.setAdj, "dying provider " 10614 + cpr.name.toShortString()); 10615 Process.killProcessQuiet(capp.pid); 10616 } 10617 } else if (capp.thread != null && conn.provider.provider != null) { 10618 try { 10619 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10620 } catch (RemoteException e) { 10621 } 10622 // In the protocol here, we don't expect the client to correctly 10623 // clean up this connection, we'll just remove it. 10624 cpr.connections.remove(i); 10625 conn.client.conProviders.remove(conn); 10626 } 10627 } 10628 10629 if (inLaunching && always) { 10630 mLaunchingProviders.remove(cpr); 10631 } 10632 return inLaunching; 10633 } 10634 10635 /** 10636 * Main code for cleaning up a process when it has gone away. This is 10637 * called both as a result of the process dying, or directly when stopping 10638 * a process when running in single process mode. 10639 */ 10640 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10641 boolean restarting, boolean allowRestart, int index) { 10642 if (index >= 0) { 10643 mLruProcesses.remove(index); 10644 } 10645 10646 mProcessesToGc.remove(app); 10647 10648 // Dismiss any open dialogs. 10649 if (app.crashDialog != null) { 10650 app.crashDialog.dismiss(); 10651 app.crashDialog = null; 10652 } 10653 if (app.anrDialog != null) { 10654 app.anrDialog.dismiss(); 10655 app.anrDialog = null; 10656 } 10657 if (app.waitDialog != null) { 10658 app.waitDialog.dismiss(); 10659 app.waitDialog = null; 10660 } 10661 10662 app.crashing = false; 10663 app.notResponding = false; 10664 10665 app.resetPackageList(); 10666 app.unlinkDeathRecipient(); 10667 app.thread = null; 10668 app.forcingToForeground = null; 10669 app.foregroundServices = false; 10670 app.foregroundActivities = false; 10671 app.hasShownUi = false; 10672 app.hasAboveClient = false; 10673 10674 mServices.killServicesLocked(app, allowRestart); 10675 10676 boolean restart = false; 10677 10678 // Remove published content providers. 10679 if (!app.pubProviders.isEmpty()) { 10680 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10681 while (it.hasNext()) { 10682 ContentProviderRecord cpr = it.next(); 10683 10684 final boolean always = app.bad || !allowRestart; 10685 if (removeDyingProviderLocked(app, cpr, always) || always) { 10686 // We left the provider in the launching list, need to 10687 // restart it. 10688 restart = true; 10689 } 10690 10691 cpr.provider = null; 10692 cpr.proc = null; 10693 } 10694 app.pubProviders.clear(); 10695 } 10696 10697 // Take care of any launching providers waiting for this process. 10698 if (checkAppInLaunchingProvidersLocked(app, false)) { 10699 restart = true; 10700 } 10701 10702 // Unregister from connected content providers. 10703 if (!app.conProviders.isEmpty()) { 10704 for (int i=0; i<app.conProviders.size(); i++) { 10705 ContentProviderConnection conn = app.conProviders.get(i); 10706 conn.provider.connections.remove(conn); 10707 } 10708 app.conProviders.clear(); 10709 } 10710 10711 // At this point there may be remaining entries in mLaunchingProviders 10712 // where we were the only one waiting, so they are no longer of use. 10713 // Look for these and clean up if found. 10714 // XXX Commented out for now. Trying to figure out a way to reproduce 10715 // the actual situation to identify what is actually going on. 10716 if (false) { 10717 for (int i=0; i<mLaunchingProviders.size(); i++) { 10718 ContentProviderRecord cpr = (ContentProviderRecord) 10719 mLaunchingProviders.get(i); 10720 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10721 synchronized (cpr) { 10722 cpr.launchingApp = null; 10723 cpr.notifyAll(); 10724 } 10725 } 10726 } 10727 } 10728 10729 skipCurrentReceiverLocked(app); 10730 10731 // Unregister any receivers. 10732 if (app.receivers.size() > 0) { 10733 Iterator<ReceiverList> it = app.receivers.iterator(); 10734 while (it.hasNext()) { 10735 removeReceiverLocked(it.next()); 10736 } 10737 app.receivers.clear(); 10738 } 10739 10740 // If the app is undergoing backup, tell the backup manager about it 10741 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10742 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10743 try { 10744 IBackupManager bm = IBackupManager.Stub.asInterface( 10745 ServiceManager.getService(Context.BACKUP_SERVICE)); 10746 bm.agentDisconnected(app.info.packageName); 10747 } catch (RemoteException e) { 10748 // can't happen; backup manager is local 10749 } 10750 } 10751 10752 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10753 ProcessChangeItem item = mPendingProcessChanges.get(i); 10754 if (item.pid == app.pid) { 10755 mPendingProcessChanges.remove(i); 10756 mAvailProcessChanges.add(item); 10757 } 10758 } 10759 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10760 10761 // If the caller is restarting this app, then leave it in its 10762 // current lists and let the caller take care of it. 10763 if (restarting) { 10764 return; 10765 } 10766 10767 if (!app.persistent || app.isolated) { 10768 if (DEBUG_PROCESSES) Slog.v(TAG, 10769 "Removing non-persistent process during cleanup: " + app); 10770 mProcessNames.remove(app.processName, app.uid); 10771 mIsolatedProcesses.remove(app.uid); 10772 if (mHeavyWeightProcess == app) { 10773 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10774 mHeavyWeightProcess.userId, 0)); 10775 mHeavyWeightProcess = null; 10776 } 10777 } else if (!app.removed) { 10778 // This app is persistent, so we need to keep its record around. 10779 // If it is not already on the pending app list, add it there 10780 // and start a new process for it. 10781 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10782 mPersistentStartingProcesses.add(app); 10783 restart = true; 10784 } 10785 } 10786 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10787 "Clean-up removing on hold: " + app); 10788 mProcessesOnHold.remove(app); 10789 10790 if (app == mHomeProcess) { 10791 mHomeProcess = null; 10792 } 10793 if (app == mPreviousProcess) { 10794 mPreviousProcess = null; 10795 } 10796 10797 if (restart && !app.isolated) { 10798 // We have components that still need to be running in the 10799 // process, so re-launch it. 10800 mProcessNames.put(app.processName, app.uid, app); 10801 startProcessLocked(app, "restart", app.processName); 10802 } else if (app.pid > 0 && app.pid != MY_PID) { 10803 // Goodbye! 10804 synchronized (mPidsSelfLocked) { 10805 mPidsSelfLocked.remove(app.pid); 10806 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10807 } 10808 app.setPid(0); 10809 } 10810 } 10811 10812 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10813 // Look through the content providers we are waiting to have launched, 10814 // and if any run in this process then either schedule a restart of 10815 // the process or kill the client waiting for it if this process has 10816 // gone bad. 10817 int NL = mLaunchingProviders.size(); 10818 boolean restart = false; 10819 for (int i=0; i<NL; i++) { 10820 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10821 if (cpr.launchingApp == app) { 10822 if (!alwaysBad && !app.bad) { 10823 restart = true; 10824 } else { 10825 removeDyingProviderLocked(app, cpr, true); 10826 // cpr should have been removed from mLaunchingProviders 10827 NL = mLaunchingProviders.size(); 10828 i--; 10829 } 10830 } 10831 } 10832 return restart; 10833 } 10834 10835 // ========================================================= 10836 // SERVICES 10837 // ========================================================= 10838 10839 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10840 int flags) { 10841 enforceNotIsolatedCaller("getServices"); 10842 synchronized (this) { 10843 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10844 } 10845 } 10846 10847 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10848 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10849 synchronized (this) { 10850 return mServices.getRunningServiceControlPanelLocked(name); 10851 } 10852 } 10853 10854 public ComponentName startService(IApplicationThread caller, Intent service, 10855 String resolvedType, int userId) { 10856 enforceNotIsolatedCaller("startService"); 10857 // Refuse possible leaked file descriptors 10858 if (service != null && service.hasFileDescriptors() == true) { 10859 throw new IllegalArgumentException("File descriptors passed in Intent"); 10860 } 10861 10862 if (DEBUG_SERVICE) 10863 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10864 synchronized(this) { 10865 final int callingPid = Binder.getCallingPid(); 10866 final int callingUid = Binder.getCallingUid(); 10867 checkValidCaller(callingUid, userId); 10868 final long origId = Binder.clearCallingIdentity(); 10869 ComponentName res = mServices.startServiceLocked(caller, service, 10870 resolvedType, callingPid, callingUid, userId); 10871 Binder.restoreCallingIdentity(origId); 10872 return res; 10873 } 10874 } 10875 10876 ComponentName startServiceInPackage(int uid, 10877 Intent service, String resolvedType, int userId) { 10878 synchronized(this) { 10879 if (DEBUG_SERVICE) 10880 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10881 final long origId = Binder.clearCallingIdentity(); 10882 ComponentName res = mServices.startServiceLocked(null, service, 10883 resolvedType, -1, uid, userId); 10884 Binder.restoreCallingIdentity(origId); 10885 return res; 10886 } 10887 } 10888 10889 public int stopService(IApplicationThread caller, Intent service, 10890 String resolvedType, int userId) { 10891 enforceNotIsolatedCaller("stopService"); 10892 // Refuse possible leaked file descriptors 10893 if (service != null && service.hasFileDescriptors() == true) { 10894 throw new IllegalArgumentException("File descriptors passed in Intent"); 10895 } 10896 10897 checkValidCaller(Binder.getCallingUid(), userId); 10898 10899 synchronized(this) { 10900 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10901 } 10902 } 10903 10904 public IBinder peekService(Intent service, String resolvedType) { 10905 enforceNotIsolatedCaller("peekService"); 10906 // Refuse possible leaked file descriptors 10907 if (service != null && service.hasFileDescriptors() == true) { 10908 throw new IllegalArgumentException("File descriptors passed in Intent"); 10909 } 10910 synchronized(this) { 10911 return mServices.peekServiceLocked(service, resolvedType); 10912 } 10913 } 10914 10915 public boolean stopServiceToken(ComponentName className, IBinder token, 10916 int startId) { 10917 synchronized(this) { 10918 return mServices.stopServiceTokenLocked(className, token, startId); 10919 } 10920 } 10921 10922 public void setServiceForeground(ComponentName className, IBinder token, 10923 int id, Notification notification, boolean removeNotification) { 10924 synchronized(this) { 10925 mServices.setServiceForegroundLocked(className, token, id, notification, 10926 removeNotification); 10927 } 10928 } 10929 10930 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10931 boolean requireFull, String name, String callerPackage) { 10932 synchronized(this) { 10933 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10934 requireFull, name, callerPackage); 10935 } 10936 } 10937 10938 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10939 boolean requireFull, String name, String callerPackage) { 10940 final int callingUserId = UserHandle.getUserId(callingUid); 10941 if (callingUserId != userId) { 10942 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10943 if ((requireFull || checkComponentPermission( 10944 android.Manifest.permission.INTERACT_ACROSS_USERS, 10945 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10946 && checkComponentPermission( 10947 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10948 callingPid, callingUid, -1, true) 10949 != PackageManager.PERMISSION_GRANTED) { 10950 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10951 // In this case, they would like to just execute as their 10952 // owner user instead of failing. 10953 userId = callingUserId; 10954 } else { 10955 StringBuilder builder = new StringBuilder(128); 10956 builder.append("Permission Denial: "); 10957 builder.append(name); 10958 if (callerPackage != null) { 10959 builder.append(" from "); 10960 builder.append(callerPackage); 10961 } 10962 builder.append(" asks to run as user "); 10963 builder.append(userId); 10964 builder.append(" but is calling from user "); 10965 builder.append(UserHandle.getUserId(callingUid)); 10966 builder.append("; this requires "); 10967 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10968 if (!requireFull) { 10969 builder.append(" or "); 10970 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10971 } 10972 String msg = builder.toString(); 10973 Slog.w(TAG, msg); 10974 throw new SecurityException(msg); 10975 } 10976 } 10977 } 10978 if (userId == UserHandle.USER_CURRENT 10979 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10980 userId = mCurrentUserId; 10981 } 10982 if (!allowAll && userId < 0) { 10983 throw new IllegalArgumentException( 10984 "Call does not support special user #" + userId); 10985 } 10986 } 10987 return userId; 10988 } 10989 10990 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10991 String className, int flags) { 10992 boolean result = false; 10993 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10994 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10995 if (ActivityManager.checkUidPermission( 10996 android.Manifest.permission.INTERACT_ACROSS_USERS, 10997 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10998 ComponentName comp = new ComponentName(aInfo.packageName, className); 10999 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11000 + " requests FLAG_SINGLE_USER, but app does not hold " 11001 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11002 Slog.w(TAG, msg); 11003 throw new SecurityException(msg); 11004 } 11005 result = true; 11006 } 11007 } else if (componentProcessName == aInfo.packageName) { 11008 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11009 } else if ("system".equals(componentProcessName)) { 11010 result = true; 11011 } 11012 if (DEBUG_MU) { 11013 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11014 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11015 } 11016 return result; 11017 } 11018 11019 public int bindService(IApplicationThread caller, IBinder token, 11020 Intent service, String resolvedType, 11021 IServiceConnection connection, int flags, int userId) { 11022 enforceNotIsolatedCaller("bindService"); 11023 // Refuse possible leaked file descriptors 11024 if (service != null && service.hasFileDescriptors() == true) { 11025 throw new IllegalArgumentException("File descriptors passed in Intent"); 11026 } 11027 11028 synchronized(this) { 11029 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11030 connection, flags, userId); 11031 } 11032 } 11033 11034 public boolean unbindService(IServiceConnection connection) { 11035 synchronized (this) { 11036 return mServices.unbindServiceLocked(connection); 11037 } 11038 } 11039 11040 public void publishService(IBinder token, Intent intent, IBinder service) { 11041 // Refuse possible leaked file descriptors 11042 if (intent != null && intent.hasFileDescriptors() == true) { 11043 throw new IllegalArgumentException("File descriptors passed in Intent"); 11044 } 11045 11046 synchronized(this) { 11047 if (!(token instanceof ServiceRecord)) { 11048 throw new IllegalArgumentException("Invalid service token"); 11049 } 11050 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11051 } 11052 } 11053 11054 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11055 // Refuse possible leaked file descriptors 11056 if (intent != null && intent.hasFileDescriptors() == true) { 11057 throw new IllegalArgumentException("File descriptors passed in Intent"); 11058 } 11059 11060 synchronized(this) { 11061 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11062 } 11063 } 11064 11065 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11066 synchronized(this) { 11067 if (!(token instanceof ServiceRecord)) { 11068 throw new IllegalArgumentException("Invalid service token"); 11069 } 11070 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11071 } 11072 } 11073 11074 // ========================================================= 11075 // BACKUP AND RESTORE 11076 // ========================================================= 11077 11078 // Cause the target app to be launched if necessary and its backup agent 11079 // instantiated. The backup agent will invoke backupAgentCreated() on the 11080 // activity manager to announce its creation. 11081 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11082 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11083 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11084 11085 synchronized(this) { 11086 // !!! TODO: currently no check here that we're already bound 11087 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11088 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11089 synchronized (stats) { 11090 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11091 } 11092 11093 // Backup agent is now in use, its package can't be stopped. 11094 try { 11095 AppGlobals.getPackageManager().setPackageStoppedState( 11096 app.packageName, false, UserHandle.getUserId(app.uid)); 11097 } catch (RemoteException e) { 11098 } catch (IllegalArgumentException e) { 11099 Slog.w(TAG, "Failed trying to unstop package " 11100 + app.packageName + ": " + e); 11101 } 11102 11103 BackupRecord r = new BackupRecord(ss, app, backupMode); 11104 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11105 ? new ComponentName(app.packageName, app.backupAgentName) 11106 : new ComponentName("android", "FullBackupAgent"); 11107 // startProcessLocked() returns existing proc's record if it's already running 11108 ProcessRecord proc = startProcessLocked(app.processName, app, 11109 false, 0, "backup", hostingName, false, false); 11110 if (proc == null) { 11111 Slog.e(TAG, "Unable to start backup agent process " + r); 11112 return false; 11113 } 11114 11115 r.app = proc; 11116 mBackupTarget = r; 11117 mBackupAppName = app.packageName; 11118 11119 // Try not to kill the process during backup 11120 updateOomAdjLocked(proc); 11121 11122 // If the process is already attached, schedule the creation of the backup agent now. 11123 // If it is not yet live, this will be done when it attaches to the framework. 11124 if (proc.thread != null) { 11125 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11126 try { 11127 proc.thread.scheduleCreateBackupAgent(app, 11128 compatibilityInfoForPackageLocked(app), backupMode); 11129 } catch (RemoteException e) { 11130 // Will time out on the backup manager side 11131 } 11132 } else { 11133 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11134 } 11135 // Invariants: at this point, the target app process exists and the application 11136 // is either already running or in the process of coming up. mBackupTarget and 11137 // mBackupAppName describe the app, so that when it binds back to the AM we 11138 // know that it's scheduled for a backup-agent operation. 11139 } 11140 11141 return true; 11142 } 11143 11144 // A backup agent has just come up 11145 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11146 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11147 + " = " + agent); 11148 11149 synchronized(this) { 11150 if (!agentPackageName.equals(mBackupAppName)) { 11151 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11152 return; 11153 } 11154 } 11155 11156 long oldIdent = Binder.clearCallingIdentity(); 11157 try { 11158 IBackupManager bm = IBackupManager.Stub.asInterface( 11159 ServiceManager.getService(Context.BACKUP_SERVICE)); 11160 bm.agentConnected(agentPackageName, agent); 11161 } catch (RemoteException e) { 11162 // can't happen; the backup manager service is local 11163 } catch (Exception e) { 11164 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11165 e.printStackTrace(); 11166 } finally { 11167 Binder.restoreCallingIdentity(oldIdent); 11168 } 11169 } 11170 11171 // done with this agent 11172 public void unbindBackupAgent(ApplicationInfo appInfo) { 11173 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11174 if (appInfo == null) { 11175 Slog.w(TAG, "unbind backup agent for null app"); 11176 return; 11177 } 11178 11179 synchronized(this) { 11180 if (mBackupAppName == null) { 11181 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11182 return; 11183 } 11184 11185 if (!mBackupAppName.equals(appInfo.packageName)) { 11186 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11187 return; 11188 } 11189 11190 ProcessRecord proc = mBackupTarget.app; 11191 mBackupTarget = null; 11192 mBackupAppName = null; 11193 11194 // Not backing this app up any more; reset its OOM adjustment 11195 updateOomAdjLocked(proc); 11196 11197 // If the app crashed during backup, 'thread' will be null here 11198 if (proc.thread != null) { 11199 try { 11200 proc.thread.scheduleDestroyBackupAgent(appInfo, 11201 compatibilityInfoForPackageLocked(appInfo)); 11202 } catch (Exception e) { 11203 Slog.e(TAG, "Exception when unbinding backup agent:"); 11204 e.printStackTrace(); 11205 } 11206 } 11207 } 11208 } 11209 // ========================================================= 11210 // BROADCASTS 11211 // ========================================================= 11212 11213 private final List getStickiesLocked(String action, IntentFilter filter, 11214 List cur, int userId) { 11215 final ContentResolver resolver = mContext.getContentResolver(); 11216 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11217 if (stickies == null) { 11218 return cur; 11219 } 11220 final ArrayList<Intent> list = stickies.get(action); 11221 if (list == null) { 11222 return cur; 11223 } 11224 int N = list.size(); 11225 for (int i=0; i<N; i++) { 11226 Intent intent = list.get(i); 11227 if (filter.match(resolver, intent, true, TAG) >= 0) { 11228 if (cur == null) { 11229 cur = new ArrayList<Intent>(); 11230 } 11231 cur.add(intent); 11232 } 11233 } 11234 return cur; 11235 } 11236 11237 boolean isPendingBroadcastProcessLocked(int pid) { 11238 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11239 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11240 } 11241 11242 void skipPendingBroadcastLocked(int pid) { 11243 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11244 for (BroadcastQueue queue : mBroadcastQueues) { 11245 queue.skipPendingBroadcastLocked(pid); 11246 } 11247 } 11248 11249 // The app just attached; send any pending broadcasts that it should receive 11250 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11251 boolean didSomething = false; 11252 for (BroadcastQueue queue : mBroadcastQueues) { 11253 didSomething |= queue.sendPendingBroadcastsLocked(app); 11254 } 11255 return didSomething; 11256 } 11257 11258 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11259 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11260 enforceNotIsolatedCaller("registerReceiver"); 11261 int callingUid; 11262 int callingPid; 11263 synchronized(this) { 11264 ProcessRecord callerApp = null; 11265 if (caller != null) { 11266 callerApp = getRecordForAppLocked(caller); 11267 if (callerApp == null) { 11268 throw new SecurityException( 11269 "Unable to find app for caller " + caller 11270 + " (pid=" + Binder.getCallingPid() 11271 + ") when registering receiver " + receiver); 11272 } 11273 if (callerApp.info.uid != Process.SYSTEM_UID && 11274 !callerApp.pkgList.contains(callerPackage)) { 11275 throw new SecurityException("Given caller package " + callerPackage 11276 + " is not running in process " + callerApp); 11277 } 11278 callingUid = callerApp.info.uid; 11279 callingPid = callerApp.pid; 11280 } else { 11281 callerPackage = null; 11282 callingUid = Binder.getCallingUid(); 11283 callingPid = Binder.getCallingPid(); 11284 } 11285 11286 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11287 true, true, "registerReceiver", callerPackage); 11288 11289 List allSticky = null; 11290 11291 // Look for any matching sticky broadcasts... 11292 Iterator actions = filter.actionsIterator(); 11293 if (actions != null) { 11294 while (actions.hasNext()) { 11295 String action = (String)actions.next(); 11296 allSticky = getStickiesLocked(action, filter, allSticky, 11297 UserHandle.USER_ALL); 11298 allSticky = getStickiesLocked(action, filter, allSticky, 11299 UserHandle.getUserId(callingUid)); 11300 } 11301 } else { 11302 allSticky = getStickiesLocked(null, filter, allSticky, 11303 UserHandle.USER_ALL); 11304 allSticky = getStickiesLocked(null, filter, allSticky, 11305 UserHandle.getUserId(callingUid)); 11306 } 11307 11308 // The first sticky in the list is returned directly back to 11309 // the client. 11310 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11311 11312 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11313 + ": " + sticky); 11314 11315 if (receiver == null) { 11316 return sticky; 11317 } 11318 11319 ReceiverList rl 11320 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11321 if (rl == null) { 11322 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11323 userId, receiver); 11324 if (rl.app != null) { 11325 rl.app.receivers.add(rl); 11326 } else { 11327 try { 11328 receiver.asBinder().linkToDeath(rl, 0); 11329 } catch (RemoteException e) { 11330 return sticky; 11331 } 11332 rl.linkedToDeath = true; 11333 } 11334 mRegisteredReceivers.put(receiver.asBinder(), rl); 11335 } else if (rl.uid != callingUid) { 11336 throw new IllegalArgumentException( 11337 "Receiver requested to register for uid " + callingUid 11338 + " was previously registered for uid " + rl.uid); 11339 } else if (rl.pid != callingPid) { 11340 throw new IllegalArgumentException( 11341 "Receiver requested to register for pid " + callingPid 11342 + " was previously registered for pid " + rl.pid); 11343 } else if (rl.userId != userId) { 11344 throw new IllegalArgumentException( 11345 "Receiver requested to register for user " + userId 11346 + " was previously registered for user " + rl.userId); 11347 } 11348 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11349 permission, callingUid, userId); 11350 rl.add(bf); 11351 if (!bf.debugCheck()) { 11352 Slog.w(TAG, "==> For Dynamic broadast"); 11353 } 11354 mReceiverResolver.addFilter(bf); 11355 11356 // Enqueue broadcasts for all existing stickies that match 11357 // this filter. 11358 if (allSticky != null) { 11359 ArrayList receivers = new ArrayList(); 11360 receivers.add(bf); 11361 11362 int N = allSticky.size(); 11363 for (int i=0; i<N; i++) { 11364 Intent intent = (Intent)allSticky.get(i); 11365 BroadcastQueue queue = broadcastQueueForIntent(intent); 11366 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11367 null, -1, -1, null, receivers, null, 0, null, null, 11368 false, true, true, -1); 11369 queue.enqueueParallelBroadcastLocked(r); 11370 queue.scheduleBroadcastsLocked(); 11371 } 11372 } 11373 11374 return sticky; 11375 } 11376 } 11377 11378 public void unregisterReceiver(IIntentReceiver receiver) { 11379 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11380 11381 final long origId = Binder.clearCallingIdentity(); 11382 try { 11383 boolean doTrim = false; 11384 11385 synchronized(this) { 11386 ReceiverList rl 11387 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11388 if (rl != null) { 11389 if (rl.curBroadcast != null) { 11390 BroadcastRecord r = rl.curBroadcast; 11391 final boolean doNext = finishReceiverLocked( 11392 receiver.asBinder(), r.resultCode, r.resultData, 11393 r.resultExtras, r.resultAbort, true); 11394 if (doNext) { 11395 doTrim = true; 11396 r.queue.processNextBroadcast(false); 11397 } 11398 } 11399 11400 if (rl.app != null) { 11401 rl.app.receivers.remove(rl); 11402 } 11403 removeReceiverLocked(rl); 11404 if (rl.linkedToDeath) { 11405 rl.linkedToDeath = false; 11406 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11407 } 11408 } 11409 } 11410 11411 // If we actually concluded any broadcasts, we might now be able 11412 // to trim the recipients' apps from our working set 11413 if (doTrim) { 11414 trimApplications(); 11415 return; 11416 } 11417 11418 } finally { 11419 Binder.restoreCallingIdentity(origId); 11420 } 11421 } 11422 11423 void removeReceiverLocked(ReceiverList rl) { 11424 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11425 int N = rl.size(); 11426 for (int i=0; i<N; i++) { 11427 mReceiverResolver.removeFilter(rl.get(i)); 11428 } 11429 } 11430 11431 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11432 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11433 ProcessRecord r = mLruProcesses.get(i); 11434 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11435 try { 11436 r.thread.dispatchPackageBroadcast(cmd, packages); 11437 } catch (RemoteException ex) { 11438 } 11439 } 11440 } 11441 } 11442 11443 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11444 int[] users) { 11445 List<ResolveInfo> receivers = null; 11446 try { 11447 HashSet<ComponentName> singleUserReceivers = null; 11448 boolean scannedFirstReceivers = false; 11449 for (int user : users) { 11450 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11451 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11452 if (newReceivers != null && newReceivers.size() == 0) { 11453 newReceivers = null; 11454 } 11455 if (receivers == null) { 11456 receivers = newReceivers; 11457 } else if (newReceivers != null) { 11458 // We need to concatenate the additional receivers 11459 // found with what we have do far. This would be easy, 11460 // but we also need to de-dup any receivers that are 11461 // singleUser. 11462 if (!scannedFirstReceivers) { 11463 // Collect any single user receivers we had already retrieved. 11464 scannedFirstReceivers = true; 11465 for (int i=0; i<receivers.size(); i++) { 11466 ResolveInfo ri = receivers.get(i); 11467 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11468 ComponentName cn = new ComponentName( 11469 ri.activityInfo.packageName, ri.activityInfo.name); 11470 if (singleUserReceivers == null) { 11471 singleUserReceivers = new HashSet<ComponentName>(); 11472 } 11473 singleUserReceivers.add(cn); 11474 } 11475 } 11476 } 11477 // Add the new results to the existing results, tracking 11478 // and de-dupping single user receivers. 11479 for (int i=0; i<newReceivers.size(); i++) { 11480 ResolveInfo ri = newReceivers.get(i); 11481 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11482 ComponentName cn = new ComponentName( 11483 ri.activityInfo.packageName, ri.activityInfo.name); 11484 if (singleUserReceivers == null) { 11485 singleUserReceivers = new HashSet<ComponentName>(); 11486 } 11487 if (!singleUserReceivers.contains(cn)) { 11488 singleUserReceivers.add(cn); 11489 receivers.add(ri); 11490 } 11491 } else { 11492 receivers.add(ri); 11493 } 11494 } 11495 } 11496 } 11497 } catch (RemoteException ex) { 11498 // pm is in same process, this will never happen. 11499 } 11500 return receivers; 11501 } 11502 11503 private final int broadcastIntentLocked(ProcessRecord callerApp, 11504 String callerPackage, Intent intent, String resolvedType, 11505 IIntentReceiver resultTo, int resultCode, String resultData, 11506 Bundle map, String requiredPermission, 11507 boolean ordered, boolean sticky, int callingPid, int callingUid, 11508 int userId) { 11509 intent = new Intent(intent); 11510 11511 // By default broadcasts do not go to stopped apps. 11512 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11513 11514 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11515 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11516 + " ordered=" + ordered + " userid=" + userId); 11517 if ((resultTo != null) && !ordered) { 11518 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11519 } 11520 11521 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11522 true, false, "broadcast", callerPackage); 11523 11524 // Make sure that the user who is receiving this broadcast is started. 11525 // If not, we will just skip it. 11526 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11527 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11528 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11529 Slog.w(TAG, "Skipping broadcast of " + intent 11530 + ": user " + userId + " is stopped"); 11531 return ActivityManager.BROADCAST_SUCCESS; 11532 } 11533 } 11534 11535 /* 11536 * Prevent non-system code (defined here to be non-persistent 11537 * processes) from sending protected broadcasts. 11538 */ 11539 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11540 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11541 callingUid == 0) { 11542 // Always okay. 11543 } else if (callerApp == null || !callerApp.persistent) { 11544 try { 11545 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11546 intent.getAction())) { 11547 String msg = "Permission Denial: not allowed to send broadcast " 11548 + intent.getAction() + " from pid=" 11549 + callingPid + ", uid=" + callingUid; 11550 Slog.w(TAG, msg); 11551 throw new SecurityException(msg); 11552 } 11553 } catch (RemoteException e) { 11554 Slog.w(TAG, "Remote exception", e); 11555 return ActivityManager.BROADCAST_SUCCESS; 11556 } 11557 } 11558 11559 // Handle special intents: if this broadcast is from the package 11560 // manager about a package being removed, we need to remove all of 11561 // its activities from the history stack. 11562 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11563 intent.getAction()); 11564 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11565 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11566 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11567 || uidRemoved) { 11568 if (checkComponentPermission( 11569 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11570 callingPid, callingUid, -1, true) 11571 == PackageManager.PERMISSION_GRANTED) { 11572 if (uidRemoved) { 11573 final Bundle intentExtras = intent.getExtras(); 11574 final int uid = intentExtras != null 11575 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11576 if (uid >= 0) { 11577 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11578 synchronized (bs) { 11579 bs.removeUidStatsLocked(uid); 11580 } 11581 } 11582 } else { 11583 // If resources are unavailable just force stop all 11584 // those packages and flush the attribute cache as well. 11585 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11586 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11587 if (list != null && (list.length > 0)) { 11588 for (String pkg : list) { 11589 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11590 } 11591 sendPackageBroadcastLocked( 11592 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11593 } 11594 } else { 11595 Uri data = intent.getData(); 11596 String ssp; 11597 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11598 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11599 forceStopPackageLocked(ssp, 11600 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11601 false, userId); 11602 } 11603 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11604 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11605 new String[] {ssp}, userId); 11606 } 11607 } 11608 } 11609 } 11610 } else { 11611 String msg = "Permission Denial: " + intent.getAction() 11612 + " broadcast from " + callerPackage + " (pid=" + callingPid 11613 + ", uid=" + callingUid + ")" 11614 + " requires " 11615 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11616 Slog.w(TAG, msg); 11617 throw new SecurityException(msg); 11618 } 11619 11620 // Special case for adding a package: by default turn on compatibility 11621 // mode. 11622 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11623 Uri data = intent.getData(); 11624 String ssp; 11625 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11626 mCompatModePackages.handlePackageAddedLocked(ssp, 11627 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11628 } 11629 } 11630 11631 /* 11632 * If this is the time zone changed action, queue up a message that will reset the timezone 11633 * of all currently running processes. This message will get queued up before the broadcast 11634 * happens. 11635 */ 11636 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11637 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11638 } 11639 11640 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11641 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11642 } 11643 11644 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11645 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11646 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11647 } 11648 11649 // Add to the sticky list if requested. 11650 if (sticky) { 11651 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11652 callingPid, callingUid) 11653 != PackageManager.PERMISSION_GRANTED) { 11654 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11655 + callingPid + ", uid=" + callingUid 11656 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11657 Slog.w(TAG, msg); 11658 throw new SecurityException(msg); 11659 } 11660 if (requiredPermission != null) { 11661 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11662 + " and enforce permission " + requiredPermission); 11663 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11664 } 11665 if (intent.getComponent() != null) { 11666 throw new SecurityException( 11667 "Sticky broadcasts can't target a specific component"); 11668 } 11669 // We use userId directly here, since the "all" target is maintained 11670 // as a separate set of sticky broadcasts. 11671 if (userId != UserHandle.USER_ALL) { 11672 // But first, if this is not a broadcast to all users, then 11673 // make sure it doesn't conflict with an existing broadcast to 11674 // all users. 11675 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11676 UserHandle.USER_ALL); 11677 if (stickies != null) { 11678 ArrayList<Intent> list = stickies.get(intent.getAction()); 11679 if (list != null) { 11680 int N = list.size(); 11681 int i; 11682 for (i=0; i<N; i++) { 11683 if (intent.filterEquals(list.get(i))) { 11684 throw new IllegalArgumentException( 11685 "Sticky broadcast " + intent + " for user " 11686 + userId + " conflicts with existing global broadcast"); 11687 } 11688 } 11689 } 11690 } 11691 } 11692 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11693 if (stickies == null) { 11694 stickies = new HashMap<String, ArrayList<Intent>>(); 11695 mStickyBroadcasts.put(userId, stickies); 11696 } 11697 ArrayList<Intent> list = stickies.get(intent.getAction()); 11698 if (list == null) { 11699 list = new ArrayList<Intent>(); 11700 stickies.put(intent.getAction(), list); 11701 } 11702 int N = list.size(); 11703 int i; 11704 for (i=0; i<N; i++) { 11705 if (intent.filterEquals(list.get(i))) { 11706 // This sticky already exists, replace it. 11707 list.set(i, new Intent(intent)); 11708 break; 11709 } 11710 } 11711 if (i >= N) { 11712 list.add(new Intent(intent)); 11713 } 11714 } 11715 11716 int[] users; 11717 if (userId == UserHandle.USER_ALL) { 11718 // Caller wants broadcast to go to all started users. 11719 users = mStartedUserArray; 11720 } else { 11721 // Caller wants broadcast to go to one specific user. 11722 users = mCurrentUserArray; 11723 } 11724 11725 // Figure out who all will receive this broadcast. 11726 List receivers = null; 11727 List<BroadcastFilter> registeredReceivers = null; 11728 // Need to resolve the intent to interested receivers... 11729 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11730 == 0) { 11731 receivers = collectReceiverComponents(intent, resolvedType, users); 11732 } 11733 if (intent.getComponent() == null) { 11734 registeredReceivers = mReceiverResolver.queryIntent(intent, 11735 resolvedType, false, userId); 11736 } 11737 11738 final boolean replacePending = 11739 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11740 11741 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11742 + " replacePending=" + replacePending); 11743 11744 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11745 if (!ordered && NR > 0) { 11746 // If we are not serializing this broadcast, then send the 11747 // registered receivers separately so they don't wait for the 11748 // components to be launched. 11749 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11750 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11751 callerPackage, callingPid, callingUid, requiredPermission, 11752 registeredReceivers, resultTo, resultCode, resultData, map, 11753 ordered, sticky, false, userId); 11754 if (DEBUG_BROADCAST) Slog.v( 11755 TAG, "Enqueueing parallel broadcast " + r); 11756 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11757 if (!replaced) { 11758 queue.enqueueParallelBroadcastLocked(r); 11759 queue.scheduleBroadcastsLocked(); 11760 } 11761 registeredReceivers = null; 11762 NR = 0; 11763 } 11764 11765 // Merge into one list. 11766 int ir = 0; 11767 if (receivers != null) { 11768 // A special case for PACKAGE_ADDED: do not allow the package 11769 // being added to see this broadcast. This prevents them from 11770 // using this as a back door to get run as soon as they are 11771 // installed. Maybe in the future we want to have a special install 11772 // broadcast or such for apps, but we'd like to deliberately make 11773 // this decision. 11774 String skipPackages[] = null; 11775 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11776 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11777 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11778 Uri data = intent.getData(); 11779 if (data != null) { 11780 String pkgName = data.getSchemeSpecificPart(); 11781 if (pkgName != null) { 11782 skipPackages = new String[] { pkgName }; 11783 } 11784 } 11785 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11786 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11787 } 11788 if (skipPackages != null && (skipPackages.length > 0)) { 11789 for (String skipPackage : skipPackages) { 11790 if (skipPackage != null) { 11791 int NT = receivers.size(); 11792 for (int it=0; it<NT; it++) { 11793 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11794 if (curt.activityInfo.packageName.equals(skipPackage)) { 11795 receivers.remove(it); 11796 it--; 11797 NT--; 11798 } 11799 } 11800 } 11801 } 11802 } 11803 11804 int NT = receivers != null ? receivers.size() : 0; 11805 int it = 0; 11806 ResolveInfo curt = null; 11807 BroadcastFilter curr = null; 11808 while (it < NT && ir < NR) { 11809 if (curt == null) { 11810 curt = (ResolveInfo)receivers.get(it); 11811 } 11812 if (curr == null) { 11813 curr = registeredReceivers.get(ir); 11814 } 11815 if (curr.getPriority() >= curt.priority) { 11816 // Insert this broadcast record into the final list. 11817 receivers.add(it, curr); 11818 ir++; 11819 curr = null; 11820 it++; 11821 NT++; 11822 } else { 11823 // Skip to the next ResolveInfo in the final list. 11824 it++; 11825 curt = null; 11826 } 11827 } 11828 } 11829 while (ir < NR) { 11830 if (receivers == null) { 11831 receivers = new ArrayList(); 11832 } 11833 receivers.add(registeredReceivers.get(ir)); 11834 ir++; 11835 } 11836 11837 if ((receivers != null && receivers.size() > 0) 11838 || resultTo != null) { 11839 BroadcastQueue queue = broadcastQueueForIntent(intent); 11840 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11841 callerPackage, callingPid, callingUid, requiredPermission, 11842 receivers, resultTo, resultCode, resultData, map, ordered, 11843 sticky, false, userId); 11844 if (DEBUG_BROADCAST) Slog.v( 11845 TAG, "Enqueueing ordered broadcast " + r 11846 + ": prev had " + queue.mOrderedBroadcasts.size()); 11847 if (DEBUG_BROADCAST) { 11848 int seq = r.intent.getIntExtra("seq", -1); 11849 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11850 } 11851 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11852 if (!replaced) { 11853 queue.enqueueOrderedBroadcastLocked(r); 11854 queue.scheduleBroadcastsLocked(); 11855 } 11856 } 11857 11858 return ActivityManager.BROADCAST_SUCCESS; 11859 } 11860 11861 final Intent verifyBroadcastLocked(Intent intent) { 11862 // Refuse possible leaked file descriptors 11863 if (intent != null && intent.hasFileDescriptors() == true) { 11864 throw new IllegalArgumentException("File descriptors passed in Intent"); 11865 } 11866 11867 int flags = intent.getFlags(); 11868 11869 if (!mProcessesReady) { 11870 // if the caller really truly claims to know what they're doing, go 11871 // ahead and allow the broadcast without launching any receivers 11872 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11873 intent = new Intent(intent); 11874 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11875 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11876 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11877 + " before boot completion"); 11878 throw new IllegalStateException("Cannot broadcast before boot completed"); 11879 } 11880 } 11881 11882 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11883 throw new IllegalArgumentException( 11884 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11885 } 11886 11887 return intent; 11888 } 11889 11890 public final int broadcastIntent(IApplicationThread caller, 11891 Intent intent, String resolvedType, IIntentReceiver resultTo, 11892 int resultCode, String resultData, Bundle map, 11893 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11894 enforceNotIsolatedCaller("broadcastIntent"); 11895 synchronized(this) { 11896 intent = verifyBroadcastLocked(intent); 11897 11898 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11899 final int callingPid = Binder.getCallingPid(); 11900 final int callingUid = Binder.getCallingUid(); 11901 final long origId = Binder.clearCallingIdentity(); 11902 int res = broadcastIntentLocked(callerApp, 11903 callerApp != null ? callerApp.info.packageName : null, 11904 intent, resolvedType, resultTo, 11905 resultCode, resultData, map, requiredPermission, serialized, sticky, 11906 callingPid, callingUid, userId); 11907 Binder.restoreCallingIdentity(origId); 11908 return res; 11909 } 11910 } 11911 11912 int broadcastIntentInPackage(String packageName, int uid, 11913 Intent intent, String resolvedType, IIntentReceiver resultTo, 11914 int resultCode, String resultData, Bundle map, 11915 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11916 synchronized(this) { 11917 intent = verifyBroadcastLocked(intent); 11918 11919 final long origId = Binder.clearCallingIdentity(); 11920 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11921 resultTo, resultCode, resultData, map, requiredPermission, 11922 serialized, sticky, -1, uid, userId); 11923 Binder.restoreCallingIdentity(origId); 11924 return res; 11925 } 11926 } 11927 11928 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11929 // Refuse possible leaked file descriptors 11930 if (intent != null && intent.hasFileDescriptors() == true) { 11931 throw new IllegalArgumentException("File descriptors passed in Intent"); 11932 } 11933 11934 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11935 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11936 11937 synchronized(this) { 11938 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11939 != PackageManager.PERMISSION_GRANTED) { 11940 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11941 + Binder.getCallingPid() 11942 + ", uid=" + Binder.getCallingUid() 11943 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11944 Slog.w(TAG, msg); 11945 throw new SecurityException(msg); 11946 } 11947 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11948 if (stickies != null) { 11949 ArrayList<Intent> list = stickies.get(intent.getAction()); 11950 if (list != null) { 11951 int N = list.size(); 11952 int i; 11953 for (i=0; i<N; i++) { 11954 if (intent.filterEquals(list.get(i))) { 11955 list.remove(i); 11956 break; 11957 } 11958 } 11959 if (list.size() <= 0) { 11960 stickies.remove(intent.getAction()); 11961 } 11962 } 11963 if (stickies.size() <= 0) { 11964 mStickyBroadcasts.remove(userId); 11965 } 11966 } 11967 } 11968 } 11969 11970 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11971 String resultData, Bundle resultExtras, boolean resultAbort, 11972 boolean explicit) { 11973 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11974 if (r == null) { 11975 Slog.w(TAG, "finishReceiver called but not found on queue"); 11976 return false; 11977 } 11978 11979 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11980 explicit); 11981 } 11982 11983 public void finishReceiver(IBinder who, int resultCode, String resultData, 11984 Bundle resultExtras, boolean resultAbort) { 11985 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11986 11987 // Refuse possible leaked file descriptors 11988 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11989 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11990 } 11991 11992 final long origId = Binder.clearCallingIdentity(); 11993 try { 11994 boolean doNext = false; 11995 BroadcastRecord r = null; 11996 11997 synchronized(this) { 11998 r = broadcastRecordForReceiverLocked(who); 11999 if (r != null) { 12000 doNext = r.queue.finishReceiverLocked(r, resultCode, 12001 resultData, resultExtras, resultAbort, true); 12002 } 12003 } 12004 12005 if (doNext) { 12006 r.queue.processNextBroadcast(false); 12007 } 12008 trimApplications(); 12009 } finally { 12010 Binder.restoreCallingIdentity(origId); 12011 } 12012 } 12013 12014 // ========================================================= 12015 // INSTRUMENTATION 12016 // ========================================================= 12017 12018 public boolean startInstrumentation(ComponentName className, 12019 String profileFile, int flags, Bundle arguments, 12020 IInstrumentationWatcher watcher, int userId) { 12021 enforceNotIsolatedCaller("startInstrumentation"); 12022 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 12023 userId, false, true, "startInstrumentation", null); 12024 // Refuse possible leaked file descriptors 12025 if (arguments != null && arguments.hasFileDescriptors()) { 12026 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12027 } 12028 12029 synchronized(this) { 12030 InstrumentationInfo ii = null; 12031 ApplicationInfo ai = null; 12032 try { 12033 ii = mContext.getPackageManager().getInstrumentationInfo( 12034 className, STOCK_PM_FLAGS); 12035 ai = AppGlobals.getPackageManager().getApplicationInfo( 12036 ii.targetPackage, STOCK_PM_FLAGS, userId); 12037 } catch (PackageManager.NameNotFoundException e) { 12038 } catch (RemoteException e) { 12039 } 12040 if (ii == null) { 12041 reportStartInstrumentationFailure(watcher, className, 12042 "Unable to find instrumentation info for: " + className); 12043 return false; 12044 } 12045 if (ai == null) { 12046 reportStartInstrumentationFailure(watcher, className, 12047 "Unable to find instrumentation target package: " + ii.targetPackage); 12048 return false; 12049 } 12050 12051 int match = mContext.getPackageManager().checkSignatures( 12052 ii.targetPackage, ii.packageName); 12053 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12054 String msg = "Permission Denial: starting instrumentation " 12055 + className + " from pid=" 12056 + Binder.getCallingPid() 12057 + ", uid=" + Binder.getCallingPid() 12058 + " not allowed because package " + ii.packageName 12059 + " does not have a signature matching the target " 12060 + ii.targetPackage; 12061 reportStartInstrumentationFailure(watcher, className, msg); 12062 throw new SecurityException(msg); 12063 } 12064 12065 final long origId = Binder.clearCallingIdentity(); 12066 // Instrumentation can kill and relaunch even persistent processes 12067 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12068 ProcessRecord app = addAppLocked(ai, false); 12069 app.instrumentationClass = className; 12070 app.instrumentationInfo = ai; 12071 app.instrumentationProfileFile = profileFile; 12072 app.instrumentationArguments = arguments; 12073 app.instrumentationWatcher = watcher; 12074 app.instrumentationResultClass = className; 12075 Binder.restoreCallingIdentity(origId); 12076 } 12077 12078 return true; 12079 } 12080 12081 /** 12082 * Report errors that occur while attempting to start Instrumentation. Always writes the 12083 * error to the logs, but if somebody is watching, send the report there too. This enables 12084 * the "am" command to report errors with more information. 12085 * 12086 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12087 * @param cn The component name of the instrumentation. 12088 * @param report The error report. 12089 */ 12090 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12091 ComponentName cn, String report) { 12092 Slog.w(TAG, report); 12093 try { 12094 if (watcher != null) { 12095 Bundle results = new Bundle(); 12096 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12097 results.putString("Error", report); 12098 watcher.instrumentationStatus(cn, -1, results); 12099 } 12100 } catch (RemoteException e) { 12101 Slog.w(TAG, e); 12102 } 12103 } 12104 12105 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12106 if (app.instrumentationWatcher != null) { 12107 try { 12108 // NOTE: IInstrumentationWatcher *must* be oneway here 12109 app.instrumentationWatcher.instrumentationFinished( 12110 app.instrumentationClass, 12111 resultCode, 12112 results); 12113 } catch (RemoteException e) { 12114 } 12115 } 12116 app.instrumentationWatcher = null; 12117 app.instrumentationClass = null; 12118 app.instrumentationInfo = null; 12119 app.instrumentationProfileFile = null; 12120 app.instrumentationArguments = null; 12121 12122 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12123 } 12124 12125 public void finishInstrumentation(IApplicationThread target, 12126 int resultCode, Bundle results) { 12127 int userId = UserHandle.getCallingUserId(); 12128 // Refuse possible leaked file descriptors 12129 if (results != null && results.hasFileDescriptors()) { 12130 throw new IllegalArgumentException("File descriptors passed in Intent"); 12131 } 12132 12133 synchronized(this) { 12134 ProcessRecord app = getRecordForAppLocked(target); 12135 if (app == null) { 12136 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12137 return; 12138 } 12139 final long origId = Binder.clearCallingIdentity(); 12140 finishInstrumentationLocked(app, resultCode, results); 12141 Binder.restoreCallingIdentity(origId); 12142 } 12143 } 12144 12145 // ========================================================= 12146 // CONFIGURATION 12147 // ========================================================= 12148 12149 public ConfigurationInfo getDeviceConfigurationInfo() { 12150 ConfigurationInfo config = new ConfigurationInfo(); 12151 synchronized (this) { 12152 config.reqTouchScreen = mConfiguration.touchscreen; 12153 config.reqKeyboardType = mConfiguration.keyboard; 12154 config.reqNavigation = mConfiguration.navigation; 12155 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12156 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12157 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12158 } 12159 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12160 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12161 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12162 } 12163 config.reqGlEsVersion = GL_ES_VERSION; 12164 } 12165 return config; 12166 } 12167 12168 public Configuration getConfiguration() { 12169 Configuration ci; 12170 synchronized(this) { 12171 ci = new Configuration(mConfiguration); 12172 } 12173 return ci; 12174 } 12175 12176 public void updatePersistentConfiguration(Configuration values) { 12177 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12178 "updateConfiguration()"); 12179 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12180 "updateConfiguration()"); 12181 if (values == null) { 12182 throw new NullPointerException("Configuration must not be null"); 12183 } 12184 12185 synchronized(this) { 12186 final long origId = Binder.clearCallingIdentity(); 12187 updateConfigurationLocked(values, null, true, false); 12188 Binder.restoreCallingIdentity(origId); 12189 } 12190 } 12191 12192 public void updateConfiguration(Configuration values) { 12193 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12194 "updateConfiguration()"); 12195 12196 synchronized(this) { 12197 if (values == null && mWindowManager != null) { 12198 // sentinel: fetch the current configuration from the window manager 12199 values = mWindowManager.computeNewConfiguration(); 12200 } 12201 12202 if (mWindowManager != null) { 12203 mProcessList.applyDisplaySize(mWindowManager); 12204 } 12205 12206 final long origId = Binder.clearCallingIdentity(); 12207 if (values != null) { 12208 Settings.System.clearConfiguration(values); 12209 } 12210 updateConfigurationLocked(values, null, false, false); 12211 Binder.restoreCallingIdentity(origId); 12212 } 12213 } 12214 12215 /** 12216 * Do either or both things: (1) change the current configuration, and (2) 12217 * make sure the given activity is running with the (now) current 12218 * configuration. Returns true if the activity has been left running, or 12219 * false if <var>starting</var> is being destroyed to match the new 12220 * configuration. 12221 * @param persistent TODO 12222 */ 12223 boolean updateConfigurationLocked(Configuration values, 12224 ActivityRecord starting, boolean persistent, boolean initLocale) { 12225 // do nothing if we are headless 12226 if (mHeadless) return true; 12227 12228 int changes = 0; 12229 12230 boolean kept = true; 12231 12232 if (values != null) { 12233 Configuration newConfig = new Configuration(mConfiguration); 12234 changes = newConfig.updateFrom(values); 12235 if (changes != 0) { 12236 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12237 Slog.i(TAG, "Updating configuration to: " + values); 12238 } 12239 12240 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12241 12242 if (values.locale != null && !initLocale) { 12243 saveLocaleLocked(values.locale, 12244 !values.locale.equals(mConfiguration.locale), 12245 values.userSetLocale); 12246 } 12247 12248 mConfigurationSeq++; 12249 if (mConfigurationSeq <= 0) { 12250 mConfigurationSeq = 1; 12251 } 12252 newConfig.seq = mConfigurationSeq; 12253 mConfiguration = newConfig; 12254 Slog.i(TAG, "Config changed: " + newConfig); 12255 12256 final Configuration configCopy = new Configuration(mConfiguration); 12257 12258 // TODO: If our config changes, should we auto dismiss any currently 12259 // showing dialogs? 12260 mShowDialogs = shouldShowDialogs(newConfig); 12261 12262 AttributeCache ac = AttributeCache.instance(); 12263 if (ac != null) { 12264 ac.updateConfiguration(configCopy); 12265 } 12266 12267 // Make sure all resources in our process are updated 12268 // right now, so that anyone who is going to retrieve 12269 // resource values after we return will be sure to get 12270 // the new ones. This is especially important during 12271 // boot, where the first config change needs to guarantee 12272 // all resources have that config before following boot 12273 // code is executed. 12274 mSystemThread.applyConfigurationToResources(configCopy); 12275 12276 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12277 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12278 msg.obj = new Configuration(configCopy); 12279 mHandler.sendMessage(msg); 12280 } 12281 12282 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12283 ProcessRecord app = mLruProcesses.get(i); 12284 try { 12285 if (app.thread != null) { 12286 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12287 + app.processName + " new config " + mConfiguration); 12288 app.thread.scheduleConfigurationChanged(configCopy); 12289 } 12290 } catch (Exception e) { 12291 } 12292 } 12293 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12295 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12296 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12297 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12298 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12299 broadcastIntentLocked(null, null, 12300 new Intent(Intent.ACTION_LOCALE_CHANGED), 12301 null, null, 0, null, null, 12302 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12303 } 12304 } 12305 } 12306 12307 if (changes != 0 && starting == null) { 12308 // If the configuration changed, and the caller is not already 12309 // in the process of starting an activity, then find the top 12310 // activity to check if its configuration needs to change. 12311 starting = mMainStack.topRunningActivityLocked(null); 12312 } 12313 12314 if (starting != null) { 12315 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12316 // And we need to make sure at this point that all other activities 12317 // are made visible with the correct configuration. 12318 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12319 } 12320 12321 if (values != null && mWindowManager != null) { 12322 mWindowManager.setNewConfiguration(mConfiguration); 12323 } 12324 12325 return kept; 12326 } 12327 12328 /** 12329 * Decide based on the configuration whether we should shouw the ANR, 12330 * crash, etc dialogs. The idea is that if there is no affordnace to 12331 * press the on-screen buttons, we shouldn't show the dialog. 12332 * 12333 * A thought: SystemUI might also want to get told about this, the Power 12334 * dialog / global actions also might want different behaviors. 12335 */ 12336 private static final boolean shouldShowDialogs(Configuration config) { 12337 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12338 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12339 } 12340 12341 /** 12342 * Save the locale. You must be inside a synchronized (this) block. 12343 */ 12344 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12345 if(isDiff) { 12346 SystemProperties.set("user.language", l.getLanguage()); 12347 SystemProperties.set("user.region", l.getCountry()); 12348 } 12349 12350 if(isPersist) { 12351 SystemProperties.set("persist.sys.language", l.getLanguage()); 12352 SystemProperties.set("persist.sys.country", l.getCountry()); 12353 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12354 } 12355 } 12356 12357 @Override 12358 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12359 ActivityRecord srec = ActivityRecord.forToken(token); 12360 return srec != null && srec.task.affinity != null && 12361 srec.task.affinity.equals(destAffinity); 12362 } 12363 12364 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12365 Intent resultData) { 12366 ComponentName dest = destIntent.getComponent(); 12367 12368 synchronized (this) { 12369 ActivityRecord srec = ActivityRecord.forToken(token); 12370 if (srec == null) { 12371 return false; 12372 } 12373 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12374 final int start = history.indexOf(srec); 12375 if (start < 0) { 12376 // Current activity is not in history stack; do nothing. 12377 return false; 12378 } 12379 int finishTo = start - 1; 12380 ActivityRecord parent = null; 12381 boolean foundParentInTask = false; 12382 if (dest != null) { 12383 TaskRecord tr = srec.task; 12384 for (int i = start - 1; i >= 0; i--) { 12385 ActivityRecord r = history.get(i); 12386 if (tr != r.task) { 12387 // Couldn't find parent in the same task; stop at the one above this. 12388 // (Root of current task; in-app "home" behavior) 12389 // Always at least finish the current activity. 12390 finishTo = Math.min(start - 1, i + 1); 12391 parent = history.get(finishTo); 12392 break; 12393 } else if (r.info.packageName.equals(dest.getPackageName()) && 12394 r.info.name.equals(dest.getClassName())) { 12395 finishTo = i; 12396 parent = r; 12397 foundParentInTask = true; 12398 break; 12399 } 12400 } 12401 } 12402 12403 if (mController != null) { 12404 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12405 if (next != null) { 12406 // ask watcher if this is allowed 12407 boolean resumeOK = true; 12408 try { 12409 resumeOK = mController.activityResuming(next.packageName); 12410 } catch (RemoteException e) { 12411 mController = null; 12412 } 12413 12414 if (!resumeOK) { 12415 return false; 12416 } 12417 } 12418 } 12419 final long origId = Binder.clearCallingIdentity(); 12420 for (int i = start; i > finishTo; i--) { 12421 ActivityRecord r = history.get(i); 12422 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12423 "navigate-up", true); 12424 // Only return the supplied result for the first activity finished 12425 resultCode = Activity.RESULT_CANCELED; 12426 resultData = null; 12427 } 12428 12429 if (parent != null && foundParentInTask) { 12430 final int parentLaunchMode = parent.info.launchMode; 12431 final int destIntentFlags = destIntent.getFlags(); 12432 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12433 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12434 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12435 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12436 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12437 } else { 12438 try { 12439 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12440 destIntent.getComponent(), 0, srec.userId); 12441 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12442 null, aInfo, parent.appToken, null, 12443 0, -1, parent.launchedFromUid, 0, null, true, null); 12444 foundParentInTask = res == ActivityManager.START_SUCCESS; 12445 } catch (RemoteException e) { 12446 foundParentInTask = false; 12447 } 12448 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12449 resultData, "navigate-up", true); 12450 } 12451 } 12452 Binder.restoreCallingIdentity(origId); 12453 return foundParentInTask; 12454 } 12455 } 12456 12457 public int getLaunchedFromUid(IBinder activityToken) { 12458 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12459 if (srec == null) { 12460 return -1; 12461 } 12462 return srec.launchedFromUid; 12463 } 12464 12465 // ========================================================= 12466 // LIFETIME MANAGEMENT 12467 // ========================================================= 12468 12469 // Returns which broadcast queue the app is the current [or imminent] receiver 12470 // on, or 'null' if the app is not an active broadcast recipient. 12471 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12472 BroadcastRecord r = app.curReceiver; 12473 if (r != null) { 12474 return r.queue; 12475 } 12476 12477 // It's not the current receiver, but it might be starting up to become one 12478 synchronized (this) { 12479 for (BroadcastQueue queue : mBroadcastQueues) { 12480 r = queue.mPendingBroadcast; 12481 if (r != null && r.curApp == app) { 12482 // found it; report which queue it's in 12483 return queue; 12484 } 12485 } 12486 } 12487 12488 return null; 12489 } 12490 12491 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12492 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12493 if (mAdjSeq == app.adjSeq) { 12494 // This adjustment has already been computed. If we are calling 12495 // from the top, we may have already computed our adjustment with 12496 // an earlier hidden adjustment that isn't really for us... if 12497 // so, use the new hidden adjustment. 12498 if (!recursed && app.hidden) { 12499 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12500 app.hasActivities ? hiddenAdj : emptyAdj; 12501 } 12502 return app.curRawAdj; 12503 } 12504 12505 if (app.thread == null) { 12506 app.adjSeq = mAdjSeq; 12507 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12508 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12509 } 12510 12511 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12512 app.adjSource = null; 12513 app.adjTarget = null; 12514 app.empty = false; 12515 app.hidden = false; 12516 12517 final int activitiesSize = app.activities.size(); 12518 12519 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12520 // The max adjustment doesn't allow this app to be anything 12521 // below foreground, so it is not worth doing work for it. 12522 app.adjType = "fixed"; 12523 app.adjSeq = mAdjSeq; 12524 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12525 app.hasActivities = false; 12526 app.foregroundActivities = false; 12527 app.keeping = true; 12528 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12529 // System process can do UI, and when they do we want to have 12530 // them trim their memory after the user leaves the UI. To 12531 // facilitate this, here we need to determine whether or not it 12532 // is currently showing UI. 12533 app.systemNoUi = true; 12534 if (app == TOP_APP) { 12535 app.systemNoUi = false; 12536 app.hasActivities = true; 12537 } else if (activitiesSize > 0) { 12538 for (int j = 0; j < activitiesSize; j++) { 12539 final ActivityRecord r = app.activities.get(j); 12540 if (r.visible) { 12541 app.systemNoUi = false; 12542 } 12543 if (r.app == app) { 12544 app.hasActivities = true; 12545 } 12546 } 12547 } 12548 return (app.curAdj=app.maxAdj); 12549 } 12550 12551 app.keeping = false; 12552 app.systemNoUi = false; 12553 app.hasActivities = false; 12554 12555 // Determine the importance of the process, starting with most 12556 // important to least, and assign an appropriate OOM adjustment. 12557 int adj; 12558 int schedGroup; 12559 boolean foregroundActivities = false; 12560 boolean interesting = false; 12561 BroadcastQueue queue; 12562 if (app == TOP_APP) { 12563 // The last app on the list is the foreground app. 12564 adj = ProcessList.FOREGROUND_APP_ADJ; 12565 schedGroup = Process.THREAD_GROUP_DEFAULT; 12566 app.adjType = "top-activity"; 12567 foregroundActivities = true; 12568 interesting = true; 12569 app.hasActivities = true; 12570 } else if (app.instrumentationClass != null) { 12571 // Don't want to kill running instrumentation. 12572 adj = ProcessList.FOREGROUND_APP_ADJ; 12573 schedGroup = Process.THREAD_GROUP_DEFAULT; 12574 app.adjType = "instrumentation"; 12575 interesting = true; 12576 } else if ((queue = isReceivingBroadcast(app)) != null) { 12577 // An app that is currently receiving a broadcast also 12578 // counts as being in the foreground for OOM killer purposes. 12579 // It's placed in a sched group based on the nature of the 12580 // broadcast as reflected by which queue it's active in. 12581 adj = ProcessList.FOREGROUND_APP_ADJ; 12582 schedGroup = (queue == mFgBroadcastQueue) 12583 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12584 app.adjType = "broadcast"; 12585 } else if (app.executingServices.size() > 0) { 12586 // An app that is currently executing a service callback also 12587 // counts as being in the foreground. 12588 adj = ProcessList.FOREGROUND_APP_ADJ; 12589 schedGroup = Process.THREAD_GROUP_DEFAULT; 12590 app.adjType = "exec-service"; 12591 } else { 12592 // Assume process is hidden (has activities); we will correct 12593 // later if this is not the case. 12594 adj = hiddenAdj; 12595 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12596 app.hidden = true; 12597 app.adjType = "bg-activities"; 12598 } 12599 12600 boolean hasStoppingActivities = false; 12601 12602 // Examine all activities if not already foreground. 12603 if (!foregroundActivities && activitiesSize > 0) { 12604 for (int j = 0; j < activitiesSize; j++) { 12605 final ActivityRecord r = app.activities.get(j); 12606 if (r.visible) { 12607 // App has a visible activity; only upgrade adjustment. 12608 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12609 adj = ProcessList.VISIBLE_APP_ADJ; 12610 app.adjType = "visible"; 12611 } 12612 schedGroup = Process.THREAD_GROUP_DEFAULT; 12613 app.hidden = false; 12614 app.hasActivities = true; 12615 foregroundActivities = true; 12616 break; 12617 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12618 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12619 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12620 app.adjType = "pausing"; 12621 } 12622 app.hidden = false; 12623 foregroundActivities = true; 12624 } else if (r.state == ActivityState.STOPPING) { 12625 // We will apply the actual adjustment later, because 12626 // we want to allow this process to immediately go through 12627 // any memory trimming that is in effect. 12628 app.hidden = false; 12629 foregroundActivities = true; 12630 hasStoppingActivities = true; 12631 } 12632 if (r.app == app) { 12633 app.hasActivities = true; 12634 } 12635 } 12636 } 12637 12638 if (adj == hiddenAdj && !app.hasActivities) { 12639 // Whoops, this process is completely empty as far as we know 12640 // at this point. 12641 adj = emptyAdj; 12642 app.empty = true; 12643 app.adjType = "bg-empty"; 12644 } 12645 12646 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12647 if (app.foregroundServices) { 12648 // The user is aware of this app, so make it visible. 12649 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12650 app.hidden = false; 12651 app.adjType = "foreground-service"; 12652 schedGroup = Process.THREAD_GROUP_DEFAULT; 12653 } else if (app.forcingToForeground != null) { 12654 // The user is aware of this app, so make it visible. 12655 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12656 app.hidden = false; 12657 app.adjType = "force-foreground"; 12658 app.adjSource = app.forcingToForeground; 12659 schedGroup = Process.THREAD_GROUP_DEFAULT; 12660 } 12661 } 12662 12663 if (app.foregroundServices) { 12664 interesting = true; 12665 } 12666 12667 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12668 // We don't want to kill the current heavy-weight process. 12669 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12670 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12671 app.hidden = false; 12672 app.adjType = "heavy"; 12673 } 12674 12675 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12676 // This process is hosting what we currently consider to be the 12677 // home app, so we don't want to let it go into the background. 12678 adj = ProcessList.HOME_APP_ADJ; 12679 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12680 app.hidden = false; 12681 app.adjType = "home"; 12682 } 12683 12684 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12685 && app.activities.size() > 0) { 12686 // This was the previous process that showed UI to the user. 12687 // We want to try to keep it around more aggressively, to give 12688 // a good experience around switching between two apps. 12689 adj = ProcessList.PREVIOUS_APP_ADJ; 12690 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12691 app.hidden = false; 12692 app.adjType = "previous"; 12693 } 12694 12695 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12696 + " reason=" + app.adjType); 12697 12698 // By default, we use the computed adjustment. It may be changed if 12699 // there are applications dependent on our services or providers, but 12700 // this gives us a baseline and makes sure we don't get into an 12701 // infinite recursion. 12702 app.adjSeq = mAdjSeq; 12703 app.curRawAdj = app.nonStoppingAdj = adj; 12704 12705 if (mBackupTarget != null && app == mBackupTarget.app) { 12706 // If possible we want to avoid killing apps while they're being backed up 12707 if (adj > ProcessList.BACKUP_APP_ADJ) { 12708 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12709 adj = ProcessList.BACKUP_APP_ADJ; 12710 app.adjType = "backup"; 12711 app.hidden = false; 12712 } 12713 } 12714 12715 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12716 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12717 final long now = SystemClock.uptimeMillis(); 12718 // This process is more important if the top activity is 12719 // bound to the service. 12720 Iterator<ServiceRecord> jt = app.services.iterator(); 12721 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12722 ServiceRecord s = jt.next(); 12723 if (s.startRequested) { 12724 if (app.hasShownUi && app != mHomeProcess) { 12725 // If this process has shown some UI, let it immediately 12726 // go to the LRU list because it may be pretty heavy with 12727 // UI stuff. We'll tag it with a label just to help 12728 // debug and understand what is going on. 12729 if (adj > ProcessList.SERVICE_ADJ) { 12730 app.adjType = "started-bg-ui-services"; 12731 } 12732 } else { 12733 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12734 // This service has seen some activity within 12735 // recent memory, so we will keep its process ahead 12736 // of the background processes. 12737 if (adj > ProcessList.SERVICE_ADJ) { 12738 adj = ProcessList.SERVICE_ADJ; 12739 app.adjType = "started-services"; 12740 app.hidden = false; 12741 } 12742 } 12743 // If we have let the service slide into the background 12744 // state, still have some text describing what it is doing 12745 // even though the service no longer has an impact. 12746 if (adj > ProcessList.SERVICE_ADJ) { 12747 app.adjType = "started-bg-services"; 12748 } 12749 } 12750 // Don't kill this process because it is doing work; it 12751 // has said it is doing work. 12752 app.keeping = true; 12753 } 12754 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12755 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12756 Iterator<ArrayList<ConnectionRecord>> kt 12757 = s.connections.values().iterator(); 12758 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12759 ArrayList<ConnectionRecord> clist = kt.next(); 12760 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12761 // XXX should compute this based on the max of 12762 // all connected clients. 12763 ConnectionRecord cr = clist.get(i); 12764 if (cr.binding.client == app) { 12765 // Binding to ourself is not interesting. 12766 continue; 12767 } 12768 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12769 ProcessRecord client = cr.binding.client; 12770 int clientAdj = adj; 12771 int myHiddenAdj = hiddenAdj; 12772 if (myHiddenAdj > client.hiddenAdj) { 12773 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12774 myHiddenAdj = client.hiddenAdj; 12775 } else { 12776 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12777 } 12778 } 12779 int myEmptyAdj = emptyAdj; 12780 if (myEmptyAdj > client.emptyAdj) { 12781 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12782 myEmptyAdj = client.emptyAdj; 12783 } else { 12784 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12785 } 12786 } 12787 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12788 myEmptyAdj, TOP_APP, true, doingAll); 12789 String adjType = null; 12790 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12791 // Not doing bind OOM management, so treat 12792 // this guy more like a started service. 12793 if (app.hasShownUi && app != mHomeProcess) { 12794 // If this process has shown some UI, let it immediately 12795 // go to the LRU list because it may be pretty heavy with 12796 // UI stuff. We'll tag it with a label just to help 12797 // debug and understand what is going on. 12798 if (adj > clientAdj) { 12799 adjType = "bound-bg-ui-services"; 12800 } 12801 app.hidden = false; 12802 clientAdj = adj; 12803 } else { 12804 if (now >= (s.lastActivity 12805 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12806 // This service has not seen activity within 12807 // recent memory, so allow it to drop to the 12808 // LRU list if there is no other reason to keep 12809 // it around. We'll also tag it with a label just 12810 // to help debug and undertand what is going on. 12811 if (adj > clientAdj) { 12812 adjType = "bound-bg-services"; 12813 } 12814 clientAdj = adj; 12815 } 12816 } 12817 } 12818 if (adj > clientAdj) { 12819 // If this process has recently shown UI, and 12820 // the process that is binding to it is less 12821 // important than being visible, then we don't 12822 // care about the binding as much as we care 12823 // about letting this process get into the LRU 12824 // list to be killed and restarted if needed for 12825 // memory. 12826 if (app.hasShownUi && app != mHomeProcess 12827 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12828 adjType = "bound-bg-ui-services"; 12829 } else { 12830 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12831 |Context.BIND_IMPORTANT)) != 0) { 12832 adj = clientAdj; 12833 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12834 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12835 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12836 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12837 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12838 adj = clientAdj; 12839 } else { 12840 app.pendingUiClean = true; 12841 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12842 adj = ProcessList.VISIBLE_APP_ADJ; 12843 } 12844 } 12845 if (!client.hidden) { 12846 app.hidden = false; 12847 } 12848 if (client.keeping) { 12849 app.keeping = true; 12850 } 12851 adjType = "service"; 12852 } 12853 } 12854 if (adjType != null) { 12855 app.adjType = adjType; 12856 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12857 .REASON_SERVICE_IN_USE; 12858 app.adjSource = cr.binding.client; 12859 app.adjSourceOom = clientAdj; 12860 app.adjTarget = s.name; 12861 } 12862 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12863 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12864 schedGroup = Process.THREAD_GROUP_DEFAULT; 12865 } 12866 } 12867 } 12868 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12869 ActivityRecord a = cr.activity; 12870 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12871 (a.visible || a.state == ActivityState.RESUMED 12872 || a.state == ActivityState.PAUSING)) { 12873 adj = ProcessList.FOREGROUND_APP_ADJ; 12874 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12875 schedGroup = Process.THREAD_GROUP_DEFAULT; 12876 } 12877 app.hidden = false; 12878 app.adjType = "service"; 12879 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12880 .REASON_SERVICE_IN_USE; 12881 app.adjSource = a; 12882 app.adjSourceOom = adj; 12883 app.adjTarget = s.name; 12884 } 12885 } 12886 } 12887 } 12888 } 12889 } 12890 12891 // Finally, if this process has active services running in it, we 12892 // would like to avoid killing it unless it would prevent the current 12893 // application from running. By default we put the process in 12894 // with the rest of the background processes; as we scan through 12895 // its services we may bump it up from there. 12896 if (adj > hiddenAdj) { 12897 adj = hiddenAdj; 12898 app.hidden = false; 12899 app.adjType = "bg-services"; 12900 } 12901 } 12902 12903 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12904 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12905 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12906 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12907 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12908 ContentProviderRecord cpr = jt.next(); 12909 for (int i = cpr.connections.size()-1; 12910 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12911 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12912 i--) { 12913 ContentProviderConnection conn = cpr.connections.get(i); 12914 ProcessRecord client = conn.client; 12915 if (client == app) { 12916 // Being our own client is not interesting. 12917 continue; 12918 } 12919 int myHiddenAdj = hiddenAdj; 12920 if (myHiddenAdj > client.hiddenAdj) { 12921 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12922 myHiddenAdj = client.hiddenAdj; 12923 } else { 12924 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12925 } 12926 } 12927 int myEmptyAdj = emptyAdj; 12928 if (myEmptyAdj > client.emptyAdj) { 12929 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12930 myEmptyAdj = client.emptyAdj; 12931 } else { 12932 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12933 } 12934 } 12935 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12936 myEmptyAdj, TOP_APP, true, doingAll); 12937 if (adj > clientAdj) { 12938 if (app.hasShownUi && app != mHomeProcess 12939 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12940 app.adjType = "bg-ui-provider"; 12941 } else { 12942 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12943 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12944 app.adjType = "provider"; 12945 } 12946 if (!client.hidden) { 12947 app.hidden = false; 12948 } 12949 if (client.keeping) { 12950 app.keeping = true; 12951 } 12952 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12953 .REASON_PROVIDER_IN_USE; 12954 app.adjSource = client; 12955 app.adjSourceOom = clientAdj; 12956 app.adjTarget = cpr.name; 12957 } 12958 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12959 schedGroup = Process.THREAD_GROUP_DEFAULT; 12960 } 12961 } 12962 // If the provider has external (non-framework) process 12963 // dependencies, ensure that its adjustment is at least 12964 // FOREGROUND_APP_ADJ. 12965 if (cpr.hasExternalProcessHandles()) { 12966 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12967 adj = ProcessList.FOREGROUND_APP_ADJ; 12968 schedGroup = Process.THREAD_GROUP_DEFAULT; 12969 app.hidden = false; 12970 app.keeping = true; 12971 app.adjType = "provider"; 12972 app.adjTarget = cpr.name; 12973 } 12974 } 12975 } 12976 } 12977 12978 if (adj == ProcessList.SERVICE_ADJ) { 12979 if (doingAll) { 12980 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12981 mNewNumServiceProcs++; 12982 } 12983 if (app.serviceb) { 12984 adj = ProcessList.SERVICE_B_ADJ; 12985 } 12986 } else { 12987 app.serviceb = false; 12988 } 12989 12990 app.nonStoppingAdj = adj; 12991 12992 if (hasStoppingActivities) { 12993 // Only upgrade adjustment. 12994 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12995 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12996 app.adjType = "stopping"; 12997 } 12998 } 12999 13000 app.curRawAdj = adj; 13001 13002 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13003 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13004 if (adj > app.maxAdj) { 13005 adj = app.maxAdj; 13006 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13007 schedGroup = Process.THREAD_GROUP_DEFAULT; 13008 } 13009 } 13010 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13011 app.keeping = true; 13012 } 13013 13014 if (app.hasAboveClient) { 13015 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13016 // then we need to drop its adjustment to be lower than the service's 13017 // in order to honor the request. We want to drop it by one adjustment 13018 // level... but there is special meaning applied to various levels so 13019 // we will skip some of them. 13020 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13021 // System process will not get dropped, ever 13022 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13023 adj = ProcessList.VISIBLE_APP_ADJ; 13024 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13025 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13026 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13027 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13028 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13029 adj++; 13030 } 13031 } 13032 13033 int importance = app.memImportance; 13034 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13035 app.curAdj = adj; 13036 app.curSchedGroup = schedGroup; 13037 if (!interesting) { 13038 // For this reporting, if there is not something explicitly 13039 // interesting in this process then we will push it to the 13040 // background importance. 13041 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13042 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13043 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13044 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13045 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13046 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13047 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13048 } else if (adj >= ProcessList.SERVICE_ADJ) { 13049 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13050 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13051 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13052 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13053 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13054 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13055 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13056 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13057 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13058 } else { 13059 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13060 } 13061 } 13062 13063 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13064 if (foregroundActivities != app.foregroundActivities) { 13065 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13066 } 13067 if (changes != 0) { 13068 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13069 app.memImportance = importance; 13070 app.foregroundActivities = foregroundActivities; 13071 int i = mPendingProcessChanges.size()-1; 13072 ProcessChangeItem item = null; 13073 while (i >= 0) { 13074 item = mPendingProcessChanges.get(i); 13075 if (item.pid == app.pid) { 13076 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13077 break; 13078 } 13079 i--; 13080 } 13081 if (i < 0) { 13082 // No existing item in pending changes; need a new one. 13083 final int NA = mAvailProcessChanges.size(); 13084 if (NA > 0) { 13085 item = mAvailProcessChanges.remove(NA-1); 13086 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13087 } else { 13088 item = new ProcessChangeItem(); 13089 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13090 } 13091 item.changes = 0; 13092 item.pid = app.pid; 13093 item.uid = app.info.uid; 13094 if (mPendingProcessChanges.size() == 0) { 13095 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13096 "*** Enqueueing dispatch processes changed!"); 13097 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13098 } 13099 mPendingProcessChanges.add(item); 13100 } 13101 item.changes |= changes; 13102 item.importance = importance; 13103 item.foregroundActivities = foregroundActivities; 13104 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13105 + Integer.toHexString(System.identityHashCode(item)) 13106 + " " + app.toShortString() + ": changes=" + item.changes 13107 + " importance=" + item.importance 13108 + " foreground=" + item.foregroundActivities 13109 + " type=" + app.adjType + " source=" + app.adjSource 13110 + " target=" + app.adjTarget); 13111 } 13112 13113 return app.curRawAdj; 13114 } 13115 13116 /** 13117 * Ask a given process to GC right now. 13118 */ 13119 final void performAppGcLocked(ProcessRecord app) { 13120 try { 13121 app.lastRequestedGc = SystemClock.uptimeMillis(); 13122 if (app.thread != null) { 13123 if (app.reportLowMemory) { 13124 app.reportLowMemory = false; 13125 app.thread.scheduleLowMemory(); 13126 } else { 13127 app.thread.processInBackground(); 13128 } 13129 } 13130 } catch (Exception e) { 13131 // whatever. 13132 } 13133 } 13134 13135 /** 13136 * Returns true if things are idle enough to perform GCs. 13137 */ 13138 private final boolean canGcNowLocked() { 13139 boolean processingBroadcasts = false; 13140 for (BroadcastQueue q : mBroadcastQueues) { 13141 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13142 processingBroadcasts = true; 13143 } 13144 } 13145 return !processingBroadcasts 13146 && (mSleeping || (mMainStack.mResumedActivity != null && 13147 mMainStack.mResumedActivity.idle)); 13148 } 13149 13150 /** 13151 * Perform GCs on all processes that are waiting for it, but only 13152 * if things are idle. 13153 */ 13154 final void performAppGcsLocked() { 13155 final int N = mProcessesToGc.size(); 13156 if (N <= 0) { 13157 return; 13158 } 13159 if (canGcNowLocked()) { 13160 while (mProcessesToGc.size() > 0) { 13161 ProcessRecord proc = mProcessesToGc.remove(0); 13162 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13163 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13164 <= SystemClock.uptimeMillis()) { 13165 // To avoid spamming the system, we will GC processes one 13166 // at a time, waiting a few seconds between each. 13167 performAppGcLocked(proc); 13168 scheduleAppGcsLocked(); 13169 return; 13170 } else { 13171 // It hasn't been long enough since we last GCed this 13172 // process... put it in the list to wait for its time. 13173 addProcessToGcListLocked(proc); 13174 break; 13175 } 13176 } 13177 } 13178 13179 scheduleAppGcsLocked(); 13180 } 13181 } 13182 13183 /** 13184 * If all looks good, perform GCs on all processes waiting for them. 13185 */ 13186 final void performAppGcsIfAppropriateLocked() { 13187 if (canGcNowLocked()) { 13188 performAppGcsLocked(); 13189 return; 13190 } 13191 // Still not idle, wait some more. 13192 scheduleAppGcsLocked(); 13193 } 13194 13195 /** 13196 * Schedule the execution of all pending app GCs. 13197 */ 13198 final void scheduleAppGcsLocked() { 13199 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13200 13201 if (mProcessesToGc.size() > 0) { 13202 // Schedule a GC for the time to the next process. 13203 ProcessRecord proc = mProcessesToGc.get(0); 13204 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13205 13206 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13207 long now = SystemClock.uptimeMillis(); 13208 if (when < (now+GC_TIMEOUT)) { 13209 when = now + GC_TIMEOUT; 13210 } 13211 mHandler.sendMessageAtTime(msg, when); 13212 } 13213 } 13214 13215 /** 13216 * Add a process to the array of processes waiting to be GCed. Keeps the 13217 * list in sorted order by the last GC time. The process can't already be 13218 * on the list. 13219 */ 13220 final void addProcessToGcListLocked(ProcessRecord proc) { 13221 boolean added = false; 13222 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13223 if (mProcessesToGc.get(i).lastRequestedGc < 13224 proc.lastRequestedGc) { 13225 added = true; 13226 mProcessesToGc.add(i+1, proc); 13227 break; 13228 } 13229 } 13230 if (!added) { 13231 mProcessesToGc.add(0, proc); 13232 } 13233 } 13234 13235 /** 13236 * Set up to ask a process to GC itself. This will either do it 13237 * immediately, or put it on the list of processes to gc the next 13238 * time things are idle. 13239 */ 13240 final void scheduleAppGcLocked(ProcessRecord app) { 13241 long now = SystemClock.uptimeMillis(); 13242 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13243 return; 13244 } 13245 if (!mProcessesToGc.contains(app)) { 13246 addProcessToGcListLocked(app); 13247 scheduleAppGcsLocked(); 13248 } 13249 } 13250 13251 final void checkExcessivePowerUsageLocked(boolean doKills) { 13252 updateCpuStatsNow(); 13253 13254 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13255 boolean doWakeKills = doKills; 13256 boolean doCpuKills = doKills; 13257 if (mLastPowerCheckRealtime == 0) { 13258 doWakeKills = false; 13259 } 13260 if (mLastPowerCheckUptime == 0) { 13261 doCpuKills = false; 13262 } 13263 if (stats.isScreenOn()) { 13264 doWakeKills = false; 13265 } 13266 final long curRealtime = SystemClock.elapsedRealtime(); 13267 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13268 final long curUptime = SystemClock.uptimeMillis(); 13269 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13270 mLastPowerCheckRealtime = curRealtime; 13271 mLastPowerCheckUptime = curUptime; 13272 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13273 doWakeKills = false; 13274 } 13275 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13276 doCpuKills = false; 13277 } 13278 int i = mLruProcesses.size(); 13279 while (i > 0) { 13280 i--; 13281 ProcessRecord app = mLruProcesses.get(i); 13282 if (!app.keeping) { 13283 long wtime; 13284 synchronized (stats) { 13285 wtime = stats.getProcessWakeTime(app.info.uid, 13286 app.pid, curRealtime); 13287 } 13288 long wtimeUsed = wtime - app.lastWakeTime; 13289 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13290 if (DEBUG_POWER) { 13291 StringBuilder sb = new StringBuilder(128); 13292 sb.append("Wake for "); 13293 app.toShortString(sb); 13294 sb.append(": over "); 13295 TimeUtils.formatDuration(realtimeSince, sb); 13296 sb.append(" used "); 13297 TimeUtils.formatDuration(wtimeUsed, sb); 13298 sb.append(" ("); 13299 sb.append((wtimeUsed*100)/realtimeSince); 13300 sb.append("%)"); 13301 Slog.i(TAG, sb.toString()); 13302 sb.setLength(0); 13303 sb.append("CPU for "); 13304 app.toShortString(sb); 13305 sb.append(": over "); 13306 TimeUtils.formatDuration(uptimeSince, sb); 13307 sb.append(" used "); 13308 TimeUtils.formatDuration(cputimeUsed, sb); 13309 sb.append(" ("); 13310 sb.append((cputimeUsed*100)/uptimeSince); 13311 sb.append("%)"); 13312 Slog.i(TAG, sb.toString()); 13313 } 13314 // If a process has held a wake lock for more 13315 // than 50% of the time during this period, 13316 // that sounds bad. Kill! 13317 if (doWakeKills && realtimeSince > 0 13318 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13319 synchronized (stats) { 13320 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13321 realtimeSince, wtimeUsed); 13322 } 13323 Slog.w(TAG, "Excessive wake lock in " + app.processName 13324 + " (pid " + app.pid + "): held " + wtimeUsed 13325 + " during " + realtimeSince); 13326 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13327 app.processName, app.setAdj, "excessive wake lock"); 13328 Process.killProcessQuiet(app.pid); 13329 } else if (doCpuKills && uptimeSince > 0 13330 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13331 synchronized (stats) { 13332 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13333 uptimeSince, cputimeUsed); 13334 } 13335 Slog.w(TAG, "Excessive CPU in " + app.processName 13336 + " (pid " + app.pid + "): used " + cputimeUsed 13337 + " during " + uptimeSince); 13338 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13339 app.processName, app.setAdj, "excessive cpu"); 13340 Process.killProcessQuiet(app.pid); 13341 } else { 13342 app.lastWakeTime = wtime; 13343 app.lastCpuTime = app.curCpuTime; 13344 } 13345 } 13346 } 13347 } 13348 13349 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13350 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13351 app.hiddenAdj = hiddenAdj; 13352 app.emptyAdj = emptyAdj; 13353 13354 if (app.thread == null) { 13355 return false; 13356 } 13357 13358 final boolean wasKeeping = app.keeping; 13359 13360 boolean success = true; 13361 13362 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13363 13364 if (app.curRawAdj != app.setRawAdj) { 13365 if (wasKeeping && !app.keeping) { 13366 // This app is no longer something we want to keep. Note 13367 // its current wake lock time to later know to kill it if 13368 // it is not behaving well. 13369 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13370 synchronized (stats) { 13371 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13372 app.pid, SystemClock.elapsedRealtime()); 13373 } 13374 app.lastCpuTime = app.curCpuTime; 13375 } 13376 13377 app.setRawAdj = app.curRawAdj; 13378 } 13379 13380 if (app.curAdj != app.setAdj) { 13381 if (Process.setOomAdj(app.pid, app.curAdj)) { 13382 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13383 TAG, "Set " + app.pid + " " + app.processName + 13384 " adj " + app.curAdj + ": " + app.adjType); 13385 app.setAdj = app.curAdj; 13386 } else { 13387 success = false; 13388 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13389 } 13390 } 13391 if (app.setSchedGroup != app.curSchedGroup) { 13392 app.setSchedGroup = app.curSchedGroup; 13393 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13394 "Setting process group of " + app.processName 13395 + " to " + app.curSchedGroup); 13396 if (app.waitingToKill != null && 13397 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13398 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13399 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13400 app.processName, app.setAdj, app.waitingToKill); 13401 app.killedBackground = true; 13402 Process.killProcessQuiet(app.pid); 13403 success = false; 13404 } else { 13405 if (true) { 13406 long oldId = Binder.clearCallingIdentity(); 13407 try { 13408 Process.setProcessGroup(app.pid, app.curSchedGroup); 13409 } catch (Exception e) { 13410 Slog.w(TAG, "Failed setting process group of " + app.pid 13411 + " to " + app.curSchedGroup); 13412 e.printStackTrace(); 13413 } finally { 13414 Binder.restoreCallingIdentity(oldId); 13415 } 13416 } else { 13417 if (app.thread != null) { 13418 try { 13419 app.thread.setSchedulingGroup(app.curSchedGroup); 13420 } catch (RemoteException e) { 13421 } 13422 } 13423 } 13424 } 13425 } 13426 return success; 13427 } 13428 13429 private final ActivityRecord resumedAppLocked() { 13430 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13431 if (resumedActivity == null || resumedActivity.app == null) { 13432 resumedActivity = mMainStack.mPausingActivity; 13433 if (resumedActivity == null || resumedActivity.app == null) { 13434 resumedActivity = mMainStack.topRunningActivityLocked(null); 13435 } 13436 } 13437 return resumedActivity; 13438 } 13439 13440 final boolean updateOomAdjLocked(ProcessRecord app) { 13441 final ActivityRecord TOP_ACT = resumedAppLocked(); 13442 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13443 int curAdj = app.curAdj; 13444 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13445 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13446 13447 mAdjSeq++; 13448 13449 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13450 TOP_APP, false); 13451 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13452 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13453 if (nowHidden != wasHidden) { 13454 // Changed to/from hidden state, so apps after it in the LRU 13455 // list may also be changed. 13456 updateOomAdjLocked(); 13457 } 13458 return success; 13459 } 13460 13461 final void updateOomAdjLocked() { 13462 final ActivityRecord TOP_ACT = resumedAppLocked(); 13463 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13464 13465 if (false) { 13466 RuntimeException e = new RuntimeException(); 13467 e.fillInStackTrace(); 13468 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13469 } 13470 13471 mAdjSeq++; 13472 mNewNumServiceProcs = 0; 13473 13474 // Let's determine how many processes we have running vs. 13475 // how many slots we have for background processes; we may want 13476 // to put multiple processes in a slot of there are enough of 13477 // them. 13478 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13479 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13480 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13481 if (emptyFactor < 1) emptyFactor = 1; 13482 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13483 if (hiddenFactor < 1) hiddenFactor = 1; 13484 int stepHidden = 0; 13485 int stepEmpty = 0; 13486 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13487 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13488 int numHidden = 0; 13489 int numEmpty = 0; 13490 int numTrimming = 0; 13491 13492 mNumNonHiddenProcs = 0; 13493 mNumHiddenProcs = 0; 13494 13495 // First update the OOM adjustment for each of the 13496 // application processes based on their current state. 13497 int i = mLruProcesses.size(); 13498 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13499 int nextHiddenAdj = curHiddenAdj+1; 13500 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13501 int nextEmptyAdj = curEmptyAdj+2; 13502 while (i > 0) { 13503 i--; 13504 ProcessRecord app = mLruProcesses.get(i); 13505 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13506 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13507 if (!app.killedBackground) { 13508 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13509 // This process was assigned as a hidden process... step the 13510 // hidden level. 13511 mNumHiddenProcs++; 13512 if (curHiddenAdj != nextHiddenAdj) { 13513 stepHidden++; 13514 if (stepHidden >= hiddenFactor) { 13515 stepHidden = 0; 13516 curHiddenAdj = nextHiddenAdj; 13517 nextHiddenAdj += 2; 13518 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13519 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13520 } 13521 } 13522 } 13523 numHidden++; 13524 if (numHidden > hiddenProcessLimit) { 13525 Slog.i(TAG, "No longer want " + app.processName 13526 + " (pid " + app.pid + "): hidden #" + numHidden); 13527 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13528 app.processName, app.setAdj, "too many background"); 13529 app.killedBackground = true; 13530 Process.killProcessQuiet(app.pid); 13531 } 13532 } else { 13533 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13534 // This process was assigned as an empty process... step the 13535 // empty level. 13536 if (curEmptyAdj != nextEmptyAdj) { 13537 stepEmpty++; 13538 if (stepEmpty >= emptyFactor) { 13539 stepEmpty = 0; 13540 curEmptyAdj = nextEmptyAdj; 13541 nextEmptyAdj += 2; 13542 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13543 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13544 } 13545 } 13546 } 13547 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13548 mNumNonHiddenProcs++; 13549 } 13550 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13551 numEmpty++; 13552 if (numEmpty > emptyProcessLimit) { 13553 Slog.i(TAG, "No longer want " + app.processName 13554 + " (pid " + app.pid + "): empty #" + numEmpty); 13555 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13556 app.processName, app.setAdj, "too many background"); 13557 app.killedBackground = true; 13558 Process.killProcessQuiet(app.pid); 13559 } 13560 } 13561 } 13562 if (app.isolated && app.services.size() <= 0) { 13563 // If this is an isolated process, and there are no 13564 // services running in it, then the process is no longer 13565 // needed. We agressively kill these because we can by 13566 // definition not re-use the same process again, and it is 13567 // good to avoid having whatever code was running in them 13568 // left sitting around after no longer needed. 13569 Slog.i(TAG, "Isolated process " + app.processName 13570 + " (pid " + app.pid + ") no longer needed"); 13571 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13572 app.processName, app.setAdj, "isolated not needed"); 13573 app.killedBackground = true; 13574 Process.killProcessQuiet(app.pid); 13575 } 13576 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13577 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13578 && !app.killedBackground) { 13579 numTrimming++; 13580 } 13581 } 13582 } 13583 13584 mNumServiceProcs = mNewNumServiceProcs; 13585 13586 // Now determine the memory trimming level of background processes. 13587 // Unfortunately we need to start at the back of the list to do this 13588 // properly. We only do this if the number of background apps we 13589 // are managing to keep around is less than half the maximum we desire; 13590 // if we are keeping a good number around, we'll let them use whatever 13591 // memory they want. 13592 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13593 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13594 final int numHiddenAndEmpty = numHidden + numEmpty; 13595 final int N = mLruProcesses.size(); 13596 int factor = numTrimming/3; 13597 int minFactor = 2; 13598 if (mHomeProcess != null) minFactor++; 13599 if (mPreviousProcess != null) minFactor++; 13600 if (factor < minFactor) factor = minFactor; 13601 int step = 0; 13602 int fgTrimLevel; 13603 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13604 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13605 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13606 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13607 } else { 13608 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13609 } 13610 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13611 for (i=0; i<N; i++) { 13612 ProcessRecord app = mLruProcesses.get(i); 13613 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13614 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13615 && !app.killedBackground) { 13616 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13617 try { 13618 app.thread.scheduleTrimMemory(curLevel); 13619 } catch (RemoteException e) { 13620 } 13621 if (false) { 13622 // For now we won't do this; our memory trimming seems 13623 // to be good enough at this point that destroying 13624 // activities causes more harm than good. 13625 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13626 && app != mHomeProcess && app != mPreviousProcess) { 13627 // Need to do this on its own message because the stack may not 13628 // be in a consistent state at this point. 13629 // For these apps we will also finish their activities 13630 // to help them free memory. 13631 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13632 } 13633 } 13634 } 13635 app.trimMemoryLevel = curLevel; 13636 step++; 13637 if (step >= factor) { 13638 step = 0; 13639 switch (curLevel) { 13640 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13641 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13642 break; 13643 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13644 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13645 break; 13646 } 13647 } 13648 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13649 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13650 && app.thread != null) { 13651 try { 13652 app.thread.scheduleTrimMemory( 13653 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13654 } catch (RemoteException e) { 13655 } 13656 } 13657 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13658 } else { 13659 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13660 && app.pendingUiClean) { 13661 // If this application is now in the background and it 13662 // had done UI, then give it the special trim level to 13663 // have it free UI resources. 13664 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13665 if (app.trimMemoryLevel < level && app.thread != null) { 13666 try { 13667 app.thread.scheduleTrimMemory(level); 13668 } catch (RemoteException e) { 13669 } 13670 } 13671 app.pendingUiClean = false; 13672 } 13673 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13674 try { 13675 app.thread.scheduleTrimMemory(fgTrimLevel); 13676 } catch (RemoteException e) { 13677 } 13678 } 13679 app.trimMemoryLevel = fgTrimLevel; 13680 } 13681 } 13682 } else { 13683 final int N = mLruProcesses.size(); 13684 for (i=0; i<N; i++) { 13685 ProcessRecord app = mLruProcesses.get(i); 13686 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13687 && app.pendingUiClean) { 13688 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13689 && app.thread != null) { 13690 try { 13691 app.thread.scheduleTrimMemory( 13692 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13693 } catch (RemoteException e) { 13694 } 13695 } 13696 app.pendingUiClean = false; 13697 } 13698 app.trimMemoryLevel = 0; 13699 } 13700 } 13701 13702 if (mAlwaysFinishActivities) { 13703 // Need to do this on its own message because the stack may not 13704 // be in a consistent state at this point. 13705 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13706 } 13707 } 13708 13709 final void trimApplications() { 13710 synchronized (this) { 13711 int i; 13712 13713 // First remove any unused application processes whose package 13714 // has been removed. 13715 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13716 final ProcessRecord app = mRemovedProcesses.get(i); 13717 if (app.activities.size() == 0 13718 && app.curReceiver == null && app.services.size() == 0) { 13719 Slog.i( 13720 TAG, "Exiting empty application process " 13721 + app.processName + " (" 13722 + (app.thread != null ? app.thread.asBinder() : null) 13723 + ")\n"); 13724 if (app.pid > 0 && app.pid != MY_PID) { 13725 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13726 app.processName, app.setAdj, "empty"); 13727 Process.killProcessQuiet(app.pid); 13728 } else { 13729 try { 13730 app.thread.scheduleExit(); 13731 } catch (Exception e) { 13732 // Ignore exceptions. 13733 } 13734 } 13735 cleanUpApplicationRecordLocked(app, false, true, -1); 13736 mRemovedProcesses.remove(i); 13737 13738 if (app.persistent) { 13739 if (app.persistent) { 13740 addAppLocked(app.info, false); 13741 } 13742 } 13743 } 13744 } 13745 13746 // Now update the oom adj for all processes. 13747 updateOomAdjLocked(); 13748 } 13749 } 13750 13751 /** This method sends the specified signal to each of the persistent apps */ 13752 public void signalPersistentProcesses(int sig) throws RemoteException { 13753 if (sig != Process.SIGNAL_USR1) { 13754 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13755 } 13756 13757 synchronized (this) { 13758 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13759 != PackageManager.PERMISSION_GRANTED) { 13760 throw new SecurityException("Requires permission " 13761 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13762 } 13763 13764 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13765 ProcessRecord r = mLruProcesses.get(i); 13766 if (r.thread != null && r.persistent) { 13767 Process.sendSignal(r.pid, sig); 13768 } 13769 } 13770 } 13771 } 13772 13773 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13774 if (proc == null || proc == mProfileProc) { 13775 proc = mProfileProc; 13776 path = mProfileFile; 13777 profileType = mProfileType; 13778 clearProfilerLocked(); 13779 } 13780 if (proc == null) { 13781 return; 13782 } 13783 try { 13784 proc.thread.profilerControl(false, path, null, profileType); 13785 } catch (RemoteException e) { 13786 throw new IllegalStateException("Process disappeared"); 13787 } 13788 } 13789 13790 private void clearProfilerLocked() { 13791 if (mProfileFd != null) { 13792 try { 13793 mProfileFd.close(); 13794 } catch (IOException e) { 13795 } 13796 } 13797 mProfileApp = null; 13798 mProfileProc = null; 13799 mProfileFile = null; 13800 mProfileType = 0; 13801 mAutoStopProfiler = false; 13802 } 13803 13804 public boolean profileControl(String process, int userId, boolean start, 13805 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13806 13807 try { 13808 synchronized (this) { 13809 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13810 // its own permission. 13811 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13812 != PackageManager.PERMISSION_GRANTED) { 13813 throw new SecurityException("Requires permission " 13814 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13815 } 13816 13817 if (start && fd == null) { 13818 throw new IllegalArgumentException("null fd"); 13819 } 13820 13821 ProcessRecord proc = null; 13822 if (process != null) { 13823 proc = findProcessLocked(process, userId, "profileControl"); 13824 } 13825 13826 if (start && (proc == null || proc.thread == null)) { 13827 throw new IllegalArgumentException("Unknown process: " + process); 13828 } 13829 13830 if (start) { 13831 stopProfilerLocked(null, null, 0); 13832 setProfileApp(proc.info, proc.processName, path, fd, false); 13833 mProfileProc = proc; 13834 mProfileType = profileType; 13835 try { 13836 fd = fd.dup(); 13837 } catch (IOException e) { 13838 fd = null; 13839 } 13840 proc.thread.profilerControl(start, path, fd, profileType); 13841 fd = null; 13842 mProfileFd = null; 13843 } else { 13844 stopProfilerLocked(proc, path, profileType); 13845 if (fd != null) { 13846 try { 13847 fd.close(); 13848 } catch (IOException e) { 13849 } 13850 } 13851 } 13852 13853 return true; 13854 } 13855 } catch (RemoteException e) { 13856 throw new IllegalStateException("Process disappeared"); 13857 } finally { 13858 if (fd != null) { 13859 try { 13860 fd.close(); 13861 } catch (IOException e) { 13862 } 13863 } 13864 } 13865 } 13866 13867 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13868 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13869 userId, true, true, callName, null); 13870 ProcessRecord proc = null; 13871 try { 13872 int pid = Integer.parseInt(process); 13873 synchronized (mPidsSelfLocked) { 13874 proc = mPidsSelfLocked.get(pid); 13875 } 13876 } catch (NumberFormatException e) { 13877 } 13878 13879 if (proc == null) { 13880 HashMap<String, SparseArray<ProcessRecord>> all 13881 = mProcessNames.getMap(); 13882 SparseArray<ProcessRecord> procs = all.get(process); 13883 if (procs != null && procs.size() > 0) { 13884 proc = procs.valueAt(0); 13885 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13886 for (int i=1; i<procs.size(); i++) { 13887 ProcessRecord thisProc = procs.valueAt(i); 13888 if (thisProc.userId == userId) { 13889 proc = thisProc; 13890 break; 13891 } 13892 } 13893 } 13894 } 13895 } 13896 13897 return proc; 13898 } 13899 13900 public boolean dumpHeap(String process, int userId, boolean managed, 13901 String path, ParcelFileDescriptor fd) throws RemoteException { 13902 13903 try { 13904 synchronized (this) { 13905 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13906 // its own permission (same as profileControl). 13907 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13908 != PackageManager.PERMISSION_GRANTED) { 13909 throw new SecurityException("Requires permission " 13910 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13911 } 13912 13913 if (fd == null) { 13914 throw new IllegalArgumentException("null fd"); 13915 } 13916 13917 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13918 if (proc == null || proc.thread == null) { 13919 throw new IllegalArgumentException("Unknown process: " + process); 13920 } 13921 13922 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13923 if (!isDebuggable) { 13924 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13925 throw new SecurityException("Process not debuggable: " + proc); 13926 } 13927 } 13928 13929 proc.thread.dumpHeap(managed, path, fd); 13930 fd = null; 13931 return true; 13932 } 13933 } catch (RemoteException e) { 13934 throw new IllegalStateException("Process disappeared"); 13935 } finally { 13936 if (fd != null) { 13937 try { 13938 fd.close(); 13939 } catch (IOException e) { 13940 } 13941 } 13942 } 13943 } 13944 13945 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13946 public void monitor() { 13947 synchronized (this) { } 13948 } 13949 13950 void onCoreSettingsChange(Bundle settings) { 13951 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13952 ProcessRecord processRecord = mLruProcesses.get(i); 13953 try { 13954 if (processRecord.thread != null) { 13955 processRecord.thread.setCoreSettings(settings); 13956 } 13957 } catch (RemoteException re) { 13958 /* ignore */ 13959 } 13960 } 13961 } 13962 13963 // Multi-user methods 13964 13965 @Override 13966 public boolean switchUser(int userId) { 13967 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13968 != PackageManager.PERMISSION_GRANTED) { 13969 String msg = "Permission Denial: switchUser() from pid=" 13970 + Binder.getCallingPid() 13971 + ", uid=" + Binder.getCallingUid() 13972 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13973 Slog.w(TAG, msg); 13974 throw new SecurityException(msg); 13975 } 13976 13977 final long ident = Binder.clearCallingIdentity(); 13978 try { 13979 synchronized (this) { 13980 final int oldUserId = mCurrentUserId; 13981 if (oldUserId == userId) { 13982 return true; 13983 } 13984 13985 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 13986 if (userInfo == null) { 13987 Slog.w(TAG, "No user info for user #" + userId); 13988 return false; 13989 } 13990 13991 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13992 R.anim.screen_user_enter); 13993 13994 // If the user we are switching to is not currently started, then 13995 // we need to start it now. 13996 if (mStartedUsers.get(userId) == null) { 13997 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13998 updateStartedUserArrayLocked(); 13999 } 14000 14001 mCurrentUserId = userId; 14002 mCurrentUserArray = new int[] { userId }; 14003 final Integer userIdInt = Integer.valueOf(userId); 14004 mUserLru.remove(userIdInt); 14005 mUserLru.add(userIdInt); 14006 14007 mWindowManager.setCurrentUser(userId); 14008 14009 final UserStartedState uss = mStartedUsers.get(userId); 14010 14011 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14012 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14013 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14014 oldUserId, userId, uss)); 14015 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14016 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14017 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14018 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14019 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14020 broadcastIntentLocked(null, null, intent, 14021 null, null, 0, null, null, null, 14022 false, false, MY_PID, Process.SYSTEM_UID, userId); 14023 14024 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14025 if (userId != 0) { 14026 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14027 broadcastIntentLocked(null, null, intent, null, 14028 new IIntentReceiver.Stub() { 14029 public void performReceive(Intent intent, int resultCode, 14030 String data, Bundle extras, boolean ordered, 14031 boolean sticky, int sendingUser) { 14032 synchronized (ActivityManagerService.this) { 14033 getUserManagerLocked().makeInitialized(userInfo.id); 14034 } 14035 } 14036 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14037 userId); 14038 } else { 14039 getUserManagerLocked().makeInitialized(userInfo.id); 14040 } 14041 } 14042 14043 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14044 if (!haveActivities) { 14045 startHomeActivityLocked(userId); 14046 } 14047 14048 getUserManagerLocked().userForeground(userId); 14049 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14050 } 14051 } finally { 14052 Binder.restoreCallingIdentity(ident); 14053 } 14054 14055 return true; 14056 } 14057 14058 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14059 long ident = Binder.clearCallingIdentity(); 14060 try { 14061 Intent intent; 14062 if (oldUserId >= 0) { 14063 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14065 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14066 broadcastIntentLocked(null, null, intent, 14067 null, null, 0, null, null, null, 14068 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14069 } 14070 if (newUserId >= 0) { 14071 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14072 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14073 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14074 broadcastIntentLocked(null, null, intent, 14075 null, null, 0, null, null, null, 14076 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14077 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14078 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14079 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14080 broadcastIntentLocked(null, null, intent, 14081 null, null, 0, null, null, 14082 android.Manifest.permission.MANAGE_USERS, 14083 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14084 } 14085 } finally { 14086 Binder.restoreCallingIdentity(ident); 14087 } 14088 } 14089 14090 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14091 final int newUserId) { 14092 final int N = mUserSwitchObservers.beginBroadcast(); 14093 if (N > 0) { 14094 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14095 int mCount = 0; 14096 @Override 14097 public void sendResult(Bundle data) throws RemoteException { 14098 synchronized (ActivityManagerService.this) { 14099 if (mCurUserSwitchCallback == this) { 14100 mCount++; 14101 if (mCount == N) { 14102 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14103 } 14104 } 14105 } 14106 } 14107 }; 14108 synchronized (this) { 14109 mCurUserSwitchCallback = callback; 14110 } 14111 for (int i=0; i<N; i++) { 14112 try { 14113 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14114 newUserId, callback); 14115 } catch (RemoteException e) { 14116 } 14117 } 14118 } else { 14119 synchronized (this) { 14120 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14121 } 14122 } 14123 mUserSwitchObservers.finishBroadcast(); 14124 } 14125 14126 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14127 synchronized (this) { 14128 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14129 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14130 } 14131 } 14132 14133 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14134 mCurUserSwitchCallback = null; 14135 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14136 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14137 oldUserId, newUserId, uss)); 14138 } 14139 14140 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14141 final int N = mUserSwitchObservers.beginBroadcast(); 14142 for (int i=0; i<N; i++) { 14143 try { 14144 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14145 } catch (RemoteException e) { 14146 } 14147 } 14148 mUserSwitchObservers.finishBroadcast(); 14149 synchronized (this) { 14150 mWindowManager.stopFreezingScreen(); 14151 } 14152 } 14153 14154 void finishUserSwitch(UserStartedState uss) { 14155 synchronized (this) { 14156 if (uss.mState == UserStartedState.STATE_BOOTING 14157 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14158 uss.mState = UserStartedState.STATE_RUNNING; 14159 final int userId = uss.mHandle.getIdentifier(); 14160 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14161 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14162 broadcastIntentLocked(null, null, intent, 14163 null, null, 0, null, null, 14164 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14165 false, false, MY_PID, Process.SYSTEM_UID, userId); 14166 } 14167 int num = mUserLru.size(); 14168 int i = 0; 14169 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14170 Integer oldUserId = mUserLru.get(i); 14171 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14172 if (oldUss == null) { 14173 // Shouldn't happen, but be sane if it does. 14174 mUserLru.remove(i); 14175 num--; 14176 continue; 14177 } 14178 if (oldUss.mState == UserStartedState.STATE_STOPPING) { 14179 // This user is already stopping, doesn't count. 14180 num--; 14181 i++; 14182 continue; 14183 } 14184 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14185 // Owner and current can't be stopped, but count as running. 14186 i++; 14187 continue; 14188 } 14189 // This is a user to be stopped. 14190 stopUserLocked(oldUserId, null); 14191 num--; 14192 i++; 14193 } 14194 } 14195 } 14196 14197 @Override 14198 public int stopUser(final int userId, final IStopUserCallback callback) { 14199 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14200 != PackageManager.PERMISSION_GRANTED) { 14201 String msg = "Permission Denial: switchUser() from pid=" 14202 + Binder.getCallingPid() 14203 + ", uid=" + Binder.getCallingUid() 14204 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14205 Slog.w(TAG, msg); 14206 throw new SecurityException(msg); 14207 } 14208 if (userId <= 0) { 14209 throw new IllegalArgumentException("Can't stop primary user " + userId); 14210 } 14211 synchronized (this) { 14212 return stopUserLocked(userId, callback); 14213 } 14214 } 14215 14216 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14217 if (mCurrentUserId == userId) { 14218 return ActivityManager.USER_OP_IS_CURRENT; 14219 } 14220 14221 final UserStartedState uss = mStartedUsers.get(userId); 14222 if (uss == null) { 14223 // User is not started, nothing to do... but we do need to 14224 // callback if requested. 14225 if (callback != null) { 14226 mHandler.post(new Runnable() { 14227 @Override 14228 public void run() { 14229 try { 14230 callback.userStopped(userId); 14231 } catch (RemoteException e) { 14232 } 14233 } 14234 }); 14235 } 14236 return ActivityManager.USER_OP_SUCCESS; 14237 } 14238 14239 if (callback != null) { 14240 uss.mStopCallbacks.add(callback); 14241 } 14242 14243 if (uss.mState != UserStartedState.STATE_STOPPING) { 14244 uss.mState = UserStartedState.STATE_STOPPING; 14245 14246 long ident = Binder.clearCallingIdentity(); 14247 try { 14248 // Inform of user switch 14249 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14250 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14251 @Override 14252 public void performReceive(Intent intent, int resultCode, String data, 14253 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14254 finishUserStop(uss); 14255 } 14256 }; 14257 broadcastIntentLocked(null, null, intent, 14258 null, resultReceiver, 0, null, null, null, 14259 true, false, MY_PID, Process.SYSTEM_UID, userId); 14260 } finally { 14261 Binder.restoreCallingIdentity(ident); 14262 } 14263 } 14264 14265 return ActivityManager.USER_OP_SUCCESS; 14266 } 14267 14268 void finishUserStop(UserStartedState uss) { 14269 final int userId = uss.mHandle.getIdentifier(); 14270 boolean stopped; 14271 ArrayList<IStopUserCallback> callbacks; 14272 synchronized (this) { 14273 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14274 if (uss.mState != UserStartedState.STATE_STOPPING 14275 || mStartedUsers.get(userId) != uss) { 14276 stopped = false; 14277 } else { 14278 stopped = true; 14279 // User can no longer run. 14280 mStartedUsers.remove(userId); 14281 mUserLru.remove(Integer.valueOf(userId)); 14282 updateStartedUserArrayLocked(); 14283 14284 // Clean up all state and processes associated with the user. 14285 // Kill all the processes for the user. 14286 forceStopUserLocked(userId); 14287 } 14288 } 14289 14290 for (int i=0; i<callbacks.size(); i++) { 14291 try { 14292 if (stopped) callbacks.get(i).userStopped(userId); 14293 else callbacks.get(i).userStopAborted(userId); 14294 } catch (RemoteException e) { 14295 } 14296 } 14297 } 14298 14299 @Override 14300 public UserInfo getCurrentUser() { 14301 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14302 != PackageManager.PERMISSION_GRANTED) && ( 14303 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14304 != PackageManager.PERMISSION_GRANTED)) { 14305 String msg = "Permission Denial: getCurrentUser() from pid=" 14306 + Binder.getCallingPid() 14307 + ", uid=" + Binder.getCallingUid() 14308 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14309 Slog.w(TAG, msg); 14310 throw new SecurityException(msg); 14311 } 14312 synchronized (this) { 14313 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14314 } 14315 } 14316 14317 int getCurrentUserIdLocked() { 14318 return mCurrentUserId; 14319 } 14320 14321 @Override 14322 public boolean isUserRunning(int userId) { 14323 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14324 != PackageManager.PERMISSION_GRANTED) { 14325 String msg = "Permission Denial: isUserRunning() from pid=" 14326 + Binder.getCallingPid() 14327 + ", uid=" + Binder.getCallingUid() 14328 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14329 Slog.w(TAG, msg); 14330 throw new SecurityException(msg); 14331 } 14332 synchronized (this) { 14333 return isUserRunningLocked(userId); 14334 } 14335 } 14336 14337 boolean isUserRunningLocked(int userId) { 14338 UserStartedState state = mStartedUsers.get(userId); 14339 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14340 } 14341 14342 @Override 14343 public int[] getRunningUserIds() { 14344 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14345 != PackageManager.PERMISSION_GRANTED) { 14346 String msg = "Permission Denial: isUserRunning() from pid=" 14347 + Binder.getCallingPid() 14348 + ", uid=" + Binder.getCallingUid() 14349 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14350 Slog.w(TAG, msg); 14351 throw new SecurityException(msg); 14352 } 14353 synchronized (this) { 14354 return mStartedUserArray; 14355 } 14356 } 14357 14358 private void updateStartedUserArrayLocked() { 14359 mStartedUserArray = new int[mStartedUsers.size()]; 14360 for (int i=0; i<mStartedUsers.size(); i++) { 14361 mStartedUserArray[i] = mStartedUsers.keyAt(i); 14362 } 14363 } 14364 14365 @Override 14366 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14367 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14368 != PackageManager.PERMISSION_GRANTED) { 14369 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14370 + Binder.getCallingPid() 14371 + ", uid=" + Binder.getCallingUid() 14372 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14373 Slog.w(TAG, msg); 14374 throw new SecurityException(msg); 14375 } 14376 14377 mUserSwitchObservers.register(observer); 14378 } 14379 14380 @Override 14381 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14382 mUserSwitchObservers.unregister(observer); 14383 } 14384 14385 private boolean userExists(int userId) { 14386 if (userId == 0) { 14387 return true; 14388 } 14389 UserManagerService ums = getUserManagerLocked(); 14390 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14391 } 14392 14393 int[] getUsersLocked() { 14394 UserManagerService ums = getUserManagerLocked(); 14395 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14396 } 14397 14398 UserManagerService getUserManagerLocked() { 14399 if (mUserManager == null) { 14400 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14401 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14402 } 14403 return mUserManager; 14404 } 14405 14406 private void checkValidCaller(int uid, int userId) { 14407 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14408 14409 throw new SecurityException("Caller uid=" + uid 14410 + " is not privileged to communicate with user=" + userId); 14411 } 14412 14413 private int applyUserId(int uid, int userId) { 14414 return UserHandle.getUid(userId, uid); 14415 } 14416 14417 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14418 if (info == null) return null; 14419 ApplicationInfo newInfo = new ApplicationInfo(info); 14420 newInfo.uid = applyUserId(info.uid, userId); 14421 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14422 + info.packageName; 14423 return newInfo; 14424 } 14425 14426 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14427 if (aInfo == null 14428 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14429 return aInfo; 14430 } 14431 14432 ActivityInfo info = new ActivityInfo(aInfo); 14433 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14434 return info; 14435 } 14436} 14437