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