ActivityManagerService.java revision c0bd747b0605af251ff136277f14220a5a4c9818
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.internal.widget.LockPatternUtils; 25import com.android.server.AttributeCache; 26import com.android.server.IntentResolver; 27import com.android.server.ProcessMap; 28import com.android.server.SystemServer; 29import com.android.server.Watchdog; 30import com.android.server.am.ActivityStack.ActivityState; 31import com.android.server.pm.UserManagerService; 32import com.android.server.wm.WindowManagerService; 33 34import dalvik.system.Zygote; 35 36import android.app.Activity; 37import android.app.ActivityManager; 38import android.app.ActivityManagerNative; 39import android.app.ActivityOptions; 40import android.app.ActivityThread; 41import android.app.AlertDialog; 42import android.app.AppGlobals; 43import android.app.ApplicationErrorReport; 44import android.app.Dialog; 45import android.app.IActivityController; 46import android.app.IApplicationThread; 47import android.app.IInstrumentationWatcher; 48import android.app.INotificationManager; 49import android.app.IProcessObserver; 50import android.app.IServiceConnection; 51import android.app.IStopUserCallback; 52import android.app.IThumbnailReceiver; 53import android.app.IUserSwitchObserver; 54import android.app.Instrumentation; 55import android.app.Notification; 56import android.app.NotificationManager; 57import android.app.PendingIntent; 58import android.app.backup.IBackupManager; 59import android.content.ActivityNotFoundException; 60import android.content.BroadcastReceiver; 61import android.content.ClipData; 62import android.content.ComponentCallbacks2; 63import android.content.ComponentName; 64import android.content.ContentProvider; 65import android.content.ContentResolver; 66import android.content.Context; 67import android.content.DialogInterface; 68import android.content.IContentProvider; 69import android.content.IIntentReceiver; 70import android.content.IIntentSender; 71import android.content.Intent; 72import android.content.IntentFilter; 73import android.content.IntentSender; 74import android.content.pm.ActivityInfo; 75import android.content.pm.ApplicationInfo; 76import android.content.pm.ConfigurationInfo; 77import android.content.pm.IPackageDataObserver; 78import android.content.pm.IPackageManager; 79import android.content.pm.InstrumentationInfo; 80import android.content.pm.PackageInfo; 81import android.content.pm.PackageManager; 82import android.content.pm.UserInfo; 83import android.content.pm.PackageManager.NameNotFoundException; 84import android.content.pm.PathPermission; 85import android.content.pm.ProviderInfo; 86import android.content.pm.ResolveInfo; 87import android.content.pm.ServiceInfo; 88import android.content.res.CompatibilityInfo; 89import android.content.res.Configuration; 90import android.graphics.Bitmap; 91import android.net.Proxy; 92import android.net.ProxyProperties; 93import android.net.Uri; 94import android.os.Binder; 95import android.os.Build; 96import android.os.Bundle; 97import android.os.Debug; 98import android.os.DropBoxManager; 99import android.os.Environment; 100import android.os.FileObserver; 101import android.os.FileUtils; 102import android.os.Handler; 103import android.os.IBinder; 104import android.os.IPermissionController; 105import android.os.IRemoteCallback; 106import android.os.IUserManager; 107import android.os.Looper; 108import android.os.Message; 109import android.os.Parcel; 110import android.os.ParcelFileDescriptor; 111import android.os.Process; 112import android.os.RemoteCallbackList; 113import android.os.RemoteException; 114import android.os.SELinux; 115import android.os.ServiceManager; 116import android.os.StrictMode; 117import android.os.SystemClock; 118import android.os.SystemProperties; 119import android.os.UserHandle; 120import android.provider.Settings; 121import android.text.format.Time; 122import android.util.EventLog; 123import android.util.Log; 124import android.util.Pair; 125import android.util.PrintWriterPrinter; 126import android.util.Slog; 127import android.util.SparseArray; 128import android.util.TimeUtils; 129import android.view.Gravity; 130import android.view.LayoutInflater; 131import android.view.View; 132import android.view.WindowManager; 133import android.view.WindowManagerPolicy; 134 135import java.io.BufferedInputStream; 136import java.io.BufferedOutputStream; 137import java.io.BufferedReader; 138import java.io.DataInputStream; 139import java.io.DataOutputStream; 140import java.io.File; 141import java.io.FileDescriptor; 142import java.io.FileInputStream; 143import java.io.FileNotFoundException; 144import java.io.FileOutputStream; 145import java.io.IOException; 146import java.io.InputStreamReader; 147import java.io.PrintWriter; 148import java.io.StringWriter; 149import java.lang.ref.WeakReference; 150import java.util.ArrayList; 151import java.util.Arrays; 152import java.util.Collections; 153import java.util.Comparator; 154import java.util.HashMap; 155import java.util.HashSet; 156import java.util.Iterator; 157import java.util.List; 158import java.util.Locale; 159import java.util.Map; 160import java.util.Set; 161import java.util.concurrent.atomic.AtomicBoolean; 162import java.util.concurrent.atomic.AtomicLong; 163 164public final class ActivityManagerService extends ActivityManagerNative 165 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 166 private static final String USER_DATA_DIR = "/data/user/"; 167 static final String TAG = "ActivityManager"; 168 static final String TAG_MU = "ActivityManagerServiceMU"; 169 static final boolean DEBUG = false; 170 static final boolean localLOGV = DEBUG; 171 static final boolean DEBUG_SWITCH = localLOGV || false; 172 static final boolean DEBUG_TASKS = localLOGV || false; 173 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 174 static final boolean DEBUG_PAUSE = localLOGV || false; 175 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 176 static final boolean DEBUG_TRANSITION = localLOGV || false; 177 static final boolean DEBUG_BROADCAST = localLOGV || false; 178 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 180 static final boolean DEBUG_SERVICE = localLOGV || false; 181 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 182 static final boolean DEBUG_VISBILITY = localLOGV || false; 183 static final boolean DEBUG_PROCESSES = localLOGV || false; 184 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 185 static final boolean DEBUG_CLEANUP = localLOGV || false; 186 static final boolean DEBUG_PROVIDER = localLOGV || false; 187 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 188 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 189 static final boolean DEBUG_RESULTS = localLOGV || false; 190 static final boolean DEBUG_BACKUP = localLOGV || false; 191 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 192 static final boolean DEBUG_POWER = localLOGV || false; 193 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 194 static final boolean DEBUG_MU = localLOGV || false; 195 static final boolean VALIDATE_TOKENS = false; 196 static final boolean SHOW_ACTIVITY_START_TIME = true; 197 198 // Control over CPU and battery monitoring. 199 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 200 static final boolean MONITOR_CPU_USAGE = true; 201 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 202 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 203 static final boolean MONITOR_THREAD_CPU_USAGE = false; 204 205 // The flags that are set for all calls we make to the package manager. 206 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 207 208 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 209 210 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 211 212 // Maximum number of recent tasks that we can remember. 213 static final int MAX_RECENT_TASKS = 20; 214 215 // Amount of time after a call to stopAppSwitches() during which we will 216 // prevent further untrusted switches from happening. 217 static final long APP_SWITCH_DELAY_TIME = 5*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real. 221 static final int PROC_START_TIMEOUT = 10*1000; 222 223 // How long we wait for a launched process to attach to the activity manager 224 // before we decide it's never going to come up for real, when the process was 225 // started with a wrapper for instrumentation (such as Valgrind) because it 226 // could take much longer than usual. 227 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 228 229 // How long to wait after going idle before forcing apps to GC. 230 static final int GC_TIMEOUT = 5*1000; 231 232 // The minimum amount of time between successive GC requests for a process. 233 static final int GC_MIN_INTERVAL = 60*1000; 234 235 // The rate at which we check for apps using excessive power -- 15 mins. 236 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on wake locks to start killing things. 240 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // The minimum sample duration we will allow before deciding we have 243 // enough data on CPU usage to start killing things. 244 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 245 246 // How long we allow a receiver to run before giving up on it. 247 static final int BROADCAST_FG_TIMEOUT = 10*1000; 248 static final int BROADCAST_BG_TIMEOUT = 60*1000; 249 250 // How long we wait until we timeout on key dispatching. 251 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 252 253 // How long we wait until we timeout on key dispatching during instrumentation. 254 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 255 256 // Amount of time we wait for observers to handle a user switch before 257 // giving up on them and unfreezing the screen. 258 static final int USER_SWITCH_TIMEOUT = 2*1000; 259 260 // Maximum number of users we allow to be running at a time. 261 static final int MAX_RUNNING_USERS = 3; 262 263 static final int MY_PID = Process.myPid(); 264 265 static final String[] EMPTY_STRING_ARRAY = new String[0]; 266 267 public ActivityStack mMainStack; 268 269 private final boolean mHeadless; 270 271 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 272 // default actuion automatically. Important for devices without direct input 273 // devices. 274 private boolean mShowDialogs = true; 275 276 /** 277 * Description of a request to start a new activity, which has been held 278 * due to app switches being disabled. 279 */ 280 static class PendingActivityLaunch { 281 ActivityRecord r; 282 ActivityRecord sourceRecord; 283 int startFlags; 284 } 285 286 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 287 = new ArrayList<PendingActivityLaunch>(); 288 289 290 BroadcastQueue mFgBroadcastQueue; 291 BroadcastQueue mBgBroadcastQueue; 292 // Convenient for easy iteration over the queues. Foreground is first 293 // so that dispatch of foreground broadcasts gets precedence. 294 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 295 296 BroadcastQueue broadcastQueueForIntent(Intent intent) { 297 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 298 if (DEBUG_BACKGROUND_BROADCAST) { 299 Slog.i(TAG, "Broadcast intent " + intent + " on " 300 + (isFg ? "foreground" : "background") 301 + " queue"); 302 } 303 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 304 } 305 306 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 307 for (BroadcastQueue queue : mBroadcastQueues) { 308 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 309 if (r != null) { 310 return r; 311 } 312 } 313 return null; 314 } 315 316 /** 317 * Activity we have told the window manager to have key focus. 318 */ 319 ActivityRecord mFocusedActivity = null; 320 /** 321 * List of intents that were used to start the most recent tasks. 322 */ 323 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 324 325 /** 326 * Process management. 327 */ 328 final ProcessList mProcessList = new ProcessList(); 329 330 /** 331 * All of the applications we currently have running organized by name. 332 * The keys are strings of the application package name (as 333 * returned by the package manager), and the keys are ApplicationRecord 334 * objects. 335 */ 336 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 337 338 /** 339 * The currently running isolated processes. 340 */ 341 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 342 343 /** 344 * Counter for assigning isolated process uids, to avoid frequently reusing the 345 * same ones. 346 */ 347 int mNextIsolatedProcessUid = 0; 348 349 /** 350 * The currently running heavy-weight process, if any. 351 */ 352 ProcessRecord mHeavyWeightProcess = null; 353 354 /** 355 * The last time that various processes have crashed. 356 */ 357 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 358 359 /** 360 * Set of applications that we consider to be bad, and will reject 361 * incoming broadcasts from (which the user has no control over). 362 * Processes are added to this set when they have crashed twice within 363 * a minimum amount of time; they are removed from it when they are 364 * later restarted (hopefully due to some user action). The value is the 365 * time it was added to the list. 366 */ 367 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 368 369 /** 370 * All of the processes we currently have running organized by pid. 371 * The keys are the pid running the application. 372 * 373 * <p>NOTE: This object is protected by its own lock, NOT the global 374 * activity manager lock! 375 */ 376 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 377 378 /** 379 * All of the processes that have been forced to be foreground. The key 380 * is the pid of the caller who requested it (we hold a death 381 * link on it). 382 */ 383 abstract class ForegroundToken implements IBinder.DeathRecipient { 384 int pid; 385 IBinder token; 386 } 387 final SparseArray<ForegroundToken> mForegroundProcesses 388 = new SparseArray<ForegroundToken>(); 389 390 /** 391 * List of records for processes that someone had tried to start before the 392 * system was ready. We don't start them at that point, but ensure they 393 * are started by the time booting is complete. 394 */ 395 final ArrayList<ProcessRecord> mProcessesOnHold 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * List of persistent applications that are in the process 400 * of being started. 401 */ 402 final ArrayList<ProcessRecord> mPersistentStartingProcesses 403 = new ArrayList<ProcessRecord>(); 404 405 /** 406 * Processes that are being forcibly torn down. 407 */ 408 final ArrayList<ProcessRecord> mRemovedProcesses 409 = new ArrayList<ProcessRecord>(); 410 411 /** 412 * List of running applications, sorted by recent usage. 413 * The first entry in the list is the least recently used. 414 * It contains ApplicationRecord objects. This list does NOT include 415 * any persistent application records (since we never want to exit them). 416 */ 417 final ArrayList<ProcessRecord> mLruProcesses 418 = new ArrayList<ProcessRecord>(); 419 420 /** 421 * List of processes that should gc as soon as things are idle. 422 */ 423 final ArrayList<ProcessRecord> mProcessesToGc 424 = new ArrayList<ProcessRecord>(); 425 426 /** 427 * This is the process holding what we currently consider to be 428 * the "home" activity. 429 */ 430 ProcessRecord mHomeProcess; 431 432 /** 433 * This is the process holding the activity the user last visited that 434 * is in a different process from the one they are currently in. 435 */ 436 ProcessRecord mPreviousProcess; 437 438 /** 439 * The time at which the previous process was last visible. 440 */ 441 long mPreviousProcessVisibleTime; 442 443 /** 444 * Which uses have been started, so are allowed to run code. 445 */ 446 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 447 448 /** 449 * LRU list of history of current users. Most recently current is at the end. 450 */ 451 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 452 453 /** 454 * Constant array of the users that are currently started. 455 */ 456 int[] mStartedUserArray = new int[] { 0 }; 457 458 /** 459 * Registered observers of the user switching mechanics. 460 */ 461 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 462 = new RemoteCallbackList<IUserSwitchObserver>(); 463 464 /** 465 * Currently active user switch. 466 */ 467 Object mCurUserSwitchCallback; 468 469 /** 470 * Packages that the user has asked to have run in screen size 471 * compatibility mode instead of filling the screen. 472 */ 473 final CompatModePackages mCompatModePackages; 474 475 /** 476 * Set of PendingResultRecord objects that are currently active. 477 */ 478 final HashSet mPendingResultRecords = new HashSet(); 479 480 /** 481 * Set of IntentSenderRecord objects that are currently active. 482 */ 483 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 484 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 485 486 /** 487 * Fingerprints (hashCode()) of stack traces that we've 488 * already logged DropBox entries for. Guarded by itself. If 489 * something (rogue user app) forces this over 490 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 491 */ 492 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 493 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 494 495 /** 496 * Strict Mode background batched logging state. 497 * 498 * The string buffer is guarded by itself, and its lock is also 499 * used to determine if another batched write is already 500 * in-flight. 501 */ 502 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 503 504 /** 505 * Keeps track of all IIntentReceivers that have been registered for 506 * broadcasts. Hash keys are the receiver IBinder, hash value is 507 * a ReceiverList. 508 */ 509 final HashMap mRegisteredReceivers = new HashMap(); 510 511 /** 512 * Resolver for broadcast intents to registered receivers. 513 * Holds BroadcastFilter (subclass of IntentFilter). 514 */ 515 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 516 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 517 @Override 518 protected boolean allowFilterResult( 519 BroadcastFilter filter, List<BroadcastFilter> dest) { 520 IBinder target = filter.receiverList.receiver.asBinder(); 521 for (int i=dest.size()-1; i>=0; i--) { 522 if (dest.get(i).receiverList.receiver.asBinder() == target) { 523 return false; 524 } 525 } 526 return true; 527 } 528 529 @Override 530 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 531 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 532 || userId == filter.owningUserId) { 533 return super.newResult(filter, match, userId); 534 } 535 return null; 536 } 537 538 @Override 539 protected BroadcastFilter[] newArray(int size) { 540 return new BroadcastFilter[size]; 541 } 542 543 @Override 544 protected String packageForFilter(BroadcastFilter filter) { 545 return filter.packageName; 546 } 547 }; 548 549 /** 550 * State of all active sticky broadcasts per user. Keys are the action of the 551 * sticky Intent, values are an ArrayList of all broadcasted intents with 552 * that action (which should usually be one). The SparseArray is keyed 553 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 554 * for stickies that are sent to all users. 555 */ 556 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 557 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 558 559 final ActiveServices mServices; 560 561 /** 562 * Backup/restore process management 563 */ 564 String mBackupAppName = null; 565 BackupRecord mBackupTarget = null; 566 567 /** 568 * List of PendingThumbnailsRecord objects of clients who are still 569 * waiting to receive all of the thumbnails for a task. 570 */ 571 final ArrayList mPendingThumbnails = new ArrayList(); 572 573 /** 574 * List of HistoryRecord objects that have been finished and must 575 * still report back to a pending thumbnail receiver. 576 */ 577 final ArrayList mCancelledThumbnails = new ArrayList(); 578 579 final ProviderMap mProviderMap; 580 581 /** 582 * List of content providers who have clients waiting for them. The 583 * application is currently being launched and the provider will be 584 * removed from this list once it is published. 585 */ 586 final ArrayList<ContentProviderRecord> mLaunchingProviders 587 = new ArrayList<ContentProviderRecord>(); 588 589 /** 590 * Global set of specific Uri permissions that have been granted. 591 */ 592 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 593 = new SparseArray<HashMap<Uri, UriPermission>>(); 594 595 CoreSettingsObserver mCoreSettingsObserver; 596 597 /** 598 * Thread-local storage used to carry caller permissions over through 599 * indirect content-provider access. 600 * @see #ActivityManagerService.openContentUri() 601 */ 602 private class Identity { 603 public int pid; 604 public int uid; 605 606 Identity(int _pid, int _uid) { 607 pid = _pid; 608 uid = _uid; 609 } 610 } 611 612 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 613 614 /** 615 * All information we have collected about the runtime performance of 616 * any user id that can impact battery performance. 617 */ 618 final BatteryStatsService mBatteryStatsService; 619 620 /** 621 * information about component usage 622 */ 623 final UsageStatsService mUsageStatsService; 624 625 /** 626 * Current configuration information. HistoryRecord objects are given 627 * a reference to this object to indicate which configuration they are 628 * currently running in, so this object must be kept immutable. 629 */ 630 Configuration mConfiguration = new Configuration(); 631 632 /** 633 * Current sequencing integer of the configuration, for skipping old 634 * configurations. 635 */ 636 int mConfigurationSeq = 0; 637 638 /** 639 * Hardware-reported OpenGLES version. 640 */ 641 final int GL_ES_VERSION; 642 643 /** 644 * List of initialization arguments to pass to all processes when binding applications to them. 645 * For example, references to the commonly used services. 646 */ 647 HashMap<String, IBinder> mAppBindArgs; 648 649 /** 650 * Temporary to avoid allocations. Protected by main lock. 651 */ 652 final StringBuilder mStringBuilder = new StringBuilder(256); 653 654 /** 655 * Used to control how we initialize the service. 656 */ 657 boolean mStartRunning = false; 658 ComponentName mTopComponent; 659 String mTopAction; 660 String mTopData; 661 boolean mProcessesReady = false; 662 boolean mSystemReady = false; 663 boolean mBooting = false; 664 boolean mWaitingUpdate = false; 665 boolean mDidUpdate = false; 666 boolean mOnBattery = false; 667 boolean mLaunchWarningShown = false; 668 669 Context mContext; 670 671 int mFactoryTest; 672 673 boolean mCheckedForSetup; 674 675 /** 676 * The time at which we will allow normal application switches again, 677 * after a call to {@link #stopAppSwitches()}. 678 */ 679 long mAppSwitchesAllowedTime; 680 681 /** 682 * This is set to true after the first switch after mAppSwitchesAllowedTime 683 * is set; any switches after that will clear the time. 684 */ 685 boolean mDidAppSwitch; 686 687 /** 688 * Last time (in realtime) at which we checked for power usage. 689 */ 690 long mLastPowerCheckRealtime; 691 692 /** 693 * Last time (in uptime) at which we checked for power usage. 694 */ 695 long mLastPowerCheckUptime; 696 697 /** 698 * Set while we are wanting to sleep, to prevent any 699 * activities from being started/resumed. 700 */ 701 boolean mSleeping = false; 702 703 /** 704 * State of external calls telling us if the device is asleep. 705 */ 706 boolean mWentToSleep = false; 707 708 /** 709 * State of external call telling us if the lock screen is shown. 710 */ 711 boolean mLockScreenShown = false; 712 713 /** 714 * Set if we are shutting down the system, similar to sleeping. 715 */ 716 boolean mShuttingDown = false; 717 718 /** 719 * Task identifier that activities are currently being started 720 * in. Incremented each time a new task is created. 721 * todo: Replace this with a TokenSpace class that generates non-repeating 722 * integers that won't wrap. 723 */ 724 int mCurTask = 1; 725 726 /** 727 * Current sequence id for oom_adj computation traversal. 728 */ 729 int mAdjSeq = 0; 730 731 /** 732 * Current sequence id for process LRU updating. 733 */ 734 int mLruSeq = 0; 735 736 /** 737 * Keep track of the non-hidden/empty process we last found, to help 738 * determine how to distribute hidden/empty processes next time. 739 */ 740 int mNumNonHiddenProcs = 0; 741 742 /** 743 * Keep track of the number of hidden procs, to balance oom adj 744 * distribution between those and empty procs. 745 */ 746 int mNumHiddenProcs = 0; 747 748 /** 749 * Keep track of the number of service processes we last found, to 750 * determine on the next iteration which should be B services. 751 */ 752 int mNumServiceProcs = 0; 753 int mNewNumServiceProcs = 0; 754 755 /** 756 * System monitoring: number of processes that died since the last 757 * N procs were started. 758 */ 759 int[] mProcDeaths = new int[20]; 760 761 /** 762 * This is set if we had to do a delayed dexopt of an app before launching 763 * it, to increasing the ANR timeouts in that case. 764 */ 765 boolean mDidDexOpt; 766 767 String mDebugApp = null; 768 boolean mWaitForDebugger = false; 769 boolean mDebugTransient = false; 770 String mOrigDebugApp = null; 771 boolean mOrigWaitForDebugger = false; 772 boolean mAlwaysFinishActivities = false; 773 IActivityController mController = null; 774 String mProfileApp = null; 775 ProcessRecord mProfileProc = null; 776 String mProfileFile; 777 ParcelFileDescriptor mProfileFd; 778 int mProfileType = 0; 779 boolean mAutoStopProfiler = false; 780 String mOpenGlTraceApp = null; 781 782 static class ProcessChangeItem { 783 static final int CHANGE_ACTIVITIES = 1<<0; 784 static final int CHANGE_IMPORTANCE= 1<<1; 785 int changes; 786 int uid; 787 int pid; 788 int importance; 789 boolean foregroundActivities; 790 } 791 792 final RemoteCallbackList<IProcessObserver> mProcessObservers 793 = new RemoteCallbackList<IProcessObserver>(); 794 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 795 796 final ArrayList<ProcessChangeItem> mPendingProcessChanges 797 = new ArrayList<ProcessChangeItem>(); 798 final ArrayList<ProcessChangeItem> mAvailProcessChanges 799 = new ArrayList<ProcessChangeItem>(); 800 801 /** 802 * Callback of last caller to {@link #requestPss}. 803 */ 804 Runnable mRequestPssCallback; 805 806 /** 807 * Remaining processes for which we are waiting results from the last 808 * call to {@link #requestPss}. 809 */ 810 final ArrayList<ProcessRecord> mRequestPssList 811 = new ArrayList<ProcessRecord>(); 812 813 /** 814 * Runtime statistics collection thread. This object's lock is used to 815 * protect all related state. 816 */ 817 final Thread mProcessStatsThread; 818 819 /** 820 * Used to collect process stats when showing not responding dialog. 821 * Protected by mProcessStatsThread. 822 */ 823 final ProcessStats mProcessStats = new ProcessStats( 824 MONITOR_THREAD_CPU_USAGE); 825 final AtomicLong mLastCpuTime = new AtomicLong(0); 826 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 827 828 long mLastWriteTime = 0; 829 830 /** 831 * Set to true after the system has finished booting. 832 */ 833 boolean mBooted = false; 834 835 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 836 int mProcessLimitOverride = -1; 837 838 WindowManagerService mWindowManager; 839 840 static ActivityManagerService mSelf; 841 static ActivityThread mSystemThread; 842 843 private int mCurrentUserId = 0; 844 private int[] mCurrentUserArray = new int[] { 0 }; 845 private UserManagerService mUserManager; 846 847 private final class AppDeathRecipient implements IBinder.DeathRecipient { 848 final ProcessRecord mApp; 849 final int mPid; 850 final IApplicationThread mAppThread; 851 852 AppDeathRecipient(ProcessRecord app, int pid, 853 IApplicationThread thread) { 854 if (localLOGV) Slog.v( 855 TAG, "New death recipient " + this 856 + " for thread " + thread.asBinder()); 857 mApp = app; 858 mPid = pid; 859 mAppThread = thread; 860 } 861 862 public void binderDied() { 863 if (localLOGV) Slog.v( 864 TAG, "Death received in " + this 865 + " for thread " + mAppThread.asBinder()); 866 synchronized(ActivityManagerService.this) { 867 appDiedLocked(mApp, mPid, mAppThread); 868 } 869 } 870 } 871 872 static final int SHOW_ERROR_MSG = 1; 873 static final int SHOW_NOT_RESPONDING_MSG = 2; 874 static final int SHOW_FACTORY_ERROR_MSG = 3; 875 static final int UPDATE_CONFIGURATION_MSG = 4; 876 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 877 static final int WAIT_FOR_DEBUGGER_MSG = 6; 878 static final int SERVICE_TIMEOUT_MSG = 12; 879 static final int UPDATE_TIME_ZONE = 13; 880 static final int SHOW_UID_ERROR_MSG = 14; 881 static final int IM_FEELING_LUCKY_MSG = 15; 882 static final int PROC_START_TIMEOUT_MSG = 20; 883 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 884 static final int KILL_APPLICATION_MSG = 22; 885 static final int FINALIZE_PENDING_INTENT_MSG = 23; 886 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 887 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 888 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 889 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 890 static final int CLEAR_DNS_CACHE = 28; 891 static final int UPDATE_HTTP_PROXY = 29; 892 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 893 static final int DISPATCH_PROCESSES_CHANGED = 31; 894 static final int DISPATCH_PROCESS_DIED = 32; 895 static final int REPORT_MEM_USAGE = 33; 896 static final int REPORT_USER_SWITCH_MSG = 34; 897 static final int CONTINUE_USER_SWITCH_MSG = 35; 898 static final int USER_SWITCH_TIMEOUT_MSG = 36; 899 900 static final int FIRST_ACTIVITY_STACK_MSG = 100; 901 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 902 static final int FIRST_COMPAT_MODE_MSG = 300; 903 904 AlertDialog mUidAlert; 905 CompatModeDialog mCompatModeDialog; 906 long mLastMemUsageReportTime = 0; 907 908 final Handler mHandler = new Handler() { 909 //public Handler() { 910 // if (localLOGV) Slog.v(TAG, "Handler started!"); 911 //} 912 913 public void handleMessage(Message msg) { 914 switch (msg.what) { 915 case SHOW_ERROR_MSG: { 916 HashMap data = (HashMap) msg.obj; 917 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 918 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 919 synchronized (ActivityManagerService.this) { 920 ProcessRecord proc = (ProcessRecord)data.get("app"); 921 AppErrorResult res = (AppErrorResult) data.get("result"); 922 if (proc != null && proc.crashDialog != null) { 923 Slog.e(TAG, "App already has crash dialog: " + proc); 924 if (res != null) { 925 res.set(0); 926 } 927 return; 928 } 929 if (!showBackground && UserHandle.getAppId(proc.uid) 930 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 931 && proc.pid != MY_PID) { 932 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 933 if (res != null) { 934 res.set(0); 935 } 936 return; 937 } 938 if (mShowDialogs && !mSleeping && !mShuttingDown) { 939 Dialog d = new AppErrorDialog(mContext, 940 ActivityManagerService.this, res, proc); 941 d.show(); 942 proc.crashDialog = d; 943 } else { 944 // The device is asleep, so just pretend that the user 945 // saw a crash dialog and hit "force quit". 946 if (res != null) { 947 res.set(0); 948 } 949 } 950 } 951 952 ensureBootCompleted(); 953 } break; 954 case SHOW_NOT_RESPONDING_MSG: { 955 synchronized (ActivityManagerService.this) { 956 HashMap data = (HashMap) msg.obj; 957 ProcessRecord proc = (ProcessRecord)data.get("app"); 958 if (proc != null && proc.anrDialog != null) { 959 Slog.e(TAG, "App already has anr dialog: " + proc); 960 return; 961 } 962 963 Intent intent = new Intent("android.intent.action.ANR"); 964 if (!mProcessesReady) { 965 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 966 | Intent.FLAG_RECEIVER_FOREGROUND); 967 } 968 broadcastIntentLocked(null, null, intent, 969 null, null, 0, null, null, null, 970 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 971 972 if (mShowDialogs) { 973 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 974 mContext, proc, (ActivityRecord)data.get("activity"), 975 msg.arg1 != 0); 976 d.show(); 977 proc.anrDialog = d; 978 } else { 979 // Just kill the app if there is no dialog to be shown. 980 killAppAtUsersRequest(proc, null); 981 } 982 } 983 984 ensureBootCompleted(); 985 } break; 986 case SHOW_STRICT_MODE_VIOLATION_MSG: { 987 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 988 synchronized (ActivityManagerService.this) { 989 ProcessRecord proc = (ProcessRecord) data.get("app"); 990 if (proc == null) { 991 Slog.e(TAG, "App not found when showing strict mode dialog."); 992 break; 993 } 994 if (proc.crashDialog != null) { 995 Slog.e(TAG, "App already has strict mode dialog: " + proc); 996 return; 997 } 998 AppErrorResult res = (AppErrorResult) data.get("result"); 999 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1000 Dialog d = new StrictModeViolationDialog(mContext, 1001 ActivityManagerService.this, res, proc); 1002 d.show(); 1003 proc.crashDialog = d; 1004 } else { 1005 // The device is asleep, so just pretend that the user 1006 // saw a crash dialog and hit "force quit". 1007 res.set(0); 1008 } 1009 } 1010 ensureBootCompleted(); 1011 } break; 1012 case SHOW_FACTORY_ERROR_MSG: { 1013 Dialog d = new FactoryErrorDialog( 1014 mContext, msg.getData().getCharSequence("msg")); 1015 d.show(); 1016 ensureBootCompleted(); 1017 } break; 1018 case UPDATE_CONFIGURATION_MSG: { 1019 final ContentResolver resolver = mContext.getContentResolver(); 1020 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1021 } break; 1022 case GC_BACKGROUND_PROCESSES_MSG: { 1023 synchronized (ActivityManagerService.this) { 1024 performAppGcsIfAppropriateLocked(); 1025 } 1026 } break; 1027 case WAIT_FOR_DEBUGGER_MSG: { 1028 synchronized (ActivityManagerService.this) { 1029 ProcessRecord app = (ProcessRecord)msg.obj; 1030 if (msg.arg1 != 0) { 1031 if (!app.waitedForDebugger) { 1032 Dialog d = new AppWaitingForDebuggerDialog( 1033 ActivityManagerService.this, 1034 mContext, app); 1035 app.waitDialog = d; 1036 app.waitedForDebugger = true; 1037 d.show(); 1038 } 1039 } else { 1040 if (app.waitDialog != null) { 1041 app.waitDialog.dismiss(); 1042 app.waitDialog = null; 1043 } 1044 } 1045 } 1046 } break; 1047 case SERVICE_TIMEOUT_MSG: { 1048 if (mDidDexOpt) { 1049 mDidDexOpt = false; 1050 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1051 nmsg.obj = msg.obj; 1052 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1053 return; 1054 } 1055 mServices.serviceTimeout((ProcessRecord)msg.obj); 1056 } break; 1057 case UPDATE_TIME_ZONE: { 1058 synchronized (ActivityManagerService.this) { 1059 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1060 ProcessRecord r = mLruProcesses.get(i); 1061 if (r.thread != null) { 1062 try { 1063 r.thread.updateTimeZone(); 1064 } catch (RemoteException ex) { 1065 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1066 } 1067 } 1068 } 1069 } 1070 } break; 1071 case CLEAR_DNS_CACHE: { 1072 synchronized (ActivityManagerService.this) { 1073 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1074 ProcessRecord r = mLruProcesses.get(i); 1075 if (r.thread != null) { 1076 try { 1077 r.thread.clearDnsCache(); 1078 } catch (RemoteException ex) { 1079 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1080 } 1081 } 1082 } 1083 } 1084 } break; 1085 case UPDATE_HTTP_PROXY: { 1086 ProxyProperties proxy = (ProxyProperties)msg.obj; 1087 String host = ""; 1088 String port = ""; 1089 String exclList = ""; 1090 if (proxy != null) { 1091 host = proxy.getHost(); 1092 port = Integer.toString(proxy.getPort()); 1093 exclList = proxy.getExclusionList(); 1094 } 1095 synchronized (ActivityManagerService.this) { 1096 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1097 ProcessRecord r = mLruProcesses.get(i); 1098 if (r.thread != null) { 1099 try { 1100 r.thread.setHttpProxy(host, port, exclList); 1101 } catch (RemoteException ex) { 1102 Slog.w(TAG, "Failed to update http proxy for: " + 1103 r.info.processName); 1104 } 1105 } 1106 } 1107 } 1108 } break; 1109 case SHOW_UID_ERROR_MSG: { 1110 String title = "System UIDs Inconsistent"; 1111 String text = "UIDs on the system are inconsistent, you need to wipe your" 1112 + " data partition or your device will be unstable."; 1113 Log.e(TAG, title + ": " + text); 1114 if (mShowDialogs) { 1115 // XXX This is a temporary dialog, no need to localize. 1116 AlertDialog d = new BaseErrorDialog(mContext); 1117 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1118 d.setCancelable(false); 1119 d.setTitle(title); 1120 d.setMessage(text); 1121 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1122 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1123 mUidAlert = d; 1124 d.show(); 1125 } 1126 } break; 1127 case IM_FEELING_LUCKY_MSG: { 1128 if (mUidAlert != null) { 1129 mUidAlert.dismiss(); 1130 mUidAlert = null; 1131 } 1132 } break; 1133 case PROC_START_TIMEOUT_MSG: { 1134 if (mDidDexOpt) { 1135 mDidDexOpt = false; 1136 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1137 nmsg.obj = msg.obj; 1138 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1139 return; 1140 } 1141 ProcessRecord app = (ProcessRecord)msg.obj; 1142 synchronized (ActivityManagerService.this) { 1143 processStartTimedOutLocked(app); 1144 } 1145 } break; 1146 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1147 synchronized (ActivityManagerService.this) { 1148 doPendingActivityLaunchesLocked(true); 1149 } 1150 } break; 1151 case KILL_APPLICATION_MSG: { 1152 synchronized (ActivityManagerService.this) { 1153 int appid = msg.arg1; 1154 boolean restart = (msg.arg2 == 1); 1155 String pkg = (String) msg.obj; 1156 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1157 UserHandle.USER_ALL); 1158 } 1159 } break; 1160 case FINALIZE_PENDING_INTENT_MSG: { 1161 ((PendingIntentRecord)msg.obj).completeFinalize(); 1162 } break; 1163 case POST_HEAVY_NOTIFICATION_MSG: { 1164 INotificationManager inm = NotificationManager.getService(); 1165 if (inm == null) { 1166 return; 1167 } 1168 1169 ActivityRecord root = (ActivityRecord)msg.obj; 1170 ProcessRecord process = root.app; 1171 if (process == null) { 1172 return; 1173 } 1174 1175 try { 1176 Context context = mContext.createPackageContext(process.info.packageName, 0); 1177 String text = mContext.getString(R.string.heavy_weight_notification, 1178 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1179 Notification notification = new Notification(); 1180 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1181 notification.when = 0; 1182 notification.flags = Notification.FLAG_ONGOING_EVENT; 1183 notification.tickerText = text; 1184 notification.defaults = 0; // please be quiet 1185 notification.sound = null; 1186 notification.vibrate = null; 1187 notification.setLatestEventInfo(context, text, 1188 mContext.getText(R.string.heavy_weight_notification_detail), 1189 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1190 PendingIntent.FLAG_CANCEL_CURRENT, null, 1191 new UserHandle(root.userId))); 1192 1193 try { 1194 int[] outId = new int[1]; 1195 inm.enqueueNotificationWithTag("android", null, 1196 R.string.heavy_weight_notification, 1197 notification, outId, root.userId); 1198 } catch (RuntimeException e) { 1199 Slog.w(ActivityManagerService.TAG, 1200 "Error showing notification for heavy-weight app", e); 1201 } catch (RemoteException e) { 1202 } 1203 } catch (NameNotFoundException e) { 1204 Slog.w(TAG, "Unable to create context for heavy notification", e); 1205 } 1206 } break; 1207 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1208 INotificationManager inm = NotificationManager.getService(); 1209 if (inm == null) { 1210 return; 1211 } 1212 try { 1213 inm.cancelNotificationWithTag("android", null, 1214 R.string.heavy_weight_notification, msg.arg1); 1215 } catch (RuntimeException e) { 1216 Slog.w(ActivityManagerService.TAG, 1217 "Error canceling notification for service", e); 1218 } catch (RemoteException e) { 1219 } 1220 } break; 1221 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1222 synchronized (ActivityManagerService.this) { 1223 checkExcessivePowerUsageLocked(true); 1224 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1225 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1226 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1227 } 1228 } break; 1229 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1230 synchronized (ActivityManagerService.this) { 1231 ActivityRecord ar = (ActivityRecord)msg.obj; 1232 if (mCompatModeDialog != null) { 1233 if (mCompatModeDialog.mAppInfo.packageName.equals( 1234 ar.info.applicationInfo.packageName)) { 1235 return; 1236 } 1237 mCompatModeDialog.dismiss(); 1238 mCompatModeDialog = null; 1239 } 1240 if (ar != null && false) { 1241 if (mCompatModePackages.getPackageAskCompatModeLocked( 1242 ar.packageName)) { 1243 int mode = mCompatModePackages.computeCompatModeLocked( 1244 ar.info.applicationInfo); 1245 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1246 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1247 mCompatModeDialog = new CompatModeDialog( 1248 ActivityManagerService.this, mContext, 1249 ar.info.applicationInfo); 1250 mCompatModeDialog.show(); 1251 } 1252 } 1253 } 1254 } 1255 break; 1256 } 1257 case DISPATCH_PROCESSES_CHANGED: { 1258 dispatchProcessesChanged(); 1259 break; 1260 } 1261 case DISPATCH_PROCESS_DIED: { 1262 final int pid = msg.arg1; 1263 final int uid = msg.arg2; 1264 dispatchProcessDied(pid, uid); 1265 break; 1266 } 1267 case REPORT_MEM_USAGE: { 1268 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1269 if (!isDebuggable) { 1270 return; 1271 } 1272 synchronized (ActivityManagerService.this) { 1273 long now = SystemClock.uptimeMillis(); 1274 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1275 // Don't report more than every 5 minutes to somewhat 1276 // avoid spamming. 1277 return; 1278 } 1279 mLastMemUsageReportTime = now; 1280 } 1281 Thread thread = new Thread() { 1282 @Override public void run() { 1283 StringBuilder dropBuilder = new StringBuilder(1024); 1284 StringBuilder logBuilder = new StringBuilder(1024); 1285 StringWriter oomSw = new StringWriter(); 1286 PrintWriter oomPw = new PrintWriter(oomSw); 1287 StringWriter catSw = new StringWriter(); 1288 PrintWriter catPw = new PrintWriter(catSw); 1289 String[] emptyArgs = new String[] { }; 1290 StringBuilder tag = new StringBuilder(128); 1291 StringBuilder stack = new StringBuilder(128); 1292 tag.append("Low on memory -- "); 1293 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1294 tag, stack); 1295 dropBuilder.append(stack); 1296 dropBuilder.append('\n'); 1297 dropBuilder.append('\n'); 1298 String oomString = oomSw.toString(); 1299 dropBuilder.append(oomString); 1300 dropBuilder.append('\n'); 1301 logBuilder.append(oomString); 1302 try { 1303 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1304 "procrank", }); 1305 final InputStreamReader converter = new InputStreamReader( 1306 proc.getInputStream()); 1307 BufferedReader in = new BufferedReader(converter); 1308 String line; 1309 while (true) { 1310 line = in.readLine(); 1311 if (line == null) { 1312 break; 1313 } 1314 if (line.length() > 0) { 1315 logBuilder.append(line); 1316 logBuilder.append('\n'); 1317 } 1318 dropBuilder.append(line); 1319 dropBuilder.append('\n'); 1320 } 1321 converter.close(); 1322 } catch (IOException e) { 1323 } 1324 synchronized (ActivityManagerService.this) { 1325 catPw.println(); 1326 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1327 catPw.println(); 1328 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1329 false, false, null); 1330 catPw.println(); 1331 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1332 } 1333 dropBuilder.append(catSw.toString()); 1334 addErrorToDropBox("lowmem", null, "system_server", null, 1335 null, tag.toString(), dropBuilder.toString(), null, null); 1336 Slog.i(TAG, logBuilder.toString()); 1337 synchronized (ActivityManagerService.this) { 1338 long now = SystemClock.uptimeMillis(); 1339 if (mLastMemUsageReportTime < now) { 1340 mLastMemUsageReportTime = now; 1341 } 1342 } 1343 } 1344 }; 1345 thread.start(); 1346 break; 1347 } 1348 case REPORT_USER_SWITCH_MSG: { 1349 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1350 break; 1351 } 1352 case CONTINUE_USER_SWITCH_MSG: { 1353 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1354 break; 1355 } 1356 case USER_SWITCH_TIMEOUT_MSG: { 1357 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1358 break; 1359 } 1360 } 1361 } 1362 }; 1363 1364 public static void setSystemProcess() { 1365 try { 1366 ActivityManagerService m = mSelf; 1367 1368 ServiceManager.addService("activity", m, true); 1369 ServiceManager.addService("meminfo", new MemBinder(m)); 1370 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1371 ServiceManager.addService("dbinfo", new DbBinder(m)); 1372 if (MONITOR_CPU_USAGE) { 1373 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1374 } 1375 ServiceManager.addService("permission", new PermissionController(m)); 1376 1377 ApplicationInfo info = 1378 mSelf.mContext.getPackageManager().getApplicationInfo( 1379 "android", STOCK_PM_FLAGS); 1380 mSystemThread.installSystemApplicationInfo(info); 1381 1382 synchronized (mSelf) { 1383 ProcessRecord app = mSelf.newProcessRecordLocked( 1384 mSystemThread.getApplicationThread(), info, 1385 info.processName, false); 1386 app.persistent = true; 1387 app.pid = MY_PID; 1388 app.maxAdj = ProcessList.SYSTEM_ADJ; 1389 mSelf.mProcessNames.put(app.processName, app.uid, app); 1390 synchronized (mSelf.mPidsSelfLocked) { 1391 mSelf.mPidsSelfLocked.put(app.pid, app); 1392 } 1393 mSelf.updateLruProcessLocked(app, true); 1394 } 1395 } catch (PackageManager.NameNotFoundException e) { 1396 throw new RuntimeException( 1397 "Unable to find android system package", e); 1398 } 1399 } 1400 1401 public void setWindowManager(WindowManagerService wm) { 1402 mWindowManager = wm; 1403 } 1404 1405 public static final Context main(int factoryTest) { 1406 AThread thr = new AThread(); 1407 thr.start(); 1408 1409 synchronized (thr) { 1410 while (thr.mService == null) { 1411 try { 1412 thr.wait(); 1413 } catch (InterruptedException e) { 1414 } 1415 } 1416 } 1417 1418 ActivityManagerService m = thr.mService; 1419 mSelf = m; 1420 ActivityThread at = ActivityThread.systemMain(); 1421 mSystemThread = at; 1422 Context context = at.getSystemContext(); 1423 context.setTheme(android.R.style.Theme_Holo); 1424 m.mContext = context; 1425 m.mFactoryTest = factoryTest; 1426 m.mMainStack = new ActivityStack(m, context, true); 1427 1428 m.mBatteryStatsService.publish(context); 1429 m.mUsageStatsService.publish(context); 1430 1431 synchronized (thr) { 1432 thr.mReady = true; 1433 thr.notifyAll(); 1434 } 1435 1436 m.startRunning(null, null, null, null); 1437 1438 return context; 1439 } 1440 1441 public static ActivityManagerService self() { 1442 return mSelf; 1443 } 1444 1445 static class AThread extends Thread { 1446 ActivityManagerService mService; 1447 boolean mReady = false; 1448 1449 public AThread() { 1450 super("ActivityManager"); 1451 } 1452 1453 public void run() { 1454 Looper.prepare(); 1455 1456 android.os.Process.setThreadPriority( 1457 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1458 android.os.Process.setCanSelfBackground(false); 1459 1460 ActivityManagerService m = new ActivityManagerService(); 1461 1462 synchronized (this) { 1463 mService = m; 1464 notifyAll(); 1465 } 1466 1467 synchronized (this) { 1468 while (!mReady) { 1469 try { 1470 wait(); 1471 } catch (InterruptedException e) { 1472 } 1473 } 1474 } 1475 1476 // For debug builds, log event loop stalls to dropbox for analysis. 1477 if (StrictMode.conditionallyEnableDebugLogging()) { 1478 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1479 } 1480 1481 Looper.loop(); 1482 } 1483 } 1484 1485 static class MemBinder extends Binder { 1486 ActivityManagerService mActivityManagerService; 1487 MemBinder(ActivityManagerService activityManagerService) { 1488 mActivityManagerService = activityManagerService; 1489 } 1490 1491 @Override 1492 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1493 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1494 != PackageManager.PERMISSION_GRANTED) { 1495 pw.println("Permission Denial: can't dump meminfo from from pid=" 1496 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1497 + " without permission " + android.Manifest.permission.DUMP); 1498 return; 1499 } 1500 1501 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1502 false, null, null, null); 1503 } 1504 } 1505 1506 static class GraphicsBinder extends Binder { 1507 ActivityManagerService mActivityManagerService; 1508 GraphicsBinder(ActivityManagerService activityManagerService) { 1509 mActivityManagerService = activityManagerService; 1510 } 1511 1512 @Override 1513 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1514 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1515 != PackageManager.PERMISSION_GRANTED) { 1516 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1517 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1518 + " without permission " + android.Manifest.permission.DUMP); 1519 return; 1520 } 1521 1522 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1523 } 1524 } 1525 1526 static class DbBinder extends Binder { 1527 ActivityManagerService mActivityManagerService; 1528 DbBinder(ActivityManagerService activityManagerService) { 1529 mActivityManagerService = activityManagerService; 1530 } 1531 1532 @Override 1533 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1534 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1535 != PackageManager.PERMISSION_GRANTED) { 1536 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1537 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1538 + " without permission " + android.Manifest.permission.DUMP); 1539 return; 1540 } 1541 1542 mActivityManagerService.dumpDbInfo(fd, pw, args); 1543 } 1544 } 1545 1546 static class CpuBinder extends Binder { 1547 ActivityManagerService mActivityManagerService; 1548 CpuBinder(ActivityManagerService activityManagerService) { 1549 mActivityManagerService = activityManagerService; 1550 } 1551 1552 @Override 1553 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1554 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1555 != PackageManager.PERMISSION_GRANTED) { 1556 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1557 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1558 + " without permission " + android.Manifest.permission.DUMP); 1559 return; 1560 } 1561 1562 synchronized (mActivityManagerService.mProcessStatsThread) { 1563 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1564 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1565 SystemClock.uptimeMillis())); 1566 } 1567 } 1568 } 1569 1570 private ActivityManagerService() { 1571 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1572 1573 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1574 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1575 mBroadcastQueues[0] = mFgBroadcastQueue; 1576 mBroadcastQueues[1] = mBgBroadcastQueue; 1577 1578 mServices = new ActiveServices(this); 1579 mProviderMap = new ProviderMap(this); 1580 1581 File dataDir = Environment.getDataDirectory(); 1582 File systemDir = new File(dataDir, "system"); 1583 systemDir.mkdirs(); 1584 mBatteryStatsService = new BatteryStatsService(new File( 1585 systemDir, "batterystats.bin").toString()); 1586 mBatteryStatsService.getActiveStatistics().readLocked(); 1587 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1588 mOnBattery = DEBUG_POWER ? true 1589 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1590 mBatteryStatsService.getActiveStatistics().setCallback(this); 1591 1592 mUsageStatsService = new UsageStatsService(new File( 1593 systemDir, "usagestats").toString()); 1594 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1595 1596 // User 0 is the first and only user that runs at boot. 1597 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1598 mUserLru.add(Integer.valueOf(0)); 1599 updateStartedUserArrayLocked(); 1600 1601 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1602 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1603 1604 mConfiguration.setToDefaults(); 1605 mConfiguration.setLocale(Locale.getDefault()); 1606 1607 mConfigurationSeq = mConfiguration.seq = 1; 1608 mProcessStats.init(); 1609 1610 mCompatModePackages = new CompatModePackages(this, systemDir); 1611 1612 // Add ourself to the Watchdog monitors. 1613 Watchdog.getInstance().addMonitor(this); 1614 1615 mProcessStatsThread = new Thread("ProcessStats") { 1616 public void run() { 1617 while (true) { 1618 try { 1619 try { 1620 synchronized(this) { 1621 final long now = SystemClock.uptimeMillis(); 1622 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1623 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1624 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1625 // + ", write delay=" + nextWriteDelay); 1626 if (nextWriteDelay < nextCpuDelay) { 1627 nextCpuDelay = nextWriteDelay; 1628 } 1629 if (nextCpuDelay > 0) { 1630 mProcessStatsMutexFree.set(true); 1631 this.wait(nextCpuDelay); 1632 } 1633 } 1634 } catch (InterruptedException e) { 1635 } 1636 updateCpuStatsNow(); 1637 } catch (Exception e) { 1638 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1639 } 1640 } 1641 } 1642 }; 1643 mProcessStatsThread.start(); 1644 } 1645 1646 @Override 1647 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1648 throws RemoteException { 1649 if (code == SYSPROPS_TRANSACTION) { 1650 // We need to tell all apps about the system property change. 1651 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1652 synchronized(this) { 1653 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1654 final int NA = apps.size(); 1655 for (int ia=0; ia<NA; ia++) { 1656 ProcessRecord app = apps.valueAt(ia); 1657 if (app.thread != null) { 1658 procs.add(app.thread.asBinder()); 1659 } 1660 } 1661 } 1662 } 1663 1664 int N = procs.size(); 1665 for (int i=0; i<N; i++) { 1666 Parcel data2 = Parcel.obtain(); 1667 try { 1668 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1669 } catch (RemoteException e) { 1670 } 1671 data2.recycle(); 1672 } 1673 } 1674 try { 1675 return super.onTransact(code, data, reply, flags); 1676 } catch (RuntimeException e) { 1677 // The activity manager only throws security exceptions, so let's 1678 // log all others. 1679 if (!(e instanceof SecurityException)) { 1680 Slog.e(TAG, "Activity Manager Crash", e); 1681 } 1682 throw e; 1683 } 1684 } 1685 1686 void updateCpuStats() { 1687 final long now = SystemClock.uptimeMillis(); 1688 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1689 return; 1690 } 1691 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1692 synchronized (mProcessStatsThread) { 1693 mProcessStatsThread.notify(); 1694 } 1695 } 1696 } 1697 1698 void updateCpuStatsNow() { 1699 synchronized (mProcessStatsThread) { 1700 mProcessStatsMutexFree.set(false); 1701 final long now = SystemClock.uptimeMillis(); 1702 boolean haveNewCpuStats = false; 1703 1704 if (MONITOR_CPU_USAGE && 1705 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1706 mLastCpuTime.set(now); 1707 haveNewCpuStats = true; 1708 mProcessStats.update(); 1709 //Slog.i(TAG, mProcessStats.printCurrentState()); 1710 //Slog.i(TAG, "Total CPU usage: " 1711 // + mProcessStats.getTotalCpuPercent() + "%"); 1712 1713 // Slog the cpu usage if the property is set. 1714 if ("true".equals(SystemProperties.get("events.cpu"))) { 1715 int user = mProcessStats.getLastUserTime(); 1716 int system = mProcessStats.getLastSystemTime(); 1717 int iowait = mProcessStats.getLastIoWaitTime(); 1718 int irq = mProcessStats.getLastIrqTime(); 1719 int softIrq = mProcessStats.getLastSoftIrqTime(); 1720 int idle = mProcessStats.getLastIdleTime(); 1721 1722 int total = user + system + iowait + irq + softIrq + idle; 1723 if (total == 0) total = 1; 1724 1725 EventLog.writeEvent(EventLogTags.CPU, 1726 ((user+system+iowait+irq+softIrq) * 100) / total, 1727 (user * 100) / total, 1728 (system * 100) / total, 1729 (iowait * 100) / total, 1730 (irq * 100) / total, 1731 (softIrq * 100) / total); 1732 } 1733 } 1734 1735 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1736 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1737 synchronized(bstats) { 1738 synchronized(mPidsSelfLocked) { 1739 if (haveNewCpuStats) { 1740 if (mOnBattery) { 1741 int perc = bstats.startAddingCpuLocked(); 1742 int totalUTime = 0; 1743 int totalSTime = 0; 1744 final int N = mProcessStats.countStats(); 1745 for (int i=0; i<N; i++) { 1746 ProcessStats.Stats st = mProcessStats.getStats(i); 1747 if (!st.working) { 1748 continue; 1749 } 1750 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1751 int otherUTime = (st.rel_utime*perc)/100; 1752 int otherSTime = (st.rel_stime*perc)/100; 1753 totalUTime += otherUTime; 1754 totalSTime += otherSTime; 1755 if (pr != null) { 1756 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1757 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1758 st.rel_stime-otherSTime); 1759 ps.addSpeedStepTimes(cpuSpeedTimes); 1760 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1761 } else { 1762 BatteryStatsImpl.Uid.Proc ps = 1763 bstats.getProcessStatsLocked(st.name, st.pid); 1764 if (ps != null) { 1765 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1766 st.rel_stime-otherSTime); 1767 ps.addSpeedStepTimes(cpuSpeedTimes); 1768 } 1769 } 1770 } 1771 bstats.finishAddingCpuLocked(perc, totalUTime, 1772 totalSTime, cpuSpeedTimes); 1773 } 1774 } 1775 } 1776 1777 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1778 mLastWriteTime = now; 1779 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1780 } 1781 } 1782 } 1783 } 1784 1785 @Override 1786 public void batteryNeedsCpuUpdate() { 1787 updateCpuStatsNow(); 1788 } 1789 1790 @Override 1791 public void batteryPowerChanged(boolean onBattery) { 1792 // When plugging in, update the CPU stats first before changing 1793 // the plug state. 1794 updateCpuStatsNow(); 1795 synchronized (this) { 1796 synchronized(mPidsSelfLocked) { 1797 mOnBattery = DEBUG_POWER ? true : onBattery; 1798 } 1799 } 1800 } 1801 1802 /** 1803 * Initialize the application bind args. These are passed to each 1804 * process when the bindApplication() IPC is sent to the process. They're 1805 * lazily setup to make sure the services are running when they're asked for. 1806 */ 1807 private HashMap<String, IBinder> getCommonServicesLocked() { 1808 if (mAppBindArgs == null) { 1809 mAppBindArgs = new HashMap<String, IBinder>(); 1810 1811 // Setup the application init args 1812 mAppBindArgs.put("package", ServiceManager.getService("package")); 1813 mAppBindArgs.put("window", ServiceManager.getService("window")); 1814 mAppBindArgs.put(Context.ALARM_SERVICE, 1815 ServiceManager.getService(Context.ALARM_SERVICE)); 1816 } 1817 return mAppBindArgs; 1818 } 1819 1820 final void setFocusedActivityLocked(ActivityRecord r) { 1821 if (mFocusedActivity != r) { 1822 mFocusedActivity = r; 1823 if (r != null) { 1824 mWindowManager.setFocusedApp(r.appToken, true); 1825 } 1826 } 1827 } 1828 1829 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1830 // put it on the LRU to keep track of when it should be exited. 1831 int lrui = mLruProcesses.indexOf(app); 1832 if (lrui >= 0) mLruProcesses.remove(lrui); 1833 1834 int i = mLruProcesses.size()-1; 1835 int skipTop = 0; 1836 1837 app.lruSeq = mLruSeq; 1838 1839 // compute the new weight for this process. 1840 app.lastActivityTime = SystemClock.uptimeMillis(); 1841 if (app.activities.size() > 0) { 1842 // If this process has activities, we more strongly want to keep 1843 // it around. 1844 app.lruWeight = app.lastActivityTime; 1845 } else if (app.pubProviders.size() > 0) { 1846 // If this process contains content providers, we want to keep 1847 // it a little more strongly. 1848 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1849 // Also don't let it kick out the first few "real" hidden processes. 1850 skipTop = ProcessList.MIN_HIDDEN_APPS; 1851 } else { 1852 // If this process doesn't have activities, we less strongly 1853 // want to keep it around, and generally want to avoid getting 1854 // in front of any very recently used activities. 1855 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1856 // Also don't let it kick out the first few "real" hidden processes. 1857 skipTop = ProcessList.MIN_HIDDEN_APPS; 1858 } 1859 1860 while (i >= 0) { 1861 ProcessRecord p = mLruProcesses.get(i); 1862 // If this app shouldn't be in front of the first N background 1863 // apps, then skip over that many that are currently hidden. 1864 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1865 skipTop--; 1866 } 1867 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1868 mLruProcesses.add(i+1, app); 1869 break; 1870 } 1871 i--; 1872 } 1873 if (i < 0) { 1874 mLruProcesses.add(0, app); 1875 } 1876 1877 // If the app is currently using a content provider or service, 1878 // bump those processes as well. 1879 if (app.connections.size() > 0) { 1880 for (ConnectionRecord cr : app.connections) { 1881 if (cr.binding != null && cr.binding.service != null 1882 && cr.binding.service.app != null 1883 && cr.binding.service.app.lruSeq != mLruSeq) { 1884 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1885 } 1886 } 1887 } 1888 for (int j=app.conProviders.size()-1; j>=0; j--) { 1889 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1890 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1891 updateLruProcessInternalLocked(cpr.proc, i+1); 1892 } 1893 } 1894 } 1895 1896 final void updateLruProcessLocked(ProcessRecord app, 1897 boolean oomAdj) { 1898 mLruSeq++; 1899 updateLruProcessInternalLocked(app, 0); 1900 1901 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1902 if (oomAdj) { 1903 updateOomAdjLocked(); 1904 } 1905 } 1906 1907 final ProcessRecord getProcessRecordLocked( 1908 String processName, int uid) { 1909 if (uid == Process.SYSTEM_UID) { 1910 // The system gets to run in any process. If there are multiple 1911 // processes with the same uid, just pick the first (this 1912 // should never happen). 1913 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1914 processName); 1915 if (procs == null) return null; 1916 final int N = procs.size(); 1917 for (int i = 0; i < N; i++) { 1918 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1919 } 1920 } 1921 ProcessRecord proc = mProcessNames.get(processName, uid); 1922 return proc; 1923 } 1924 1925 void ensurePackageDexOpt(String packageName) { 1926 IPackageManager pm = AppGlobals.getPackageManager(); 1927 try { 1928 if (pm.performDexOpt(packageName)) { 1929 mDidDexOpt = true; 1930 } 1931 } catch (RemoteException e) { 1932 } 1933 } 1934 1935 boolean isNextTransitionForward() { 1936 int transit = mWindowManager.getPendingAppTransition(); 1937 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1938 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1939 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1940 } 1941 1942 final ProcessRecord startProcessLocked(String processName, 1943 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1944 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1945 boolean isolated) { 1946 ProcessRecord app; 1947 if (!isolated) { 1948 app = getProcessRecordLocked(processName, info.uid); 1949 } else { 1950 // If this is an isolated process, it can't re-use an existing process. 1951 app = null; 1952 } 1953 // We don't have to do anything more if: 1954 // (1) There is an existing application record; and 1955 // (2) The caller doesn't think it is dead, OR there is no thread 1956 // object attached to it so we know it couldn't have crashed; and 1957 // (3) There is a pid assigned to it, so it is either starting or 1958 // already running. 1959 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1960 + " app=" + app + " knownToBeDead=" + knownToBeDead 1961 + " thread=" + (app != null ? app.thread : null) 1962 + " pid=" + (app != null ? app.pid : -1)); 1963 if (app != null && app.pid > 0) { 1964 if (!knownToBeDead || app.thread == null) { 1965 // We already have the app running, or are waiting for it to 1966 // come up (we have a pid but not yet its thread), so keep it. 1967 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1968 // If this is a new package in the process, add the package to the list 1969 app.addPackage(info.packageName); 1970 return app; 1971 } else { 1972 // An application record is attached to a previous process, 1973 // clean it up now. 1974 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 1975 handleAppDiedLocked(app, true, true); 1976 } 1977 } 1978 1979 String hostingNameStr = hostingName != null 1980 ? hostingName.flattenToShortString() : null; 1981 1982 if (!isolated) { 1983 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1984 // If we are in the background, then check to see if this process 1985 // is bad. If so, we will just silently fail. 1986 if (mBadProcesses.get(info.processName, info.uid) != null) { 1987 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1988 + "/" + info.processName); 1989 return null; 1990 } 1991 } else { 1992 // When the user is explicitly starting a process, then clear its 1993 // crash count so that we won't make it bad until they see at 1994 // least one crash dialog again, and make the process good again 1995 // if it had been bad. 1996 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1997 + "/" + info.processName); 1998 mProcessCrashTimes.remove(info.processName, info.uid); 1999 if (mBadProcesses.get(info.processName, info.uid) != null) { 2000 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2001 UserHandle.getUserId(info.uid), info.uid, 2002 info.processName); 2003 mBadProcesses.remove(info.processName, info.uid); 2004 if (app != null) { 2005 app.bad = false; 2006 } 2007 } 2008 } 2009 } 2010 2011 if (app == null) { 2012 app = newProcessRecordLocked(null, info, processName, isolated); 2013 if (app == null) { 2014 Slog.w(TAG, "Failed making new process record for " 2015 + processName + "/" + info.uid + " isolated=" + isolated); 2016 return null; 2017 } 2018 mProcessNames.put(processName, app.uid, app); 2019 if (isolated) { 2020 mIsolatedProcesses.put(app.uid, app); 2021 } 2022 } else { 2023 // If this is a new package in the process, add the package to the list 2024 app.addPackage(info.packageName); 2025 } 2026 2027 // If the system is not ready yet, then hold off on starting this 2028 // process until it is. 2029 if (!mProcessesReady 2030 && !isAllowedWhileBooting(info) 2031 && !allowWhileBooting) { 2032 if (!mProcessesOnHold.contains(app)) { 2033 mProcessesOnHold.add(app); 2034 } 2035 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2036 return app; 2037 } 2038 2039 startProcessLocked(app, hostingType, hostingNameStr); 2040 return (app.pid != 0) ? app : null; 2041 } 2042 2043 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2044 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2045 } 2046 2047 private final void startProcessLocked(ProcessRecord app, 2048 String hostingType, String hostingNameStr) { 2049 if (app.pid > 0 && app.pid != MY_PID) { 2050 synchronized (mPidsSelfLocked) { 2051 mPidsSelfLocked.remove(app.pid); 2052 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2053 } 2054 app.setPid(0); 2055 } 2056 2057 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2058 "startProcessLocked removing on hold: " + app); 2059 mProcessesOnHold.remove(app); 2060 2061 updateCpuStats(); 2062 2063 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2064 mProcDeaths[0] = 0; 2065 2066 try { 2067 int uid = app.uid; 2068 2069 int[] gids = null; 2070 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2071 if (!app.isolated) { 2072 int[] permGids = null; 2073 try { 2074 final PackageManager pm = mContext.getPackageManager(); 2075 permGids = pm.getPackageGids(app.info.packageName); 2076 2077 if (Environment.isExternalStorageEmulated()) { 2078 if (pm.checkPermission( 2079 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2080 app.info.packageName) == PERMISSION_GRANTED) { 2081 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2082 } else { 2083 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2084 } 2085 } 2086 } catch (PackageManager.NameNotFoundException e) { 2087 Slog.w(TAG, "Unable to retrieve gids", e); 2088 } 2089 2090 /* 2091 * Add shared application GID so applications can share some 2092 * resources like shared libraries 2093 */ 2094 if (permGids == null) { 2095 gids = new int[1]; 2096 } else { 2097 gids = new int[permGids.length + 1]; 2098 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2099 } 2100 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2101 } 2102 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2103 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2104 && mTopComponent != null 2105 && app.processName.equals(mTopComponent.getPackageName())) { 2106 uid = 0; 2107 } 2108 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2109 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2110 uid = 0; 2111 } 2112 } 2113 int debugFlags = 0; 2114 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2115 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2116 // Also turn on CheckJNI for debuggable apps. It's quite 2117 // awkward to turn on otherwise. 2118 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2119 } 2120 // Run the app in safe mode if its manifest requests so or the 2121 // system is booted in safe mode. 2122 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2123 Zygote.systemInSafeMode == true) { 2124 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2125 } 2126 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2127 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2128 } 2129 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2130 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2131 } 2132 if ("1".equals(SystemProperties.get("debug.assert"))) { 2133 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2134 } 2135 2136 // Start the process. It will either succeed and return a result containing 2137 // the PID of the new process, or else throw a RuntimeException. 2138 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2139 app.processName, uid, uid, gids, debugFlags, mountExternal, 2140 app.info.targetSdkVersion, null, null); 2141 2142 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2143 synchronized (bs) { 2144 if (bs.isOnBattery()) { 2145 app.batteryStats.incStartsLocked(); 2146 } 2147 } 2148 2149 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2150 UserHandle.getUserId(uid), startResult.pid, uid, 2151 app.processName, hostingType, 2152 hostingNameStr != null ? hostingNameStr : ""); 2153 2154 if (app.persistent) { 2155 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2156 } 2157 2158 StringBuilder buf = mStringBuilder; 2159 buf.setLength(0); 2160 buf.append("Start proc "); 2161 buf.append(app.processName); 2162 buf.append(" for "); 2163 buf.append(hostingType); 2164 if (hostingNameStr != null) { 2165 buf.append(" "); 2166 buf.append(hostingNameStr); 2167 } 2168 buf.append(": pid="); 2169 buf.append(startResult.pid); 2170 buf.append(" uid="); 2171 buf.append(uid); 2172 buf.append(" gids={"); 2173 if (gids != null) { 2174 for (int gi=0; gi<gids.length; gi++) { 2175 if (gi != 0) buf.append(", "); 2176 buf.append(gids[gi]); 2177 2178 } 2179 } 2180 buf.append("}"); 2181 Slog.i(TAG, buf.toString()); 2182 app.setPid(startResult.pid); 2183 app.usingWrapper = startResult.usingWrapper; 2184 app.removed = false; 2185 synchronized (mPidsSelfLocked) { 2186 this.mPidsSelfLocked.put(startResult.pid, app); 2187 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2188 msg.obj = app; 2189 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2190 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2191 } 2192 } catch (RuntimeException e) { 2193 // XXX do better error recovery. 2194 app.setPid(0); 2195 Slog.e(TAG, "Failure starting process " + app.processName, e); 2196 } 2197 } 2198 2199 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2200 if (resumed) { 2201 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2202 } else { 2203 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2204 } 2205 } 2206 2207 boolean startHomeActivityLocked(int userId) { 2208 if (mHeadless) { 2209 // Added because none of the other calls to ensureBootCompleted seem to fire 2210 // when running headless. 2211 ensureBootCompleted(); 2212 return false; 2213 } 2214 2215 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2216 && mTopAction == null) { 2217 // We are running in factory test mode, but unable to find 2218 // the factory test app, so just sit around displaying the 2219 // error message and don't try to start anything. 2220 return false; 2221 } 2222 Intent intent = new Intent( 2223 mTopAction, 2224 mTopData != null ? Uri.parse(mTopData) : null); 2225 intent.setComponent(mTopComponent); 2226 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2227 intent.addCategory(Intent.CATEGORY_HOME); 2228 } 2229 ActivityInfo aInfo = 2230 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2231 if (aInfo != null) { 2232 intent.setComponent(new ComponentName( 2233 aInfo.applicationInfo.packageName, aInfo.name)); 2234 // Don't do this if the home app is currently being 2235 // instrumented. 2236 aInfo = new ActivityInfo(aInfo); 2237 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2238 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2239 aInfo.applicationInfo.uid); 2240 if (app == null || app.instrumentationClass == null) { 2241 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2242 mMainStack.startActivityLocked(null, intent, null, aInfo, 2243 null, null, 0, 0, 0, 0, null, false, null); 2244 } 2245 } 2246 2247 return true; 2248 } 2249 2250 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2251 ActivityInfo ai = null; 2252 ComponentName comp = intent.getComponent(); 2253 try { 2254 if (comp != null) { 2255 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2256 } else { 2257 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2258 intent, 2259 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2260 flags, userId); 2261 2262 if (info != null) { 2263 ai = info.activityInfo; 2264 } 2265 } 2266 } catch (RemoteException e) { 2267 // ignore 2268 } 2269 2270 return ai; 2271 } 2272 2273 /** 2274 * Starts the "new version setup screen" if appropriate. 2275 */ 2276 void startSetupActivityLocked() { 2277 // Only do this once per boot. 2278 if (mCheckedForSetup) { 2279 return; 2280 } 2281 2282 // We will show this screen if the current one is a different 2283 // version than the last one shown, and we are not running in 2284 // low-level factory test mode. 2285 final ContentResolver resolver = mContext.getContentResolver(); 2286 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2287 Settings.Global.getInt(resolver, 2288 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2289 mCheckedForSetup = true; 2290 2291 // See if we should be showing the platform update setup UI. 2292 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2293 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2294 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2295 2296 // We don't allow third party apps to replace this. 2297 ResolveInfo ri = null; 2298 for (int i=0; ris != null && i<ris.size(); i++) { 2299 if ((ris.get(i).activityInfo.applicationInfo.flags 2300 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2301 ri = ris.get(i); 2302 break; 2303 } 2304 } 2305 2306 if (ri != null) { 2307 String vers = ri.activityInfo.metaData != null 2308 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2309 : null; 2310 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2311 vers = ri.activityInfo.applicationInfo.metaData.getString( 2312 Intent.METADATA_SETUP_VERSION); 2313 } 2314 String lastVers = Settings.Secure.getString( 2315 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2316 if (vers != null && !vers.equals(lastVers)) { 2317 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2318 intent.setComponent(new ComponentName( 2319 ri.activityInfo.packageName, ri.activityInfo.name)); 2320 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2321 null, null, 0, 0, 0, 0, null, false, null); 2322 } 2323 } 2324 } 2325 } 2326 2327 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2328 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2329 } 2330 2331 void enforceNotIsolatedCaller(String caller) { 2332 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2333 throw new SecurityException("Isolated process not allowed to call " + caller); 2334 } 2335 } 2336 2337 public int getFrontActivityScreenCompatMode() { 2338 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2339 synchronized (this) { 2340 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2341 } 2342 } 2343 2344 public void setFrontActivityScreenCompatMode(int mode) { 2345 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2346 "setFrontActivityScreenCompatMode"); 2347 synchronized (this) { 2348 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2349 } 2350 } 2351 2352 public int getPackageScreenCompatMode(String packageName) { 2353 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2354 synchronized (this) { 2355 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2356 } 2357 } 2358 2359 public void setPackageScreenCompatMode(String packageName, int mode) { 2360 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2361 "setPackageScreenCompatMode"); 2362 synchronized (this) { 2363 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2364 } 2365 } 2366 2367 public boolean getPackageAskScreenCompat(String packageName) { 2368 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2369 synchronized (this) { 2370 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2371 } 2372 } 2373 2374 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2375 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2376 "setPackageAskScreenCompat"); 2377 synchronized (this) { 2378 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2379 } 2380 } 2381 2382 void reportResumedActivityLocked(ActivityRecord r) { 2383 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2384 updateUsageStats(r, true); 2385 } 2386 2387 private void dispatchProcessesChanged() { 2388 int N; 2389 synchronized (this) { 2390 N = mPendingProcessChanges.size(); 2391 if (mActiveProcessChanges.length < N) { 2392 mActiveProcessChanges = new ProcessChangeItem[N]; 2393 } 2394 mPendingProcessChanges.toArray(mActiveProcessChanges); 2395 mAvailProcessChanges.addAll(mPendingProcessChanges); 2396 mPendingProcessChanges.clear(); 2397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2398 } 2399 int i = mProcessObservers.beginBroadcast(); 2400 while (i > 0) { 2401 i--; 2402 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2403 if (observer != null) { 2404 try { 2405 for (int j=0; j<N; j++) { 2406 ProcessChangeItem item = mActiveProcessChanges[j]; 2407 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2408 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2409 + item.pid + " uid=" + item.uid + ": " 2410 + item.foregroundActivities); 2411 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2412 item.foregroundActivities); 2413 } 2414 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2415 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2416 + item.pid + " uid=" + item.uid + ": " + item.importance); 2417 observer.onImportanceChanged(item.pid, item.uid, 2418 item.importance); 2419 } 2420 } 2421 } catch (RemoteException e) { 2422 } 2423 } 2424 } 2425 mProcessObservers.finishBroadcast(); 2426 } 2427 2428 private void dispatchProcessDied(int pid, int uid) { 2429 int i = mProcessObservers.beginBroadcast(); 2430 while (i > 0) { 2431 i--; 2432 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2433 if (observer != null) { 2434 try { 2435 observer.onProcessDied(pid, uid); 2436 } catch (RemoteException e) { 2437 } 2438 } 2439 } 2440 mProcessObservers.finishBroadcast(); 2441 } 2442 2443 final void doPendingActivityLaunchesLocked(boolean doResume) { 2444 final int N = mPendingActivityLaunches.size(); 2445 if (N <= 0) { 2446 return; 2447 } 2448 for (int i=0; i<N; i++) { 2449 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2450 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2451 pal.startFlags, doResume && i == (N-1), null); 2452 } 2453 mPendingActivityLaunches.clear(); 2454 } 2455 2456 public final int startActivity(IApplicationThread caller, 2457 Intent intent, String resolvedType, IBinder resultTo, 2458 String resultWho, int requestCode, int startFlags, 2459 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2460 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2461 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2462 } 2463 2464 public final int startActivityAsUser(IApplicationThread caller, 2465 Intent intent, String resolvedType, IBinder resultTo, 2466 String resultWho, int requestCode, int startFlags, 2467 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2468 enforceNotIsolatedCaller("startActivity"); 2469 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2470 false, true, "startActivity", null); 2471 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2472 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2473 null, null, options, userId); 2474 } 2475 2476 public final WaitResult startActivityAndWait(IApplicationThread caller, 2477 Intent intent, String resolvedType, IBinder resultTo, 2478 String resultWho, int requestCode, int startFlags, String profileFile, 2479 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2480 enforceNotIsolatedCaller("startActivityAndWait"); 2481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2482 false, true, "startActivityAndWait", null); 2483 WaitResult res = new WaitResult(); 2484 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2485 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2486 res, null, options, UserHandle.getCallingUserId()); 2487 return res; 2488 } 2489 2490 public final int startActivityWithConfig(IApplicationThread caller, 2491 Intent intent, String resolvedType, IBinder resultTo, 2492 String resultWho, int requestCode, int startFlags, Configuration config, 2493 Bundle options, int userId) { 2494 enforceNotIsolatedCaller("startActivityWithConfig"); 2495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2496 false, true, "startActivityWithConfig", null); 2497 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2498 resultTo, resultWho, requestCode, startFlags, 2499 null, null, null, config, options, userId); 2500 return ret; 2501 } 2502 2503 public int startActivityIntentSender(IApplicationThread caller, 2504 IntentSender intent, Intent fillInIntent, String resolvedType, 2505 IBinder resultTo, String resultWho, int requestCode, 2506 int flagsMask, int flagsValues, Bundle options) { 2507 enforceNotIsolatedCaller("startActivityIntentSender"); 2508 // Refuse possible leaked file descriptors 2509 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2510 throw new IllegalArgumentException("File descriptors passed in Intent"); 2511 } 2512 2513 IIntentSender sender = intent.getTarget(); 2514 if (!(sender instanceof PendingIntentRecord)) { 2515 throw new IllegalArgumentException("Bad PendingIntent object"); 2516 } 2517 2518 PendingIntentRecord pir = (PendingIntentRecord)sender; 2519 2520 synchronized (this) { 2521 // If this is coming from the currently resumed activity, it is 2522 // effectively saying that app switches are allowed at this point. 2523 if (mMainStack.mResumedActivity != null 2524 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2525 Binder.getCallingUid()) { 2526 mAppSwitchesAllowedTime = 0; 2527 } 2528 } 2529 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2530 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2531 return ret; 2532 } 2533 2534 public boolean startNextMatchingActivity(IBinder callingActivity, 2535 Intent intent, Bundle options) { 2536 // Refuse possible leaked file descriptors 2537 if (intent != null && intent.hasFileDescriptors() == true) { 2538 throw new IllegalArgumentException("File descriptors passed in Intent"); 2539 } 2540 2541 synchronized (this) { 2542 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2543 if (r == null) { 2544 ActivityOptions.abort(options); 2545 return false; 2546 } 2547 if (r.app == null || r.app.thread == null) { 2548 // The caller is not running... d'oh! 2549 ActivityOptions.abort(options); 2550 return false; 2551 } 2552 intent = new Intent(intent); 2553 // The caller is not allowed to change the data. 2554 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2555 // And we are resetting to find the next component... 2556 intent.setComponent(null); 2557 2558 ActivityInfo aInfo = null; 2559 try { 2560 List<ResolveInfo> resolves = 2561 AppGlobals.getPackageManager().queryIntentActivities( 2562 intent, r.resolvedType, 2563 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2564 UserHandle.getCallingUserId()); 2565 2566 // Look for the original activity in the list... 2567 final int N = resolves != null ? resolves.size() : 0; 2568 for (int i=0; i<N; i++) { 2569 ResolveInfo rInfo = resolves.get(i); 2570 if (rInfo.activityInfo.packageName.equals(r.packageName) 2571 && rInfo.activityInfo.name.equals(r.info.name)) { 2572 // We found the current one... the next matching is 2573 // after it. 2574 i++; 2575 if (i<N) { 2576 aInfo = resolves.get(i).activityInfo; 2577 } 2578 break; 2579 } 2580 } 2581 } catch (RemoteException e) { 2582 } 2583 2584 if (aInfo == null) { 2585 // Nobody who is next! 2586 ActivityOptions.abort(options); 2587 return false; 2588 } 2589 2590 intent.setComponent(new ComponentName( 2591 aInfo.applicationInfo.packageName, aInfo.name)); 2592 intent.setFlags(intent.getFlags()&~( 2593 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2594 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2595 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2596 Intent.FLAG_ACTIVITY_NEW_TASK)); 2597 2598 // Okay now we need to start the new activity, replacing the 2599 // currently running activity. This is a little tricky because 2600 // we want to start the new one as if the current one is finished, 2601 // but not finish the current one first so that there is no flicker. 2602 // And thus... 2603 final boolean wasFinishing = r.finishing; 2604 r.finishing = true; 2605 2606 // Propagate reply information over to the new activity. 2607 final ActivityRecord resultTo = r.resultTo; 2608 final String resultWho = r.resultWho; 2609 final int requestCode = r.requestCode; 2610 r.resultTo = null; 2611 if (resultTo != null) { 2612 resultTo.removeResultsLocked(r, resultWho, requestCode); 2613 } 2614 2615 final long origId = Binder.clearCallingIdentity(); 2616 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2617 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2618 resultWho, requestCode, -1, r.launchedFromUid, 0, 2619 options, false, null); 2620 Binder.restoreCallingIdentity(origId); 2621 2622 r.finishing = wasFinishing; 2623 if (res != ActivityManager.START_SUCCESS) { 2624 return false; 2625 } 2626 return true; 2627 } 2628 } 2629 2630 final int startActivityInPackage(int uid, 2631 Intent intent, String resolvedType, IBinder resultTo, 2632 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2633 2634 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2635 false, true, "startActivityInPackage", null); 2636 2637 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2638 resultTo, resultWho, requestCode, startFlags, 2639 null, null, null, null, options, userId); 2640 return ret; 2641 } 2642 2643 public final int startActivities(IApplicationThread caller, 2644 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2645 int userId) { 2646 enforceNotIsolatedCaller("startActivities"); 2647 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2648 false, true, "startActivity", null); 2649 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2650 options, userId); 2651 return ret; 2652 } 2653 2654 final int startActivitiesInPackage(int uid, 2655 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2656 Bundle options, int userId) { 2657 2658 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2659 false, true, "startActivityInPackage", null); 2660 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2661 options, userId); 2662 return ret; 2663 } 2664 2665 final void addRecentTaskLocked(TaskRecord task) { 2666 int N = mRecentTasks.size(); 2667 // Quick case: check if the top-most recent task is the same. 2668 if (N > 0 && mRecentTasks.get(0) == task) { 2669 return; 2670 } 2671 // Remove any existing entries that are the same kind of task. 2672 for (int i=0; i<N; i++) { 2673 TaskRecord tr = mRecentTasks.get(i); 2674 if (task.userId == tr.userId 2675 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2676 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2677 mRecentTasks.remove(i); 2678 i--; 2679 N--; 2680 if (task.intent == null) { 2681 // If the new recent task we are adding is not fully 2682 // specified, then replace it with the existing recent task. 2683 task = tr; 2684 } 2685 } 2686 } 2687 if (N >= MAX_RECENT_TASKS) { 2688 mRecentTasks.remove(N-1); 2689 } 2690 mRecentTasks.add(0, task); 2691 } 2692 2693 public void setRequestedOrientation(IBinder token, 2694 int requestedOrientation) { 2695 synchronized (this) { 2696 ActivityRecord r = mMainStack.isInStackLocked(token); 2697 if (r == null) { 2698 return; 2699 } 2700 final long origId = Binder.clearCallingIdentity(); 2701 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2702 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2703 mConfiguration, 2704 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2705 if (config != null) { 2706 r.frozenBeforeDestroy = true; 2707 if (!updateConfigurationLocked(config, r, false, false)) { 2708 mMainStack.resumeTopActivityLocked(null); 2709 } 2710 } 2711 Binder.restoreCallingIdentity(origId); 2712 } 2713 } 2714 2715 public int getRequestedOrientation(IBinder token) { 2716 synchronized (this) { 2717 ActivityRecord r = mMainStack.isInStackLocked(token); 2718 if (r == null) { 2719 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2720 } 2721 return mWindowManager.getAppOrientation(r.appToken); 2722 } 2723 } 2724 2725 /** 2726 * This is the internal entry point for handling Activity.finish(). 2727 * 2728 * @param token The Binder token referencing the Activity we want to finish. 2729 * @param resultCode Result code, if any, from this Activity. 2730 * @param resultData Result data (Intent), if any, from this Activity. 2731 * 2732 * @return Returns true if the activity successfully finished, or false if it is still running. 2733 */ 2734 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2735 // Refuse possible leaked file descriptors 2736 if (resultData != null && resultData.hasFileDescriptors() == true) { 2737 throw new IllegalArgumentException("File descriptors passed in Intent"); 2738 } 2739 2740 synchronized(this) { 2741 if (mController != null) { 2742 // Find the first activity that is not finishing. 2743 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2744 if (next != null) { 2745 // ask watcher if this is allowed 2746 boolean resumeOK = true; 2747 try { 2748 resumeOK = mController.activityResuming(next.packageName); 2749 } catch (RemoteException e) { 2750 mController = null; 2751 } 2752 2753 if (!resumeOK) { 2754 return false; 2755 } 2756 } 2757 } 2758 final long origId = Binder.clearCallingIdentity(); 2759 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2760 resultData, "app-request", true); 2761 Binder.restoreCallingIdentity(origId); 2762 return res; 2763 } 2764 } 2765 2766 public final void finishHeavyWeightApp() { 2767 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2768 != PackageManager.PERMISSION_GRANTED) { 2769 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2770 + Binder.getCallingPid() 2771 + ", uid=" + Binder.getCallingUid() 2772 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2773 Slog.w(TAG, msg); 2774 throw new SecurityException(msg); 2775 } 2776 2777 synchronized(this) { 2778 if (mHeavyWeightProcess == null) { 2779 return; 2780 } 2781 2782 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2783 mHeavyWeightProcess.activities); 2784 for (int i=0; i<activities.size(); i++) { 2785 ActivityRecord r = activities.get(i); 2786 if (!r.finishing) { 2787 int index = mMainStack.indexOfTokenLocked(r.appToken); 2788 if (index >= 0) { 2789 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2790 null, "finish-heavy", true); 2791 } 2792 } 2793 } 2794 2795 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2796 mHeavyWeightProcess.userId, 0)); 2797 mHeavyWeightProcess = null; 2798 } 2799 } 2800 2801 public void crashApplication(int uid, int initialPid, String packageName, 2802 String message) { 2803 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2804 != PackageManager.PERMISSION_GRANTED) { 2805 String msg = "Permission Denial: crashApplication() from pid=" 2806 + Binder.getCallingPid() 2807 + ", uid=" + Binder.getCallingUid() 2808 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2809 Slog.w(TAG, msg); 2810 throw new SecurityException(msg); 2811 } 2812 2813 synchronized(this) { 2814 ProcessRecord proc = null; 2815 2816 // Figure out which process to kill. We don't trust that initialPid 2817 // still has any relation to current pids, so must scan through the 2818 // list. 2819 synchronized (mPidsSelfLocked) { 2820 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2821 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2822 if (p.uid != uid) { 2823 continue; 2824 } 2825 if (p.pid == initialPid) { 2826 proc = p; 2827 break; 2828 } 2829 for (String str : p.pkgList) { 2830 if (str.equals(packageName)) { 2831 proc = p; 2832 } 2833 } 2834 } 2835 } 2836 2837 if (proc == null) { 2838 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2839 + " initialPid=" + initialPid 2840 + " packageName=" + packageName); 2841 return; 2842 } 2843 2844 if (proc.thread != null) { 2845 if (proc.pid == Process.myPid()) { 2846 Log.w(TAG, "crashApplication: trying to crash self!"); 2847 return; 2848 } 2849 long ident = Binder.clearCallingIdentity(); 2850 try { 2851 proc.thread.scheduleCrash(message); 2852 } catch (RemoteException e) { 2853 } 2854 Binder.restoreCallingIdentity(ident); 2855 } 2856 } 2857 } 2858 2859 public final void finishSubActivity(IBinder token, String resultWho, 2860 int requestCode) { 2861 synchronized(this) { 2862 final long origId = Binder.clearCallingIdentity(); 2863 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2864 Binder.restoreCallingIdentity(origId); 2865 } 2866 } 2867 2868 public boolean finishActivityAffinity(IBinder token) { 2869 synchronized(this) { 2870 final long origId = Binder.clearCallingIdentity(); 2871 boolean res = mMainStack.finishActivityAffinityLocked(token); 2872 Binder.restoreCallingIdentity(origId); 2873 return res; 2874 } 2875 } 2876 2877 public boolean willActivityBeVisible(IBinder token) { 2878 synchronized(this) { 2879 int i; 2880 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2881 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2882 if (r.appToken == token) { 2883 return true; 2884 } 2885 if (r.fullscreen && !r.finishing) { 2886 return false; 2887 } 2888 } 2889 return true; 2890 } 2891 } 2892 2893 public void overridePendingTransition(IBinder token, String packageName, 2894 int enterAnim, int exitAnim) { 2895 synchronized(this) { 2896 ActivityRecord self = mMainStack.isInStackLocked(token); 2897 if (self == null) { 2898 return; 2899 } 2900 2901 final long origId = Binder.clearCallingIdentity(); 2902 2903 if (self.state == ActivityState.RESUMED 2904 || self.state == ActivityState.PAUSING) { 2905 mWindowManager.overridePendingAppTransition(packageName, 2906 enterAnim, exitAnim, null); 2907 } 2908 2909 Binder.restoreCallingIdentity(origId); 2910 } 2911 } 2912 2913 /** 2914 * Main function for removing an existing process from the activity manager 2915 * as a result of that process going away. Clears out all connections 2916 * to the process. 2917 */ 2918 private final void handleAppDiedLocked(ProcessRecord app, 2919 boolean restarting, boolean allowRestart) { 2920 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2921 if (!restarting) { 2922 mLruProcesses.remove(app); 2923 } 2924 2925 if (mProfileProc == app) { 2926 clearProfilerLocked(); 2927 } 2928 2929 // Just in case... 2930 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2931 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 2932 "App died while pausing: " + mMainStack.mPausingActivity); 2933 mMainStack.mPausingActivity = null; 2934 } 2935 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2936 mMainStack.mLastPausedActivity = null; 2937 } 2938 2939 // Remove this application's activities from active lists. 2940 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 2941 2942 app.activities.clear(); 2943 2944 if (app.instrumentationClass != null) { 2945 Slog.w(TAG, "Crash of app " + app.processName 2946 + " running instrumentation " + app.instrumentationClass); 2947 Bundle info = new Bundle(); 2948 info.putString("shortMsg", "Process crashed."); 2949 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2950 } 2951 2952 if (!restarting) { 2953 if (!mMainStack.resumeTopActivityLocked(null)) { 2954 // If there was nothing to resume, and we are not already 2955 // restarting this process, but there is a visible activity that 2956 // is hosted by the process... then make sure all visible 2957 // activities are running, taking care of restarting this 2958 // process. 2959 if (hasVisibleActivities) { 2960 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2961 } 2962 } 2963 } 2964 } 2965 2966 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2967 IBinder threadBinder = thread.asBinder(); 2968 // Find the application record. 2969 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2970 ProcessRecord rec = mLruProcesses.get(i); 2971 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2972 return i; 2973 } 2974 } 2975 return -1; 2976 } 2977 2978 final ProcessRecord getRecordForAppLocked( 2979 IApplicationThread thread) { 2980 if (thread == null) { 2981 return null; 2982 } 2983 2984 int appIndex = getLRURecordIndexForAppLocked(thread); 2985 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2986 } 2987 2988 final void appDiedLocked(ProcessRecord app, int pid, 2989 IApplicationThread thread) { 2990 2991 mProcDeaths[0]++; 2992 2993 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2994 synchronized (stats) { 2995 stats.noteProcessDiedLocked(app.info.uid, pid); 2996 } 2997 2998 // Clean up already done if the process has been re-started. 2999 if (app.pid == pid && app.thread != null && 3000 app.thread.asBinder() == thread.asBinder()) { 3001 if (!app.killedBackground) { 3002 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3003 + ") has died."); 3004 } 3005 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3006 if (DEBUG_CLEANUP) Slog.v( 3007 TAG, "Dying app: " + app + ", pid: " + pid 3008 + ", thread: " + thread.asBinder()); 3009 boolean doLowMem = app.instrumentationClass == null; 3010 handleAppDiedLocked(app, false, true); 3011 3012 if (doLowMem) { 3013 // If there are no longer any background processes running, 3014 // and the app that died was not running instrumentation, 3015 // then tell everyone we are now low on memory. 3016 boolean haveBg = false; 3017 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3018 ProcessRecord rec = mLruProcesses.get(i); 3019 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3020 haveBg = true; 3021 break; 3022 } 3023 } 3024 3025 if (!haveBg) { 3026 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3027 long now = SystemClock.uptimeMillis(); 3028 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3029 ProcessRecord rec = mLruProcesses.get(i); 3030 if (rec != app && rec.thread != null && 3031 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3032 // The low memory report is overriding any current 3033 // state for a GC request. Make sure to do 3034 // heavy/important/visible/foreground processes first. 3035 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3036 rec.lastRequestedGc = 0; 3037 } else { 3038 rec.lastRequestedGc = rec.lastLowMemory; 3039 } 3040 rec.reportLowMemory = true; 3041 rec.lastLowMemory = now; 3042 mProcessesToGc.remove(rec); 3043 addProcessToGcListLocked(rec); 3044 } 3045 } 3046 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3047 scheduleAppGcsLocked(); 3048 } 3049 } 3050 } else if (app.pid != pid) { 3051 // A new process has already been started. 3052 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3053 + ") has died and restarted (pid " + app.pid + ")."); 3054 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3055 } else if (DEBUG_PROCESSES) { 3056 Slog.d(TAG, "Received spurious death notification for thread " 3057 + thread.asBinder()); 3058 } 3059 } 3060 3061 /** 3062 * If a stack trace dump file is configured, dump process stack traces. 3063 * @param clearTraces causes the dump file to be erased prior to the new 3064 * traces being written, if true; when false, the new traces will be 3065 * appended to any existing file content. 3066 * @param firstPids of dalvik VM processes to dump stack traces for first 3067 * @param lastPids of dalvik VM processes to dump stack traces for last 3068 * @param nativeProcs optional list of native process names to dump stack crawls 3069 * @return file containing stack traces, or null if no dump file is configured 3070 */ 3071 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3072 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3073 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3074 if (tracesPath == null || tracesPath.length() == 0) { 3075 return null; 3076 } 3077 3078 File tracesFile = new File(tracesPath); 3079 try { 3080 File tracesDir = tracesFile.getParentFile(); 3081 if (!tracesDir.exists()) { 3082 tracesFile.mkdirs(); 3083 if (!SELinux.restorecon(tracesDir)) { 3084 return null; 3085 } 3086 } 3087 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3088 3089 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3090 tracesFile.createNewFile(); 3091 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3092 } catch (IOException e) { 3093 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3094 return null; 3095 } 3096 3097 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3098 return tracesFile; 3099 } 3100 3101 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3102 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3103 // Use a FileObserver to detect when traces finish writing. 3104 // The order of traces is considered important to maintain for legibility. 3105 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3106 public synchronized void onEvent(int event, String path) { notify(); } 3107 }; 3108 3109 try { 3110 observer.startWatching(); 3111 3112 // First collect all of the stacks of the most important pids. 3113 if (firstPids != null) { 3114 try { 3115 int num = firstPids.size(); 3116 for (int i = 0; i < num; i++) { 3117 synchronized (observer) { 3118 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3119 observer.wait(200); // Wait for write-close, give up after 200msec 3120 } 3121 } 3122 } catch (InterruptedException e) { 3123 Log.wtf(TAG, e); 3124 } 3125 } 3126 3127 // Next measure CPU usage. 3128 if (processStats != null) { 3129 processStats.init(); 3130 System.gc(); 3131 processStats.update(); 3132 try { 3133 synchronized (processStats) { 3134 processStats.wait(500); // measure over 1/2 second. 3135 } 3136 } catch (InterruptedException e) { 3137 } 3138 processStats.update(); 3139 3140 // We'll take the stack crawls of just the top apps using CPU. 3141 final int N = processStats.countWorkingStats(); 3142 int numProcs = 0; 3143 for (int i=0; i<N && numProcs<5; i++) { 3144 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3145 if (lastPids.indexOfKey(stats.pid) >= 0) { 3146 numProcs++; 3147 try { 3148 synchronized (observer) { 3149 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3150 observer.wait(200); // Wait for write-close, give up after 200msec 3151 } 3152 } catch (InterruptedException e) { 3153 Log.wtf(TAG, e); 3154 } 3155 3156 } 3157 } 3158 } 3159 3160 } finally { 3161 observer.stopWatching(); 3162 } 3163 3164 if (nativeProcs != null) { 3165 int[] pids = Process.getPidsForCommands(nativeProcs); 3166 if (pids != null) { 3167 for (int pid : pids) { 3168 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3169 } 3170 } 3171 } 3172 } 3173 3174 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3175 if (true || IS_USER_BUILD) { 3176 return; 3177 } 3178 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3179 if (tracesPath == null || tracesPath.length() == 0) { 3180 return; 3181 } 3182 3183 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3184 StrictMode.allowThreadDiskWrites(); 3185 try { 3186 final File tracesFile = new File(tracesPath); 3187 final File tracesDir = tracesFile.getParentFile(); 3188 final File tracesTmp = new File(tracesDir, "__tmp__"); 3189 try { 3190 if (!tracesDir.exists()) { 3191 tracesFile.mkdirs(); 3192 if (!SELinux.restorecon(tracesDir.getPath())) { 3193 return; 3194 } 3195 } 3196 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3197 3198 if (tracesFile.exists()) { 3199 tracesTmp.delete(); 3200 tracesFile.renameTo(tracesTmp); 3201 } 3202 StringBuilder sb = new StringBuilder(); 3203 Time tobj = new Time(); 3204 tobj.set(System.currentTimeMillis()); 3205 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3206 sb.append(": "); 3207 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3208 sb.append(" since "); 3209 sb.append(msg); 3210 FileOutputStream fos = new FileOutputStream(tracesFile); 3211 fos.write(sb.toString().getBytes()); 3212 if (app == null) { 3213 fos.write("\n*** No application process!".getBytes()); 3214 } 3215 fos.close(); 3216 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3217 } catch (IOException e) { 3218 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3219 return; 3220 } 3221 3222 if (app != null) { 3223 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3224 firstPids.add(app.pid); 3225 dumpStackTraces(tracesPath, firstPids, null, null, null); 3226 } 3227 3228 File lastTracesFile = null; 3229 File curTracesFile = null; 3230 for (int i=9; i>=0; i--) { 3231 String name = String.format("slow%02d.txt", i); 3232 curTracesFile = new File(tracesDir, name); 3233 if (curTracesFile.exists()) { 3234 if (lastTracesFile != null) { 3235 curTracesFile.renameTo(lastTracesFile); 3236 } else { 3237 curTracesFile.delete(); 3238 } 3239 } 3240 lastTracesFile = curTracesFile; 3241 } 3242 tracesFile.renameTo(curTracesFile); 3243 if (tracesTmp.exists()) { 3244 tracesTmp.renameTo(tracesFile); 3245 } 3246 } finally { 3247 StrictMode.setThreadPolicy(oldPolicy); 3248 } 3249 } 3250 3251 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3252 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3253 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3254 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3255 3256 if (mController != null) { 3257 try { 3258 // 0 == continue, -1 = kill process immediately 3259 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3260 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3261 } catch (RemoteException e) { 3262 mController = null; 3263 } 3264 } 3265 3266 long anrTime = SystemClock.uptimeMillis(); 3267 if (MONITOR_CPU_USAGE) { 3268 updateCpuStatsNow(); 3269 } 3270 3271 synchronized (this) { 3272 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3273 if (mShuttingDown) { 3274 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3275 return; 3276 } else if (app.notResponding) { 3277 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3278 return; 3279 } else if (app.crashing) { 3280 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3281 return; 3282 } 3283 3284 // In case we come through here for the same app before completing 3285 // this one, mark as anring now so we will bail out. 3286 app.notResponding = true; 3287 3288 // Log the ANR to the event log. 3289 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3290 app.processName, app.info.flags, annotation); 3291 3292 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3293 firstPids.add(app.pid); 3294 3295 int parentPid = app.pid; 3296 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3297 if (parentPid != app.pid) firstPids.add(parentPid); 3298 3299 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3300 3301 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3302 ProcessRecord r = mLruProcesses.get(i); 3303 if (r != null && r.thread != null) { 3304 int pid = r.pid; 3305 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3306 if (r.persistent) { 3307 firstPids.add(pid); 3308 } else { 3309 lastPids.put(pid, Boolean.TRUE); 3310 } 3311 } 3312 } 3313 } 3314 } 3315 3316 // Log the ANR to the main log. 3317 StringBuilder info = new StringBuilder(); 3318 info.setLength(0); 3319 info.append("ANR in ").append(app.processName); 3320 if (activity != null && activity.shortComponentName != null) { 3321 info.append(" (").append(activity.shortComponentName).append(")"); 3322 } 3323 info.append("\n"); 3324 if (annotation != null) { 3325 info.append("Reason: ").append(annotation).append("\n"); 3326 } 3327 if (parent != null && parent != activity) { 3328 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3329 } 3330 3331 final ProcessStats processStats = new ProcessStats(true); 3332 3333 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3334 3335 String cpuInfo = null; 3336 if (MONITOR_CPU_USAGE) { 3337 updateCpuStatsNow(); 3338 synchronized (mProcessStatsThread) { 3339 cpuInfo = mProcessStats.printCurrentState(anrTime); 3340 } 3341 info.append(processStats.printCurrentLoad()); 3342 info.append(cpuInfo); 3343 } 3344 3345 info.append(processStats.printCurrentState(anrTime)); 3346 3347 Slog.e(TAG, info.toString()); 3348 if (tracesFile == null) { 3349 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3350 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3351 } 3352 3353 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3354 cpuInfo, tracesFile, null); 3355 3356 if (mController != null) { 3357 try { 3358 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3359 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3360 if (res != 0) { 3361 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3362 return; 3363 } 3364 } catch (RemoteException e) { 3365 mController = null; 3366 } 3367 } 3368 3369 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3370 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3371 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3372 3373 synchronized (this) { 3374 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3375 Slog.w(TAG, "Killing " + app + ": background ANR"); 3376 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3377 app.processName, app.setAdj, "background ANR"); 3378 Process.killProcessQuiet(app.pid); 3379 return; 3380 } 3381 3382 // Set the app's notResponding state, and look up the errorReportReceiver 3383 makeAppNotRespondingLocked(app, 3384 activity != null ? activity.shortComponentName : null, 3385 annotation != null ? "ANR " + annotation : "ANR", 3386 info.toString()); 3387 3388 // Bring up the infamous App Not Responding dialog 3389 Message msg = Message.obtain(); 3390 HashMap map = new HashMap(); 3391 msg.what = SHOW_NOT_RESPONDING_MSG; 3392 msg.obj = map; 3393 msg.arg1 = aboveSystem ? 1 : 0; 3394 map.put("app", app); 3395 if (activity != null) { 3396 map.put("activity", activity); 3397 } 3398 3399 mHandler.sendMessage(msg); 3400 } 3401 } 3402 3403 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3404 if (!mLaunchWarningShown) { 3405 mLaunchWarningShown = true; 3406 mHandler.post(new Runnable() { 3407 @Override 3408 public void run() { 3409 synchronized (ActivityManagerService.this) { 3410 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3411 d.show(); 3412 mHandler.postDelayed(new Runnable() { 3413 @Override 3414 public void run() { 3415 synchronized (ActivityManagerService.this) { 3416 d.dismiss(); 3417 mLaunchWarningShown = false; 3418 } 3419 } 3420 }, 4000); 3421 } 3422 } 3423 }); 3424 } 3425 } 3426 3427 public boolean clearApplicationUserData(final String packageName, 3428 final IPackageDataObserver observer, int userId) { 3429 enforceNotIsolatedCaller("clearApplicationUserData"); 3430 int uid = Binder.getCallingUid(); 3431 int pid = Binder.getCallingPid(); 3432 userId = handleIncomingUser(pid, uid, 3433 userId, false, true, "clearApplicationUserData", null); 3434 long callingId = Binder.clearCallingIdentity(); 3435 try { 3436 IPackageManager pm = AppGlobals.getPackageManager(); 3437 int pkgUid = -1; 3438 synchronized(this) { 3439 try { 3440 pkgUid = pm.getPackageUid(packageName, userId); 3441 } catch (RemoteException e) { 3442 } 3443 if (pkgUid == -1) { 3444 Slog.w(TAG, "Invalid packageName:" + packageName); 3445 return false; 3446 } 3447 if (uid == pkgUid || checkComponentPermission( 3448 android.Manifest.permission.CLEAR_APP_USER_DATA, 3449 pid, uid, -1, true) 3450 == PackageManager.PERMISSION_GRANTED) { 3451 forceStopPackageLocked(packageName, pkgUid); 3452 } else { 3453 throw new SecurityException(pid+" does not have permission:"+ 3454 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3455 "for process:"+packageName); 3456 } 3457 } 3458 3459 try { 3460 //clear application user data 3461 pm.clearApplicationUserData(packageName, observer, userId); 3462 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3463 Uri.fromParts("package", packageName, null)); 3464 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3465 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3466 null, null, 0, null, null, null, false, false, userId); 3467 } catch (RemoteException e) { 3468 } 3469 } finally { 3470 Binder.restoreCallingIdentity(callingId); 3471 } 3472 return true; 3473 } 3474 3475 public void killBackgroundProcesses(final String packageName, int userId) { 3476 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3477 != PackageManager.PERMISSION_GRANTED && 3478 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3479 != PackageManager.PERMISSION_GRANTED) { 3480 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3481 + Binder.getCallingPid() 3482 + ", uid=" + Binder.getCallingUid() 3483 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3484 Slog.w(TAG, msg); 3485 throw new SecurityException(msg); 3486 } 3487 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3489 userId, true, true, "killBackgroundProcesses", null); 3490 long callingId = Binder.clearCallingIdentity(); 3491 try { 3492 IPackageManager pm = AppGlobals.getPackageManager(); 3493 synchronized(this) { 3494 int appId = -1; 3495 try { 3496 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3497 } catch (RemoteException e) { 3498 } 3499 if (appId == -1) { 3500 Slog.w(TAG, "Invalid packageName: " + packageName); 3501 return; 3502 } 3503 killPackageProcessesLocked(packageName, appId, userId, 3504 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3505 } 3506 } finally { 3507 Binder.restoreCallingIdentity(callingId); 3508 } 3509 } 3510 3511 public void killAllBackgroundProcesses() { 3512 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3513 != PackageManager.PERMISSION_GRANTED) { 3514 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3515 + Binder.getCallingPid() 3516 + ", uid=" + Binder.getCallingUid() 3517 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3518 Slog.w(TAG, msg); 3519 throw new SecurityException(msg); 3520 } 3521 3522 long callingId = Binder.clearCallingIdentity(); 3523 try { 3524 synchronized(this) { 3525 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3526 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3527 final int NA = apps.size(); 3528 for (int ia=0; ia<NA; ia++) { 3529 ProcessRecord app = apps.valueAt(ia); 3530 if (app.persistent) { 3531 // we don't kill persistent processes 3532 continue; 3533 } 3534 if (app.removed) { 3535 procs.add(app); 3536 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3537 app.removed = true; 3538 procs.add(app); 3539 } 3540 } 3541 } 3542 3543 int N = procs.size(); 3544 for (int i=0; i<N; i++) { 3545 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3546 } 3547 } 3548 } finally { 3549 Binder.restoreCallingIdentity(callingId); 3550 } 3551 } 3552 3553 public void forceStopPackage(final String packageName, int userId) { 3554 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3555 != PackageManager.PERMISSION_GRANTED) { 3556 String msg = "Permission Denial: forceStopPackage() from pid=" 3557 + Binder.getCallingPid() 3558 + ", uid=" + Binder.getCallingUid() 3559 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3560 Slog.w(TAG, msg); 3561 throw new SecurityException(msg); 3562 } 3563 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3564 userId, true, true, "forceStopPackage", null); 3565 long callingId = Binder.clearCallingIdentity(); 3566 try { 3567 IPackageManager pm = AppGlobals.getPackageManager(); 3568 synchronized(this) { 3569 int[] users = userId == UserHandle.USER_ALL 3570 ? getUsersLocked() : new int[] { userId }; 3571 for (int user : users) { 3572 int pkgUid = -1; 3573 try { 3574 pkgUid = pm.getPackageUid(packageName, user); 3575 } catch (RemoteException e) { 3576 } 3577 if (pkgUid == -1) { 3578 Slog.w(TAG, "Invalid packageName: " + packageName); 3579 continue; 3580 } 3581 try { 3582 pm.setPackageStoppedState(packageName, true, user); 3583 } catch (RemoteException e) { 3584 } catch (IllegalArgumentException e) { 3585 Slog.w(TAG, "Failed trying to unstop package " 3586 + packageName + ": " + e); 3587 } 3588 if (isUserRunningLocked(user, false)) { 3589 forceStopPackageLocked(packageName, pkgUid); 3590 } 3591 } 3592 } 3593 } finally { 3594 Binder.restoreCallingIdentity(callingId); 3595 } 3596 } 3597 3598 /* 3599 * The pkg name and app id have to be specified. 3600 */ 3601 public void killApplicationWithAppId(String pkg, int appid) { 3602 if (pkg == null) { 3603 return; 3604 } 3605 // Make sure the uid is valid. 3606 if (appid < 0) { 3607 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3608 return; 3609 } 3610 int callerUid = Binder.getCallingUid(); 3611 // Only the system server can kill an application 3612 if (callerUid == Process.SYSTEM_UID) { 3613 // Post an aysnc message to kill the application 3614 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3615 msg.arg1 = appid; 3616 msg.arg2 = 0; 3617 msg.obj = pkg; 3618 mHandler.sendMessage(msg); 3619 } else { 3620 throw new SecurityException(callerUid + " cannot kill pkg: " + 3621 pkg); 3622 } 3623 } 3624 3625 public void closeSystemDialogs(String reason) { 3626 enforceNotIsolatedCaller("closeSystemDialogs"); 3627 3628 final int pid = Binder.getCallingPid(); 3629 final int uid = Binder.getCallingUid(); 3630 final long origId = Binder.clearCallingIdentity(); 3631 try { 3632 synchronized (this) { 3633 // Only allow this from foreground processes, so that background 3634 // applications can't abuse it to prevent system UI from being shown. 3635 if (uid >= Process.FIRST_APPLICATION_UID) { 3636 ProcessRecord proc; 3637 synchronized (mPidsSelfLocked) { 3638 proc = mPidsSelfLocked.get(pid); 3639 } 3640 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3641 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3642 + " from background process " + proc); 3643 return; 3644 } 3645 } 3646 closeSystemDialogsLocked(reason); 3647 } 3648 } finally { 3649 Binder.restoreCallingIdentity(origId); 3650 } 3651 } 3652 3653 void closeSystemDialogsLocked(String reason) { 3654 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3655 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3656 | Intent.FLAG_RECEIVER_FOREGROUND); 3657 if (reason != null) { 3658 intent.putExtra("reason", reason); 3659 } 3660 mWindowManager.closeSystemDialogs(reason); 3661 3662 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3663 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3664 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3665 r.stack.finishActivityLocked(r, i, 3666 Activity.RESULT_CANCELED, null, "close-sys", true); 3667 } 3668 } 3669 3670 broadcastIntentLocked(null, null, intent, null, 3671 null, 0, null, null, null, false, false, -1, 3672 Process.SYSTEM_UID, UserHandle.USER_ALL); 3673 } 3674 3675 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3676 throws RemoteException { 3677 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3678 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3679 for (int i=pids.length-1; i>=0; i--) { 3680 infos[i] = new Debug.MemoryInfo(); 3681 Debug.getMemoryInfo(pids[i], infos[i]); 3682 } 3683 return infos; 3684 } 3685 3686 public long[] getProcessPss(int[] pids) throws RemoteException { 3687 enforceNotIsolatedCaller("getProcessPss"); 3688 long[] pss = new long[pids.length]; 3689 for (int i=pids.length-1; i>=0; i--) { 3690 pss[i] = Debug.getPss(pids[i]); 3691 } 3692 return pss; 3693 } 3694 3695 public void killApplicationProcess(String processName, int uid) { 3696 if (processName == null) { 3697 return; 3698 } 3699 3700 int callerUid = Binder.getCallingUid(); 3701 // Only the system server can kill an application 3702 if (callerUid == Process.SYSTEM_UID) { 3703 synchronized (this) { 3704 ProcessRecord app = getProcessRecordLocked(processName, uid); 3705 if (app != null && app.thread != null) { 3706 try { 3707 app.thread.scheduleSuicide(); 3708 } catch (RemoteException e) { 3709 // If the other end already died, then our work here is done. 3710 } 3711 } else { 3712 Slog.w(TAG, "Process/uid not found attempting kill of " 3713 + processName + " / " + uid); 3714 } 3715 } 3716 } else { 3717 throw new SecurityException(callerUid + " cannot kill app process: " + 3718 processName); 3719 } 3720 } 3721 3722 private void forceStopPackageLocked(final String packageName, int uid) { 3723 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3724 false, true, false, UserHandle.getUserId(uid)); 3725 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3726 Uri.fromParts("package", packageName, null)); 3727 if (!mProcessesReady) { 3728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3729 | Intent.FLAG_RECEIVER_FOREGROUND); 3730 } 3731 intent.putExtra(Intent.EXTRA_UID, uid); 3732 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3733 broadcastIntentLocked(null, null, intent, 3734 null, null, 0, null, null, null, 3735 false, false, 3736 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3737 } 3738 3739 private void forceStopUserLocked(int userId) { 3740 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3741 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3743 | Intent.FLAG_RECEIVER_FOREGROUND); 3744 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3745 broadcastIntentLocked(null, null, intent, 3746 null, null, 0, null, null, null, 3747 false, false, 3748 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3749 } 3750 3751 private final boolean killPackageProcessesLocked(String packageName, int appId, 3752 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3753 boolean doit, boolean evenPersistent, String reason) { 3754 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3755 3756 // Remove all processes this package may have touched: all with the 3757 // same UID (except for the system or root user), and all whose name 3758 // matches the package name. 3759 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3760 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3761 final int NA = apps.size(); 3762 for (int ia=0; ia<NA; ia++) { 3763 ProcessRecord app = apps.valueAt(ia); 3764 if (app.persistent && !evenPersistent) { 3765 // we don't kill persistent processes 3766 continue; 3767 } 3768 if (app.removed) { 3769 if (doit) { 3770 procs.add(app); 3771 } 3772 continue; 3773 } 3774 3775 // Skip process if it doesn't meet our oom adj requirement. 3776 if (app.setAdj < minOomAdj) { 3777 continue; 3778 } 3779 3780 // If no package is specified, we call all processes under the 3781 // give user id. 3782 if (packageName == null) { 3783 if (app.userId != userId) { 3784 continue; 3785 } 3786 // Package has been specified, we want to hit all processes 3787 // that match it. We need to qualify this by the processes 3788 // that are running under the specified app and user ID. 3789 } else { 3790 if (UserHandle.getAppId(app.uid) != appId) { 3791 continue; 3792 } 3793 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3794 continue; 3795 } 3796 if (!app.pkgList.contains(packageName)) { 3797 continue; 3798 } 3799 } 3800 3801 // Process has passed all conditions, kill it! 3802 if (!doit) { 3803 return true; 3804 } 3805 app.removed = true; 3806 procs.add(app); 3807 } 3808 } 3809 3810 int N = procs.size(); 3811 for (int i=0; i<N; i++) { 3812 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3813 } 3814 return N > 0; 3815 } 3816 3817 private final boolean forceStopPackageLocked(String name, int appId, 3818 boolean callerWillRestart, boolean purgeCache, boolean doit, 3819 boolean evenPersistent, int userId) { 3820 int i; 3821 int N; 3822 3823 if (userId == UserHandle.USER_ALL && name == null) { 3824 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3825 } 3826 3827 if (appId < 0 && name != null) { 3828 try { 3829 appId = UserHandle.getAppId( 3830 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3831 } catch (RemoteException e) { 3832 } 3833 } 3834 3835 if (doit) { 3836 if (name != null) { 3837 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3838 + " user=" + userId); 3839 } else { 3840 Slog.i(TAG, "Force stopping user " + userId); 3841 } 3842 3843 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3844 while (badApps.hasNext()) { 3845 SparseArray<Long> ba = badApps.next(); 3846 for (i=ba.size()-1; i>=0; i--) { 3847 boolean remove = false; 3848 final int entUid = ba.keyAt(i); 3849 if (name != null) { 3850 if (userId == UserHandle.USER_ALL) { 3851 if (UserHandle.getAppId(entUid) == appId) { 3852 remove = true; 3853 } 3854 } else { 3855 if (entUid == UserHandle.getUid(userId, appId)) { 3856 remove = true; 3857 } 3858 } 3859 } else if (UserHandle.getUserId(entUid) == userId) { 3860 remove = true; 3861 } 3862 if (remove) { 3863 ba.removeAt(i); 3864 } 3865 } 3866 if (ba.size() == 0) { 3867 badApps.remove(); 3868 } 3869 } 3870 } 3871 3872 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3873 -100, callerWillRestart, false, doit, evenPersistent, 3874 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3875 3876 TaskRecord lastTask = null; 3877 for (i=0; i<mMainStack.mHistory.size(); i++) { 3878 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3879 final boolean samePackage = r.packageName.equals(name) 3880 || (name == null && r.userId == userId); 3881 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3882 && (samePackage || r.task == lastTask) 3883 && (r.app == null || evenPersistent || !r.app.persistent)) { 3884 if (!doit) { 3885 if (r.finishing) { 3886 // If this activity is just finishing, then it is not 3887 // interesting as far as something to stop. 3888 continue; 3889 } 3890 return true; 3891 } 3892 didSomething = true; 3893 Slog.i(TAG, " Force finishing activity " + r); 3894 if (samePackage) { 3895 if (r.app != null) { 3896 r.app.removed = true; 3897 } 3898 r.app = null; 3899 } 3900 lastTask = r.task; 3901 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3902 null, "force-stop", true)) { 3903 i--; 3904 } 3905 } 3906 } 3907 3908 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3909 if (!doit) { 3910 return true; 3911 } 3912 didSomething = true; 3913 } 3914 3915 if (name == null) { 3916 // Remove all sticky broadcasts from this user. 3917 mStickyBroadcasts.remove(userId); 3918 } 3919 3920 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3921 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3922 userId, providers)) { 3923 if (!doit) { 3924 return true; 3925 } 3926 didSomething = true; 3927 } 3928 N = providers.size(); 3929 for (i=0; i<N; i++) { 3930 removeDyingProviderLocked(null, providers.get(i), true); 3931 } 3932 3933 if (mIntentSenderRecords.size() > 0) { 3934 Iterator<WeakReference<PendingIntentRecord>> it 3935 = mIntentSenderRecords.values().iterator(); 3936 while (it.hasNext()) { 3937 WeakReference<PendingIntentRecord> wpir = it.next(); 3938 if (wpir == null) { 3939 it.remove(); 3940 continue; 3941 } 3942 PendingIntentRecord pir = wpir.get(); 3943 if (pir == null) { 3944 it.remove(); 3945 continue; 3946 } 3947 if (name == null) { 3948 // Stopping user, remove all objects for the user. 3949 if (pir.key.userId != userId) { 3950 // Not the same user, skip it. 3951 continue; 3952 } 3953 } else { 3954 if (UserHandle.getAppId(pir.uid) != appId) { 3955 // Different app id, skip it. 3956 continue; 3957 } 3958 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3959 // Different user, skip it. 3960 continue; 3961 } 3962 if (!pir.key.packageName.equals(name)) { 3963 // Different package, skip it. 3964 continue; 3965 } 3966 } 3967 if (!doit) { 3968 return true; 3969 } 3970 didSomething = true; 3971 it.remove(); 3972 pir.canceled = true; 3973 if (pir.key.activity != null) { 3974 pir.key.activity.pendingResults.remove(pir.ref); 3975 } 3976 } 3977 } 3978 3979 if (doit) { 3980 if (purgeCache && name != null) { 3981 AttributeCache ac = AttributeCache.instance(); 3982 if (ac != null) { 3983 ac.removePackage(name); 3984 } 3985 } 3986 if (mBooted) { 3987 mMainStack.resumeTopActivityLocked(null); 3988 mMainStack.scheduleIdleLocked(); 3989 } 3990 } 3991 3992 return didSomething; 3993 } 3994 3995 private final boolean removeProcessLocked(ProcessRecord app, 3996 boolean callerWillRestart, boolean allowRestart, String reason) { 3997 final String name = app.processName; 3998 final int uid = app.uid; 3999 if (DEBUG_PROCESSES) Slog.d( 4000 TAG, "Force removing proc " + app.toShortString() + " (" + name 4001 + "/" + uid + ")"); 4002 4003 mProcessNames.remove(name, uid); 4004 mIsolatedProcesses.remove(app.uid); 4005 if (mHeavyWeightProcess == app) { 4006 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4007 mHeavyWeightProcess.userId, 0)); 4008 mHeavyWeightProcess = null; 4009 } 4010 boolean needRestart = false; 4011 if (app.pid > 0 && app.pid != MY_PID) { 4012 int pid = app.pid; 4013 synchronized (mPidsSelfLocked) { 4014 mPidsSelfLocked.remove(pid); 4015 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4016 } 4017 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4018 handleAppDiedLocked(app, true, allowRestart); 4019 mLruProcesses.remove(app); 4020 Process.killProcessQuiet(pid); 4021 4022 if (app.persistent && !app.isolated) { 4023 if (!callerWillRestart) { 4024 addAppLocked(app.info, false); 4025 } else { 4026 needRestart = true; 4027 } 4028 } 4029 } else { 4030 mRemovedProcesses.add(app); 4031 } 4032 4033 return needRestart; 4034 } 4035 4036 private final void processStartTimedOutLocked(ProcessRecord app) { 4037 final int pid = app.pid; 4038 boolean gone = false; 4039 synchronized (mPidsSelfLocked) { 4040 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4041 if (knownApp != null && knownApp.thread == null) { 4042 mPidsSelfLocked.remove(pid); 4043 gone = true; 4044 } 4045 } 4046 4047 if (gone) { 4048 Slog.w(TAG, "Process " + app + " failed to attach"); 4049 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4050 pid, app.uid, app.processName); 4051 mProcessNames.remove(app.processName, app.uid); 4052 mIsolatedProcesses.remove(app.uid); 4053 if (mHeavyWeightProcess == app) { 4054 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4055 mHeavyWeightProcess.userId, 0)); 4056 mHeavyWeightProcess = null; 4057 } 4058 // Take care of any launching providers waiting for this process. 4059 checkAppInLaunchingProvidersLocked(app, true); 4060 // Take care of any services that are waiting for the process. 4061 mServices.processStartTimedOutLocked(app); 4062 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4063 app.processName, app.setAdj, "start timeout"); 4064 Process.killProcessQuiet(pid); 4065 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4066 Slog.w(TAG, "Unattached app died before backup, skipping"); 4067 try { 4068 IBackupManager bm = IBackupManager.Stub.asInterface( 4069 ServiceManager.getService(Context.BACKUP_SERVICE)); 4070 bm.agentDisconnected(app.info.packageName); 4071 } catch (RemoteException e) { 4072 // Can't happen; the backup manager is local 4073 } 4074 } 4075 if (isPendingBroadcastProcessLocked(pid)) { 4076 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4077 skipPendingBroadcastLocked(pid); 4078 } 4079 } else { 4080 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4081 } 4082 } 4083 4084 private final boolean attachApplicationLocked(IApplicationThread thread, 4085 int pid) { 4086 4087 // Find the application record that is being attached... either via 4088 // the pid if we are running in multiple processes, or just pull the 4089 // next app record if we are emulating process with anonymous threads. 4090 ProcessRecord app; 4091 if (pid != MY_PID && pid >= 0) { 4092 synchronized (mPidsSelfLocked) { 4093 app = mPidsSelfLocked.get(pid); 4094 } 4095 } else { 4096 app = null; 4097 } 4098 4099 if (app == null) { 4100 Slog.w(TAG, "No pending application record for pid " + pid 4101 + " (IApplicationThread " + thread + "); dropping process"); 4102 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4103 if (pid > 0 && pid != MY_PID) { 4104 Process.killProcessQuiet(pid); 4105 } else { 4106 try { 4107 thread.scheduleExit(); 4108 } catch (Exception e) { 4109 // Ignore exceptions. 4110 } 4111 } 4112 return false; 4113 } 4114 4115 // If this application record is still attached to a previous 4116 // process, clean it up now. 4117 if (app.thread != null) { 4118 handleAppDiedLocked(app, true, true); 4119 } 4120 4121 // Tell the process all about itself. 4122 4123 if (localLOGV) Slog.v( 4124 TAG, "Binding process pid " + pid + " to record " + app); 4125 4126 String processName = app.processName; 4127 try { 4128 AppDeathRecipient adr = new AppDeathRecipient( 4129 app, pid, thread); 4130 thread.asBinder().linkToDeath(adr, 0); 4131 app.deathRecipient = adr; 4132 } catch (RemoteException e) { 4133 app.resetPackageList(); 4134 startProcessLocked(app, "link fail", processName); 4135 return false; 4136 } 4137 4138 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4139 4140 app.thread = thread; 4141 app.curAdj = app.setAdj = -100; 4142 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4143 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4144 app.forcingToForeground = null; 4145 app.foregroundServices = false; 4146 app.hasShownUi = false; 4147 app.debugging = false; 4148 4149 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4150 4151 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4152 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4153 4154 if (!normalMode) { 4155 Slog.i(TAG, "Launching preboot mode app: " + app); 4156 } 4157 4158 if (localLOGV) Slog.v( 4159 TAG, "New app record " + app 4160 + " thread=" + thread.asBinder() + " pid=" + pid); 4161 try { 4162 int testMode = IApplicationThread.DEBUG_OFF; 4163 if (mDebugApp != null && mDebugApp.equals(processName)) { 4164 testMode = mWaitForDebugger 4165 ? IApplicationThread.DEBUG_WAIT 4166 : IApplicationThread.DEBUG_ON; 4167 app.debugging = true; 4168 if (mDebugTransient) { 4169 mDebugApp = mOrigDebugApp; 4170 mWaitForDebugger = mOrigWaitForDebugger; 4171 } 4172 } 4173 String profileFile = app.instrumentationProfileFile; 4174 ParcelFileDescriptor profileFd = null; 4175 boolean profileAutoStop = false; 4176 if (mProfileApp != null && mProfileApp.equals(processName)) { 4177 mProfileProc = app; 4178 profileFile = mProfileFile; 4179 profileFd = mProfileFd; 4180 profileAutoStop = mAutoStopProfiler; 4181 } 4182 boolean enableOpenGlTrace = false; 4183 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4184 enableOpenGlTrace = true; 4185 mOpenGlTraceApp = null; 4186 } 4187 4188 // If the app is being launched for restore or full backup, set it up specially 4189 boolean isRestrictedBackupMode = false; 4190 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4191 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4192 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4193 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4194 } 4195 4196 ensurePackageDexOpt(app.instrumentationInfo != null 4197 ? app.instrumentationInfo.packageName 4198 : app.info.packageName); 4199 if (app.instrumentationClass != null) { 4200 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4201 } 4202 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4203 + processName + " with config " + mConfiguration); 4204 ApplicationInfo appInfo = app.instrumentationInfo != null 4205 ? app.instrumentationInfo : app.info; 4206 app.compat = compatibilityInfoForPackageLocked(appInfo); 4207 if (profileFd != null) { 4208 profileFd = profileFd.dup(); 4209 } 4210 thread.bindApplication(processName, appInfo, providers, 4211 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4212 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4213 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4214 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4215 mCoreSettingsObserver.getCoreSettingsLocked()); 4216 updateLruProcessLocked(app, false); 4217 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4218 } catch (Exception e) { 4219 // todo: Yikes! What should we do? For now we will try to 4220 // start another process, but that could easily get us in 4221 // an infinite loop of restarting processes... 4222 Slog.w(TAG, "Exception thrown during bind!", e); 4223 4224 app.resetPackageList(); 4225 app.unlinkDeathRecipient(); 4226 startProcessLocked(app, "bind fail", processName); 4227 return false; 4228 } 4229 4230 // Remove this record from the list of starting applications. 4231 mPersistentStartingProcesses.remove(app); 4232 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4233 "Attach application locked removing on hold: " + app); 4234 mProcessesOnHold.remove(app); 4235 4236 boolean badApp = false; 4237 boolean didSomething = false; 4238 4239 // See if the top visible activity is waiting to run in this process... 4240 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4241 if (hr != null && normalMode) { 4242 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4243 && processName.equals(hr.processName)) { 4244 try { 4245 if (mHeadless) { 4246 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4247 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4248 didSomething = true; 4249 } 4250 } catch (Exception e) { 4251 Slog.w(TAG, "Exception in new application when starting activity " 4252 + hr.intent.getComponent().flattenToShortString(), e); 4253 badApp = true; 4254 } 4255 } else { 4256 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4257 } 4258 } 4259 4260 // Find any services that should be running in this process... 4261 if (!badApp) { 4262 try { 4263 didSomething |= mServices.attachApplicationLocked(app, processName); 4264 } catch (Exception e) { 4265 badApp = true; 4266 } 4267 } 4268 4269 // Check if a next-broadcast receiver is in this process... 4270 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4271 try { 4272 didSomething = sendPendingBroadcastsLocked(app); 4273 } catch (Exception e) { 4274 // If the app died trying to launch the receiver we declare it 'bad' 4275 badApp = true; 4276 } 4277 } 4278 4279 // Check whether the next backup agent is in this process... 4280 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4281 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4282 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4283 try { 4284 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4285 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4286 mBackupTarget.backupMode); 4287 } catch (Exception e) { 4288 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4289 e.printStackTrace(); 4290 } 4291 } 4292 4293 if (badApp) { 4294 // todo: Also need to kill application to deal with all 4295 // kinds of exceptions. 4296 handleAppDiedLocked(app, false, true); 4297 return false; 4298 } 4299 4300 if (!didSomething) { 4301 updateOomAdjLocked(); 4302 } 4303 4304 return true; 4305 } 4306 4307 public final void attachApplication(IApplicationThread thread) { 4308 synchronized (this) { 4309 int callingPid = Binder.getCallingPid(); 4310 final long origId = Binder.clearCallingIdentity(); 4311 attachApplicationLocked(thread, callingPid); 4312 Binder.restoreCallingIdentity(origId); 4313 } 4314 } 4315 4316 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4317 final long origId = Binder.clearCallingIdentity(); 4318 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4319 if (stopProfiling) { 4320 synchronized (this) { 4321 if (mProfileProc == r.app) { 4322 if (mProfileFd != null) { 4323 try { 4324 mProfileFd.close(); 4325 } catch (IOException e) { 4326 } 4327 clearProfilerLocked(); 4328 } 4329 } 4330 } 4331 } 4332 Binder.restoreCallingIdentity(origId); 4333 } 4334 4335 void enableScreenAfterBoot() { 4336 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4337 SystemClock.uptimeMillis()); 4338 mWindowManager.enableScreenAfterBoot(); 4339 4340 synchronized (this) { 4341 updateEventDispatchingLocked(); 4342 } 4343 } 4344 4345 public void showBootMessage(final CharSequence msg, final boolean always) { 4346 enforceNotIsolatedCaller("showBootMessage"); 4347 mWindowManager.showBootMessage(msg, always); 4348 } 4349 4350 public void dismissKeyguardOnNextActivity() { 4351 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4352 final long token = Binder.clearCallingIdentity(); 4353 try { 4354 synchronized (this) { 4355 if (mLockScreenShown) { 4356 mLockScreenShown = false; 4357 comeOutOfSleepIfNeededLocked(); 4358 } 4359 mMainStack.dismissKeyguardOnNextActivityLocked(); 4360 } 4361 } finally { 4362 Binder.restoreCallingIdentity(token); 4363 } 4364 } 4365 4366 final void finishBooting() { 4367 IntentFilter pkgFilter = new IntentFilter(); 4368 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4369 pkgFilter.addDataScheme("package"); 4370 mContext.registerReceiver(new BroadcastReceiver() { 4371 @Override 4372 public void onReceive(Context context, Intent intent) { 4373 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4374 if (pkgs != null) { 4375 for (String pkg : pkgs) { 4376 synchronized (ActivityManagerService.this) { 4377 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4378 setResultCode(Activity.RESULT_OK); 4379 return; 4380 } 4381 } 4382 } 4383 } 4384 } 4385 }, pkgFilter); 4386 4387 synchronized (this) { 4388 // Ensure that any processes we had put on hold are now started 4389 // up. 4390 final int NP = mProcessesOnHold.size(); 4391 if (NP > 0) { 4392 ArrayList<ProcessRecord> procs = 4393 new ArrayList<ProcessRecord>(mProcessesOnHold); 4394 for (int ip=0; ip<NP; ip++) { 4395 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4396 + procs.get(ip)); 4397 startProcessLocked(procs.get(ip), "on-hold", null); 4398 } 4399 } 4400 4401 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4402 // Start looking for apps that are abusing wake locks. 4403 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4404 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4405 // Tell anyone interested that we are done booting! 4406 SystemProperties.set("sys.boot_completed", "1"); 4407 SystemProperties.set("dev.bootcomplete", "1"); 4408 for (int i=0; i<mStartedUsers.size(); i++) { 4409 UserStartedState uss = mStartedUsers.valueAt(i); 4410 if (uss.mState == UserStartedState.STATE_BOOTING) { 4411 uss.mState = UserStartedState.STATE_RUNNING; 4412 final int userId = mStartedUsers.keyAt(i); 4413 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4414 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4415 broadcastIntentLocked(null, null, intent, 4416 null, null, 0, null, null, 4417 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4418 false, false, MY_PID, Process.SYSTEM_UID, userId); 4419 } 4420 } 4421 } 4422 } 4423 } 4424 4425 final void ensureBootCompleted() { 4426 boolean booting; 4427 boolean enableScreen; 4428 synchronized (this) { 4429 booting = mBooting; 4430 mBooting = false; 4431 enableScreen = !mBooted; 4432 mBooted = true; 4433 } 4434 4435 if (booting) { 4436 finishBooting(); 4437 } 4438 4439 if (enableScreen) { 4440 enableScreenAfterBoot(); 4441 } 4442 } 4443 4444 public final void activityResumed(IBinder token) { 4445 final long origId = Binder.clearCallingIdentity(); 4446 mMainStack.activityResumed(token); 4447 Binder.restoreCallingIdentity(origId); 4448 } 4449 4450 public final void activityPaused(IBinder token) { 4451 final long origId = Binder.clearCallingIdentity(); 4452 mMainStack.activityPaused(token, false); 4453 Binder.restoreCallingIdentity(origId); 4454 } 4455 4456 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4457 CharSequence description) { 4458 if (localLOGV) Slog.v( 4459 TAG, "Activity stopped: token=" + token); 4460 4461 // Refuse possible leaked file descriptors 4462 if (icicle != null && icicle.hasFileDescriptors()) { 4463 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4464 } 4465 4466 ActivityRecord r = null; 4467 4468 final long origId = Binder.clearCallingIdentity(); 4469 4470 synchronized (this) { 4471 r = mMainStack.isInStackLocked(token); 4472 if (r != null) { 4473 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4474 } 4475 } 4476 4477 if (r != null) { 4478 sendPendingThumbnail(r, null, null, null, false); 4479 } 4480 4481 trimApplications(); 4482 4483 Binder.restoreCallingIdentity(origId); 4484 } 4485 4486 public final void activityDestroyed(IBinder token) { 4487 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4488 mMainStack.activityDestroyed(token); 4489 } 4490 4491 public String getCallingPackage(IBinder token) { 4492 synchronized (this) { 4493 ActivityRecord r = getCallingRecordLocked(token); 4494 return r != null && r.app != null ? r.info.packageName : null; 4495 } 4496 } 4497 4498 public ComponentName getCallingActivity(IBinder token) { 4499 synchronized (this) { 4500 ActivityRecord r = getCallingRecordLocked(token); 4501 return r != null ? r.intent.getComponent() : null; 4502 } 4503 } 4504 4505 private ActivityRecord getCallingRecordLocked(IBinder token) { 4506 ActivityRecord r = mMainStack.isInStackLocked(token); 4507 if (r == null) { 4508 return null; 4509 } 4510 return r.resultTo; 4511 } 4512 4513 public ComponentName getActivityClassForToken(IBinder token) { 4514 synchronized(this) { 4515 ActivityRecord r = mMainStack.isInStackLocked(token); 4516 if (r == null) { 4517 return null; 4518 } 4519 return r.intent.getComponent(); 4520 } 4521 } 4522 4523 public String getPackageForToken(IBinder token) { 4524 synchronized(this) { 4525 ActivityRecord r = mMainStack.isInStackLocked(token); 4526 if (r == null) { 4527 return null; 4528 } 4529 return r.packageName; 4530 } 4531 } 4532 4533 public IIntentSender getIntentSender(int type, 4534 String packageName, IBinder token, String resultWho, 4535 int requestCode, Intent[] intents, String[] resolvedTypes, 4536 int flags, Bundle options, int userId) { 4537 enforceNotIsolatedCaller("getIntentSender"); 4538 // Refuse possible leaked file descriptors 4539 if (intents != null) { 4540 if (intents.length < 1) { 4541 throw new IllegalArgumentException("Intents array length must be >= 1"); 4542 } 4543 for (int i=0; i<intents.length; i++) { 4544 Intent intent = intents[i]; 4545 if (intent != null) { 4546 if (intent.hasFileDescriptors()) { 4547 throw new IllegalArgumentException("File descriptors passed in Intent"); 4548 } 4549 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4550 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4551 throw new IllegalArgumentException( 4552 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4553 } 4554 intents[i] = new Intent(intent); 4555 } 4556 } 4557 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4558 throw new IllegalArgumentException( 4559 "Intent array length does not match resolvedTypes length"); 4560 } 4561 } 4562 if (options != null) { 4563 if (options.hasFileDescriptors()) { 4564 throw new IllegalArgumentException("File descriptors passed in options"); 4565 } 4566 } 4567 4568 synchronized(this) { 4569 int callingUid = Binder.getCallingUid(); 4570 int origUserId = userId; 4571 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4572 type == ActivityManager.INTENT_SENDER_BROADCAST, true, 4573 "getIntentSender", null); 4574 if (origUserId == UserHandle.USER_CURRENT) { 4575 // We don't want to evaluate this until the pending intent is 4576 // actually executed. However, we do want to always do the 4577 // security checking for it above. 4578 userId = UserHandle.USER_CURRENT; 4579 } 4580 try { 4581 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4582 int uid = AppGlobals.getPackageManager() 4583 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4584 if (!UserHandle.isSameApp(callingUid, uid)) { 4585 String msg = "Permission Denial: getIntentSender() from pid=" 4586 + Binder.getCallingPid() 4587 + ", uid=" + Binder.getCallingUid() 4588 + ", (need uid=" + uid + ")" 4589 + " is not allowed to send as package " + packageName; 4590 Slog.w(TAG, msg); 4591 throw new SecurityException(msg); 4592 } 4593 } 4594 4595 return getIntentSenderLocked(type, packageName, callingUid, userId, 4596 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4597 4598 } catch (RemoteException e) { 4599 throw new SecurityException(e); 4600 } 4601 } 4602 } 4603 4604 IIntentSender getIntentSenderLocked(int type, String packageName, 4605 int callingUid, int userId, IBinder token, String resultWho, 4606 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4607 Bundle options) { 4608 if (DEBUG_MU) 4609 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4610 ActivityRecord activity = null; 4611 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4612 activity = mMainStack.isInStackLocked(token); 4613 if (activity == null) { 4614 return null; 4615 } 4616 if (activity.finishing) { 4617 return null; 4618 } 4619 } 4620 4621 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4622 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4623 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4624 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4625 |PendingIntent.FLAG_UPDATE_CURRENT); 4626 4627 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4628 type, packageName, activity, resultWho, 4629 requestCode, intents, resolvedTypes, flags, options, userId); 4630 WeakReference<PendingIntentRecord> ref; 4631 ref = mIntentSenderRecords.get(key); 4632 PendingIntentRecord rec = ref != null ? ref.get() : null; 4633 if (rec != null) { 4634 if (!cancelCurrent) { 4635 if (updateCurrent) { 4636 if (rec.key.requestIntent != null) { 4637 rec.key.requestIntent.replaceExtras(intents != null ? 4638 intents[intents.length - 1] : null); 4639 } 4640 if (intents != null) { 4641 intents[intents.length-1] = rec.key.requestIntent; 4642 rec.key.allIntents = intents; 4643 rec.key.allResolvedTypes = resolvedTypes; 4644 } else { 4645 rec.key.allIntents = null; 4646 rec.key.allResolvedTypes = null; 4647 } 4648 } 4649 return rec; 4650 } 4651 rec.canceled = true; 4652 mIntentSenderRecords.remove(key); 4653 } 4654 if (noCreate) { 4655 return rec; 4656 } 4657 rec = new PendingIntentRecord(this, key, callingUid); 4658 mIntentSenderRecords.put(key, rec.ref); 4659 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4660 if (activity.pendingResults == null) { 4661 activity.pendingResults 4662 = new HashSet<WeakReference<PendingIntentRecord>>(); 4663 } 4664 activity.pendingResults.add(rec.ref); 4665 } 4666 return rec; 4667 } 4668 4669 public void cancelIntentSender(IIntentSender sender) { 4670 if (!(sender instanceof PendingIntentRecord)) { 4671 return; 4672 } 4673 synchronized(this) { 4674 PendingIntentRecord rec = (PendingIntentRecord)sender; 4675 try { 4676 int uid = AppGlobals.getPackageManager() 4677 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4678 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4679 String msg = "Permission Denial: cancelIntentSender() from pid=" 4680 + Binder.getCallingPid() 4681 + ", uid=" + Binder.getCallingUid() 4682 + " is not allowed to cancel packges " 4683 + rec.key.packageName; 4684 Slog.w(TAG, msg); 4685 throw new SecurityException(msg); 4686 } 4687 } catch (RemoteException e) { 4688 throw new SecurityException(e); 4689 } 4690 cancelIntentSenderLocked(rec, true); 4691 } 4692 } 4693 4694 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4695 rec.canceled = true; 4696 mIntentSenderRecords.remove(rec.key); 4697 if (cleanActivity && rec.key.activity != null) { 4698 rec.key.activity.pendingResults.remove(rec.ref); 4699 } 4700 } 4701 4702 public String getPackageForIntentSender(IIntentSender pendingResult) { 4703 if (!(pendingResult instanceof PendingIntentRecord)) { 4704 return null; 4705 } 4706 try { 4707 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4708 return res.key.packageName; 4709 } catch (ClassCastException e) { 4710 } 4711 return null; 4712 } 4713 4714 public int getUidForIntentSender(IIntentSender sender) { 4715 if (sender instanceof PendingIntentRecord) { 4716 try { 4717 PendingIntentRecord res = (PendingIntentRecord)sender; 4718 return res.uid; 4719 } catch (ClassCastException e) { 4720 } 4721 } 4722 return -1; 4723 } 4724 4725 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4726 if (!(pendingResult instanceof PendingIntentRecord)) { 4727 return false; 4728 } 4729 try { 4730 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4731 if (res.key.allIntents == null) { 4732 return false; 4733 } 4734 for (int i=0; i<res.key.allIntents.length; i++) { 4735 Intent intent = res.key.allIntents[i]; 4736 if (intent.getPackage() != null && intent.getComponent() != null) { 4737 return false; 4738 } 4739 } 4740 return true; 4741 } catch (ClassCastException e) { 4742 } 4743 return false; 4744 } 4745 4746 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4747 if (!(pendingResult instanceof PendingIntentRecord)) { 4748 return false; 4749 } 4750 try { 4751 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4752 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4753 return true; 4754 } 4755 return false; 4756 } catch (ClassCastException e) { 4757 } 4758 return false; 4759 } 4760 4761 public void setProcessLimit(int max) { 4762 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4763 "setProcessLimit()"); 4764 synchronized (this) { 4765 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4766 mProcessLimitOverride = max; 4767 } 4768 trimApplications(); 4769 } 4770 4771 public int getProcessLimit() { 4772 synchronized (this) { 4773 return mProcessLimitOverride; 4774 } 4775 } 4776 4777 void foregroundTokenDied(ForegroundToken token) { 4778 synchronized (ActivityManagerService.this) { 4779 synchronized (mPidsSelfLocked) { 4780 ForegroundToken cur 4781 = mForegroundProcesses.get(token.pid); 4782 if (cur != token) { 4783 return; 4784 } 4785 mForegroundProcesses.remove(token.pid); 4786 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4787 if (pr == null) { 4788 return; 4789 } 4790 pr.forcingToForeground = null; 4791 pr.foregroundServices = false; 4792 } 4793 updateOomAdjLocked(); 4794 } 4795 } 4796 4797 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4798 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4799 "setProcessForeground()"); 4800 synchronized(this) { 4801 boolean changed = false; 4802 4803 synchronized (mPidsSelfLocked) { 4804 ProcessRecord pr = mPidsSelfLocked.get(pid); 4805 if (pr == null && isForeground) { 4806 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4807 return; 4808 } 4809 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4810 if (oldToken != null) { 4811 oldToken.token.unlinkToDeath(oldToken, 0); 4812 mForegroundProcesses.remove(pid); 4813 if (pr != null) { 4814 pr.forcingToForeground = null; 4815 } 4816 changed = true; 4817 } 4818 if (isForeground && token != null) { 4819 ForegroundToken newToken = new ForegroundToken() { 4820 public void binderDied() { 4821 foregroundTokenDied(this); 4822 } 4823 }; 4824 newToken.pid = pid; 4825 newToken.token = token; 4826 try { 4827 token.linkToDeath(newToken, 0); 4828 mForegroundProcesses.put(pid, newToken); 4829 pr.forcingToForeground = token; 4830 changed = true; 4831 } catch (RemoteException e) { 4832 // If the process died while doing this, we will later 4833 // do the cleanup with the process death link. 4834 } 4835 } 4836 } 4837 4838 if (changed) { 4839 updateOomAdjLocked(); 4840 } 4841 } 4842 } 4843 4844 // ========================================================= 4845 // PERMISSIONS 4846 // ========================================================= 4847 4848 static class PermissionController extends IPermissionController.Stub { 4849 ActivityManagerService mActivityManagerService; 4850 PermissionController(ActivityManagerService activityManagerService) { 4851 mActivityManagerService = activityManagerService; 4852 } 4853 4854 public boolean checkPermission(String permission, int pid, int uid) { 4855 return mActivityManagerService.checkPermission(permission, pid, 4856 uid) == PackageManager.PERMISSION_GRANTED; 4857 } 4858 } 4859 4860 /** 4861 * This can be called with or without the global lock held. 4862 */ 4863 int checkComponentPermission(String permission, int pid, int uid, 4864 int owningUid, boolean exported) { 4865 // We might be performing an operation on behalf of an indirect binder 4866 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4867 // client identity accordingly before proceeding. 4868 Identity tlsIdentity = sCallerIdentity.get(); 4869 if (tlsIdentity != null) { 4870 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4871 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4872 uid = tlsIdentity.uid; 4873 pid = tlsIdentity.pid; 4874 } 4875 4876 if (pid == MY_PID) { 4877 return PackageManager.PERMISSION_GRANTED; 4878 } 4879 4880 return ActivityManager.checkComponentPermission(permission, uid, 4881 owningUid, exported); 4882 } 4883 4884 /** 4885 * As the only public entry point for permissions checking, this method 4886 * can enforce the semantic that requesting a check on a null global 4887 * permission is automatically denied. (Internally a null permission 4888 * string is used when calling {@link #checkComponentPermission} in cases 4889 * when only uid-based security is needed.) 4890 * 4891 * This can be called with or without the global lock held. 4892 */ 4893 public int checkPermission(String permission, int pid, int uid) { 4894 if (permission == null) { 4895 return PackageManager.PERMISSION_DENIED; 4896 } 4897 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4898 } 4899 4900 /** 4901 * Binder IPC calls go through the public entry point. 4902 * This can be called with or without the global lock held. 4903 */ 4904 int checkCallingPermission(String permission) { 4905 return checkPermission(permission, 4906 Binder.getCallingPid(), 4907 UserHandle.getAppId(Binder.getCallingUid())); 4908 } 4909 4910 /** 4911 * This can be called with or without the global lock held. 4912 */ 4913 void enforceCallingPermission(String permission, String func) { 4914 if (checkCallingPermission(permission) 4915 == PackageManager.PERMISSION_GRANTED) { 4916 return; 4917 } 4918 4919 String msg = "Permission Denial: " + func + " from pid=" 4920 + Binder.getCallingPid() 4921 + ", uid=" + Binder.getCallingUid() 4922 + " requires " + permission; 4923 Slog.w(TAG, msg); 4924 throw new SecurityException(msg); 4925 } 4926 4927 /** 4928 * Determine if UID is holding permissions required to access {@link Uri} in 4929 * the given {@link ProviderInfo}. Final permission checking is always done 4930 * in {@link ContentProvider}. 4931 */ 4932 private final boolean checkHoldingPermissionsLocked( 4933 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4934 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4935 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4936 4937 if (pi.applicationInfo.uid == uid) { 4938 return true; 4939 } else if (!pi.exported) { 4940 return false; 4941 } 4942 4943 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4944 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4945 try { 4946 // check if target holds top-level <provider> permissions 4947 if (!readMet && pi.readPermission != null 4948 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4949 readMet = true; 4950 } 4951 if (!writeMet && pi.writePermission != null 4952 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4953 writeMet = true; 4954 } 4955 4956 // track if unprotected read/write is allowed; any denied 4957 // <path-permission> below removes this ability 4958 boolean allowDefaultRead = pi.readPermission == null; 4959 boolean allowDefaultWrite = pi.writePermission == null; 4960 4961 // check if target holds any <path-permission> that match uri 4962 final PathPermission[] pps = pi.pathPermissions; 4963 if (pps != null) { 4964 final String path = uri.getPath(); 4965 int i = pps.length; 4966 while (i > 0 && (!readMet || !writeMet)) { 4967 i--; 4968 PathPermission pp = pps[i]; 4969 if (pp.match(path)) { 4970 if (!readMet) { 4971 final String pprperm = pp.getReadPermission(); 4972 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4973 + pprperm + " for " + pp.getPath() 4974 + ": match=" + pp.match(path) 4975 + " check=" + pm.checkUidPermission(pprperm, uid)); 4976 if (pprperm != null) { 4977 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4978 readMet = true; 4979 } else { 4980 allowDefaultRead = false; 4981 } 4982 } 4983 } 4984 if (!writeMet) { 4985 final String ppwperm = pp.getWritePermission(); 4986 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4987 + ppwperm + " for " + pp.getPath() 4988 + ": match=" + pp.match(path) 4989 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4990 if (ppwperm != null) { 4991 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4992 writeMet = true; 4993 } else { 4994 allowDefaultWrite = false; 4995 } 4996 } 4997 } 4998 } 4999 } 5000 } 5001 5002 // grant unprotected <provider> read/write, if not blocked by 5003 // <path-permission> above 5004 if (allowDefaultRead) readMet = true; 5005 if (allowDefaultWrite) writeMet = true; 5006 5007 } catch (RemoteException e) { 5008 return false; 5009 } 5010 5011 return readMet && writeMet; 5012 } 5013 5014 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5015 int modeFlags) { 5016 // Root gets to do everything. 5017 if (uid == 0) { 5018 return true; 5019 } 5020 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5021 if (perms == null) return false; 5022 UriPermission perm = perms.get(uri); 5023 if (perm == null) return false; 5024 return (modeFlags&perm.modeFlags) == modeFlags; 5025 } 5026 5027 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5028 enforceNotIsolatedCaller("checkUriPermission"); 5029 5030 // Another redirected-binder-call permissions check as in 5031 // {@link checkComponentPermission}. 5032 Identity tlsIdentity = sCallerIdentity.get(); 5033 if (tlsIdentity != null) { 5034 uid = tlsIdentity.uid; 5035 pid = tlsIdentity.pid; 5036 } 5037 5038 // Our own process gets to do everything. 5039 if (pid == MY_PID) { 5040 return PackageManager.PERMISSION_GRANTED; 5041 } 5042 synchronized(this) { 5043 return checkUriPermissionLocked(uri, uid, modeFlags) 5044 ? PackageManager.PERMISSION_GRANTED 5045 : PackageManager.PERMISSION_DENIED; 5046 } 5047 } 5048 5049 /** 5050 * Check if the targetPkg can be granted permission to access uri by 5051 * the callingUid using the given modeFlags. Throws a security exception 5052 * if callingUid is not allowed to do this. Returns the uid of the target 5053 * if the URI permission grant should be performed; returns -1 if it is not 5054 * needed (for example targetPkg already has permission to access the URI). 5055 * If you already know the uid of the target, you can supply it in 5056 * lastTargetUid else set that to -1. 5057 */ 5058 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5059 Uri uri, int modeFlags, int lastTargetUid) { 5060 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5061 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5062 if (modeFlags == 0) { 5063 return -1; 5064 } 5065 5066 if (targetPkg != null) { 5067 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5068 "Checking grant " + targetPkg + " permission to " + uri); 5069 } 5070 5071 final IPackageManager pm = AppGlobals.getPackageManager(); 5072 5073 // If this is not a content: uri, we can't do anything with it. 5074 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5075 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5076 "Can't grant URI permission for non-content URI: " + uri); 5077 return -1; 5078 } 5079 5080 String name = uri.getAuthority(); 5081 ProviderInfo pi = null; 5082 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5083 UserHandle.getUserId(callingUid)); 5084 if (cpr != null) { 5085 pi = cpr.info; 5086 } else { 5087 try { 5088 pi = pm.resolveContentProvider(name, 5089 PackageManager.GET_URI_PERMISSION_PATTERNS, 5090 UserHandle.getUserId(callingUid)); 5091 } catch (RemoteException ex) { 5092 } 5093 } 5094 if (pi == null) { 5095 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5096 return -1; 5097 } 5098 5099 int targetUid = lastTargetUid; 5100 if (targetUid < 0 && targetPkg != null) { 5101 try { 5102 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5103 if (targetUid < 0) { 5104 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5105 "Can't grant URI permission no uid for: " + targetPkg); 5106 return -1; 5107 } 5108 } catch (RemoteException ex) { 5109 return -1; 5110 } 5111 } 5112 5113 if (targetUid >= 0) { 5114 // First... does the target actually need this permission? 5115 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5116 // No need to grant the target this permission. 5117 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5118 "Target " + targetPkg + " already has full permission to " + uri); 5119 return -1; 5120 } 5121 } else { 5122 // First... there is no target package, so can anyone access it? 5123 boolean allowed = pi.exported; 5124 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5125 if (pi.readPermission != null) { 5126 allowed = false; 5127 } 5128 } 5129 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5130 if (pi.writePermission != null) { 5131 allowed = false; 5132 } 5133 } 5134 if (allowed) { 5135 return -1; 5136 } 5137 } 5138 5139 // Second... is the provider allowing granting of URI permissions? 5140 if (!pi.grantUriPermissions) { 5141 throw new SecurityException("Provider " + pi.packageName 5142 + "/" + pi.name 5143 + " does not allow granting of Uri permissions (uri " 5144 + uri + ")"); 5145 } 5146 if (pi.uriPermissionPatterns != null) { 5147 final int N = pi.uriPermissionPatterns.length; 5148 boolean allowed = false; 5149 for (int i=0; i<N; i++) { 5150 if (pi.uriPermissionPatterns[i] != null 5151 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5152 allowed = true; 5153 break; 5154 } 5155 } 5156 if (!allowed) { 5157 throw new SecurityException("Provider " + pi.packageName 5158 + "/" + pi.name 5159 + " does not allow granting of permission to path of Uri " 5160 + uri); 5161 } 5162 } 5163 5164 // Third... does the caller itself have permission to access 5165 // this uri? 5166 if (callingUid != Process.myUid()) { 5167 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5168 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5169 throw new SecurityException("Uid " + callingUid 5170 + " does not have permission to uri " + uri); 5171 } 5172 } 5173 } 5174 5175 return targetUid; 5176 } 5177 5178 public int checkGrantUriPermission(int callingUid, String targetPkg, 5179 Uri uri, int modeFlags) { 5180 enforceNotIsolatedCaller("checkGrantUriPermission"); 5181 synchronized(this) { 5182 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5183 } 5184 } 5185 5186 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5187 Uri uri, int modeFlags, UriPermissionOwner owner) { 5188 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5189 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5190 if (modeFlags == 0) { 5191 return; 5192 } 5193 5194 // So here we are: the caller has the assumed permission 5195 // to the uri, and the target doesn't. Let's now give this to 5196 // the target. 5197 5198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5199 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5200 5201 HashMap<Uri, UriPermission> targetUris 5202 = mGrantedUriPermissions.get(targetUid); 5203 if (targetUris == null) { 5204 targetUris = new HashMap<Uri, UriPermission>(); 5205 mGrantedUriPermissions.put(targetUid, targetUris); 5206 } 5207 5208 UriPermission perm = targetUris.get(uri); 5209 if (perm == null) { 5210 perm = new UriPermission(targetUid, uri); 5211 targetUris.put(uri, perm); 5212 } 5213 5214 perm.modeFlags |= modeFlags; 5215 if (owner == null) { 5216 perm.globalModeFlags |= modeFlags; 5217 } else { 5218 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5219 perm.readOwners.add(owner); 5220 owner.addReadPermission(perm); 5221 } 5222 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5223 perm.writeOwners.add(owner); 5224 owner.addWritePermission(perm); 5225 } 5226 } 5227 } 5228 5229 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5230 int modeFlags, UriPermissionOwner owner) { 5231 if (targetPkg == null) { 5232 throw new NullPointerException("targetPkg"); 5233 } 5234 5235 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5236 if (targetUid < 0) { 5237 return; 5238 } 5239 5240 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5241 } 5242 5243 static class NeededUriGrants extends ArrayList<Uri> { 5244 final String targetPkg; 5245 final int targetUid; 5246 final int flags; 5247 5248 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5249 targetPkg = _targetPkg; 5250 targetUid = _targetUid; 5251 flags = _flags; 5252 } 5253 } 5254 5255 /** 5256 * Like checkGrantUriPermissionLocked, but takes an Intent. 5257 */ 5258 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5259 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5260 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5261 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5262 + " clip=" + (intent != null ? intent.getClipData() : null) 5263 + " from " + intent + "; flags=0x" 5264 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5265 5266 if (targetPkg == null) { 5267 throw new NullPointerException("targetPkg"); 5268 } 5269 5270 if (intent == null) { 5271 return null; 5272 } 5273 Uri data = intent.getData(); 5274 ClipData clip = intent.getClipData(); 5275 if (data == null && clip == null) { 5276 return null; 5277 } 5278 if (data != null) { 5279 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5280 mode, needed != null ? needed.targetUid : -1); 5281 if (target > 0) { 5282 if (needed == null) { 5283 needed = new NeededUriGrants(targetPkg, target, mode); 5284 } 5285 needed.add(data); 5286 } 5287 } 5288 if (clip != null) { 5289 for (int i=0; i<clip.getItemCount(); i++) { 5290 Uri uri = clip.getItemAt(i).getUri(); 5291 if (uri != null) { 5292 int target = -1; 5293 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5294 mode, needed != null ? needed.targetUid : -1); 5295 if (target > 0) { 5296 if (needed == null) { 5297 needed = new NeededUriGrants(targetPkg, target, mode); 5298 } 5299 needed.add(uri); 5300 } 5301 } else { 5302 Intent clipIntent = clip.getItemAt(i).getIntent(); 5303 if (clipIntent != null) { 5304 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5305 callingUid, targetPkg, clipIntent, mode, needed); 5306 if (newNeeded != null) { 5307 needed = newNeeded; 5308 } 5309 } 5310 } 5311 } 5312 } 5313 5314 return needed; 5315 } 5316 5317 /** 5318 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5319 */ 5320 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5321 UriPermissionOwner owner) { 5322 if (needed != null) { 5323 for (int i=0; i<needed.size(); i++) { 5324 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5325 needed.get(i), needed.flags, owner); 5326 } 5327 } 5328 } 5329 5330 void grantUriPermissionFromIntentLocked(int callingUid, 5331 String targetPkg, Intent intent, UriPermissionOwner owner) { 5332 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5333 intent, intent != null ? intent.getFlags() : 0, null); 5334 if (needed == null) { 5335 return; 5336 } 5337 5338 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5339 } 5340 5341 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5342 Uri uri, int modeFlags) { 5343 enforceNotIsolatedCaller("grantUriPermission"); 5344 synchronized(this) { 5345 final ProcessRecord r = getRecordForAppLocked(caller); 5346 if (r == null) { 5347 throw new SecurityException("Unable to find app for caller " 5348 + caller 5349 + " when granting permission to uri " + uri); 5350 } 5351 if (targetPkg == null) { 5352 throw new IllegalArgumentException("null target"); 5353 } 5354 if (uri == null) { 5355 throw new IllegalArgumentException("null uri"); 5356 } 5357 5358 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5359 null); 5360 } 5361 } 5362 5363 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5364 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5365 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5366 HashMap<Uri, UriPermission> perms 5367 = mGrantedUriPermissions.get(perm.uid); 5368 if (perms != null) { 5369 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5370 "Removing " + perm.uid + " permission to " + perm.uri); 5371 perms.remove(perm.uri); 5372 if (perms.size() == 0) { 5373 mGrantedUriPermissions.remove(perm.uid); 5374 } 5375 } 5376 } 5377 } 5378 5379 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5380 int modeFlags) { 5381 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5382 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5383 if (modeFlags == 0) { 5384 return; 5385 } 5386 5387 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5388 "Revoking all granted permissions to " + uri); 5389 5390 final IPackageManager pm = AppGlobals.getPackageManager(); 5391 5392 final String authority = uri.getAuthority(); 5393 ProviderInfo pi = null; 5394 int userId = UserHandle.getUserId(callingUid); 5395 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5396 if (cpr != null) { 5397 pi = cpr.info; 5398 } else { 5399 try { 5400 pi = pm.resolveContentProvider(authority, 5401 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5402 } catch (RemoteException ex) { 5403 } 5404 } 5405 if (pi == null) { 5406 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5407 return; 5408 } 5409 5410 // Does the caller have this permission on the URI? 5411 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5412 // Right now, if you are not the original owner of the permission, 5413 // you are not allowed to revoke it. 5414 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5415 throw new SecurityException("Uid " + callingUid 5416 + " does not have permission to uri " + uri); 5417 //} 5418 } 5419 5420 // Go through all of the permissions and remove any that match. 5421 final List<String> SEGMENTS = uri.getPathSegments(); 5422 if (SEGMENTS != null) { 5423 final int NS = SEGMENTS.size(); 5424 int N = mGrantedUriPermissions.size(); 5425 for (int i=0; i<N; i++) { 5426 HashMap<Uri, UriPermission> perms 5427 = mGrantedUriPermissions.valueAt(i); 5428 Iterator<UriPermission> it = perms.values().iterator(); 5429 toploop: 5430 while (it.hasNext()) { 5431 UriPermission perm = it.next(); 5432 Uri targetUri = perm.uri; 5433 if (!authority.equals(targetUri.getAuthority())) { 5434 continue; 5435 } 5436 List<String> targetSegments = targetUri.getPathSegments(); 5437 if (targetSegments == null) { 5438 continue; 5439 } 5440 if (targetSegments.size() < NS) { 5441 continue; 5442 } 5443 for (int j=0; j<NS; j++) { 5444 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5445 continue toploop; 5446 } 5447 } 5448 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5449 "Revoking " + perm.uid + " permission to " + perm.uri); 5450 perm.clearModes(modeFlags); 5451 if (perm.modeFlags == 0) { 5452 it.remove(); 5453 } 5454 } 5455 if (perms.size() == 0) { 5456 mGrantedUriPermissions.remove( 5457 mGrantedUriPermissions.keyAt(i)); 5458 N--; 5459 i--; 5460 } 5461 } 5462 } 5463 } 5464 5465 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5466 int modeFlags) { 5467 enforceNotIsolatedCaller("revokeUriPermission"); 5468 synchronized(this) { 5469 final ProcessRecord r = getRecordForAppLocked(caller); 5470 if (r == null) { 5471 throw new SecurityException("Unable to find app for caller " 5472 + caller 5473 + " when revoking permission to uri " + uri); 5474 } 5475 if (uri == null) { 5476 Slog.w(TAG, "revokeUriPermission: null uri"); 5477 return; 5478 } 5479 5480 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5481 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5482 if (modeFlags == 0) { 5483 return; 5484 } 5485 5486 final IPackageManager pm = AppGlobals.getPackageManager(); 5487 5488 final String authority = uri.getAuthority(); 5489 ProviderInfo pi = null; 5490 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5491 if (cpr != null) { 5492 pi = cpr.info; 5493 } else { 5494 try { 5495 pi = pm.resolveContentProvider(authority, 5496 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5497 } catch (RemoteException ex) { 5498 } 5499 } 5500 if (pi == null) { 5501 Slog.w(TAG, "No content provider found for permission revoke: " 5502 + uri.toSafeString()); 5503 return; 5504 } 5505 5506 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5507 } 5508 } 5509 5510 @Override 5511 public IBinder newUriPermissionOwner(String name) { 5512 enforceNotIsolatedCaller("newUriPermissionOwner"); 5513 synchronized(this) { 5514 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5515 return owner.getExternalTokenLocked(); 5516 } 5517 } 5518 5519 @Override 5520 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5521 Uri uri, int modeFlags) { 5522 synchronized(this) { 5523 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5524 if (owner == null) { 5525 throw new IllegalArgumentException("Unknown owner: " + token); 5526 } 5527 if (fromUid != Binder.getCallingUid()) { 5528 if (Binder.getCallingUid() != Process.myUid()) { 5529 // Only system code can grant URI permissions on behalf 5530 // of other users. 5531 throw new SecurityException("nice try"); 5532 } 5533 } 5534 if (targetPkg == null) { 5535 throw new IllegalArgumentException("null target"); 5536 } 5537 if (uri == null) { 5538 throw new IllegalArgumentException("null uri"); 5539 } 5540 5541 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5542 } 5543 } 5544 5545 @Override 5546 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5547 synchronized(this) { 5548 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5549 if (owner == null) { 5550 throw new IllegalArgumentException("Unknown owner: " + token); 5551 } 5552 5553 if (uri == null) { 5554 owner.removeUriPermissionsLocked(mode); 5555 } else { 5556 owner.removeUriPermissionLocked(uri, mode); 5557 } 5558 } 5559 } 5560 5561 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5562 synchronized (this) { 5563 ProcessRecord app = 5564 who != null ? getRecordForAppLocked(who) : null; 5565 if (app == null) return; 5566 5567 Message msg = Message.obtain(); 5568 msg.what = WAIT_FOR_DEBUGGER_MSG; 5569 msg.obj = app; 5570 msg.arg1 = waiting ? 1 : 0; 5571 mHandler.sendMessage(msg); 5572 } 5573 } 5574 5575 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5576 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5577 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5578 outInfo.availMem = Process.getFreeMemory(); 5579 outInfo.totalMem = Process.getTotalMemory(); 5580 outInfo.threshold = homeAppMem; 5581 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5582 outInfo.hiddenAppThreshold = hiddenAppMem; 5583 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5584 ProcessList.SERVICE_ADJ); 5585 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5586 ProcessList.VISIBLE_APP_ADJ); 5587 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5588 ProcessList.FOREGROUND_APP_ADJ); 5589 } 5590 5591 // ========================================================= 5592 // TASK MANAGEMENT 5593 // ========================================================= 5594 5595 public List getTasks(int maxNum, int flags, 5596 IThumbnailReceiver receiver) { 5597 ArrayList list = new ArrayList(); 5598 5599 PendingThumbnailsRecord pending = null; 5600 IApplicationThread topThumbnail = null; 5601 ActivityRecord topRecord = null; 5602 5603 synchronized(this) { 5604 if (localLOGV) Slog.v( 5605 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5606 + ", receiver=" + receiver); 5607 5608 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5609 != PackageManager.PERMISSION_GRANTED) { 5610 if (receiver != null) { 5611 // If the caller wants to wait for pending thumbnails, 5612 // it ain't gonna get them. 5613 try { 5614 receiver.finished(); 5615 } catch (RemoteException ex) { 5616 } 5617 } 5618 String msg = "Permission Denial: getTasks() from pid=" 5619 + Binder.getCallingPid() 5620 + ", uid=" + Binder.getCallingUid() 5621 + " requires " + android.Manifest.permission.GET_TASKS; 5622 Slog.w(TAG, msg); 5623 throw new SecurityException(msg); 5624 } 5625 5626 int pos = mMainStack.mHistory.size()-1; 5627 ActivityRecord next = 5628 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5629 ActivityRecord top = null; 5630 TaskRecord curTask = null; 5631 int numActivities = 0; 5632 int numRunning = 0; 5633 while (pos >= 0 && maxNum > 0) { 5634 final ActivityRecord r = next; 5635 pos--; 5636 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5637 5638 // Initialize state for next task if needed. 5639 if (top == null || 5640 (top.state == ActivityState.INITIALIZING 5641 && top.task == r.task)) { 5642 top = r; 5643 curTask = r.task; 5644 numActivities = numRunning = 0; 5645 } 5646 5647 // Add 'r' into the current task. 5648 numActivities++; 5649 if (r.app != null && r.app.thread != null) { 5650 numRunning++; 5651 } 5652 5653 if (localLOGV) Slog.v( 5654 TAG, r.intent.getComponent().flattenToShortString() 5655 + ": task=" + r.task); 5656 5657 // If the next one is a different task, generate a new 5658 // TaskInfo entry for what we have. 5659 if (next == null || next.task != curTask) { 5660 ActivityManager.RunningTaskInfo ci 5661 = new ActivityManager.RunningTaskInfo(); 5662 ci.id = curTask.taskId; 5663 ci.baseActivity = r.intent.getComponent(); 5664 ci.topActivity = top.intent.getComponent(); 5665 if (top.thumbHolder != null) { 5666 ci.description = top.thumbHolder.lastDescription; 5667 } 5668 ci.numActivities = numActivities; 5669 ci.numRunning = numRunning; 5670 //System.out.println( 5671 // "#" + maxNum + ": " + " descr=" + ci.description); 5672 if (ci.thumbnail == null && receiver != null) { 5673 if (localLOGV) Slog.v( 5674 TAG, "State=" + top.state + "Idle=" + top.idle 5675 + " app=" + top.app 5676 + " thr=" + (top.app != null ? top.app.thread : null)); 5677 if (top.state == ActivityState.RESUMED 5678 || top.state == ActivityState.PAUSING) { 5679 if (top.idle && top.app != null 5680 && top.app.thread != null) { 5681 topRecord = top; 5682 topThumbnail = top.app.thread; 5683 } else { 5684 top.thumbnailNeeded = true; 5685 } 5686 } 5687 if (pending == null) { 5688 pending = new PendingThumbnailsRecord(receiver); 5689 } 5690 pending.pendingRecords.add(top); 5691 } 5692 list.add(ci); 5693 maxNum--; 5694 top = null; 5695 } 5696 } 5697 5698 if (pending != null) { 5699 mPendingThumbnails.add(pending); 5700 } 5701 } 5702 5703 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5704 5705 if (topThumbnail != null) { 5706 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5707 try { 5708 topThumbnail.requestThumbnail(topRecord.appToken); 5709 } catch (Exception e) { 5710 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5711 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5712 } 5713 } 5714 5715 if (pending == null && receiver != null) { 5716 // In this case all thumbnails were available and the client 5717 // is being asked to be told when the remaining ones come in... 5718 // which is unusually, since the top-most currently running 5719 // activity should never have a canned thumbnail! Oh well. 5720 try { 5721 receiver.finished(); 5722 } catch (RemoteException ex) { 5723 } 5724 } 5725 5726 return list; 5727 } 5728 5729 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5730 int flags, int userId) { 5731 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5732 false, true, "getRecentTasks", null); 5733 5734 synchronized (this) { 5735 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5736 "getRecentTasks()"); 5737 final boolean detailed = checkCallingPermission( 5738 android.Manifest.permission.GET_DETAILED_TASKS) 5739 == PackageManager.PERMISSION_GRANTED; 5740 5741 IPackageManager pm = AppGlobals.getPackageManager(); 5742 5743 final int N = mRecentTasks.size(); 5744 ArrayList<ActivityManager.RecentTaskInfo> res 5745 = new ArrayList<ActivityManager.RecentTaskInfo>( 5746 maxNum < N ? maxNum : N); 5747 for (int i=0; i<N && maxNum > 0; i++) { 5748 TaskRecord tr = mRecentTasks.get(i); 5749 // Only add calling user's recent tasks 5750 if (tr.userId != userId) continue; 5751 // Return the entry if desired by the caller. We always return 5752 // the first entry, because callers always expect this to be the 5753 // foreground app. We may filter others if the caller has 5754 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5755 // we should exclude the entry. 5756 5757 if (i == 0 5758 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5759 || (tr.intent == null) 5760 || ((tr.intent.getFlags() 5761 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5762 ActivityManager.RecentTaskInfo rti 5763 = new ActivityManager.RecentTaskInfo(); 5764 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5765 rti.persistentId = tr.taskId; 5766 rti.baseIntent = new Intent( 5767 tr.intent != null ? tr.intent : tr.affinityIntent); 5768 if (!detailed) { 5769 rti.baseIntent.replaceExtras((Bundle)null); 5770 } 5771 rti.origActivity = tr.origActivity; 5772 rti.description = tr.lastDescription; 5773 5774 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5775 // Check whether this activity is currently available. 5776 try { 5777 if (rti.origActivity != null) { 5778 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5779 == null) { 5780 continue; 5781 } 5782 } else if (rti.baseIntent != null) { 5783 if (pm.queryIntentActivities(rti.baseIntent, 5784 null, 0, userId) == null) { 5785 continue; 5786 } 5787 } 5788 } catch (RemoteException e) { 5789 // Will never happen. 5790 } 5791 } 5792 5793 res.add(rti); 5794 maxNum--; 5795 } 5796 } 5797 return res; 5798 } 5799 } 5800 5801 private TaskRecord taskForIdLocked(int id) { 5802 final int N = mRecentTasks.size(); 5803 for (int i=0; i<N; i++) { 5804 TaskRecord tr = mRecentTasks.get(i); 5805 if (tr.taskId == id) { 5806 return tr; 5807 } 5808 } 5809 return null; 5810 } 5811 5812 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5813 synchronized (this) { 5814 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5815 "getTaskThumbnails()"); 5816 TaskRecord tr = taskForIdLocked(id); 5817 if (tr != null) { 5818 return mMainStack.getTaskThumbnailsLocked(tr); 5819 } 5820 } 5821 return null; 5822 } 5823 5824 public Bitmap getTaskTopThumbnail(int id) { 5825 synchronized (this) { 5826 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5827 "getTaskTopThumbnail()"); 5828 TaskRecord tr = taskForIdLocked(id); 5829 if (tr != null) { 5830 return mMainStack.getTaskTopThumbnailLocked(tr); 5831 } 5832 } 5833 return null; 5834 } 5835 5836 public boolean removeSubTask(int taskId, int subTaskIndex) { 5837 synchronized (this) { 5838 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5839 "removeSubTask()"); 5840 long ident = Binder.clearCallingIdentity(); 5841 try { 5842 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5843 true) != null; 5844 } finally { 5845 Binder.restoreCallingIdentity(ident); 5846 } 5847 } 5848 } 5849 5850 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5851 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5852 Intent baseIntent = new Intent( 5853 tr.intent != null ? tr.intent : tr.affinityIntent); 5854 ComponentName component = baseIntent.getComponent(); 5855 if (component == null) { 5856 Slog.w(TAG, "Now component for base intent of task: " + tr); 5857 return; 5858 } 5859 5860 // Find any running services associated with this app. 5861 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5862 5863 if (killProcesses) { 5864 // Find any running processes associated with this app. 5865 final String pkg = component.getPackageName(); 5866 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5867 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5868 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5869 for (int i=0; i<uids.size(); i++) { 5870 ProcessRecord proc = uids.valueAt(i); 5871 if (proc.userId != tr.userId) { 5872 continue; 5873 } 5874 if (!proc.pkgList.contains(pkg)) { 5875 continue; 5876 } 5877 procs.add(proc); 5878 } 5879 } 5880 5881 // Kill the running processes. 5882 for (int i=0; i<procs.size(); i++) { 5883 ProcessRecord pr = procs.get(i); 5884 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5885 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5886 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 5887 pr.processName, pr.setAdj, "remove task"); 5888 pr.killedBackground = true; 5889 Process.killProcessQuiet(pr.pid); 5890 } else { 5891 pr.waitingToKill = "remove task"; 5892 } 5893 } 5894 } 5895 } 5896 5897 public boolean removeTask(int taskId, int flags) { 5898 synchronized (this) { 5899 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5900 "removeTask()"); 5901 long ident = Binder.clearCallingIdentity(); 5902 try { 5903 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5904 false); 5905 if (r != null) { 5906 mRecentTasks.remove(r.task); 5907 cleanUpRemovedTaskLocked(r.task, flags); 5908 return true; 5909 } else { 5910 TaskRecord tr = null; 5911 int i=0; 5912 while (i < mRecentTasks.size()) { 5913 TaskRecord t = mRecentTasks.get(i); 5914 if (t.taskId == taskId) { 5915 tr = t; 5916 break; 5917 } 5918 i++; 5919 } 5920 if (tr != null) { 5921 if (tr.numActivities <= 0) { 5922 // Caller is just removing a recent task that is 5923 // not actively running. That is easy! 5924 mRecentTasks.remove(i); 5925 cleanUpRemovedTaskLocked(tr, flags); 5926 return true; 5927 } else { 5928 Slog.w(TAG, "removeTask: task " + taskId 5929 + " does not have activities to remove, " 5930 + " but numActivities=" + tr.numActivities 5931 + ": " + tr); 5932 } 5933 } 5934 } 5935 } finally { 5936 Binder.restoreCallingIdentity(ident); 5937 } 5938 } 5939 return false; 5940 } 5941 5942 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5943 int j; 5944 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5945 TaskRecord jt = startTask; 5946 5947 // First look backwards 5948 for (j=startIndex-1; j>=0; j--) { 5949 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5950 if (r.task != jt) { 5951 jt = r.task; 5952 if (affinity.equals(jt.affinity)) { 5953 return j; 5954 } 5955 } 5956 } 5957 5958 // Now look forwards 5959 final int N = mMainStack.mHistory.size(); 5960 jt = startTask; 5961 for (j=startIndex+1; j<N; j++) { 5962 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5963 if (r.task != jt) { 5964 if (affinity.equals(jt.affinity)) { 5965 return j; 5966 } 5967 jt = r.task; 5968 } 5969 } 5970 5971 // Might it be at the top? 5972 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5973 return N-1; 5974 } 5975 5976 return -1; 5977 } 5978 5979 /** 5980 * TODO: Add mController hook 5981 */ 5982 public void moveTaskToFront(int task, int flags, Bundle options) { 5983 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5984 "moveTaskToFront()"); 5985 5986 synchronized(this) { 5987 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5988 Binder.getCallingUid(), "Task to front")) { 5989 ActivityOptions.abort(options); 5990 return; 5991 } 5992 final long origId = Binder.clearCallingIdentity(); 5993 try { 5994 TaskRecord tr = taskForIdLocked(task); 5995 if (tr != null) { 5996 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5997 mMainStack.mUserLeaving = true; 5998 } 5999 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6000 // Caller wants the home activity moved with it. To accomplish this, 6001 // we'll just move the home task to the top first. 6002 mMainStack.moveHomeToFrontLocked(); 6003 } 6004 mMainStack.moveTaskToFrontLocked(tr, null, options); 6005 return; 6006 } 6007 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6008 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6009 if (hr.task.taskId == task) { 6010 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6011 mMainStack.mUserLeaving = true; 6012 } 6013 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6014 // Caller wants the home activity moved with it. To accomplish this, 6015 // we'll just move the home task to the top first. 6016 mMainStack.moveHomeToFrontLocked(); 6017 } 6018 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6019 return; 6020 } 6021 } 6022 } finally { 6023 Binder.restoreCallingIdentity(origId); 6024 } 6025 ActivityOptions.abort(options); 6026 } 6027 } 6028 6029 public void moveTaskToBack(int task) { 6030 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6031 "moveTaskToBack()"); 6032 6033 synchronized(this) { 6034 if (mMainStack.mResumedActivity != null 6035 && mMainStack.mResumedActivity.task.taskId == task) { 6036 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6037 Binder.getCallingUid(), "Task to back")) { 6038 return; 6039 } 6040 } 6041 final long origId = Binder.clearCallingIdentity(); 6042 mMainStack.moveTaskToBackLocked(task, null); 6043 Binder.restoreCallingIdentity(origId); 6044 } 6045 } 6046 6047 /** 6048 * Moves an activity, and all of the other activities within the same task, to the bottom 6049 * of the history stack. The activity's order within the task is unchanged. 6050 * 6051 * @param token A reference to the activity we wish to move 6052 * @param nonRoot If false then this only works if the activity is the root 6053 * of a task; if true it will work for any activity in a task. 6054 * @return Returns true if the move completed, false if not. 6055 */ 6056 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6057 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6058 synchronized(this) { 6059 final long origId = Binder.clearCallingIdentity(); 6060 int taskId = getTaskForActivityLocked(token, !nonRoot); 6061 if (taskId >= 0) { 6062 return mMainStack.moveTaskToBackLocked(taskId, null); 6063 } 6064 Binder.restoreCallingIdentity(origId); 6065 } 6066 return false; 6067 } 6068 6069 public void moveTaskBackwards(int task) { 6070 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6071 "moveTaskBackwards()"); 6072 6073 synchronized(this) { 6074 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6075 Binder.getCallingUid(), "Task backwards")) { 6076 return; 6077 } 6078 final long origId = Binder.clearCallingIdentity(); 6079 moveTaskBackwardsLocked(task); 6080 Binder.restoreCallingIdentity(origId); 6081 } 6082 } 6083 6084 private final void moveTaskBackwardsLocked(int task) { 6085 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6086 } 6087 6088 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6089 synchronized(this) { 6090 return getTaskForActivityLocked(token, onlyRoot); 6091 } 6092 } 6093 6094 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6095 final int N = mMainStack.mHistory.size(); 6096 TaskRecord lastTask = null; 6097 for (int i=0; i<N; i++) { 6098 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6099 if (r.appToken == token) { 6100 if (!onlyRoot || lastTask != r.task) { 6101 return r.task.taskId; 6102 } 6103 return -1; 6104 } 6105 lastTask = r.task; 6106 } 6107 6108 return -1; 6109 } 6110 6111 // ========================================================= 6112 // THUMBNAILS 6113 // ========================================================= 6114 6115 public void reportThumbnail(IBinder token, 6116 Bitmap thumbnail, CharSequence description) { 6117 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6118 final long origId = Binder.clearCallingIdentity(); 6119 sendPendingThumbnail(null, token, thumbnail, description, true); 6120 Binder.restoreCallingIdentity(origId); 6121 } 6122 6123 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6124 Bitmap thumbnail, CharSequence description, boolean always) { 6125 TaskRecord task = null; 6126 ArrayList receivers = null; 6127 6128 //System.out.println("Send pending thumbnail: " + r); 6129 6130 synchronized(this) { 6131 if (r == null) { 6132 r = mMainStack.isInStackLocked(token); 6133 if (r == null) { 6134 return; 6135 } 6136 } 6137 if (thumbnail == null && r.thumbHolder != null) { 6138 thumbnail = r.thumbHolder.lastThumbnail; 6139 description = r.thumbHolder.lastDescription; 6140 } 6141 if (thumbnail == null && !always) { 6142 // If there is no thumbnail, and this entry is not actually 6143 // going away, then abort for now and pick up the next 6144 // thumbnail we get. 6145 return; 6146 } 6147 task = r.task; 6148 6149 int N = mPendingThumbnails.size(); 6150 int i=0; 6151 while (i<N) { 6152 PendingThumbnailsRecord pr = 6153 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6154 //System.out.println("Looking in " + pr.pendingRecords); 6155 if (pr.pendingRecords.remove(r)) { 6156 if (receivers == null) { 6157 receivers = new ArrayList(); 6158 } 6159 receivers.add(pr); 6160 if (pr.pendingRecords.size() == 0) { 6161 pr.finished = true; 6162 mPendingThumbnails.remove(i); 6163 N--; 6164 continue; 6165 } 6166 } 6167 i++; 6168 } 6169 } 6170 6171 if (receivers != null) { 6172 final int N = receivers.size(); 6173 for (int i=0; i<N; i++) { 6174 try { 6175 PendingThumbnailsRecord pr = 6176 (PendingThumbnailsRecord)receivers.get(i); 6177 pr.receiver.newThumbnail( 6178 task != null ? task.taskId : -1, thumbnail, description); 6179 if (pr.finished) { 6180 pr.receiver.finished(); 6181 } 6182 } catch (Exception e) { 6183 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6184 } 6185 } 6186 } 6187 } 6188 6189 // ========================================================= 6190 // CONTENT PROVIDERS 6191 // ========================================================= 6192 6193 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6194 List<ProviderInfo> providers = null; 6195 try { 6196 providers = AppGlobals.getPackageManager(). 6197 queryContentProviders(app.processName, app.uid, 6198 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6199 } catch (RemoteException ex) { 6200 } 6201 if (DEBUG_MU) 6202 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6203 int userId = app.userId; 6204 if (providers != null) { 6205 int N = providers.size(); 6206 for (int i=0; i<N; i++) { 6207 ProviderInfo cpi = 6208 (ProviderInfo)providers.get(i); 6209 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6210 cpi.name, cpi.flags); 6211 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6212 // This is a singleton provider, but a user besides the 6213 // default user is asking to initialize a process it runs 6214 // in... well, no, it doesn't actually run in this process, 6215 // it runs in the process of the default user. Get rid of it. 6216 providers.remove(i); 6217 N--; 6218 continue; 6219 } 6220 6221 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6222 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6223 if (cpr == null) { 6224 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6225 mProviderMap.putProviderByClass(comp, cpr); 6226 } 6227 if (DEBUG_MU) 6228 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6229 app.pubProviders.put(cpi.name, cpr); 6230 app.addPackage(cpi.applicationInfo.packageName); 6231 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6232 } 6233 } 6234 return providers; 6235 } 6236 6237 /** 6238 * Check if {@link ProcessRecord} has a possible chance at accessing the 6239 * given {@link ProviderInfo}. Final permission checking is always done 6240 * in {@link ContentProvider}. 6241 */ 6242 private final String checkContentProviderPermissionLocked( 6243 ProviderInfo cpi, ProcessRecord r) { 6244 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6245 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6246 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6247 cpi.applicationInfo.uid, cpi.exported) 6248 == PackageManager.PERMISSION_GRANTED) { 6249 return null; 6250 } 6251 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6252 cpi.applicationInfo.uid, cpi.exported) 6253 == PackageManager.PERMISSION_GRANTED) { 6254 return null; 6255 } 6256 6257 PathPermission[] pps = cpi.pathPermissions; 6258 if (pps != null) { 6259 int i = pps.length; 6260 while (i > 0) { 6261 i--; 6262 PathPermission pp = pps[i]; 6263 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6264 cpi.applicationInfo.uid, cpi.exported) 6265 == PackageManager.PERMISSION_GRANTED) { 6266 return null; 6267 } 6268 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6269 cpi.applicationInfo.uid, cpi.exported) 6270 == PackageManager.PERMISSION_GRANTED) { 6271 return null; 6272 } 6273 } 6274 } 6275 6276 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6277 if (perms != null) { 6278 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6279 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6280 return null; 6281 } 6282 } 6283 } 6284 6285 String msg; 6286 if (!cpi.exported) { 6287 msg = "Permission Denial: opening provider " + cpi.name 6288 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6289 + ", uid=" + callingUid + ") that is not exported from uid " 6290 + cpi.applicationInfo.uid; 6291 } else { 6292 msg = "Permission Denial: opening provider " + cpi.name 6293 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6294 + ", uid=" + callingUid + ") requires " 6295 + cpi.readPermission + " or " + cpi.writePermission; 6296 } 6297 Slog.w(TAG, msg); 6298 return msg; 6299 } 6300 6301 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6302 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6303 if (r != null) { 6304 for (int i=0; i<r.conProviders.size(); i++) { 6305 ContentProviderConnection conn = r.conProviders.get(i); 6306 if (conn.provider == cpr) { 6307 if (DEBUG_PROVIDER) Slog.v(TAG, 6308 "Adding provider requested by " 6309 + r.processName + " from process " 6310 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6311 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6312 if (stable) { 6313 conn.stableCount++; 6314 conn.numStableIncs++; 6315 } else { 6316 conn.unstableCount++; 6317 conn.numUnstableIncs++; 6318 } 6319 return conn; 6320 } 6321 } 6322 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6323 if (stable) { 6324 conn.stableCount = 1; 6325 conn.numStableIncs = 1; 6326 } else { 6327 conn.unstableCount = 1; 6328 conn.numUnstableIncs = 1; 6329 } 6330 cpr.connections.add(conn); 6331 r.conProviders.add(conn); 6332 return conn; 6333 } 6334 cpr.addExternalProcessHandleLocked(externalProcessToken); 6335 return null; 6336 } 6337 6338 boolean decProviderCountLocked(ContentProviderConnection conn, 6339 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6340 if (conn != null) { 6341 cpr = conn.provider; 6342 if (DEBUG_PROVIDER) Slog.v(TAG, 6343 "Removing provider requested by " 6344 + conn.client.processName + " from process " 6345 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6346 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6347 if (stable) { 6348 conn.stableCount--; 6349 } else { 6350 conn.unstableCount--; 6351 } 6352 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6353 cpr.connections.remove(conn); 6354 conn.client.conProviders.remove(conn); 6355 return true; 6356 } 6357 return false; 6358 } 6359 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6360 return false; 6361 } 6362 6363 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6364 String name, IBinder token, boolean stable, int userId) { 6365 ContentProviderRecord cpr; 6366 ContentProviderConnection conn = null; 6367 ProviderInfo cpi = null; 6368 6369 synchronized(this) { 6370 ProcessRecord r = null; 6371 if (caller != null) { 6372 r = getRecordForAppLocked(caller); 6373 if (r == null) { 6374 throw new SecurityException( 6375 "Unable to find app for caller " + caller 6376 + " (pid=" + Binder.getCallingPid() 6377 + ") when getting content provider " + name); 6378 } 6379 } 6380 6381 // First check if this content provider has been published... 6382 cpr = mProviderMap.getProviderByName(name, userId); 6383 boolean providerRunning = cpr != null; 6384 if (providerRunning) { 6385 cpi = cpr.info; 6386 String msg; 6387 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6388 throw new SecurityException(msg); 6389 } 6390 6391 if (r != null && cpr.canRunHere(r)) { 6392 // This provider has been published or is in the process 6393 // of being published... but it is also allowed to run 6394 // in the caller's process, so don't make a connection 6395 // and just let the caller instantiate its own instance. 6396 ContentProviderHolder holder = cpr.newHolder(null); 6397 // don't give caller the provider object, it needs 6398 // to make its own. 6399 holder.provider = null; 6400 return holder; 6401 } 6402 6403 final long origId = Binder.clearCallingIdentity(); 6404 6405 // In this case the provider instance already exists, so we can 6406 // return it right away. 6407 conn = incProviderCountLocked(r, cpr, token, stable); 6408 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6409 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6410 // If this is a perceptible app accessing the provider, 6411 // make sure to count it as being accessed and thus 6412 // back up on the LRU list. This is good because 6413 // content providers are often expensive to start. 6414 updateLruProcessLocked(cpr.proc, false); 6415 } 6416 } 6417 6418 if (cpr.proc != null) { 6419 if (false) { 6420 if (cpr.name.flattenToShortString().equals( 6421 "com.android.providers.calendar/.CalendarProvider2")) { 6422 Slog.v(TAG, "****************** KILLING " 6423 + cpr.name.flattenToShortString()); 6424 Process.killProcess(cpr.proc.pid); 6425 } 6426 } 6427 boolean success = updateOomAdjLocked(cpr.proc); 6428 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6429 // NOTE: there is still a race here where a signal could be 6430 // pending on the process even though we managed to update its 6431 // adj level. Not sure what to do about this, but at least 6432 // the race is now smaller. 6433 if (!success) { 6434 // Uh oh... it looks like the provider's process 6435 // has been killed on us. We need to wait for a new 6436 // process to be started, and make sure its death 6437 // doesn't kill our process. 6438 Slog.i(TAG, 6439 "Existing provider " + cpr.name.flattenToShortString() 6440 + " is crashing; detaching " + r); 6441 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6442 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6443 if (!lastRef) { 6444 // This wasn't the last ref our process had on 6445 // the provider... we have now been killed, bail. 6446 return null; 6447 } 6448 providerRunning = false; 6449 conn = null; 6450 } 6451 } 6452 6453 Binder.restoreCallingIdentity(origId); 6454 } 6455 6456 boolean singleton; 6457 if (!providerRunning) { 6458 try { 6459 cpi = AppGlobals.getPackageManager(). 6460 resolveContentProvider(name, 6461 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6462 } catch (RemoteException ex) { 6463 } 6464 if (cpi == null) { 6465 return null; 6466 } 6467 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6468 cpi.name, cpi.flags); 6469 if (singleton) { 6470 userId = 0; 6471 } 6472 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6473 6474 String msg; 6475 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6476 throw new SecurityException(msg); 6477 } 6478 6479 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6480 && !cpi.processName.equals("system")) { 6481 // If this content provider does not run in the system 6482 // process, and the system is not yet ready to run other 6483 // processes, then fail fast instead of hanging. 6484 throw new IllegalArgumentException( 6485 "Attempt to launch content provider before system ready"); 6486 } 6487 6488 // Make sure that the user who owns this provider is started. If not, 6489 // we don't want to allow it to run. 6490 if (mStartedUsers.get(userId) == null) { 6491 Slog.w(TAG, "Unable to launch app " 6492 + cpi.applicationInfo.packageName + "/" 6493 + cpi.applicationInfo.uid + " for provider " 6494 + name + ": user " + userId + " is stopped"); 6495 return null; 6496 } 6497 6498 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6499 cpr = mProviderMap.getProviderByClass(comp, userId); 6500 final boolean firstClass = cpr == null; 6501 if (firstClass) { 6502 try { 6503 ApplicationInfo ai = 6504 AppGlobals.getPackageManager(). 6505 getApplicationInfo( 6506 cpi.applicationInfo.packageName, 6507 STOCK_PM_FLAGS, userId); 6508 if (ai == null) { 6509 Slog.w(TAG, "No package info for content provider " 6510 + cpi.name); 6511 return null; 6512 } 6513 ai = getAppInfoForUser(ai, userId); 6514 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6515 } catch (RemoteException ex) { 6516 // pm is in same process, this will never happen. 6517 } 6518 } 6519 6520 if (r != null && cpr.canRunHere(r)) { 6521 // If this is a multiprocess provider, then just return its 6522 // info and allow the caller to instantiate it. Only do 6523 // this if the provider is the same user as the caller's 6524 // process, or can run as root (so can be in any process). 6525 return cpr.newHolder(null); 6526 } 6527 6528 if (DEBUG_PROVIDER) { 6529 RuntimeException e = new RuntimeException("here"); 6530 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6531 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6532 } 6533 6534 // This is single process, and our app is now connecting to it. 6535 // See if we are already in the process of launching this 6536 // provider. 6537 final int N = mLaunchingProviders.size(); 6538 int i; 6539 for (i=0; i<N; i++) { 6540 if (mLaunchingProviders.get(i) == cpr) { 6541 break; 6542 } 6543 } 6544 6545 // If the provider is not already being launched, then get it 6546 // started. 6547 if (i >= N) { 6548 final long origId = Binder.clearCallingIdentity(); 6549 6550 try { 6551 // Content provider is now in use, its package can't be stopped. 6552 try { 6553 AppGlobals.getPackageManager().setPackageStoppedState( 6554 cpr.appInfo.packageName, false, userId); 6555 } catch (RemoteException e) { 6556 } catch (IllegalArgumentException e) { 6557 Slog.w(TAG, "Failed trying to unstop package " 6558 + cpr.appInfo.packageName + ": " + e); 6559 } 6560 6561 ProcessRecord proc = startProcessLocked(cpi.processName, 6562 cpr.appInfo, false, 0, "content provider", 6563 new ComponentName(cpi.applicationInfo.packageName, 6564 cpi.name), false, false); 6565 if (proc == null) { 6566 Slog.w(TAG, "Unable to launch app " 6567 + cpi.applicationInfo.packageName + "/" 6568 + cpi.applicationInfo.uid + " for provider " 6569 + name + ": process is bad"); 6570 return null; 6571 } 6572 cpr.launchingApp = proc; 6573 mLaunchingProviders.add(cpr); 6574 } finally { 6575 Binder.restoreCallingIdentity(origId); 6576 } 6577 } 6578 6579 // Make sure the provider is published (the same provider class 6580 // may be published under multiple names). 6581 if (firstClass) { 6582 mProviderMap.putProviderByClass(comp, cpr); 6583 } 6584 6585 mProviderMap.putProviderByName(name, cpr); 6586 conn = incProviderCountLocked(r, cpr, token, stable); 6587 if (conn != null) { 6588 conn.waiting = true; 6589 } 6590 } 6591 } 6592 6593 // Wait for the provider to be published... 6594 synchronized (cpr) { 6595 while (cpr.provider == null) { 6596 if (cpr.launchingApp == null) { 6597 Slog.w(TAG, "Unable to launch app " 6598 + cpi.applicationInfo.packageName + "/" 6599 + cpi.applicationInfo.uid + " for provider " 6600 + name + ": launching app became null"); 6601 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6602 UserHandle.getUserId(cpi.applicationInfo.uid), 6603 cpi.applicationInfo.packageName, 6604 cpi.applicationInfo.uid, name); 6605 return null; 6606 } 6607 try { 6608 if (DEBUG_MU) { 6609 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6610 + cpr.launchingApp); 6611 } 6612 if (conn != null) { 6613 conn.waiting = true; 6614 } 6615 cpr.wait(); 6616 } catch (InterruptedException ex) { 6617 } finally { 6618 if (conn != null) { 6619 conn.waiting = false; 6620 } 6621 } 6622 } 6623 } 6624 return cpr != null ? cpr.newHolder(conn) : null; 6625 } 6626 6627 public final ContentProviderHolder getContentProvider( 6628 IApplicationThread caller, String name, int userId, boolean stable) { 6629 enforceNotIsolatedCaller("getContentProvider"); 6630 if (caller == null) { 6631 String msg = "null IApplicationThread when getting content provider " 6632 + name; 6633 Slog.w(TAG, msg); 6634 throw new SecurityException(msg); 6635 } 6636 6637 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6638 false, true, "getContentProvider", null); 6639 return getContentProviderImpl(caller, name, null, stable, userId); 6640 } 6641 6642 public ContentProviderHolder getContentProviderExternal( 6643 String name, int userId, IBinder token) { 6644 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6645 "Do not have permission in call getContentProviderExternal()"); 6646 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6647 false, true, "getContentProvider", null); 6648 return getContentProviderExternalUnchecked(name, token, userId); 6649 } 6650 6651 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6652 IBinder token, int userId) { 6653 return getContentProviderImpl(null, name, token, true, userId); 6654 } 6655 6656 /** 6657 * Drop a content provider from a ProcessRecord's bookkeeping 6658 * @param cpr 6659 */ 6660 public void removeContentProvider(IBinder connection, boolean stable) { 6661 enforceNotIsolatedCaller("removeContentProvider"); 6662 synchronized (this) { 6663 ContentProviderConnection conn; 6664 try { 6665 conn = (ContentProviderConnection)connection; 6666 } catch (ClassCastException e) { 6667 String msg ="removeContentProvider: " + connection 6668 + " not a ContentProviderConnection"; 6669 Slog.w(TAG, msg); 6670 throw new IllegalArgumentException(msg); 6671 } 6672 if (conn == null) { 6673 throw new NullPointerException("connection is null"); 6674 } 6675 if (decProviderCountLocked(conn, null, null, stable)) { 6676 updateOomAdjLocked(); 6677 } 6678 } 6679 } 6680 6681 public void removeContentProviderExternal(String name, IBinder token) { 6682 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6683 "Do not have permission in call removeContentProviderExternal()"); 6684 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6685 } 6686 6687 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6688 synchronized (this) { 6689 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6690 if(cpr == null) { 6691 //remove from mProvidersByClass 6692 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6693 return; 6694 } 6695 6696 //update content provider record entry info 6697 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6698 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6699 if (localCpr.hasExternalProcessHandles()) { 6700 if (localCpr.removeExternalProcessHandleLocked(token)) { 6701 updateOomAdjLocked(); 6702 } else { 6703 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6704 + " with no external reference for token: " 6705 + token + "."); 6706 } 6707 } else { 6708 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6709 + " with no external references."); 6710 } 6711 } 6712 } 6713 6714 public final void publishContentProviders(IApplicationThread caller, 6715 List<ContentProviderHolder> providers) { 6716 if (providers == null) { 6717 return; 6718 } 6719 6720 enforceNotIsolatedCaller("publishContentProviders"); 6721 synchronized (this) { 6722 final ProcessRecord r = getRecordForAppLocked(caller); 6723 if (DEBUG_MU) 6724 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6725 if (r == null) { 6726 throw new SecurityException( 6727 "Unable to find app for caller " + caller 6728 + " (pid=" + Binder.getCallingPid() 6729 + ") when publishing content providers"); 6730 } 6731 6732 final long origId = Binder.clearCallingIdentity(); 6733 6734 final int N = providers.size(); 6735 for (int i=0; i<N; i++) { 6736 ContentProviderHolder src = providers.get(i); 6737 if (src == null || src.info == null || src.provider == null) { 6738 continue; 6739 } 6740 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6741 if (DEBUG_MU) 6742 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6743 if (dst != null) { 6744 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6745 mProviderMap.putProviderByClass(comp, dst); 6746 String names[] = dst.info.authority.split(";"); 6747 for (int j = 0; j < names.length; j++) { 6748 mProviderMap.putProviderByName(names[j], dst); 6749 } 6750 6751 int NL = mLaunchingProviders.size(); 6752 int j; 6753 for (j=0; j<NL; j++) { 6754 if (mLaunchingProviders.get(j) == dst) { 6755 mLaunchingProviders.remove(j); 6756 j--; 6757 NL--; 6758 } 6759 } 6760 synchronized (dst) { 6761 dst.provider = src.provider; 6762 dst.proc = r; 6763 dst.notifyAll(); 6764 } 6765 updateOomAdjLocked(r); 6766 } 6767 } 6768 6769 Binder.restoreCallingIdentity(origId); 6770 } 6771 } 6772 6773 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6774 ContentProviderConnection conn; 6775 try { 6776 conn = (ContentProviderConnection)connection; 6777 } catch (ClassCastException e) { 6778 String msg ="refContentProvider: " + connection 6779 + " not a ContentProviderConnection"; 6780 Slog.w(TAG, msg); 6781 throw new IllegalArgumentException(msg); 6782 } 6783 if (conn == null) { 6784 throw new NullPointerException("connection is null"); 6785 } 6786 6787 synchronized (this) { 6788 if (stable > 0) { 6789 conn.numStableIncs += stable; 6790 } 6791 stable = conn.stableCount + stable; 6792 if (stable < 0) { 6793 throw new IllegalStateException("stableCount < 0: " + stable); 6794 } 6795 6796 if (unstable > 0) { 6797 conn.numUnstableIncs += unstable; 6798 } 6799 unstable = conn.unstableCount + unstable; 6800 if (unstable < 0) { 6801 throw new IllegalStateException("unstableCount < 0: " + unstable); 6802 } 6803 6804 if ((stable+unstable) <= 0) { 6805 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6806 + stable + " unstable=" + unstable); 6807 } 6808 conn.stableCount = stable; 6809 conn.unstableCount = unstable; 6810 return !conn.dead; 6811 } 6812 } 6813 6814 public void unstableProviderDied(IBinder connection) { 6815 ContentProviderConnection conn; 6816 try { 6817 conn = (ContentProviderConnection)connection; 6818 } catch (ClassCastException e) { 6819 String msg ="refContentProvider: " + connection 6820 + " not a ContentProviderConnection"; 6821 Slog.w(TAG, msg); 6822 throw new IllegalArgumentException(msg); 6823 } 6824 if (conn == null) { 6825 throw new NullPointerException("connection is null"); 6826 } 6827 6828 // Safely retrieve the content provider associated with the connection. 6829 IContentProvider provider; 6830 synchronized (this) { 6831 provider = conn.provider.provider; 6832 } 6833 6834 if (provider == null) { 6835 // Um, yeah, we're way ahead of you. 6836 return; 6837 } 6838 6839 // Make sure the caller is being honest with us. 6840 if (provider.asBinder().pingBinder()) { 6841 // Er, no, still looks good to us. 6842 synchronized (this) { 6843 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6844 + " says " + conn + " died, but we don't agree"); 6845 return; 6846 } 6847 } 6848 6849 // Well look at that! It's dead! 6850 synchronized (this) { 6851 if (conn.provider.provider != provider) { 6852 // But something changed... good enough. 6853 return; 6854 } 6855 6856 ProcessRecord proc = conn.provider.proc; 6857 if (proc == null || proc.thread == null) { 6858 // Seems like the process is already cleaned up. 6859 return; 6860 } 6861 6862 // As far as we're concerned, this is just like receiving a 6863 // death notification... just a bit prematurely. 6864 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6865 + ") early provider death"); 6866 final long ident = Binder.clearCallingIdentity(); 6867 try { 6868 appDiedLocked(proc, proc.pid, proc.thread); 6869 } finally { 6870 Binder.restoreCallingIdentity(ident); 6871 } 6872 } 6873 } 6874 6875 public static final void installSystemProviders() { 6876 List<ProviderInfo> providers; 6877 synchronized (mSelf) { 6878 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6879 providers = mSelf.generateApplicationProvidersLocked(app); 6880 if (providers != null) { 6881 for (int i=providers.size()-1; i>=0; i--) { 6882 ProviderInfo pi = (ProviderInfo)providers.get(i); 6883 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6884 Slog.w(TAG, "Not installing system proc provider " + pi.name 6885 + ": not system .apk"); 6886 providers.remove(i); 6887 } 6888 } 6889 } 6890 } 6891 if (providers != null) { 6892 mSystemThread.installSystemProviders(providers); 6893 } 6894 6895 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6896 6897 mSelf.mUsageStatsService.monitorPackages(); 6898 } 6899 6900 /** 6901 * Allows app to retrieve the MIME type of a URI without having permission 6902 * to access its content provider. 6903 * 6904 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6905 * 6906 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6907 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6908 */ 6909 public String getProviderMimeType(Uri uri, int userId) { 6910 enforceNotIsolatedCaller("getProviderMimeType"); 6911 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6912 userId, false, true, "getProviderMimeType", null); 6913 final String name = uri.getAuthority(); 6914 final long ident = Binder.clearCallingIdentity(); 6915 ContentProviderHolder holder = null; 6916 6917 try { 6918 holder = getContentProviderExternalUnchecked(name, null, userId); 6919 if (holder != null) { 6920 return holder.provider.getType(uri); 6921 } 6922 } catch (RemoteException e) { 6923 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6924 return null; 6925 } finally { 6926 if (holder != null) { 6927 removeContentProviderExternalUnchecked(name, null, userId); 6928 } 6929 Binder.restoreCallingIdentity(ident); 6930 } 6931 6932 return null; 6933 } 6934 6935 // ========================================================= 6936 // GLOBAL MANAGEMENT 6937 // ========================================================= 6938 6939 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6940 ApplicationInfo info, String customProcess, boolean isolated) { 6941 String proc = customProcess != null ? customProcess : info.processName; 6942 BatteryStatsImpl.Uid.Proc ps = null; 6943 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6944 int uid = info.uid; 6945 if (isolated) { 6946 int userId = UserHandle.getUserId(uid); 6947 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6948 uid = 0; 6949 while (true) { 6950 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6951 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6952 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6953 } 6954 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6955 mNextIsolatedProcessUid++; 6956 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6957 // No process for this uid, use it. 6958 break; 6959 } 6960 stepsLeft--; 6961 if (stepsLeft <= 0) { 6962 return null; 6963 } 6964 } 6965 } 6966 synchronized (stats) { 6967 ps = stats.getProcessStatsLocked(info.uid, proc); 6968 } 6969 return new ProcessRecord(ps, thread, info, proc, uid); 6970 } 6971 6972 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6973 ProcessRecord app; 6974 if (!isolated) { 6975 app = getProcessRecordLocked(info.processName, info.uid); 6976 } else { 6977 app = null; 6978 } 6979 6980 if (app == null) { 6981 app = newProcessRecordLocked(null, info, null, isolated); 6982 mProcessNames.put(info.processName, app.uid, app); 6983 if (isolated) { 6984 mIsolatedProcesses.put(app.uid, app); 6985 } 6986 updateLruProcessLocked(app, true); 6987 } 6988 6989 // This package really, really can not be stopped. 6990 try { 6991 AppGlobals.getPackageManager().setPackageStoppedState( 6992 info.packageName, false, UserHandle.getUserId(app.uid)); 6993 } catch (RemoteException e) { 6994 } catch (IllegalArgumentException e) { 6995 Slog.w(TAG, "Failed trying to unstop package " 6996 + info.packageName + ": " + e); 6997 } 6998 6999 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7000 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7001 app.persistent = true; 7002 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7003 } 7004 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7005 mPersistentStartingProcesses.add(app); 7006 startProcessLocked(app, "added application", app.processName); 7007 } 7008 7009 return app; 7010 } 7011 7012 public void unhandledBack() { 7013 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7014 "unhandledBack()"); 7015 7016 synchronized(this) { 7017 int count = mMainStack.mHistory.size(); 7018 if (DEBUG_SWITCH) Slog.d( 7019 TAG, "Performing unhandledBack(): stack size = " + count); 7020 if (count > 1) { 7021 final long origId = Binder.clearCallingIdentity(); 7022 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7023 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7024 Binder.restoreCallingIdentity(origId); 7025 } 7026 } 7027 } 7028 7029 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7030 enforceNotIsolatedCaller("openContentUri"); 7031 final int userId = UserHandle.getCallingUserId(); 7032 String name = uri.getAuthority(); 7033 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7034 ParcelFileDescriptor pfd = null; 7035 if (cph != null) { 7036 // We record the binder invoker's uid in thread-local storage before 7037 // going to the content provider to open the file. Later, in the code 7038 // that handles all permissions checks, we look for this uid and use 7039 // that rather than the Activity Manager's own uid. The effect is that 7040 // we do the check against the caller's permissions even though it looks 7041 // to the content provider like the Activity Manager itself is making 7042 // the request. 7043 sCallerIdentity.set(new Identity( 7044 Binder.getCallingPid(), Binder.getCallingUid())); 7045 try { 7046 pfd = cph.provider.openFile(uri, "r"); 7047 } catch (FileNotFoundException e) { 7048 // do nothing; pfd will be returned null 7049 } finally { 7050 // Ensure that whatever happens, we clean up the identity state 7051 sCallerIdentity.remove(); 7052 } 7053 7054 // We've got the fd now, so we're done with the provider. 7055 removeContentProviderExternalUnchecked(name, null, userId); 7056 } else { 7057 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7058 } 7059 return pfd; 7060 } 7061 7062 // Actually is sleeping or shutting down or whatever else in the future 7063 // is an inactive state. 7064 public boolean isSleeping() { 7065 return mSleeping || mShuttingDown; 7066 } 7067 7068 public void goingToSleep() { 7069 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7070 != PackageManager.PERMISSION_GRANTED) { 7071 throw new SecurityException("Requires permission " 7072 + android.Manifest.permission.DEVICE_POWER); 7073 } 7074 7075 synchronized(this) { 7076 mWentToSleep = true; 7077 updateEventDispatchingLocked(); 7078 7079 if (!mSleeping) { 7080 mSleeping = true; 7081 mMainStack.stopIfSleepingLocked(); 7082 7083 // Initialize the wake times of all processes. 7084 checkExcessivePowerUsageLocked(false); 7085 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7086 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7087 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7088 } 7089 } 7090 } 7091 7092 public boolean shutdown(int timeout) { 7093 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7094 != PackageManager.PERMISSION_GRANTED) { 7095 throw new SecurityException("Requires permission " 7096 + android.Manifest.permission.SHUTDOWN); 7097 } 7098 7099 boolean timedout = false; 7100 7101 synchronized(this) { 7102 mShuttingDown = true; 7103 updateEventDispatchingLocked(); 7104 7105 if (mMainStack.mResumedActivity != null) { 7106 mMainStack.stopIfSleepingLocked(); 7107 final long endTime = System.currentTimeMillis() + timeout; 7108 while (mMainStack.mResumedActivity != null 7109 || mMainStack.mPausingActivity != null) { 7110 long delay = endTime - System.currentTimeMillis(); 7111 if (delay <= 0) { 7112 Slog.w(TAG, "Activity manager shutdown timed out"); 7113 timedout = true; 7114 break; 7115 } 7116 try { 7117 this.wait(); 7118 } catch (InterruptedException e) { 7119 } 7120 } 7121 } 7122 } 7123 7124 mUsageStatsService.shutdown(); 7125 mBatteryStatsService.shutdown(); 7126 7127 return timedout; 7128 } 7129 7130 public final void activitySlept(IBinder token) { 7131 if (localLOGV) Slog.v( 7132 TAG, "Activity slept: token=" + token); 7133 7134 ActivityRecord r = null; 7135 7136 final long origId = Binder.clearCallingIdentity(); 7137 7138 synchronized (this) { 7139 r = mMainStack.isInStackLocked(token); 7140 if (r != null) { 7141 mMainStack.activitySleptLocked(r); 7142 } 7143 } 7144 7145 Binder.restoreCallingIdentity(origId); 7146 } 7147 7148 private void comeOutOfSleepIfNeededLocked() { 7149 if (!mWentToSleep && !mLockScreenShown) { 7150 if (mSleeping) { 7151 mSleeping = false; 7152 mMainStack.awakeFromSleepingLocked(); 7153 mMainStack.resumeTopActivityLocked(null); 7154 } 7155 } 7156 } 7157 7158 public void wakingUp() { 7159 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7160 != PackageManager.PERMISSION_GRANTED) { 7161 throw new SecurityException("Requires permission " 7162 + android.Manifest.permission.DEVICE_POWER); 7163 } 7164 7165 synchronized(this) { 7166 mWentToSleep = false; 7167 updateEventDispatchingLocked(); 7168 comeOutOfSleepIfNeededLocked(); 7169 } 7170 } 7171 7172 private void updateEventDispatchingLocked() { 7173 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7174 } 7175 7176 public void setLockScreenShown(boolean shown) { 7177 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7178 != PackageManager.PERMISSION_GRANTED) { 7179 throw new SecurityException("Requires permission " 7180 + android.Manifest.permission.DEVICE_POWER); 7181 } 7182 7183 synchronized(this) { 7184 mLockScreenShown = shown; 7185 comeOutOfSleepIfNeededLocked(); 7186 } 7187 } 7188 7189 public void stopAppSwitches() { 7190 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7191 != PackageManager.PERMISSION_GRANTED) { 7192 throw new SecurityException("Requires permission " 7193 + android.Manifest.permission.STOP_APP_SWITCHES); 7194 } 7195 7196 synchronized(this) { 7197 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7198 + APP_SWITCH_DELAY_TIME; 7199 mDidAppSwitch = false; 7200 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7201 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7202 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7203 } 7204 } 7205 7206 public void resumeAppSwitches() { 7207 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7208 != PackageManager.PERMISSION_GRANTED) { 7209 throw new SecurityException("Requires permission " 7210 + android.Manifest.permission.STOP_APP_SWITCHES); 7211 } 7212 7213 synchronized(this) { 7214 // Note that we don't execute any pending app switches... we will 7215 // let those wait until either the timeout, or the next start 7216 // activity request. 7217 mAppSwitchesAllowedTime = 0; 7218 } 7219 } 7220 7221 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7222 String name) { 7223 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7224 return true; 7225 } 7226 7227 final int perm = checkComponentPermission( 7228 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7229 callingUid, -1, true); 7230 if (perm == PackageManager.PERMISSION_GRANTED) { 7231 return true; 7232 } 7233 7234 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7235 return false; 7236 } 7237 7238 public void setDebugApp(String packageName, boolean waitForDebugger, 7239 boolean persistent) { 7240 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7241 "setDebugApp()"); 7242 7243 // Note that this is not really thread safe if there are multiple 7244 // callers into it at the same time, but that's not a situation we 7245 // care about. 7246 if (persistent) { 7247 final ContentResolver resolver = mContext.getContentResolver(); 7248 Settings.System.putString( 7249 resolver, Settings.System.DEBUG_APP, 7250 packageName); 7251 Settings.System.putInt( 7252 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7253 waitForDebugger ? 1 : 0); 7254 } 7255 7256 synchronized (this) { 7257 if (!persistent) { 7258 mOrigDebugApp = mDebugApp; 7259 mOrigWaitForDebugger = mWaitForDebugger; 7260 } 7261 mDebugApp = packageName; 7262 mWaitForDebugger = waitForDebugger; 7263 mDebugTransient = !persistent; 7264 if (packageName != null) { 7265 final long origId = Binder.clearCallingIdentity(); 7266 forceStopPackageLocked(packageName, -1, false, false, true, true, 7267 UserHandle.USER_ALL); 7268 Binder.restoreCallingIdentity(origId); 7269 } 7270 } 7271 } 7272 7273 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7274 synchronized (this) { 7275 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7276 if (!isDebuggable) { 7277 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7278 throw new SecurityException("Process not debuggable: " + app.packageName); 7279 } 7280 } 7281 7282 mOpenGlTraceApp = processName; 7283 } 7284 } 7285 7286 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7287 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7288 synchronized (this) { 7289 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7290 if (!isDebuggable) { 7291 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7292 throw new SecurityException("Process not debuggable: " + app.packageName); 7293 } 7294 } 7295 mProfileApp = processName; 7296 mProfileFile = profileFile; 7297 if (mProfileFd != null) { 7298 try { 7299 mProfileFd.close(); 7300 } catch (IOException e) { 7301 } 7302 mProfileFd = null; 7303 } 7304 mProfileFd = profileFd; 7305 mProfileType = 0; 7306 mAutoStopProfiler = autoStopProfiler; 7307 } 7308 } 7309 7310 public void setAlwaysFinish(boolean enabled) { 7311 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7312 "setAlwaysFinish()"); 7313 7314 Settings.System.putInt( 7315 mContext.getContentResolver(), 7316 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7317 7318 synchronized (this) { 7319 mAlwaysFinishActivities = enabled; 7320 } 7321 } 7322 7323 public void setActivityController(IActivityController controller) { 7324 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7325 "setActivityController()"); 7326 synchronized (this) { 7327 mController = controller; 7328 } 7329 } 7330 7331 public boolean isUserAMonkey() { 7332 // For now the fact that there is a controller implies 7333 // we have a monkey. 7334 synchronized (this) { 7335 return mController != null; 7336 } 7337 } 7338 7339 public void requestBugReport() { 7340 // No permission check because this can't do anything harmful -- 7341 // it will just eventually cause the user to be presented with 7342 // a UI to select where the bug report goes. 7343 SystemProperties.set("ctl.start", "bugreport"); 7344 } 7345 7346 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) { 7347 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 7348 != PackageManager.PERMISSION_GRANTED) { 7349 throw new SecurityException("Requires permission " 7350 + android.Manifest.permission.FILTER_EVENTS); 7351 } 7352 7353 ProcessRecord proc; 7354 7355 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut(). 7356 synchronized (this) { 7357 synchronized (mPidsSelfLocked) { 7358 proc = mPidsSelfLocked.get(pid); 7359 } 7360 if (proc != null) { 7361 if (proc.debugging) { 7362 return -1; 7363 } 7364 7365 if (mDidDexOpt) { 7366 // Give more time since we were dexopting. 7367 mDidDexOpt = false; 7368 return -1; 7369 } 7370 7371 if (proc.instrumentationClass != null) { 7372 Bundle info = new Bundle(); 7373 info.putString("shortMsg", "keyDispatchingTimedOut"); 7374 info.putString("longMsg", "Timed out while dispatching key event"); 7375 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 7376 proc = null; 7377 } 7378 } 7379 } 7380 7381 if (proc != null) { 7382 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut"); 7383 if (proc.instrumentationClass != null || proc.usingWrapper) { 7384 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 7385 } 7386 } 7387 7388 return KEY_DISPATCHING_TIMEOUT; 7389 } 7390 7391 public void registerProcessObserver(IProcessObserver observer) { 7392 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7393 "registerProcessObserver()"); 7394 synchronized (this) { 7395 mProcessObservers.register(observer); 7396 } 7397 } 7398 7399 public void unregisterProcessObserver(IProcessObserver observer) { 7400 synchronized (this) { 7401 mProcessObservers.unregister(observer); 7402 } 7403 } 7404 7405 public void setImmersive(IBinder token, boolean immersive) { 7406 synchronized(this) { 7407 ActivityRecord r = mMainStack.isInStackLocked(token); 7408 if (r == null) { 7409 throw new IllegalArgumentException(); 7410 } 7411 r.immersive = immersive; 7412 } 7413 } 7414 7415 public boolean isImmersive(IBinder token) { 7416 synchronized (this) { 7417 ActivityRecord r = mMainStack.isInStackLocked(token); 7418 if (r == null) { 7419 throw new IllegalArgumentException(); 7420 } 7421 return r.immersive; 7422 } 7423 } 7424 7425 public boolean isTopActivityImmersive() { 7426 enforceNotIsolatedCaller("startActivity"); 7427 synchronized (this) { 7428 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7429 return (r != null) ? r.immersive : false; 7430 } 7431 } 7432 7433 public final void enterSafeMode() { 7434 synchronized(this) { 7435 // It only makes sense to do this before the system is ready 7436 // and started launching other packages. 7437 if (!mSystemReady) { 7438 try { 7439 AppGlobals.getPackageManager().enterSafeMode(); 7440 } catch (RemoteException e) { 7441 } 7442 } 7443 } 7444 } 7445 7446 public final void showSafeModeOverlay() { 7447 View v = LayoutInflater.from(mContext).inflate( 7448 com.android.internal.R.layout.safe_mode, null); 7449 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7450 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7451 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7452 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7453 lp.gravity = Gravity.BOTTOM | Gravity.START; 7454 lp.format = v.getBackground().getOpacity(); 7455 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7456 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7457 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 7458 ((WindowManager)mContext.getSystemService( 7459 Context.WINDOW_SERVICE)).addView(v, lp); 7460 } 7461 7462 public void noteWakeupAlarm(IIntentSender sender) { 7463 if (!(sender instanceof PendingIntentRecord)) { 7464 return; 7465 } 7466 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7467 synchronized (stats) { 7468 if (mBatteryStatsService.isOnBattery()) { 7469 mBatteryStatsService.enforceCallingPermission(); 7470 PendingIntentRecord rec = (PendingIntentRecord)sender; 7471 int MY_UID = Binder.getCallingUid(); 7472 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7473 BatteryStatsImpl.Uid.Pkg pkg = 7474 stats.getPackageStatsLocked(uid, rec.key.packageName); 7475 pkg.incWakeupsLocked(); 7476 } 7477 } 7478 } 7479 7480 public boolean killPids(int[] pids, String pReason, boolean secure) { 7481 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7482 throw new SecurityException("killPids only available to the system"); 7483 } 7484 String reason = (pReason == null) ? "Unknown" : pReason; 7485 // XXX Note: don't acquire main activity lock here, because the window 7486 // manager calls in with its locks held. 7487 7488 boolean killed = false; 7489 synchronized (mPidsSelfLocked) { 7490 int[] types = new int[pids.length]; 7491 int worstType = 0; 7492 for (int i=0; i<pids.length; i++) { 7493 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7494 if (proc != null) { 7495 int type = proc.setAdj; 7496 types[i] = type; 7497 if (type > worstType) { 7498 worstType = type; 7499 } 7500 } 7501 } 7502 7503 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7504 // then constrain it so we will kill all hidden procs. 7505 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7506 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7507 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7508 } 7509 7510 // If this is not a secure call, don't let it kill processes that 7511 // are important. 7512 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7513 worstType = ProcessList.SERVICE_ADJ; 7514 } 7515 7516 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7517 for (int i=0; i<pids.length; i++) { 7518 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7519 if (proc == null) { 7520 continue; 7521 } 7522 int adj = proc.setAdj; 7523 if (adj >= worstType && !proc.killedBackground) { 7524 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7525 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7526 proc.processName, adj, reason); 7527 killed = true; 7528 proc.killedBackground = true; 7529 Process.killProcessQuiet(pids[i]); 7530 } 7531 } 7532 } 7533 return killed; 7534 } 7535 7536 @Override 7537 public boolean killProcessesBelowForeground(String reason) { 7538 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7539 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7540 } 7541 7542 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7543 } 7544 7545 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7546 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7547 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7548 } 7549 7550 boolean killed = false; 7551 synchronized (mPidsSelfLocked) { 7552 final int size = mPidsSelfLocked.size(); 7553 for (int i = 0; i < size; i++) { 7554 final int pid = mPidsSelfLocked.keyAt(i); 7555 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7556 if (proc == null) continue; 7557 7558 final int adj = proc.setAdj; 7559 if (adj > belowAdj && !proc.killedBackground) { 7560 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7561 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7562 proc.pid, proc.processName, adj, reason); 7563 killed = true; 7564 proc.killedBackground = true; 7565 Process.killProcessQuiet(pid); 7566 } 7567 } 7568 } 7569 return killed; 7570 } 7571 7572 public final void startRunning(String pkg, String cls, String action, 7573 String data) { 7574 synchronized(this) { 7575 if (mStartRunning) { 7576 return; 7577 } 7578 mStartRunning = true; 7579 mTopComponent = pkg != null && cls != null 7580 ? new ComponentName(pkg, cls) : null; 7581 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7582 mTopData = data; 7583 if (!mSystemReady) { 7584 return; 7585 } 7586 } 7587 7588 systemReady(null); 7589 } 7590 7591 private void retrieveSettings() { 7592 final ContentResolver resolver = mContext.getContentResolver(); 7593 String debugApp = Settings.System.getString( 7594 resolver, Settings.System.DEBUG_APP); 7595 boolean waitForDebugger = Settings.System.getInt( 7596 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7597 boolean alwaysFinishActivities = Settings.System.getInt( 7598 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7599 7600 Configuration configuration = new Configuration(); 7601 Settings.System.getConfiguration(resolver, configuration); 7602 7603 synchronized (this) { 7604 mDebugApp = mOrigDebugApp = debugApp; 7605 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7606 mAlwaysFinishActivities = alwaysFinishActivities; 7607 // This happens before any activities are started, so we can 7608 // change mConfiguration in-place. 7609 updateConfigurationLocked(configuration, null, false, true); 7610 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7611 } 7612 } 7613 7614 public boolean testIsSystemReady() { 7615 // no need to synchronize(this) just to read & return the value 7616 return mSystemReady; 7617 } 7618 7619 private static File getCalledPreBootReceiversFile() { 7620 File dataDir = Environment.getDataDirectory(); 7621 File systemDir = new File(dataDir, "system"); 7622 File fname = new File(systemDir, "called_pre_boots.dat"); 7623 return fname; 7624 } 7625 7626 static final int LAST_DONE_VERSION = 10000; 7627 7628 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7629 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7630 File file = getCalledPreBootReceiversFile(); 7631 FileInputStream fis = null; 7632 try { 7633 fis = new FileInputStream(file); 7634 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7635 int fvers = dis.readInt(); 7636 if (fvers == LAST_DONE_VERSION) { 7637 String vers = dis.readUTF(); 7638 String codename = dis.readUTF(); 7639 String build = dis.readUTF(); 7640 if (android.os.Build.VERSION.RELEASE.equals(vers) 7641 && android.os.Build.VERSION.CODENAME.equals(codename) 7642 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7643 int num = dis.readInt(); 7644 while (num > 0) { 7645 num--; 7646 String pkg = dis.readUTF(); 7647 String cls = dis.readUTF(); 7648 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7649 } 7650 } 7651 } 7652 } catch (FileNotFoundException e) { 7653 } catch (IOException e) { 7654 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7655 } finally { 7656 if (fis != null) { 7657 try { 7658 fis.close(); 7659 } catch (IOException e) { 7660 } 7661 } 7662 } 7663 return lastDoneReceivers; 7664 } 7665 7666 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7667 File file = getCalledPreBootReceiversFile(); 7668 FileOutputStream fos = null; 7669 DataOutputStream dos = null; 7670 try { 7671 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7672 fos = new FileOutputStream(file); 7673 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7674 dos.writeInt(LAST_DONE_VERSION); 7675 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7676 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7677 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7678 dos.writeInt(list.size()); 7679 for (int i=0; i<list.size(); i++) { 7680 dos.writeUTF(list.get(i).getPackageName()); 7681 dos.writeUTF(list.get(i).getClassName()); 7682 } 7683 } catch (IOException e) { 7684 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7685 file.delete(); 7686 } finally { 7687 FileUtils.sync(fos); 7688 if (dos != null) { 7689 try { 7690 dos.close(); 7691 } catch (IOException e) { 7692 // TODO Auto-generated catch block 7693 e.printStackTrace(); 7694 } 7695 } 7696 } 7697 } 7698 7699 public void systemReady(final Runnable goingCallback) { 7700 synchronized(this) { 7701 if (mSystemReady) { 7702 if (goingCallback != null) goingCallback.run(); 7703 return; 7704 } 7705 7706 // Check to see if there are any update receivers to run. 7707 if (!mDidUpdate) { 7708 if (mWaitingUpdate) { 7709 return; 7710 } 7711 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7712 List<ResolveInfo> ris = null; 7713 try { 7714 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7715 intent, null, 0, 0); 7716 } catch (RemoteException e) { 7717 } 7718 if (ris != null) { 7719 for (int i=ris.size()-1; i>=0; i--) { 7720 if ((ris.get(i).activityInfo.applicationInfo.flags 7721 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7722 ris.remove(i); 7723 } 7724 } 7725 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7726 7727 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7728 7729 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7730 for (int i=0; i<ris.size(); i++) { 7731 ActivityInfo ai = ris.get(i).activityInfo; 7732 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7733 if (lastDoneReceivers.contains(comp)) { 7734 ris.remove(i); 7735 i--; 7736 } 7737 } 7738 7739 final int[] users = getUsersLocked(); 7740 for (int i=0; i<ris.size(); i++) { 7741 ActivityInfo ai = ris.get(i).activityInfo; 7742 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7743 doneReceivers.add(comp); 7744 intent.setComponent(comp); 7745 for (int j=0; j<users.length; j++) { 7746 IIntentReceiver finisher = null; 7747 if (i == ris.size()-1 && j == users.length-1) { 7748 finisher = new IIntentReceiver.Stub() { 7749 public void performReceive(Intent intent, int resultCode, 7750 String data, Bundle extras, boolean ordered, 7751 boolean sticky, int sendingUser) { 7752 // The raw IIntentReceiver interface is called 7753 // with the AM lock held, so redispatch to 7754 // execute our code without the lock. 7755 mHandler.post(new Runnable() { 7756 public void run() { 7757 synchronized (ActivityManagerService.this) { 7758 mDidUpdate = true; 7759 } 7760 writeLastDonePreBootReceivers(doneReceivers); 7761 showBootMessage(mContext.getText( 7762 R.string.android_upgrading_complete), 7763 false); 7764 systemReady(goingCallback); 7765 } 7766 }); 7767 } 7768 }; 7769 } 7770 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7771 + " for user " + users[j]); 7772 broadcastIntentLocked(null, null, intent, null, finisher, 7773 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7774 users[j]); 7775 if (finisher != null) { 7776 mWaitingUpdate = true; 7777 } 7778 } 7779 } 7780 } 7781 if (mWaitingUpdate) { 7782 return; 7783 } 7784 mDidUpdate = true; 7785 } 7786 7787 mSystemReady = true; 7788 if (!mStartRunning) { 7789 return; 7790 } 7791 } 7792 7793 ArrayList<ProcessRecord> procsToKill = null; 7794 synchronized(mPidsSelfLocked) { 7795 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7796 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7797 if (!isAllowedWhileBooting(proc.info)){ 7798 if (procsToKill == null) { 7799 procsToKill = new ArrayList<ProcessRecord>(); 7800 } 7801 procsToKill.add(proc); 7802 } 7803 } 7804 } 7805 7806 synchronized(this) { 7807 if (procsToKill != null) { 7808 for (int i=procsToKill.size()-1; i>=0; i--) { 7809 ProcessRecord proc = procsToKill.get(i); 7810 Slog.i(TAG, "Removing system update proc: " + proc); 7811 removeProcessLocked(proc, true, false, "system update done"); 7812 } 7813 } 7814 7815 // Now that we have cleaned up any update processes, we 7816 // are ready to start launching real processes and know that 7817 // we won't trample on them any more. 7818 mProcessesReady = true; 7819 } 7820 7821 Slog.i(TAG, "System now ready"); 7822 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7823 SystemClock.uptimeMillis()); 7824 7825 synchronized(this) { 7826 // Make sure we have no pre-ready processes sitting around. 7827 7828 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7829 ResolveInfo ri = mContext.getPackageManager() 7830 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7831 STOCK_PM_FLAGS); 7832 CharSequence errorMsg = null; 7833 if (ri != null) { 7834 ActivityInfo ai = ri.activityInfo; 7835 ApplicationInfo app = ai.applicationInfo; 7836 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7837 mTopAction = Intent.ACTION_FACTORY_TEST; 7838 mTopData = null; 7839 mTopComponent = new ComponentName(app.packageName, 7840 ai.name); 7841 } else { 7842 errorMsg = mContext.getResources().getText( 7843 com.android.internal.R.string.factorytest_not_system); 7844 } 7845 } else { 7846 errorMsg = mContext.getResources().getText( 7847 com.android.internal.R.string.factorytest_no_action); 7848 } 7849 if (errorMsg != null) { 7850 mTopAction = null; 7851 mTopData = null; 7852 mTopComponent = null; 7853 Message msg = Message.obtain(); 7854 msg.what = SHOW_FACTORY_ERROR_MSG; 7855 msg.getData().putCharSequence("msg", errorMsg); 7856 mHandler.sendMessage(msg); 7857 } 7858 } 7859 } 7860 7861 retrieveSettings(); 7862 7863 if (goingCallback != null) goingCallback.run(); 7864 7865 synchronized (this) { 7866 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7867 try { 7868 List apps = AppGlobals.getPackageManager(). 7869 getPersistentApplications(STOCK_PM_FLAGS); 7870 if (apps != null) { 7871 int N = apps.size(); 7872 int i; 7873 for (i=0; i<N; i++) { 7874 ApplicationInfo info 7875 = (ApplicationInfo)apps.get(i); 7876 if (info != null && 7877 !info.packageName.equals("android")) { 7878 addAppLocked(info, false); 7879 } 7880 } 7881 } 7882 } catch (RemoteException ex) { 7883 // pm is in same process, this will never happen. 7884 } 7885 } 7886 7887 // Start up initial activity. 7888 mBooting = true; 7889 7890 try { 7891 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7892 Message msg = Message.obtain(); 7893 msg.what = SHOW_UID_ERROR_MSG; 7894 mHandler.sendMessage(msg); 7895 } 7896 } catch (RemoteException e) { 7897 } 7898 7899 long ident = Binder.clearCallingIdentity(); 7900 try { 7901 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7902 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 7903 | Intent.FLAG_RECEIVER_FOREGROUND); 7904 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7905 broadcastIntentLocked(null, null, intent, 7906 null, null, 0, null, null, null, 7907 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7908 intent = new Intent(Intent.ACTION_USER_STARTING); 7909 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7910 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7911 broadcastIntentLocked(null, null, intent, 7912 null, new IIntentReceiver.Stub() { 7913 @Override 7914 public void performReceive(Intent intent, int resultCode, String data, 7915 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 7916 throws RemoteException { 7917 } 7918 }, 0, null, null, 7919 android.Manifest.permission.INTERACT_ACROSS_USERS, 7920 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 7921 } finally { 7922 Binder.restoreCallingIdentity(ident); 7923 } 7924 mMainStack.resumeTopActivityLocked(null); 7925 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7926 } 7927 } 7928 7929 private boolean makeAppCrashingLocked(ProcessRecord app, 7930 String shortMsg, String longMsg, String stackTrace) { 7931 app.crashing = true; 7932 app.crashingReport = generateProcessError(app, 7933 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7934 startAppProblemLocked(app); 7935 app.stopFreezingAllLocked(); 7936 return handleAppCrashLocked(app); 7937 } 7938 7939 private void makeAppNotRespondingLocked(ProcessRecord app, 7940 String activity, String shortMsg, String longMsg) { 7941 app.notResponding = true; 7942 app.notRespondingReport = generateProcessError(app, 7943 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7944 activity, shortMsg, longMsg, null); 7945 startAppProblemLocked(app); 7946 app.stopFreezingAllLocked(); 7947 } 7948 7949 /** 7950 * Generate a process error record, suitable for attachment to a ProcessRecord. 7951 * 7952 * @param app The ProcessRecord in which the error occurred. 7953 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7954 * ActivityManager.AppErrorStateInfo 7955 * @param activity The activity associated with the crash, if known. 7956 * @param shortMsg Short message describing the crash. 7957 * @param longMsg Long message describing the crash. 7958 * @param stackTrace Full crash stack trace, may be null. 7959 * 7960 * @return Returns a fully-formed AppErrorStateInfo record. 7961 */ 7962 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7963 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7964 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7965 7966 report.condition = condition; 7967 report.processName = app.processName; 7968 report.pid = app.pid; 7969 report.uid = app.info.uid; 7970 report.tag = activity; 7971 report.shortMsg = shortMsg; 7972 report.longMsg = longMsg; 7973 report.stackTrace = stackTrace; 7974 7975 return report; 7976 } 7977 7978 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7979 synchronized (this) { 7980 app.crashing = false; 7981 app.crashingReport = null; 7982 app.notResponding = false; 7983 app.notRespondingReport = null; 7984 if (app.anrDialog == fromDialog) { 7985 app.anrDialog = null; 7986 } 7987 if (app.waitDialog == fromDialog) { 7988 app.waitDialog = null; 7989 } 7990 if (app.pid > 0 && app.pid != MY_PID) { 7991 handleAppCrashLocked(app); 7992 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7993 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 7994 app.processName, app.setAdj, "user's request after error"); 7995 Process.killProcessQuiet(app.pid); 7996 } 7997 } 7998 } 7999 8000 private boolean handleAppCrashLocked(ProcessRecord app) { 8001 if (mHeadless) { 8002 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 8003 return false; 8004 } 8005 long now = SystemClock.uptimeMillis(); 8006 8007 Long crashTime; 8008 if (!app.isolated) { 8009 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 8010 } else { 8011 crashTime = null; 8012 } 8013 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 8014 // This process loses! 8015 Slog.w(TAG, "Process " + app.info.processName 8016 + " has crashed too many times: killing!"); 8017 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8018 app.userId, app.info.processName, app.uid); 8019 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 8020 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 8021 if (r.app == app) { 8022 Slog.w(TAG, " Force finishing activity " 8023 + r.intent.getComponent().flattenToShortString()); 8024 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 8025 null, "crashed", false); 8026 } 8027 } 8028 if (!app.persistent) { 8029 // We don't want to start this process again until the user 8030 // explicitly does so... but for persistent process, we really 8031 // need to keep it running. If a persistent process is actually 8032 // repeatedly crashing, then badness for everyone. 8033 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 8034 app.info.processName); 8035 if (!app.isolated) { 8036 // XXX We don't have a way to mark isolated processes 8037 // as bad, since they don't have a peristent identity. 8038 mBadProcesses.put(app.info.processName, app.uid, now); 8039 mProcessCrashTimes.remove(app.info.processName, app.uid); 8040 } 8041 app.bad = true; 8042 app.removed = true; 8043 // Don't let services in this process be restarted and potentially 8044 // annoy the user repeatedly. Unless it is persistent, since those 8045 // processes run critical code. 8046 removeProcessLocked(app, false, false, "crash"); 8047 mMainStack.resumeTopActivityLocked(null); 8048 return false; 8049 } 8050 mMainStack.resumeTopActivityLocked(null); 8051 } else { 8052 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8053 if (r != null && r.app == app) { 8054 // If the top running activity is from this crashing 8055 // process, then terminate it to avoid getting in a loop. 8056 Slog.w(TAG, " Force finishing activity " 8057 + r.intent.getComponent().flattenToShortString()); 8058 int index = mMainStack.indexOfActivityLocked(r); 8059 r.stack.finishActivityLocked(r, index, 8060 Activity.RESULT_CANCELED, null, "crashed", false); 8061 // Also terminate any activities below it that aren't yet 8062 // stopped, to avoid a situation where one will get 8063 // re-start our crashing activity once it gets resumed again. 8064 index--; 8065 if (index >= 0) { 8066 r = (ActivityRecord)mMainStack.mHistory.get(index); 8067 if (r.state == ActivityState.RESUMED 8068 || r.state == ActivityState.PAUSING 8069 || r.state == ActivityState.PAUSED) { 8070 if (!r.isHomeActivity || mHomeProcess != r.app) { 8071 Slog.w(TAG, " Force finishing activity " 8072 + r.intent.getComponent().flattenToShortString()); 8073 r.stack.finishActivityLocked(r, index, 8074 Activity.RESULT_CANCELED, null, "crashed", false); 8075 } 8076 } 8077 } 8078 } 8079 } 8080 8081 // Bump up the crash count of any services currently running in the proc. 8082 if (app.services.size() != 0) { 8083 // Any services running in the application need to be placed 8084 // back in the pending list. 8085 Iterator<ServiceRecord> it = app.services.iterator(); 8086 while (it.hasNext()) { 8087 ServiceRecord sr = it.next(); 8088 sr.crashCount++; 8089 } 8090 } 8091 8092 // If the crashing process is what we consider to be the "home process" and it has been 8093 // replaced by a third-party app, clear the package preferred activities from packages 8094 // with a home activity running in the process to prevent a repeatedly crashing app 8095 // from blocking the user to manually clear the list. 8096 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8097 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8098 Iterator it = mHomeProcess.activities.iterator(); 8099 while (it.hasNext()) { 8100 ActivityRecord r = (ActivityRecord)it.next(); 8101 if (r.isHomeActivity) { 8102 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8103 try { 8104 ActivityThread.getPackageManager() 8105 .clearPackagePreferredActivities(r.packageName); 8106 } catch (RemoteException c) { 8107 // pm is in same process, this will never happen. 8108 } 8109 } 8110 } 8111 } 8112 8113 if (!app.isolated) { 8114 // XXX Can't keep track of crash times for isolated processes, 8115 // because they don't have a perisistent identity. 8116 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8117 } 8118 8119 return true; 8120 } 8121 8122 void startAppProblemLocked(ProcessRecord app) { 8123 if (app.userId == mCurrentUserId) { 8124 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8125 mContext, app.info.packageName, app.info.flags); 8126 } else { 8127 // If this app is not running under the current user, then we 8128 // can't give it a report button because that would require 8129 // launching the report UI under a different user. 8130 app.errorReportReceiver = null; 8131 } 8132 skipCurrentReceiverLocked(app); 8133 } 8134 8135 void skipCurrentReceiverLocked(ProcessRecord app) { 8136 for (BroadcastQueue queue : mBroadcastQueues) { 8137 queue.skipCurrentReceiverLocked(app); 8138 } 8139 } 8140 8141 /** 8142 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8143 * The application process will exit immediately after this call returns. 8144 * @param app object of the crashing app, null for the system server 8145 * @param crashInfo describing the exception 8146 */ 8147 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8148 ProcessRecord r = findAppProcess(app, "Crash"); 8149 final String processName = app == null ? "system_server" 8150 : (r == null ? "unknown" : r.processName); 8151 8152 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8153 UserHandle.getUserId(Binder.getCallingUid()), processName, 8154 r == null ? -1 : r.info.flags, 8155 crashInfo.exceptionClassName, 8156 crashInfo.exceptionMessage, 8157 crashInfo.throwFileName, 8158 crashInfo.throwLineNumber); 8159 8160 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8161 8162 crashApplication(r, crashInfo); 8163 } 8164 8165 public void handleApplicationStrictModeViolation( 8166 IBinder app, 8167 int violationMask, 8168 StrictMode.ViolationInfo info) { 8169 ProcessRecord r = findAppProcess(app, "StrictMode"); 8170 if (r == null) { 8171 return; 8172 } 8173 8174 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8175 Integer stackFingerprint = info.hashCode(); 8176 boolean logIt = true; 8177 synchronized (mAlreadyLoggedViolatedStacks) { 8178 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8179 logIt = false; 8180 // TODO: sub-sample into EventLog for these, with 8181 // the info.durationMillis? Then we'd get 8182 // the relative pain numbers, without logging all 8183 // the stack traces repeatedly. We'd want to do 8184 // likewise in the client code, which also does 8185 // dup suppression, before the Binder call. 8186 } else { 8187 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8188 mAlreadyLoggedViolatedStacks.clear(); 8189 } 8190 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8191 } 8192 } 8193 if (logIt) { 8194 logStrictModeViolationToDropBox(r, info); 8195 } 8196 } 8197 8198 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8199 AppErrorResult result = new AppErrorResult(); 8200 synchronized (this) { 8201 final long origId = Binder.clearCallingIdentity(); 8202 8203 Message msg = Message.obtain(); 8204 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8205 HashMap<String, Object> data = new HashMap<String, Object>(); 8206 data.put("result", result); 8207 data.put("app", r); 8208 data.put("violationMask", violationMask); 8209 data.put("info", info); 8210 msg.obj = data; 8211 mHandler.sendMessage(msg); 8212 8213 Binder.restoreCallingIdentity(origId); 8214 } 8215 int res = result.get(); 8216 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8217 } 8218 } 8219 8220 // Depending on the policy in effect, there could be a bunch of 8221 // these in quick succession so we try to batch these together to 8222 // minimize disk writes, number of dropbox entries, and maximize 8223 // compression, by having more fewer, larger records. 8224 private void logStrictModeViolationToDropBox( 8225 ProcessRecord process, 8226 StrictMode.ViolationInfo info) { 8227 if (info == null) { 8228 return; 8229 } 8230 final boolean isSystemApp = process == null || 8231 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8232 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8233 final String processName = process == null ? "unknown" : process.processName; 8234 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8235 final DropBoxManager dbox = (DropBoxManager) 8236 mContext.getSystemService(Context.DROPBOX_SERVICE); 8237 8238 // Exit early if the dropbox isn't configured to accept this report type. 8239 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8240 8241 boolean bufferWasEmpty; 8242 boolean needsFlush; 8243 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8244 synchronized (sb) { 8245 bufferWasEmpty = sb.length() == 0; 8246 appendDropBoxProcessHeaders(process, processName, sb); 8247 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8248 sb.append("System-App: ").append(isSystemApp).append("\n"); 8249 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8250 if (info.violationNumThisLoop != 0) { 8251 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8252 } 8253 if (info.numAnimationsRunning != 0) { 8254 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8255 } 8256 if (info.broadcastIntentAction != null) { 8257 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8258 } 8259 if (info.durationMillis != -1) { 8260 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8261 } 8262 if (info.numInstances != -1) { 8263 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8264 } 8265 if (info.tags != null) { 8266 for (String tag : info.tags) { 8267 sb.append("Span-Tag: ").append(tag).append("\n"); 8268 } 8269 } 8270 sb.append("\n"); 8271 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8272 sb.append(info.crashInfo.stackTrace); 8273 } 8274 sb.append("\n"); 8275 8276 // Only buffer up to ~64k. Various logging bits truncate 8277 // things at 128k. 8278 needsFlush = (sb.length() > 64 * 1024); 8279 } 8280 8281 // Flush immediately if the buffer's grown too large, or this 8282 // is a non-system app. Non-system apps are isolated with a 8283 // different tag & policy and not batched. 8284 // 8285 // Batching is useful during internal testing with 8286 // StrictMode settings turned up high. Without batching, 8287 // thousands of separate files could be created on boot. 8288 if (!isSystemApp || needsFlush) { 8289 new Thread("Error dump: " + dropboxTag) { 8290 @Override 8291 public void run() { 8292 String report; 8293 synchronized (sb) { 8294 report = sb.toString(); 8295 sb.delete(0, sb.length()); 8296 sb.trimToSize(); 8297 } 8298 if (report.length() != 0) { 8299 dbox.addText(dropboxTag, report); 8300 } 8301 } 8302 }.start(); 8303 return; 8304 } 8305 8306 // System app batching: 8307 if (!bufferWasEmpty) { 8308 // An existing dropbox-writing thread is outstanding, so 8309 // we don't need to start it up. The existing thread will 8310 // catch the buffer appends we just did. 8311 return; 8312 } 8313 8314 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8315 // (After this point, we shouldn't access AMS internal data structures.) 8316 new Thread("Error dump: " + dropboxTag) { 8317 @Override 8318 public void run() { 8319 // 5 second sleep to let stacks arrive and be batched together 8320 try { 8321 Thread.sleep(5000); // 5 seconds 8322 } catch (InterruptedException e) {} 8323 8324 String errorReport; 8325 synchronized (mStrictModeBuffer) { 8326 errorReport = mStrictModeBuffer.toString(); 8327 if (errorReport.length() == 0) { 8328 return; 8329 } 8330 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8331 mStrictModeBuffer.trimToSize(); 8332 } 8333 dbox.addText(dropboxTag, errorReport); 8334 } 8335 }.start(); 8336 } 8337 8338 /** 8339 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8340 * @param app object of the crashing app, null for the system server 8341 * @param tag reported by the caller 8342 * @param crashInfo describing the context of the error 8343 * @return true if the process should exit immediately (WTF is fatal) 8344 */ 8345 public boolean handleApplicationWtf(IBinder app, String tag, 8346 ApplicationErrorReport.CrashInfo crashInfo) { 8347 ProcessRecord r = findAppProcess(app, "WTF"); 8348 final String processName = app == null ? "system_server" 8349 : (r == null ? "unknown" : r.processName); 8350 8351 EventLog.writeEvent(EventLogTags.AM_WTF, 8352 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8353 processName, 8354 r == null ? -1 : r.info.flags, 8355 tag, crashInfo.exceptionMessage); 8356 8357 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8358 8359 if (r != null && r.pid != Process.myPid() && 8360 Settings.Global.getInt(mContext.getContentResolver(), 8361 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8362 crashApplication(r, crashInfo); 8363 return true; 8364 } else { 8365 return false; 8366 } 8367 } 8368 8369 /** 8370 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8371 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8372 */ 8373 private ProcessRecord findAppProcess(IBinder app, String reason) { 8374 if (app == null) { 8375 return null; 8376 } 8377 8378 synchronized (this) { 8379 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8380 final int NA = apps.size(); 8381 for (int ia=0; ia<NA; ia++) { 8382 ProcessRecord p = apps.valueAt(ia); 8383 if (p.thread != null && p.thread.asBinder() == app) { 8384 return p; 8385 } 8386 } 8387 } 8388 8389 Slog.w(TAG, "Can't find mystery application for " + reason 8390 + " from pid=" + Binder.getCallingPid() 8391 + " uid=" + Binder.getCallingUid() + ": " + app); 8392 return null; 8393 } 8394 } 8395 8396 /** 8397 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8398 * to append various headers to the dropbox log text. 8399 */ 8400 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8401 StringBuilder sb) { 8402 // Watchdog thread ends up invoking this function (with 8403 // a null ProcessRecord) to add the stack file to dropbox. 8404 // Do not acquire a lock on this (am) in such cases, as it 8405 // could cause a potential deadlock, if and when watchdog 8406 // is invoked due to unavailability of lock on am and it 8407 // would prevent watchdog from killing system_server. 8408 if (process == null) { 8409 sb.append("Process: ").append(processName).append("\n"); 8410 return; 8411 } 8412 // Note: ProcessRecord 'process' is guarded by the service 8413 // instance. (notably process.pkgList, which could otherwise change 8414 // concurrently during execution of this method) 8415 synchronized (this) { 8416 sb.append("Process: ").append(processName).append("\n"); 8417 int flags = process.info.flags; 8418 IPackageManager pm = AppGlobals.getPackageManager(); 8419 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8420 for (String pkg : process.pkgList) { 8421 sb.append("Package: ").append(pkg); 8422 try { 8423 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8424 if (pi != null) { 8425 sb.append(" v").append(pi.versionCode); 8426 if (pi.versionName != null) { 8427 sb.append(" (").append(pi.versionName).append(")"); 8428 } 8429 } 8430 } catch (RemoteException e) { 8431 Slog.e(TAG, "Error getting package info: " + pkg, e); 8432 } 8433 sb.append("\n"); 8434 } 8435 } 8436 } 8437 8438 private static String processClass(ProcessRecord process) { 8439 if (process == null || process.pid == MY_PID) { 8440 return "system_server"; 8441 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8442 return "system_app"; 8443 } else { 8444 return "data_app"; 8445 } 8446 } 8447 8448 /** 8449 * Write a description of an error (crash, WTF, ANR) to the drop box. 8450 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8451 * @param process which caused the error, null means the system server 8452 * @param activity which triggered the error, null if unknown 8453 * @param parent activity related to the error, null if unknown 8454 * @param subject line related to the error, null if absent 8455 * @param report in long form describing the error, null if absent 8456 * @param logFile to include in the report, null if none 8457 * @param crashInfo giving an application stack trace, null if absent 8458 */ 8459 public void addErrorToDropBox(String eventType, 8460 ProcessRecord process, String processName, ActivityRecord activity, 8461 ActivityRecord parent, String subject, 8462 final String report, final File logFile, 8463 final ApplicationErrorReport.CrashInfo crashInfo) { 8464 // NOTE -- this must never acquire the ActivityManagerService lock, 8465 // otherwise the watchdog may be prevented from resetting the system. 8466 8467 final String dropboxTag = processClass(process) + "_" + eventType; 8468 final DropBoxManager dbox = (DropBoxManager) 8469 mContext.getSystemService(Context.DROPBOX_SERVICE); 8470 8471 // Exit early if the dropbox isn't configured to accept this report type. 8472 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8473 8474 final StringBuilder sb = new StringBuilder(1024); 8475 appendDropBoxProcessHeaders(process, processName, sb); 8476 if (activity != null) { 8477 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8478 } 8479 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8480 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8481 } 8482 if (parent != null && parent != activity) { 8483 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8484 } 8485 if (subject != null) { 8486 sb.append("Subject: ").append(subject).append("\n"); 8487 } 8488 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8489 if (Debug.isDebuggerConnected()) { 8490 sb.append("Debugger: Connected\n"); 8491 } 8492 sb.append("\n"); 8493 8494 // Do the rest in a worker thread to avoid blocking the caller on I/O 8495 // (After this point, we shouldn't access AMS internal data structures.) 8496 Thread worker = new Thread("Error dump: " + dropboxTag) { 8497 @Override 8498 public void run() { 8499 if (report != null) { 8500 sb.append(report); 8501 } 8502 if (logFile != null) { 8503 try { 8504 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8505 } catch (IOException e) { 8506 Slog.e(TAG, "Error reading " + logFile, e); 8507 } 8508 } 8509 if (crashInfo != null && crashInfo.stackTrace != null) { 8510 sb.append(crashInfo.stackTrace); 8511 } 8512 8513 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8514 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8515 if (lines > 0) { 8516 sb.append("\n"); 8517 8518 // Merge several logcat streams, and take the last N lines 8519 InputStreamReader input = null; 8520 try { 8521 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8522 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8523 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8524 8525 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8526 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8527 input = new InputStreamReader(logcat.getInputStream()); 8528 8529 int num; 8530 char[] buf = new char[8192]; 8531 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8532 } catch (IOException e) { 8533 Slog.e(TAG, "Error running logcat", e); 8534 } finally { 8535 if (input != null) try { input.close(); } catch (IOException e) {} 8536 } 8537 } 8538 8539 dbox.addText(dropboxTag, sb.toString()); 8540 } 8541 }; 8542 8543 if (process == null) { 8544 // If process is null, we are being called from some internal code 8545 // and may be about to die -- run this synchronously. 8546 worker.run(); 8547 } else { 8548 worker.start(); 8549 } 8550 } 8551 8552 /** 8553 * Bring up the "unexpected error" dialog box for a crashing app. 8554 * Deal with edge cases (intercepts from instrumented applications, 8555 * ActivityController, error intent receivers, that sort of thing). 8556 * @param r the application crashing 8557 * @param crashInfo describing the failure 8558 */ 8559 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8560 long timeMillis = System.currentTimeMillis(); 8561 String shortMsg = crashInfo.exceptionClassName; 8562 String longMsg = crashInfo.exceptionMessage; 8563 String stackTrace = crashInfo.stackTrace; 8564 if (shortMsg != null && longMsg != null) { 8565 longMsg = shortMsg + ": " + longMsg; 8566 } else if (shortMsg != null) { 8567 longMsg = shortMsg; 8568 } 8569 8570 AppErrorResult result = new AppErrorResult(); 8571 synchronized (this) { 8572 if (mController != null) { 8573 try { 8574 String name = r != null ? r.processName : null; 8575 int pid = r != null ? r.pid : Binder.getCallingPid(); 8576 if (!mController.appCrashed(name, pid, 8577 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8578 Slog.w(TAG, "Force-killing crashed app " + name 8579 + " at watcher's request"); 8580 Process.killProcess(pid); 8581 return; 8582 } 8583 } catch (RemoteException e) { 8584 mController = null; 8585 } 8586 } 8587 8588 final long origId = Binder.clearCallingIdentity(); 8589 8590 // If this process is running instrumentation, finish it. 8591 if (r != null && r.instrumentationClass != null) { 8592 Slog.w(TAG, "Error in app " + r.processName 8593 + " running instrumentation " + r.instrumentationClass + ":"); 8594 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8595 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8596 Bundle info = new Bundle(); 8597 info.putString("shortMsg", shortMsg); 8598 info.putString("longMsg", longMsg); 8599 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8600 Binder.restoreCallingIdentity(origId); 8601 return; 8602 } 8603 8604 // If we can't identify the process or it's already exceeded its crash quota, 8605 // quit right away without showing a crash dialog. 8606 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8607 Binder.restoreCallingIdentity(origId); 8608 return; 8609 } 8610 8611 Message msg = Message.obtain(); 8612 msg.what = SHOW_ERROR_MSG; 8613 HashMap data = new HashMap(); 8614 data.put("result", result); 8615 data.put("app", r); 8616 msg.obj = data; 8617 mHandler.sendMessage(msg); 8618 8619 Binder.restoreCallingIdentity(origId); 8620 } 8621 8622 int res = result.get(); 8623 8624 Intent appErrorIntent = null; 8625 synchronized (this) { 8626 if (r != null && !r.isolated) { 8627 // XXX Can't keep track of crash time for isolated processes, 8628 // since they don't have a persistent identity. 8629 mProcessCrashTimes.put(r.info.processName, r.uid, 8630 SystemClock.uptimeMillis()); 8631 } 8632 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8633 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8634 } 8635 } 8636 8637 if (appErrorIntent != null) { 8638 try { 8639 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8640 } catch (ActivityNotFoundException e) { 8641 Slog.w(TAG, "bug report receiver dissappeared", e); 8642 } 8643 } 8644 } 8645 8646 Intent createAppErrorIntentLocked(ProcessRecord r, 8647 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8648 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8649 if (report == null) { 8650 return null; 8651 } 8652 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8653 result.setComponent(r.errorReportReceiver); 8654 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8655 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8656 return result; 8657 } 8658 8659 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8660 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8661 if (r.errorReportReceiver == null) { 8662 return null; 8663 } 8664 8665 if (!r.crashing && !r.notResponding) { 8666 return null; 8667 } 8668 8669 ApplicationErrorReport report = new ApplicationErrorReport(); 8670 report.packageName = r.info.packageName; 8671 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8672 report.processName = r.processName; 8673 report.time = timeMillis; 8674 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8675 8676 if (r.crashing) { 8677 report.type = ApplicationErrorReport.TYPE_CRASH; 8678 report.crashInfo = crashInfo; 8679 } else if (r.notResponding) { 8680 report.type = ApplicationErrorReport.TYPE_ANR; 8681 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8682 8683 report.anrInfo.activity = r.notRespondingReport.tag; 8684 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8685 report.anrInfo.info = r.notRespondingReport.longMsg; 8686 } 8687 8688 return report; 8689 } 8690 8691 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8692 enforceNotIsolatedCaller("getProcessesInErrorState"); 8693 // assume our apps are happy - lazy create the list 8694 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8695 8696 final boolean allUsers = ActivityManager.checkUidPermission( 8697 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8698 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8699 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8700 8701 synchronized (this) { 8702 8703 // iterate across all processes 8704 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8705 ProcessRecord app = mLruProcesses.get(i); 8706 if (!allUsers && app.userId != userId) { 8707 continue; 8708 } 8709 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8710 // This one's in trouble, so we'll generate a report for it 8711 // crashes are higher priority (in case there's a crash *and* an anr) 8712 ActivityManager.ProcessErrorStateInfo report = null; 8713 if (app.crashing) { 8714 report = app.crashingReport; 8715 } else if (app.notResponding) { 8716 report = app.notRespondingReport; 8717 } 8718 8719 if (report != null) { 8720 if (errList == null) { 8721 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8722 } 8723 errList.add(report); 8724 } else { 8725 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8726 " crashing = " + app.crashing + 8727 " notResponding = " + app.notResponding); 8728 } 8729 } 8730 } 8731 } 8732 8733 return errList; 8734 } 8735 8736 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8737 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8738 if (currApp != null) { 8739 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8740 } 8741 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8742 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8743 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8744 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8745 if (currApp != null) { 8746 currApp.lru = 0; 8747 } 8748 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8749 } else if (adj >= ProcessList.SERVICE_ADJ) { 8750 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8751 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8752 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8753 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8754 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8755 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8756 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8757 } else { 8758 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8759 } 8760 } 8761 8762 private void fillInProcMemInfo(ProcessRecord app, 8763 ActivityManager.RunningAppProcessInfo outInfo) { 8764 outInfo.pid = app.pid; 8765 outInfo.uid = app.info.uid; 8766 if (mHeavyWeightProcess == app) { 8767 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8768 } 8769 if (app.persistent) { 8770 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8771 } 8772 if (app.hasActivities) { 8773 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8774 } 8775 outInfo.lastTrimLevel = app.trimMemoryLevel; 8776 int adj = app.curAdj; 8777 outInfo.importance = oomAdjToImportance(adj, outInfo); 8778 outInfo.importanceReasonCode = app.adjTypeCode; 8779 } 8780 8781 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8782 enforceNotIsolatedCaller("getRunningAppProcesses"); 8783 // Lazy instantiation of list 8784 List<ActivityManager.RunningAppProcessInfo> runList = null; 8785 final boolean allUsers = ActivityManager.checkUidPermission( 8786 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8787 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8788 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8789 synchronized (this) { 8790 // Iterate across all processes 8791 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8792 ProcessRecord app = mLruProcesses.get(i); 8793 if (!allUsers && app.userId != userId) { 8794 continue; 8795 } 8796 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8797 // Generate process state info for running application 8798 ActivityManager.RunningAppProcessInfo currApp = 8799 new ActivityManager.RunningAppProcessInfo(app.processName, 8800 app.pid, app.getPackageList()); 8801 fillInProcMemInfo(app, currApp); 8802 if (app.adjSource instanceof ProcessRecord) { 8803 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8804 currApp.importanceReasonImportance = oomAdjToImportance( 8805 app.adjSourceOom, null); 8806 } else if (app.adjSource instanceof ActivityRecord) { 8807 ActivityRecord r = (ActivityRecord)app.adjSource; 8808 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8809 } 8810 if (app.adjTarget instanceof ComponentName) { 8811 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8812 } 8813 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8814 // + " lru=" + currApp.lru); 8815 if (runList == null) { 8816 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8817 } 8818 runList.add(currApp); 8819 } 8820 } 8821 } 8822 return runList; 8823 } 8824 8825 public List<ApplicationInfo> getRunningExternalApplications() { 8826 enforceNotIsolatedCaller("getRunningExternalApplications"); 8827 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8828 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8829 if (runningApps != null && runningApps.size() > 0) { 8830 Set<String> extList = new HashSet<String>(); 8831 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8832 if (app.pkgList != null) { 8833 for (String pkg : app.pkgList) { 8834 extList.add(pkg); 8835 } 8836 } 8837 } 8838 IPackageManager pm = AppGlobals.getPackageManager(); 8839 for (String pkg : extList) { 8840 try { 8841 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8842 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8843 retList.add(info); 8844 } 8845 } catch (RemoteException e) { 8846 } 8847 } 8848 } 8849 return retList; 8850 } 8851 8852 @Override 8853 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8854 enforceNotIsolatedCaller("getMyMemoryState"); 8855 synchronized (this) { 8856 ProcessRecord proc; 8857 synchronized (mPidsSelfLocked) { 8858 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8859 } 8860 fillInProcMemInfo(proc, outInfo); 8861 } 8862 } 8863 8864 @Override 8865 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8866 if (checkCallingPermission(android.Manifest.permission.DUMP) 8867 != PackageManager.PERMISSION_GRANTED) { 8868 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8869 + Binder.getCallingPid() 8870 + ", uid=" + Binder.getCallingUid() 8871 + " without permission " 8872 + android.Manifest.permission.DUMP); 8873 return; 8874 } 8875 8876 boolean dumpAll = false; 8877 boolean dumpClient = false; 8878 String dumpPackage = null; 8879 8880 int opti = 0; 8881 while (opti < args.length) { 8882 String opt = args[opti]; 8883 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8884 break; 8885 } 8886 opti++; 8887 if ("-a".equals(opt)) { 8888 dumpAll = true; 8889 } else if ("-c".equals(opt)) { 8890 dumpClient = true; 8891 } else if ("-h".equals(opt)) { 8892 pw.println("Activity manager dump options:"); 8893 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8894 pw.println(" cmd may be one of:"); 8895 pw.println(" a[ctivities]: activity stack state"); 8896 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 8897 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8898 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8899 pw.println(" o[om]: out of memory management"); 8900 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8901 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8902 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8903 pw.println(" service [COMP_SPEC]: service client-side state"); 8904 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8905 pw.println(" all: dump all activities"); 8906 pw.println(" top: dump the top activity"); 8907 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8908 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8909 pw.println(" a partial substring in a component name, a"); 8910 pw.println(" hex object identifier."); 8911 pw.println(" -a: include all available server state."); 8912 pw.println(" -c: include client state."); 8913 return; 8914 } else { 8915 pw.println("Unknown argument: " + opt + "; use -h for help"); 8916 } 8917 } 8918 8919 long origId = Binder.clearCallingIdentity(); 8920 boolean more = false; 8921 // Is the caller requesting to dump a particular piece of data? 8922 if (opti < args.length) { 8923 String cmd = args[opti]; 8924 opti++; 8925 if ("activities".equals(cmd) || "a".equals(cmd)) { 8926 synchronized (this) { 8927 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8928 } 8929 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8930 String[] newArgs; 8931 String name; 8932 if (opti >= args.length) { 8933 name = null; 8934 newArgs = EMPTY_STRING_ARRAY; 8935 } else { 8936 name = args[opti]; 8937 opti++; 8938 newArgs = new String[args.length - opti]; 8939 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8940 args.length - opti); 8941 } 8942 synchronized (this) { 8943 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8944 } 8945 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8946 String[] newArgs; 8947 String name; 8948 if (opti >= args.length) { 8949 name = null; 8950 newArgs = EMPTY_STRING_ARRAY; 8951 } else { 8952 name = args[opti]; 8953 opti++; 8954 newArgs = new String[args.length - opti]; 8955 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8956 args.length - opti); 8957 } 8958 synchronized (this) { 8959 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8960 } 8961 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8962 String[] newArgs; 8963 String name; 8964 if (opti >= args.length) { 8965 name = null; 8966 newArgs = EMPTY_STRING_ARRAY; 8967 } else { 8968 name = args[opti]; 8969 opti++; 8970 newArgs = new String[args.length - opti]; 8971 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8972 args.length - opti); 8973 } 8974 synchronized (this) { 8975 dumpProcessesLocked(fd, pw, args, opti, true, name); 8976 } 8977 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8978 synchronized (this) { 8979 dumpOomLocked(fd, pw, args, opti, true); 8980 } 8981 } else if ("provider".equals(cmd)) { 8982 String[] newArgs; 8983 String name; 8984 if (opti >= args.length) { 8985 name = null; 8986 newArgs = EMPTY_STRING_ARRAY; 8987 } else { 8988 name = args[opti]; 8989 opti++; 8990 newArgs = new String[args.length - opti]; 8991 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8992 } 8993 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8994 pw.println("No providers match: " + name); 8995 pw.println("Use -h for help."); 8996 } 8997 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8998 synchronized (this) { 8999 dumpProvidersLocked(fd, pw, args, opti, true, null); 9000 } 9001 } else if ("service".equals(cmd)) { 9002 String[] newArgs; 9003 String name; 9004 if (opti >= args.length) { 9005 name = null; 9006 newArgs = EMPTY_STRING_ARRAY; 9007 } else { 9008 name = args[opti]; 9009 opti++; 9010 newArgs = new String[args.length - opti]; 9011 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9012 args.length - opti); 9013 } 9014 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 9015 pw.println("No services match: " + name); 9016 pw.println("Use -h for help."); 9017 } 9018 } else if ("package".equals(cmd)) { 9019 String[] newArgs; 9020 if (opti >= args.length) { 9021 pw.println("package: no package name specified"); 9022 pw.println("Use -h for help."); 9023 } else { 9024 dumpPackage = args[opti]; 9025 opti++; 9026 newArgs = new String[args.length - opti]; 9027 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 9028 args.length - opti); 9029 args = newArgs; 9030 opti = 0; 9031 more = true; 9032 } 9033 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9034 synchronized (this) { 9035 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 9036 } 9037 } else { 9038 // Dumping a single activity? 9039 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9040 pw.println("Bad activity command, or no activities match: " + cmd); 9041 pw.println("Use -h for help."); 9042 } 9043 } 9044 if (!more) { 9045 Binder.restoreCallingIdentity(origId); 9046 return; 9047 } 9048 } 9049 9050 // No piece of data specified, dump everything. 9051 synchronized (this) { 9052 boolean needSep; 9053 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9054 if (needSep) { 9055 pw.println(" "); 9056 } 9057 if (dumpAll) { 9058 pw.println("-------------------------------------------------------------------------------"); 9059 } 9060 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9061 if (needSep) { 9062 pw.println(" "); 9063 } 9064 if (dumpAll) { 9065 pw.println("-------------------------------------------------------------------------------"); 9066 } 9067 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9068 if (needSep) { 9069 pw.println(" "); 9070 } 9071 if (dumpAll) { 9072 pw.println("-------------------------------------------------------------------------------"); 9073 } 9074 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9075 if (needSep) { 9076 pw.println(" "); 9077 } 9078 if (dumpAll) { 9079 pw.println("-------------------------------------------------------------------------------"); 9080 } 9081 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9082 if (needSep) { 9083 pw.println(" "); 9084 } 9085 if (dumpAll) { 9086 pw.println("-------------------------------------------------------------------------------"); 9087 } 9088 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9089 } 9090 Binder.restoreCallingIdentity(origId); 9091 } 9092 9093 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9094 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9095 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9096 pw.println(" Main stack:"); 9097 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9098 dumpPackage); 9099 pw.println(" "); 9100 pw.println(" Running activities (most recent first):"); 9101 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9102 dumpPackage); 9103 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9104 pw.println(" "); 9105 pw.println(" Activities waiting for another to become visible:"); 9106 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9107 !dumpAll, false, dumpPackage); 9108 } 9109 if (mMainStack.mStoppingActivities.size() > 0) { 9110 pw.println(" "); 9111 pw.println(" Activities waiting to stop:"); 9112 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9113 !dumpAll, false, dumpPackage); 9114 } 9115 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9116 pw.println(" "); 9117 pw.println(" Activities waiting to sleep:"); 9118 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9119 !dumpAll, false, dumpPackage); 9120 } 9121 if (mMainStack.mFinishingActivities.size() > 0) { 9122 pw.println(" "); 9123 pw.println(" Activities waiting to finish:"); 9124 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9125 !dumpAll, false, dumpPackage); 9126 } 9127 9128 pw.println(" "); 9129 if (mMainStack.mPausingActivity != null) { 9130 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9131 } 9132 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9133 pw.println(" mFocusedActivity: " + mFocusedActivity); 9134 if (dumpAll) { 9135 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9136 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9137 pw.println(" mDismissKeyguardOnNextActivity: " 9138 + mMainStack.mDismissKeyguardOnNextActivity); 9139 } 9140 9141 if (mRecentTasks.size() > 0) { 9142 pw.println(); 9143 pw.println(" Recent tasks:"); 9144 9145 final int N = mRecentTasks.size(); 9146 for (int i=0; i<N; i++) { 9147 TaskRecord tr = mRecentTasks.get(i); 9148 if (dumpPackage != null) { 9149 if (tr.realActivity == null || 9150 !dumpPackage.equals(tr.realActivity)) { 9151 continue; 9152 } 9153 } 9154 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9155 pw.println(tr); 9156 if (dumpAll) { 9157 mRecentTasks.get(i).dump(pw, " "); 9158 } 9159 } 9160 } 9161 9162 if (dumpAll) { 9163 pw.println(" "); 9164 pw.println(" mCurTask: " + mCurTask); 9165 } 9166 9167 return true; 9168 } 9169 9170 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9171 int opti, boolean dumpAll, String dumpPackage) { 9172 boolean needSep = false; 9173 int numPers = 0; 9174 9175 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9176 9177 if (dumpAll) { 9178 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9179 final int NA = procs.size(); 9180 for (int ia=0; ia<NA; ia++) { 9181 ProcessRecord r = procs.valueAt(ia); 9182 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9183 continue; 9184 } 9185 if (!needSep) { 9186 pw.println(" All known processes:"); 9187 needSep = true; 9188 } 9189 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9190 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9191 pw.print(" "); pw.println(r); 9192 r.dump(pw, " "); 9193 if (r.persistent) { 9194 numPers++; 9195 } 9196 } 9197 } 9198 } 9199 9200 if (mIsolatedProcesses.size() > 0) { 9201 if (needSep) pw.println(" "); 9202 needSep = true; 9203 pw.println(" Isolated process list (sorted by uid):"); 9204 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9205 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9206 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9207 continue; 9208 } 9209 pw.println(String.format("%sIsolated #%2d: %s", 9210 " ", i, r.toString())); 9211 } 9212 } 9213 9214 if (mLruProcesses.size() > 0) { 9215 if (needSep) pw.println(" "); 9216 needSep = true; 9217 pw.println(" Process LRU list (sorted by oom_adj):"); 9218 dumpProcessOomList(pw, this, mLruProcesses, " ", 9219 "Proc", "PERS", false, dumpPackage); 9220 needSep = true; 9221 } 9222 9223 if (dumpAll) { 9224 synchronized (mPidsSelfLocked) { 9225 boolean printed = false; 9226 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9227 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9228 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9229 continue; 9230 } 9231 if (!printed) { 9232 if (needSep) pw.println(" "); 9233 needSep = true; 9234 pw.println(" PID mappings:"); 9235 printed = true; 9236 } 9237 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9238 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9239 } 9240 } 9241 } 9242 9243 if (mForegroundProcesses.size() > 0) { 9244 synchronized (mPidsSelfLocked) { 9245 boolean printed = false; 9246 for (int i=0; i<mForegroundProcesses.size(); i++) { 9247 ProcessRecord r = mPidsSelfLocked.get( 9248 mForegroundProcesses.valueAt(i).pid); 9249 if (dumpPackage != null && (r == null 9250 || !dumpPackage.equals(r.info.packageName))) { 9251 continue; 9252 } 9253 if (!printed) { 9254 if (needSep) pw.println(" "); 9255 needSep = true; 9256 pw.println(" Foreground Processes:"); 9257 printed = true; 9258 } 9259 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9260 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9261 } 9262 } 9263 } 9264 9265 if (mPersistentStartingProcesses.size() > 0) { 9266 if (needSep) pw.println(" "); 9267 needSep = true; 9268 pw.println(" Persisent processes that are starting:"); 9269 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9270 "Starting Norm", "Restarting PERS", dumpPackage); 9271 } 9272 9273 if (mRemovedProcesses.size() > 0) { 9274 if (needSep) pw.println(" "); 9275 needSep = true; 9276 pw.println(" Processes that are being removed:"); 9277 dumpProcessList(pw, this, mRemovedProcesses, " ", 9278 "Removed Norm", "Removed PERS", dumpPackage); 9279 } 9280 9281 if (mProcessesOnHold.size() > 0) { 9282 if (needSep) pw.println(" "); 9283 needSep = true; 9284 pw.println(" Processes that are on old until the system is ready:"); 9285 dumpProcessList(pw, this, mProcessesOnHold, " ", 9286 "OnHold Norm", "OnHold PERS", dumpPackage); 9287 } 9288 9289 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9290 9291 if (mProcessCrashTimes.getMap().size() > 0) { 9292 boolean printed = false; 9293 long now = SystemClock.uptimeMillis(); 9294 for (Map.Entry<String, SparseArray<Long>> procs 9295 : mProcessCrashTimes.getMap().entrySet()) { 9296 String pname = procs.getKey(); 9297 SparseArray<Long> uids = procs.getValue(); 9298 final int N = uids.size(); 9299 for (int i=0; i<N; i++) { 9300 int puid = uids.keyAt(i); 9301 ProcessRecord r = mProcessNames.get(pname, puid); 9302 if (dumpPackage != null && (r == null 9303 || !dumpPackage.equals(r.info.packageName))) { 9304 continue; 9305 } 9306 if (!printed) { 9307 if (needSep) pw.println(" "); 9308 needSep = true; 9309 pw.println(" Time since processes crashed:"); 9310 printed = true; 9311 } 9312 pw.print(" Process "); pw.print(pname); 9313 pw.print(" uid "); pw.print(puid); 9314 pw.print(": last crashed "); 9315 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9316 pw.println(" ago"); 9317 } 9318 } 9319 } 9320 9321 if (mBadProcesses.getMap().size() > 0) { 9322 boolean printed = false; 9323 for (Map.Entry<String, SparseArray<Long>> procs 9324 : mBadProcesses.getMap().entrySet()) { 9325 String pname = procs.getKey(); 9326 SparseArray<Long> uids = procs.getValue(); 9327 final int N = uids.size(); 9328 for (int i=0; i<N; i++) { 9329 int puid = uids.keyAt(i); 9330 ProcessRecord r = mProcessNames.get(pname, puid); 9331 if (dumpPackage != null && (r == null 9332 || !dumpPackage.equals(r.info.packageName))) { 9333 continue; 9334 } 9335 if (!printed) { 9336 if (needSep) pw.println(" "); 9337 needSep = true; 9338 pw.println(" Bad processes:"); 9339 } 9340 pw.print(" Bad process "); pw.print(pname); 9341 pw.print(" uid "); pw.print(puid); 9342 pw.print(": crashed at time "); 9343 pw.println(uids.valueAt(i)); 9344 } 9345 } 9346 } 9347 9348 pw.println(); 9349 pw.println(" mStartedUsers:"); 9350 for (int i=0; i<mStartedUsers.size(); i++) { 9351 UserStartedState uss = mStartedUsers.valueAt(i); 9352 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9353 pw.print(": "); uss.dump("", pw); 9354 } 9355 pw.print(" mStartedUserArray: ["); 9356 for (int i=0; i<mStartedUserArray.length; i++) { 9357 if (i > 0) pw.print(", "); 9358 pw.print(mStartedUserArray[i]); 9359 } 9360 pw.println("]"); 9361 pw.print(" mUserLru: ["); 9362 for (int i=0; i<mUserLru.size(); i++) { 9363 if (i > 0) pw.print(", "); 9364 pw.print(mUserLru.get(i)); 9365 } 9366 pw.println("]"); 9367 if (dumpAll) { 9368 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9369 } 9370 pw.println(" mHomeProcess: " + mHomeProcess); 9371 pw.println(" mPreviousProcess: " + mPreviousProcess); 9372 if (dumpAll) { 9373 StringBuilder sb = new StringBuilder(128); 9374 sb.append(" mPreviousProcessVisibleTime: "); 9375 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9376 pw.println(sb); 9377 } 9378 if (mHeavyWeightProcess != null) { 9379 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9380 } 9381 pw.println(" mConfiguration: " + mConfiguration); 9382 if (dumpAll) { 9383 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9384 if (mCompatModePackages.getPackages().size() > 0) { 9385 boolean printed = false; 9386 for (Map.Entry<String, Integer> entry 9387 : mCompatModePackages.getPackages().entrySet()) { 9388 String pkg = entry.getKey(); 9389 int mode = entry.getValue(); 9390 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9391 continue; 9392 } 9393 if (!printed) { 9394 pw.println(" mScreenCompatPackages:"); 9395 printed = true; 9396 } 9397 pw.print(" "); pw.print(pkg); pw.print(": "); 9398 pw.print(mode); pw.println(); 9399 } 9400 } 9401 } 9402 if (mSleeping || mWentToSleep || mLockScreenShown) { 9403 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9404 + " mLockScreenShown " + mLockScreenShown); 9405 } 9406 if (mShuttingDown) { 9407 pw.println(" mShuttingDown=" + mShuttingDown); 9408 } 9409 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9410 || mOrigWaitForDebugger) { 9411 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9412 + " mDebugTransient=" + mDebugTransient 9413 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9414 } 9415 if (mOpenGlTraceApp != null) { 9416 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9417 } 9418 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9419 || mProfileFd != null) { 9420 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9421 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9422 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9423 + mAutoStopProfiler); 9424 } 9425 if (mAlwaysFinishActivities || mController != null) { 9426 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9427 + " mController=" + mController); 9428 } 9429 if (dumpAll) { 9430 pw.println(" Total persistent processes: " + numPers); 9431 pw.println(" mStartRunning=" + mStartRunning 9432 + " mProcessesReady=" + mProcessesReady 9433 + " mSystemReady=" + mSystemReady); 9434 pw.println(" mBooting=" + mBooting 9435 + " mBooted=" + mBooted 9436 + " mFactoryTest=" + mFactoryTest); 9437 pw.print(" mLastPowerCheckRealtime="); 9438 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9439 pw.println(""); 9440 pw.print(" mLastPowerCheckUptime="); 9441 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9442 pw.println(""); 9443 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9444 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9445 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9446 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9447 + " mNumHiddenProcs=" + mNumHiddenProcs 9448 + " mNumServiceProcs=" + mNumServiceProcs 9449 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9450 } 9451 9452 return true; 9453 } 9454 9455 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9456 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9457 if (mProcessesToGc.size() > 0) { 9458 boolean printed = false; 9459 long now = SystemClock.uptimeMillis(); 9460 for (int i=0; i<mProcessesToGc.size(); i++) { 9461 ProcessRecord proc = mProcessesToGc.get(i); 9462 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9463 continue; 9464 } 9465 if (!printed) { 9466 if (needSep) pw.println(" "); 9467 needSep = true; 9468 pw.println(" Processes that are waiting to GC:"); 9469 printed = true; 9470 } 9471 pw.print(" Process "); pw.println(proc); 9472 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9473 pw.print(", last gced="); 9474 pw.print(now-proc.lastRequestedGc); 9475 pw.print(" ms ago, last lowMem="); 9476 pw.print(now-proc.lastLowMemory); 9477 pw.println(" ms ago"); 9478 9479 } 9480 } 9481 return needSep; 9482 } 9483 9484 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9485 int opti, boolean dumpAll) { 9486 boolean needSep = false; 9487 9488 if (mLruProcesses.size() > 0) { 9489 if (needSep) pw.println(" "); 9490 needSep = true; 9491 pw.println(" OOM levels:"); 9492 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9493 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9494 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9495 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9496 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9497 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9498 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9499 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9500 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9501 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9502 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9503 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9504 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9505 9506 if (needSep) pw.println(" "); 9507 needSep = true; 9508 pw.println(" Process OOM control:"); 9509 dumpProcessOomList(pw, this, mLruProcesses, " ", 9510 "Proc", "PERS", true, null); 9511 needSep = true; 9512 } 9513 9514 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9515 9516 pw.println(); 9517 pw.println(" mHomeProcess: " + mHomeProcess); 9518 pw.println(" mPreviousProcess: " + mPreviousProcess); 9519 if (mHeavyWeightProcess != null) { 9520 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9521 } 9522 9523 return true; 9524 } 9525 9526 /** 9527 * There are three ways to call this: 9528 * - no provider specified: dump all the providers 9529 * - a flattened component name that matched an existing provider was specified as the 9530 * first arg: dump that one provider 9531 * - the first arg isn't the flattened component name of an existing provider: 9532 * dump all providers whose component contains the first arg as a substring 9533 */ 9534 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9535 int opti, boolean dumpAll) { 9536 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9537 } 9538 9539 static class ItemMatcher { 9540 ArrayList<ComponentName> components; 9541 ArrayList<String> strings; 9542 ArrayList<Integer> objects; 9543 boolean all; 9544 9545 ItemMatcher() { 9546 all = true; 9547 } 9548 9549 void build(String name) { 9550 ComponentName componentName = ComponentName.unflattenFromString(name); 9551 if (componentName != null) { 9552 if (components == null) { 9553 components = new ArrayList<ComponentName>(); 9554 } 9555 components.add(componentName); 9556 all = false; 9557 } else { 9558 int objectId = 0; 9559 // Not a '/' separated full component name; maybe an object ID? 9560 try { 9561 objectId = Integer.parseInt(name, 16); 9562 if (objects == null) { 9563 objects = new ArrayList<Integer>(); 9564 } 9565 objects.add(objectId); 9566 all = false; 9567 } catch (RuntimeException e) { 9568 // Not an integer; just do string match. 9569 if (strings == null) { 9570 strings = new ArrayList<String>(); 9571 } 9572 strings.add(name); 9573 all = false; 9574 } 9575 } 9576 } 9577 9578 int build(String[] args, int opti) { 9579 for (; opti<args.length; opti++) { 9580 String name = args[opti]; 9581 if ("--".equals(name)) { 9582 return opti+1; 9583 } 9584 build(name); 9585 } 9586 return opti; 9587 } 9588 9589 boolean match(Object object, ComponentName comp) { 9590 if (all) { 9591 return true; 9592 } 9593 if (components != null) { 9594 for (int i=0; i<components.size(); i++) { 9595 if (components.get(i).equals(comp)) { 9596 return true; 9597 } 9598 } 9599 } 9600 if (objects != null) { 9601 for (int i=0; i<objects.size(); i++) { 9602 if (System.identityHashCode(object) == objects.get(i)) { 9603 return true; 9604 } 9605 } 9606 } 9607 if (strings != null) { 9608 String flat = comp.flattenToString(); 9609 for (int i=0; i<strings.size(); i++) { 9610 if (flat.contains(strings.get(i))) { 9611 return true; 9612 } 9613 } 9614 } 9615 return false; 9616 } 9617 } 9618 9619 /** 9620 * There are three things that cmd can be: 9621 * - a flattened component name that matches an existing activity 9622 * - the cmd arg isn't the flattened component name of an existing activity: 9623 * dump all activity whose component contains the cmd as a substring 9624 * - A hex number of the ActivityRecord object instance. 9625 */ 9626 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9627 int opti, boolean dumpAll) { 9628 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9629 9630 if ("all".equals(name)) { 9631 synchronized (this) { 9632 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9633 activities.add(r1); 9634 } 9635 } 9636 } else if ("top".equals(name)) { 9637 synchronized (this) { 9638 final int N = mMainStack.mHistory.size(); 9639 if (N > 0) { 9640 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9641 } 9642 } 9643 } else { 9644 ItemMatcher matcher = new ItemMatcher(); 9645 matcher.build(name); 9646 9647 synchronized (this) { 9648 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9649 if (matcher.match(r1, r1.intent.getComponent())) { 9650 activities.add(r1); 9651 } 9652 } 9653 } 9654 } 9655 9656 if (activities.size() <= 0) { 9657 return false; 9658 } 9659 9660 String[] newArgs = new String[args.length - opti]; 9661 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9662 9663 TaskRecord lastTask = null; 9664 boolean needSep = false; 9665 for (int i=activities.size()-1; i>=0; i--) { 9666 ActivityRecord r = (ActivityRecord)activities.get(i); 9667 if (needSep) { 9668 pw.println(); 9669 } 9670 needSep = true; 9671 synchronized (this) { 9672 if (lastTask != r.task) { 9673 lastTask = r.task; 9674 pw.print("TASK "); pw.print(lastTask.affinity); 9675 pw.print(" id="); pw.println(lastTask.taskId); 9676 if (dumpAll) { 9677 lastTask.dump(pw, " "); 9678 } 9679 } 9680 } 9681 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9682 } 9683 return true; 9684 } 9685 9686 /** 9687 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9688 * there is a thread associated with the activity. 9689 */ 9690 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9691 final ActivityRecord r, String[] args, boolean dumpAll) { 9692 String innerPrefix = prefix + " "; 9693 synchronized (this) { 9694 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9695 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9696 pw.print(" pid="); 9697 if (r.app != null) pw.println(r.app.pid); 9698 else pw.println("(not running)"); 9699 if (dumpAll) { 9700 r.dump(pw, innerPrefix); 9701 } 9702 } 9703 if (r.app != null && r.app.thread != null) { 9704 // flush anything that is already in the PrintWriter since the thread is going 9705 // to write to the file descriptor directly 9706 pw.flush(); 9707 try { 9708 TransferPipe tp = new TransferPipe(); 9709 try { 9710 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9711 r.appToken, innerPrefix, args); 9712 tp.go(fd); 9713 } finally { 9714 tp.kill(); 9715 } 9716 } catch (IOException e) { 9717 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9718 } catch (RemoteException e) { 9719 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9720 } 9721 } 9722 } 9723 9724 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9725 int opti, boolean dumpAll, String dumpPackage) { 9726 boolean needSep = false; 9727 boolean onlyHistory = false; 9728 9729 if ("history".equals(dumpPackage)) { 9730 if (opti < args.length && "-s".equals(args[opti])) { 9731 dumpAll = false; 9732 } 9733 onlyHistory = true; 9734 dumpPackage = null; 9735 } 9736 9737 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9738 if (!onlyHistory && dumpAll) { 9739 if (mRegisteredReceivers.size() > 0) { 9740 boolean printed = false; 9741 Iterator it = mRegisteredReceivers.values().iterator(); 9742 while (it.hasNext()) { 9743 ReceiverList r = (ReceiverList)it.next(); 9744 if (dumpPackage != null && (r.app == null || 9745 !dumpPackage.equals(r.app.info.packageName))) { 9746 continue; 9747 } 9748 if (!printed) { 9749 pw.println(" Registered Receivers:"); 9750 needSep = true; 9751 printed = true; 9752 } 9753 pw.print(" * "); pw.println(r); 9754 r.dump(pw, " "); 9755 } 9756 } 9757 9758 if (mReceiverResolver.dump(pw, needSep ? 9759 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9760 " ", dumpPackage, false)) { 9761 needSep = true; 9762 } 9763 } 9764 9765 for (BroadcastQueue q : mBroadcastQueues) { 9766 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9767 } 9768 9769 needSep = true; 9770 9771 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9772 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9773 if (needSep) { 9774 pw.println(); 9775 } 9776 needSep = true; 9777 pw.print(" Sticky broadcasts for user "); 9778 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9779 StringBuilder sb = new StringBuilder(128); 9780 for (Map.Entry<String, ArrayList<Intent>> ent 9781 : mStickyBroadcasts.valueAt(user).entrySet()) { 9782 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9783 if (dumpAll) { 9784 pw.println(":"); 9785 ArrayList<Intent> intents = ent.getValue(); 9786 final int N = intents.size(); 9787 for (int i=0; i<N; i++) { 9788 sb.setLength(0); 9789 sb.append(" Intent: "); 9790 intents.get(i).toShortString(sb, false, true, false, false); 9791 pw.println(sb.toString()); 9792 Bundle bundle = intents.get(i).getExtras(); 9793 if (bundle != null) { 9794 pw.print(" "); 9795 pw.println(bundle.toString()); 9796 } 9797 } 9798 } else { 9799 pw.println(""); 9800 } 9801 } 9802 } 9803 } 9804 9805 if (!onlyHistory && dumpAll) { 9806 pw.println(); 9807 for (BroadcastQueue queue : mBroadcastQueues) { 9808 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9809 + queue.mBroadcastsScheduled); 9810 } 9811 pw.println(" mHandler:"); 9812 mHandler.dump(new PrintWriterPrinter(pw), " "); 9813 needSep = true; 9814 } 9815 9816 return needSep; 9817 } 9818 9819 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9820 int opti, boolean dumpAll, String dumpPackage) { 9821 boolean needSep = true; 9822 9823 ItemMatcher matcher = new ItemMatcher(); 9824 matcher.build(args, opti); 9825 9826 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9827 9828 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9829 9830 if (mLaunchingProviders.size() > 0) { 9831 boolean printed = false; 9832 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9833 ContentProviderRecord r = mLaunchingProviders.get(i); 9834 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9835 continue; 9836 } 9837 if (!printed) { 9838 if (needSep) pw.println(" "); 9839 needSep = true; 9840 pw.println(" Launching content providers:"); 9841 printed = true; 9842 } 9843 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9844 pw.println(r); 9845 } 9846 } 9847 9848 if (mGrantedUriPermissions.size() > 0) { 9849 if (needSep) pw.println(); 9850 needSep = true; 9851 pw.println("Granted Uri Permissions:"); 9852 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9853 int uid = mGrantedUriPermissions.keyAt(i); 9854 HashMap<Uri, UriPermission> perms 9855 = mGrantedUriPermissions.valueAt(i); 9856 pw.print(" * UID "); pw.print(uid); 9857 pw.println(" holds:"); 9858 for (UriPermission perm : perms.values()) { 9859 pw.print(" "); pw.println(perm); 9860 if (dumpAll) { 9861 perm.dump(pw, " "); 9862 } 9863 } 9864 } 9865 needSep = true; 9866 } 9867 9868 return needSep; 9869 } 9870 9871 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9872 int opti, boolean dumpAll, String dumpPackage) { 9873 boolean needSep = false; 9874 9875 if (mIntentSenderRecords.size() > 0) { 9876 boolean printed = false; 9877 Iterator<WeakReference<PendingIntentRecord>> it 9878 = mIntentSenderRecords.values().iterator(); 9879 while (it.hasNext()) { 9880 WeakReference<PendingIntentRecord> ref = it.next(); 9881 PendingIntentRecord rec = ref != null ? ref.get(): null; 9882 if (dumpPackage != null && (rec == null 9883 || !dumpPackage.equals(rec.key.packageName))) { 9884 continue; 9885 } 9886 if (!printed) { 9887 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9888 printed = true; 9889 } 9890 needSep = true; 9891 if (rec != null) { 9892 pw.print(" * "); pw.println(rec); 9893 if (dumpAll) { 9894 rec.dump(pw, " "); 9895 } 9896 } else { 9897 pw.print(" * "); pw.println(ref); 9898 } 9899 } 9900 } 9901 9902 return needSep; 9903 } 9904 9905 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9906 String prefix, String label, boolean complete, boolean brief, boolean client, 9907 String dumpPackage) { 9908 TaskRecord lastTask = null; 9909 boolean needNL = false; 9910 final String innerPrefix = prefix + " "; 9911 final String[] args = new String[0]; 9912 for (int i=list.size()-1; i>=0; i--) { 9913 final ActivityRecord r = (ActivityRecord)list.get(i); 9914 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9915 continue; 9916 } 9917 final boolean full = !brief && (complete || !r.isInHistory()); 9918 if (needNL) { 9919 pw.println(" "); 9920 needNL = false; 9921 } 9922 if (lastTask != r.task) { 9923 lastTask = r.task; 9924 pw.print(prefix); 9925 pw.print(full ? "* " : " "); 9926 pw.println(lastTask); 9927 if (full) { 9928 lastTask.dump(pw, prefix + " "); 9929 } else if (complete) { 9930 // Complete + brief == give a summary. Isn't that obvious?!? 9931 if (lastTask.intent != null) { 9932 pw.print(prefix); pw.print(" "); 9933 pw.println(lastTask.intent.toInsecureStringWithClip()); 9934 } 9935 } 9936 } 9937 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9938 pw.print(" #"); pw.print(i); pw.print(": "); 9939 pw.println(r); 9940 if (full) { 9941 r.dump(pw, innerPrefix); 9942 } else if (complete) { 9943 // Complete + brief == give a summary. Isn't that obvious?!? 9944 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9945 if (r.app != null) { 9946 pw.print(innerPrefix); pw.println(r.app); 9947 } 9948 } 9949 if (client && r.app != null && r.app.thread != null) { 9950 // flush anything that is already in the PrintWriter since the thread is going 9951 // to write to the file descriptor directly 9952 pw.flush(); 9953 try { 9954 TransferPipe tp = new TransferPipe(); 9955 try { 9956 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9957 r.appToken, innerPrefix, args); 9958 // Short timeout, since blocking here can 9959 // deadlock with the application. 9960 tp.go(fd, 2000); 9961 } finally { 9962 tp.kill(); 9963 } 9964 } catch (IOException e) { 9965 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9966 } catch (RemoteException e) { 9967 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9968 } 9969 needNL = true; 9970 } 9971 } 9972 } 9973 9974 private static String buildOomTag(String prefix, String space, int val, int base) { 9975 if (val == base) { 9976 if (space == null) return prefix; 9977 return prefix + " "; 9978 } 9979 return prefix + "+" + Integer.toString(val-base); 9980 } 9981 9982 private static final int dumpProcessList(PrintWriter pw, 9983 ActivityManagerService service, List list, 9984 String prefix, String normalLabel, String persistentLabel, 9985 String dumpPackage) { 9986 int numPers = 0; 9987 final int N = list.size()-1; 9988 for (int i=N; i>=0; i--) { 9989 ProcessRecord r = (ProcessRecord)list.get(i); 9990 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9991 continue; 9992 } 9993 pw.println(String.format("%s%s #%2d: %s", 9994 prefix, (r.persistent ? persistentLabel : normalLabel), 9995 i, r.toString())); 9996 if (r.persistent) { 9997 numPers++; 9998 } 9999 } 10000 return numPers; 10001 } 10002 10003 private static final boolean dumpProcessOomList(PrintWriter pw, 10004 ActivityManagerService service, List<ProcessRecord> origList, 10005 String prefix, String normalLabel, String persistentLabel, 10006 boolean inclDetails, String dumpPackage) { 10007 10008 ArrayList<Pair<ProcessRecord, Integer>> list 10009 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 10010 for (int i=0; i<origList.size(); i++) { 10011 ProcessRecord r = origList.get(i); 10012 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 10013 continue; 10014 } 10015 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 10016 } 10017 10018 if (list.size() <= 0) { 10019 return false; 10020 } 10021 10022 Comparator<Pair<ProcessRecord, Integer>> comparator 10023 = new Comparator<Pair<ProcessRecord, Integer>>() { 10024 @Override 10025 public int compare(Pair<ProcessRecord, Integer> object1, 10026 Pair<ProcessRecord, Integer> object2) { 10027 if (object1.first.setAdj != object2.first.setAdj) { 10028 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10029 } 10030 if (object1.second.intValue() != object2.second.intValue()) { 10031 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10032 } 10033 return 0; 10034 } 10035 }; 10036 10037 Collections.sort(list, comparator); 10038 10039 final long curRealtime = SystemClock.elapsedRealtime(); 10040 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10041 final long curUptime = SystemClock.uptimeMillis(); 10042 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10043 10044 for (int i=list.size()-1; i>=0; i--) { 10045 ProcessRecord r = list.get(i).first; 10046 String oomAdj; 10047 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10048 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10049 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10050 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10051 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10052 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10053 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10054 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10055 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10056 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10057 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10058 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10059 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10060 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10061 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10062 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10063 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10064 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10065 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10066 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10067 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10068 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10069 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10070 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10071 } else { 10072 oomAdj = Integer.toString(r.setAdj); 10073 } 10074 String schedGroup; 10075 switch (r.setSchedGroup) { 10076 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10077 schedGroup = "B"; 10078 break; 10079 case Process.THREAD_GROUP_DEFAULT: 10080 schedGroup = "F"; 10081 break; 10082 default: 10083 schedGroup = Integer.toString(r.setSchedGroup); 10084 break; 10085 } 10086 String foreground; 10087 if (r.foregroundActivities) { 10088 foreground = "A"; 10089 } else if (r.foregroundServices) { 10090 foreground = "S"; 10091 } else { 10092 foreground = " "; 10093 } 10094 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10095 prefix, (r.persistent ? persistentLabel : normalLabel), 10096 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10097 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10098 if (r.adjSource != null || r.adjTarget != null) { 10099 pw.print(prefix); 10100 pw.print(" "); 10101 if (r.adjTarget instanceof ComponentName) { 10102 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10103 } else if (r.adjTarget != null) { 10104 pw.print(r.adjTarget.toString()); 10105 } else { 10106 pw.print("{null}"); 10107 } 10108 pw.print("<="); 10109 if (r.adjSource instanceof ProcessRecord) { 10110 pw.print("Proc{"); 10111 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10112 pw.println("}"); 10113 } else if (r.adjSource != null) { 10114 pw.println(r.adjSource.toString()); 10115 } else { 10116 pw.println("{null}"); 10117 } 10118 } 10119 if (inclDetails) { 10120 pw.print(prefix); 10121 pw.print(" "); 10122 pw.print("oom: max="); pw.print(r.maxAdj); 10123 pw.print(" hidden="); pw.print(r.hiddenAdj); 10124 pw.print(" client="); pw.print(r.clientHiddenAdj); 10125 pw.print(" empty="); pw.print(r.emptyAdj); 10126 pw.print(" curRaw="); pw.print(r.curRawAdj); 10127 pw.print(" setRaw="); pw.print(r.setRawAdj); 10128 pw.print(" cur="); pw.print(r.curAdj); 10129 pw.print(" set="); pw.println(r.setAdj); 10130 pw.print(prefix); 10131 pw.print(" "); 10132 pw.print("keeping="); pw.print(r.keeping); 10133 pw.print(" hidden="); pw.print(r.hidden); 10134 pw.print(" empty="); pw.print(r.empty); 10135 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10136 10137 if (!r.keeping) { 10138 if (r.lastWakeTime != 0) { 10139 long wtime; 10140 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10141 synchronized (stats) { 10142 wtime = stats.getProcessWakeTime(r.info.uid, 10143 r.pid, curRealtime); 10144 } 10145 long timeUsed = wtime - r.lastWakeTime; 10146 pw.print(prefix); 10147 pw.print(" "); 10148 pw.print("keep awake over "); 10149 TimeUtils.formatDuration(realtimeSince, pw); 10150 pw.print(" used "); 10151 TimeUtils.formatDuration(timeUsed, pw); 10152 pw.print(" ("); 10153 pw.print((timeUsed*100)/realtimeSince); 10154 pw.println("%)"); 10155 } 10156 if (r.lastCpuTime != 0) { 10157 long timeUsed = r.curCpuTime - r.lastCpuTime; 10158 pw.print(prefix); 10159 pw.print(" "); 10160 pw.print("run cpu over "); 10161 TimeUtils.formatDuration(uptimeSince, pw); 10162 pw.print(" used "); 10163 TimeUtils.formatDuration(timeUsed, pw); 10164 pw.print(" ("); 10165 pw.print((timeUsed*100)/uptimeSince); 10166 pw.println("%)"); 10167 } 10168 } 10169 } 10170 } 10171 return true; 10172 } 10173 10174 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10175 ArrayList<ProcessRecord> procs; 10176 synchronized (this) { 10177 if (args != null && args.length > start 10178 && args[start].charAt(0) != '-') { 10179 procs = new ArrayList<ProcessRecord>(); 10180 int pid = -1; 10181 try { 10182 pid = Integer.parseInt(args[start]); 10183 } catch (NumberFormatException e) { 10184 10185 } 10186 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10187 ProcessRecord proc = mLruProcesses.get(i); 10188 if (proc.pid == pid) { 10189 procs.add(proc); 10190 } else if (proc.processName.equals(args[start])) { 10191 procs.add(proc); 10192 } 10193 } 10194 if (procs.size() <= 0) { 10195 pw.println("No process found for: " + args[start]); 10196 return null; 10197 } 10198 } else { 10199 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10200 } 10201 } 10202 return procs; 10203 } 10204 10205 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10206 PrintWriter pw, String[] args) { 10207 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10208 if (procs == null) { 10209 return; 10210 } 10211 10212 long uptime = SystemClock.uptimeMillis(); 10213 long realtime = SystemClock.elapsedRealtime(); 10214 pw.println("Applications Graphics Acceleration Info:"); 10215 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10216 10217 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10218 ProcessRecord r = procs.get(i); 10219 if (r.thread != null) { 10220 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10221 pw.flush(); 10222 try { 10223 TransferPipe tp = new TransferPipe(); 10224 try { 10225 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10226 tp.go(fd); 10227 } finally { 10228 tp.kill(); 10229 } 10230 } catch (IOException e) { 10231 pw.println("Failure while dumping the app: " + r); 10232 pw.flush(); 10233 } catch (RemoteException e) { 10234 pw.println("Got a RemoteException while dumping the app " + r); 10235 pw.flush(); 10236 } 10237 } 10238 } 10239 } 10240 10241 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10242 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10243 if (procs == null) { 10244 return; 10245 } 10246 10247 pw.println("Applications Database Info:"); 10248 10249 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10250 ProcessRecord r = procs.get(i); 10251 if (r.thread != null) { 10252 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10253 pw.flush(); 10254 try { 10255 TransferPipe tp = new TransferPipe(); 10256 try { 10257 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10258 tp.go(fd); 10259 } finally { 10260 tp.kill(); 10261 } 10262 } catch (IOException e) { 10263 pw.println("Failure while dumping the app: " + r); 10264 pw.flush(); 10265 } catch (RemoteException e) { 10266 pw.println("Got a RemoteException while dumping the app " + r); 10267 pw.flush(); 10268 } 10269 } 10270 } 10271 } 10272 10273 final static class MemItem { 10274 final String label; 10275 final String shortLabel; 10276 final long pss; 10277 final int id; 10278 ArrayList<MemItem> subitems; 10279 10280 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10281 label = _label; 10282 shortLabel = _shortLabel; 10283 pss = _pss; 10284 id = _id; 10285 } 10286 } 10287 10288 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10289 boolean sort) { 10290 if (sort) { 10291 Collections.sort(items, new Comparator<MemItem>() { 10292 @Override 10293 public int compare(MemItem lhs, MemItem rhs) { 10294 if (lhs.pss < rhs.pss) { 10295 return 1; 10296 } else if (lhs.pss > rhs.pss) { 10297 return -1; 10298 } 10299 return 0; 10300 } 10301 }); 10302 } 10303 10304 for (int i=0; i<items.size(); i++) { 10305 MemItem mi = items.get(i); 10306 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10307 if (mi.subitems != null) { 10308 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10309 } 10310 } 10311 } 10312 10313 // These are in KB. 10314 static final long[] DUMP_MEM_BUCKETS = new long[] { 10315 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10316 120*1024, 160*1024, 200*1024, 10317 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10318 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10319 }; 10320 10321 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10322 boolean stackLike) { 10323 int start = label.lastIndexOf('.'); 10324 if (start >= 0) start++; 10325 else start = 0; 10326 int end = label.length(); 10327 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10328 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10329 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10330 out.append(bucket); 10331 out.append(stackLike ? "MB." : "MB "); 10332 out.append(label, start, end); 10333 return; 10334 } 10335 } 10336 out.append(memKB/1024); 10337 out.append(stackLike ? "MB." : "MB "); 10338 out.append(label, start, end); 10339 } 10340 10341 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10342 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10343 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10344 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10345 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10346 }; 10347 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10348 "System", "Persistent", "Foreground", 10349 "Visible", "Perceptible", "Heavy Weight", 10350 "Backup", "A Services", "Home", "Previous", 10351 "B Services", "Background" 10352 }; 10353 10354 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10355 PrintWriter pw, String prefix, String[] args, boolean brief, 10356 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10357 boolean dumpAll = false; 10358 boolean oomOnly = false; 10359 10360 int opti = 0; 10361 while (opti < args.length) { 10362 String opt = args[opti]; 10363 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10364 break; 10365 } 10366 opti++; 10367 if ("-a".equals(opt)) { 10368 dumpAll = true; 10369 } else if ("--oom".equals(opt)) { 10370 oomOnly = true; 10371 } else if ("-h".equals(opt)) { 10372 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10373 pw.println(" -a: include all available information for each process."); 10374 pw.println(" --oom: only show processes organized by oom adj."); 10375 pw.println("If [process] is specified it can be the name or "); 10376 pw.println("pid of a specific process to dump."); 10377 return; 10378 } else { 10379 pw.println("Unknown argument: " + opt + "; use -h for help"); 10380 } 10381 } 10382 10383 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10384 if (procs == null) { 10385 return; 10386 } 10387 10388 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10389 long uptime = SystemClock.uptimeMillis(); 10390 long realtime = SystemClock.elapsedRealtime(); 10391 10392 if (procs.size() == 1 || isCheckinRequest) { 10393 dumpAll = true; 10394 } 10395 10396 if (isCheckinRequest) { 10397 // short checkin version 10398 pw.println(uptime + "," + realtime); 10399 pw.flush(); 10400 } else { 10401 pw.println("Applications Memory Usage (kB):"); 10402 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10403 } 10404 10405 String[] innerArgs = new String[args.length-opti]; 10406 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10407 10408 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10409 long nativePss=0, dalvikPss=0, otherPss=0; 10410 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10411 10412 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10413 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10414 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10415 10416 long totalPss = 0; 10417 10418 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10419 ProcessRecord r = procs.get(i); 10420 if (r.thread != null) { 10421 if (!isCheckinRequest && dumpAll) { 10422 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10423 pw.flush(); 10424 } 10425 Debug.MemoryInfo mi = null; 10426 if (dumpAll) { 10427 try { 10428 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10429 } catch (RemoteException e) { 10430 if (!isCheckinRequest) { 10431 pw.println("Got RemoteException!"); 10432 pw.flush(); 10433 } 10434 } 10435 } else { 10436 mi = new Debug.MemoryInfo(); 10437 Debug.getMemoryInfo(r.pid, mi); 10438 } 10439 10440 if (!isCheckinRequest && mi != null) { 10441 long myTotalPss = mi.getTotalPss(); 10442 totalPss += myTotalPss; 10443 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10444 r.processName, myTotalPss, 0); 10445 procMems.add(pssItem); 10446 10447 nativePss += mi.nativePss; 10448 dalvikPss += mi.dalvikPss; 10449 otherPss += mi.otherPss; 10450 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10451 long mem = mi.getOtherPss(j); 10452 miscPss[j] += mem; 10453 otherPss -= mem; 10454 } 10455 10456 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10457 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10458 || oomIndex == (oomPss.length-1)) { 10459 oomPss[oomIndex] += myTotalPss; 10460 if (oomProcs[oomIndex] == null) { 10461 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10462 } 10463 oomProcs[oomIndex].add(pssItem); 10464 break; 10465 } 10466 } 10467 } 10468 } 10469 } 10470 10471 if (!isCheckinRequest && procs.size() > 1) { 10472 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10473 10474 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10475 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10476 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10477 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10478 String label = Debug.MemoryInfo.getOtherLabel(j); 10479 catMems.add(new MemItem(label, label, miscPss[j], j)); 10480 } 10481 10482 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10483 for (int j=0; j<oomPss.length; j++) { 10484 if (oomPss[j] != 0) { 10485 String label = DUMP_MEM_OOM_LABEL[j]; 10486 MemItem item = new MemItem(label, label, oomPss[j], 10487 DUMP_MEM_OOM_ADJ[j]); 10488 item.subitems = oomProcs[j]; 10489 oomMems.add(item); 10490 } 10491 } 10492 10493 if (outTag != null || outStack != null) { 10494 if (outTag != null) { 10495 appendMemBucket(outTag, totalPss, "total", false); 10496 } 10497 if (outStack != null) { 10498 appendMemBucket(outStack, totalPss, "total", true); 10499 } 10500 boolean firstLine = true; 10501 for (int i=0; i<oomMems.size(); i++) { 10502 MemItem miCat = oomMems.get(i); 10503 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10504 continue; 10505 } 10506 if (miCat.id < ProcessList.SERVICE_ADJ 10507 || miCat.id == ProcessList.HOME_APP_ADJ 10508 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10509 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10510 outTag.append(" / "); 10511 } 10512 if (outStack != null) { 10513 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10514 if (firstLine) { 10515 outStack.append(":"); 10516 firstLine = false; 10517 } 10518 outStack.append("\n\t at "); 10519 } else { 10520 outStack.append("$"); 10521 } 10522 } 10523 for (int j=0; j<miCat.subitems.size(); j++) { 10524 MemItem mi = miCat.subitems.get(j); 10525 if (j > 0) { 10526 if (outTag != null) { 10527 outTag.append(" "); 10528 } 10529 if (outStack != null) { 10530 outStack.append("$"); 10531 } 10532 } 10533 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10534 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10535 } 10536 if (outStack != null) { 10537 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10538 } 10539 } 10540 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10541 outStack.append("("); 10542 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10543 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10544 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10545 outStack.append(":"); 10546 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10547 } 10548 } 10549 outStack.append(")"); 10550 } 10551 } 10552 } 10553 } 10554 10555 if (!brief && !oomOnly) { 10556 pw.println(); 10557 pw.println("Total PSS by process:"); 10558 dumpMemItems(pw, " ", procMems, true); 10559 pw.println(); 10560 } 10561 pw.println("Total PSS by OOM adjustment:"); 10562 dumpMemItems(pw, " ", oomMems, false); 10563 if (!oomOnly) { 10564 PrintWriter out = categoryPw != null ? categoryPw : pw; 10565 out.println(); 10566 out.println("Total PSS by category:"); 10567 dumpMemItems(out, " ", catMems, true); 10568 } 10569 pw.println(); 10570 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10571 final int[] SINGLE_LONG_FORMAT = new int[] { 10572 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10573 }; 10574 long[] longOut = new long[1]; 10575 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10576 SINGLE_LONG_FORMAT, null, longOut, null); 10577 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10578 longOut[0] = 0; 10579 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10580 SINGLE_LONG_FORMAT, null, longOut, null); 10581 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10582 longOut[0] = 0; 10583 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10584 SINGLE_LONG_FORMAT, null, longOut, null); 10585 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10586 longOut[0] = 0; 10587 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10588 SINGLE_LONG_FORMAT, null, longOut, null); 10589 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10590 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10591 pw.print(shared); pw.println(" kB"); 10592 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10593 pw.print(voltile); pw.println(" kB volatile"); 10594 } 10595 } 10596 10597 /** 10598 * Searches array of arguments for the specified string 10599 * @param args array of argument strings 10600 * @param value value to search for 10601 * @return true if the value is contained in the array 10602 */ 10603 private static boolean scanArgs(String[] args, String value) { 10604 if (args != null) { 10605 for (String arg : args) { 10606 if (value.equals(arg)) { 10607 return true; 10608 } 10609 } 10610 } 10611 return false; 10612 } 10613 10614 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10615 ContentProviderRecord cpr, boolean always) { 10616 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10617 10618 if (!inLaunching || always) { 10619 synchronized (cpr) { 10620 cpr.launchingApp = null; 10621 cpr.notifyAll(); 10622 } 10623 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10624 String names[] = cpr.info.authority.split(";"); 10625 for (int j = 0; j < names.length; j++) { 10626 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10627 } 10628 } 10629 10630 for (int i=0; i<cpr.connections.size(); i++) { 10631 ContentProviderConnection conn = cpr.connections.get(i); 10632 if (conn.waiting) { 10633 // If this connection is waiting for the provider, then we don't 10634 // need to mess with its process unless we are always removing 10635 // or for some reason the provider is not currently launching. 10636 if (inLaunching && !always) { 10637 continue; 10638 } 10639 } 10640 ProcessRecord capp = conn.client; 10641 conn.dead = true; 10642 if (conn.stableCount > 0) { 10643 if (!capp.persistent && capp.thread != null 10644 && capp.pid != 0 10645 && capp.pid != MY_PID) { 10646 Slog.i(TAG, "Kill " + capp.processName 10647 + " (pid " + capp.pid + "): provider " + cpr.info.name 10648 + " in dying process " + (proc != null ? proc.processName : "??")); 10649 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10650 capp.processName, capp.setAdj, "dying provider " 10651 + cpr.name.toShortString()); 10652 Process.killProcessQuiet(capp.pid); 10653 } 10654 } else if (capp.thread != null && conn.provider.provider != null) { 10655 try { 10656 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10657 } catch (RemoteException e) { 10658 } 10659 // In the protocol here, we don't expect the client to correctly 10660 // clean up this connection, we'll just remove it. 10661 cpr.connections.remove(i); 10662 conn.client.conProviders.remove(conn); 10663 } 10664 } 10665 10666 if (inLaunching && always) { 10667 mLaunchingProviders.remove(cpr); 10668 } 10669 return inLaunching; 10670 } 10671 10672 /** 10673 * Main code for cleaning up a process when it has gone away. This is 10674 * called both as a result of the process dying, or directly when stopping 10675 * a process when running in single process mode. 10676 */ 10677 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10678 boolean restarting, boolean allowRestart, int index) { 10679 if (index >= 0) { 10680 mLruProcesses.remove(index); 10681 } 10682 10683 mProcessesToGc.remove(app); 10684 10685 // Dismiss any open dialogs. 10686 if (app.crashDialog != null) { 10687 app.crashDialog.dismiss(); 10688 app.crashDialog = null; 10689 } 10690 if (app.anrDialog != null) { 10691 app.anrDialog.dismiss(); 10692 app.anrDialog = null; 10693 } 10694 if (app.waitDialog != null) { 10695 app.waitDialog.dismiss(); 10696 app.waitDialog = null; 10697 } 10698 10699 app.crashing = false; 10700 app.notResponding = false; 10701 10702 app.resetPackageList(); 10703 app.unlinkDeathRecipient(); 10704 app.thread = null; 10705 app.forcingToForeground = null; 10706 app.foregroundServices = false; 10707 app.foregroundActivities = false; 10708 app.hasShownUi = false; 10709 app.hasAboveClient = false; 10710 10711 mServices.killServicesLocked(app, allowRestart); 10712 10713 boolean restart = false; 10714 10715 // Remove published content providers. 10716 if (!app.pubProviders.isEmpty()) { 10717 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10718 while (it.hasNext()) { 10719 ContentProviderRecord cpr = it.next(); 10720 10721 final boolean always = app.bad || !allowRestart; 10722 if (removeDyingProviderLocked(app, cpr, always) || always) { 10723 // We left the provider in the launching list, need to 10724 // restart it. 10725 restart = true; 10726 } 10727 10728 cpr.provider = null; 10729 cpr.proc = null; 10730 } 10731 app.pubProviders.clear(); 10732 } 10733 10734 // Take care of any launching providers waiting for this process. 10735 if (checkAppInLaunchingProvidersLocked(app, false)) { 10736 restart = true; 10737 } 10738 10739 // Unregister from connected content providers. 10740 if (!app.conProviders.isEmpty()) { 10741 for (int i=0; i<app.conProviders.size(); i++) { 10742 ContentProviderConnection conn = app.conProviders.get(i); 10743 conn.provider.connections.remove(conn); 10744 } 10745 app.conProviders.clear(); 10746 } 10747 10748 // At this point there may be remaining entries in mLaunchingProviders 10749 // where we were the only one waiting, so they are no longer of use. 10750 // Look for these and clean up if found. 10751 // XXX Commented out for now. Trying to figure out a way to reproduce 10752 // the actual situation to identify what is actually going on. 10753 if (false) { 10754 for (int i=0; i<mLaunchingProviders.size(); i++) { 10755 ContentProviderRecord cpr = (ContentProviderRecord) 10756 mLaunchingProviders.get(i); 10757 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10758 synchronized (cpr) { 10759 cpr.launchingApp = null; 10760 cpr.notifyAll(); 10761 } 10762 } 10763 } 10764 } 10765 10766 skipCurrentReceiverLocked(app); 10767 10768 // Unregister any receivers. 10769 if (app.receivers.size() > 0) { 10770 Iterator<ReceiverList> it = app.receivers.iterator(); 10771 while (it.hasNext()) { 10772 removeReceiverLocked(it.next()); 10773 } 10774 app.receivers.clear(); 10775 } 10776 10777 // If the app is undergoing backup, tell the backup manager about it 10778 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10779 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10780 + mBackupTarget.appInfo + " died during backup"); 10781 try { 10782 IBackupManager bm = IBackupManager.Stub.asInterface( 10783 ServiceManager.getService(Context.BACKUP_SERVICE)); 10784 bm.agentDisconnected(app.info.packageName); 10785 } catch (RemoteException e) { 10786 // can't happen; backup manager is local 10787 } 10788 } 10789 10790 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10791 ProcessChangeItem item = mPendingProcessChanges.get(i); 10792 if (item.pid == app.pid) { 10793 mPendingProcessChanges.remove(i); 10794 mAvailProcessChanges.add(item); 10795 } 10796 } 10797 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10798 10799 // If the caller is restarting this app, then leave it in its 10800 // current lists and let the caller take care of it. 10801 if (restarting) { 10802 return; 10803 } 10804 10805 if (!app.persistent || app.isolated) { 10806 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10807 "Removing non-persistent process during cleanup: " + app); 10808 mProcessNames.remove(app.processName, app.uid); 10809 mIsolatedProcesses.remove(app.uid); 10810 if (mHeavyWeightProcess == app) { 10811 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10812 mHeavyWeightProcess.userId, 0)); 10813 mHeavyWeightProcess = null; 10814 } 10815 } else if (!app.removed) { 10816 // This app is persistent, so we need to keep its record around. 10817 // If it is not already on the pending app list, add it there 10818 // and start a new process for it. 10819 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10820 mPersistentStartingProcesses.add(app); 10821 restart = true; 10822 } 10823 } 10824 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10825 "Clean-up removing on hold: " + app); 10826 mProcessesOnHold.remove(app); 10827 10828 if (app == mHomeProcess) { 10829 mHomeProcess = null; 10830 } 10831 if (app == mPreviousProcess) { 10832 mPreviousProcess = null; 10833 } 10834 10835 if (restart && !app.isolated) { 10836 // We have components that still need to be running in the 10837 // process, so re-launch it. 10838 mProcessNames.put(app.processName, app.uid, app); 10839 startProcessLocked(app, "restart", app.processName); 10840 } else if (app.pid > 0 && app.pid != MY_PID) { 10841 // Goodbye! 10842 synchronized (mPidsSelfLocked) { 10843 mPidsSelfLocked.remove(app.pid); 10844 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10845 } 10846 app.setPid(0); 10847 } 10848 } 10849 10850 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10851 // Look through the content providers we are waiting to have launched, 10852 // and if any run in this process then either schedule a restart of 10853 // the process or kill the client waiting for it if this process has 10854 // gone bad. 10855 int NL = mLaunchingProviders.size(); 10856 boolean restart = false; 10857 for (int i=0; i<NL; i++) { 10858 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10859 if (cpr.launchingApp == app) { 10860 if (!alwaysBad && !app.bad) { 10861 restart = true; 10862 } else { 10863 removeDyingProviderLocked(app, cpr, true); 10864 // cpr should have been removed from mLaunchingProviders 10865 NL = mLaunchingProviders.size(); 10866 i--; 10867 } 10868 } 10869 } 10870 return restart; 10871 } 10872 10873 // ========================================================= 10874 // SERVICES 10875 // ========================================================= 10876 10877 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10878 int flags) { 10879 enforceNotIsolatedCaller("getServices"); 10880 synchronized (this) { 10881 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10882 } 10883 } 10884 10885 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10886 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10887 synchronized (this) { 10888 return mServices.getRunningServiceControlPanelLocked(name); 10889 } 10890 } 10891 10892 public ComponentName startService(IApplicationThread caller, Intent service, 10893 String resolvedType, int userId) { 10894 enforceNotIsolatedCaller("startService"); 10895 // Refuse possible leaked file descriptors 10896 if (service != null && service.hasFileDescriptors() == true) { 10897 throw new IllegalArgumentException("File descriptors passed in Intent"); 10898 } 10899 10900 if (DEBUG_SERVICE) 10901 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10902 synchronized(this) { 10903 final int callingPid = Binder.getCallingPid(); 10904 final int callingUid = Binder.getCallingUid(); 10905 checkValidCaller(callingUid, userId); 10906 final long origId = Binder.clearCallingIdentity(); 10907 ComponentName res = mServices.startServiceLocked(caller, service, 10908 resolvedType, callingPid, callingUid, userId); 10909 Binder.restoreCallingIdentity(origId); 10910 return res; 10911 } 10912 } 10913 10914 ComponentName startServiceInPackage(int uid, 10915 Intent service, String resolvedType, int userId) { 10916 synchronized(this) { 10917 if (DEBUG_SERVICE) 10918 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10919 final long origId = Binder.clearCallingIdentity(); 10920 ComponentName res = mServices.startServiceLocked(null, service, 10921 resolvedType, -1, uid, userId); 10922 Binder.restoreCallingIdentity(origId); 10923 return res; 10924 } 10925 } 10926 10927 public int stopService(IApplicationThread caller, Intent service, 10928 String resolvedType, int userId) { 10929 enforceNotIsolatedCaller("stopService"); 10930 // Refuse possible leaked file descriptors 10931 if (service != null && service.hasFileDescriptors() == true) { 10932 throw new IllegalArgumentException("File descriptors passed in Intent"); 10933 } 10934 10935 checkValidCaller(Binder.getCallingUid(), userId); 10936 10937 synchronized(this) { 10938 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10939 } 10940 } 10941 10942 public IBinder peekService(Intent service, String resolvedType) { 10943 enforceNotIsolatedCaller("peekService"); 10944 // Refuse possible leaked file descriptors 10945 if (service != null && service.hasFileDescriptors() == true) { 10946 throw new IllegalArgumentException("File descriptors passed in Intent"); 10947 } 10948 synchronized(this) { 10949 return mServices.peekServiceLocked(service, resolvedType); 10950 } 10951 } 10952 10953 public boolean stopServiceToken(ComponentName className, IBinder token, 10954 int startId) { 10955 synchronized(this) { 10956 return mServices.stopServiceTokenLocked(className, token, startId); 10957 } 10958 } 10959 10960 public void setServiceForeground(ComponentName className, IBinder token, 10961 int id, Notification notification, boolean removeNotification) { 10962 synchronized(this) { 10963 mServices.setServiceForegroundLocked(className, token, id, notification, 10964 removeNotification); 10965 } 10966 } 10967 10968 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10969 boolean requireFull, String name, String callerPackage) { 10970 final int callingUserId = UserHandle.getUserId(callingUid); 10971 if (callingUserId != userId) { 10972 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10973 if ((requireFull || checkComponentPermission( 10974 android.Manifest.permission.INTERACT_ACROSS_USERS, 10975 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10976 && checkComponentPermission( 10977 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10978 callingPid, callingUid, -1, true) 10979 != PackageManager.PERMISSION_GRANTED) { 10980 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10981 // In this case, they would like to just execute as their 10982 // owner user instead of failing. 10983 userId = callingUserId; 10984 } else { 10985 StringBuilder builder = new StringBuilder(128); 10986 builder.append("Permission Denial: "); 10987 builder.append(name); 10988 if (callerPackage != null) { 10989 builder.append(" from "); 10990 builder.append(callerPackage); 10991 } 10992 builder.append(" asks to run as user "); 10993 builder.append(userId); 10994 builder.append(" but is calling from user "); 10995 builder.append(UserHandle.getUserId(callingUid)); 10996 builder.append("; this requires "); 10997 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10998 if (!requireFull) { 10999 builder.append(" or "); 11000 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 11001 } 11002 String msg = builder.toString(); 11003 Slog.w(TAG, msg); 11004 throw new SecurityException(msg); 11005 } 11006 } 11007 } 11008 if (userId == UserHandle.USER_CURRENT 11009 || userId == UserHandle.USER_CURRENT_OR_SELF) { 11010 // Note that we may be accessing this outside of a lock... 11011 // shouldn't be a big deal, if this is being called outside 11012 // of a locked context there is intrinsically a race with 11013 // the value the caller will receive and someone else changing it. 11014 userId = mCurrentUserId; 11015 } 11016 if (!allowAll && userId < 0) { 11017 throw new IllegalArgumentException( 11018 "Call does not support special user #" + userId); 11019 } 11020 } 11021 return userId; 11022 } 11023 11024 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 11025 String className, int flags) { 11026 boolean result = false; 11027 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11028 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 11029 if (ActivityManager.checkUidPermission( 11030 android.Manifest.permission.INTERACT_ACROSS_USERS, 11031 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 11032 ComponentName comp = new ComponentName(aInfo.packageName, className); 11033 String msg = "Permission Denial: Component " + comp.flattenToShortString() 11034 + " requests FLAG_SINGLE_USER, but app does not hold " 11035 + android.Manifest.permission.INTERACT_ACROSS_USERS; 11036 Slog.w(TAG, msg); 11037 throw new SecurityException(msg); 11038 } 11039 result = true; 11040 } 11041 } else if (componentProcessName == aInfo.packageName) { 11042 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11043 } else if ("system".equals(componentProcessName)) { 11044 result = true; 11045 } 11046 if (DEBUG_MU) { 11047 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11048 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11049 } 11050 return result; 11051 } 11052 11053 public int bindService(IApplicationThread caller, IBinder token, 11054 Intent service, String resolvedType, 11055 IServiceConnection connection, int flags, int userId) { 11056 enforceNotIsolatedCaller("bindService"); 11057 // Refuse possible leaked file descriptors 11058 if (service != null && service.hasFileDescriptors() == true) { 11059 throw new IllegalArgumentException("File descriptors passed in Intent"); 11060 } 11061 11062 synchronized(this) { 11063 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11064 connection, flags, userId); 11065 } 11066 } 11067 11068 public boolean unbindService(IServiceConnection connection) { 11069 synchronized (this) { 11070 return mServices.unbindServiceLocked(connection); 11071 } 11072 } 11073 11074 public void publishService(IBinder token, Intent intent, IBinder service) { 11075 // Refuse possible leaked file descriptors 11076 if (intent != null && intent.hasFileDescriptors() == true) { 11077 throw new IllegalArgumentException("File descriptors passed in Intent"); 11078 } 11079 11080 synchronized(this) { 11081 if (!(token instanceof ServiceRecord)) { 11082 throw new IllegalArgumentException("Invalid service token"); 11083 } 11084 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11085 } 11086 } 11087 11088 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11089 // Refuse possible leaked file descriptors 11090 if (intent != null && intent.hasFileDescriptors() == true) { 11091 throw new IllegalArgumentException("File descriptors passed in Intent"); 11092 } 11093 11094 synchronized(this) { 11095 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11096 } 11097 } 11098 11099 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11100 synchronized(this) { 11101 if (!(token instanceof ServiceRecord)) { 11102 throw new IllegalArgumentException("Invalid service token"); 11103 } 11104 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11105 } 11106 } 11107 11108 // ========================================================= 11109 // BACKUP AND RESTORE 11110 // ========================================================= 11111 11112 // Cause the target app to be launched if necessary and its backup agent 11113 // instantiated. The backup agent will invoke backupAgentCreated() on the 11114 // activity manager to announce its creation. 11115 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11116 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11117 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11118 11119 synchronized(this) { 11120 // !!! TODO: currently no check here that we're already bound 11121 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11122 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11123 synchronized (stats) { 11124 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11125 } 11126 11127 // Backup agent is now in use, its package can't be stopped. 11128 try { 11129 AppGlobals.getPackageManager().setPackageStoppedState( 11130 app.packageName, false, UserHandle.getUserId(app.uid)); 11131 } catch (RemoteException e) { 11132 } catch (IllegalArgumentException e) { 11133 Slog.w(TAG, "Failed trying to unstop package " 11134 + app.packageName + ": " + e); 11135 } 11136 11137 BackupRecord r = new BackupRecord(ss, app, backupMode); 11138 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11139 ? new ComponentName(app.packageName, app.backupAgentName) 11140 : new ComponentName("android", "FullBackupAgent"); 11141 // startProcessLocked() returns existing proc's record if it's already running 11142 ProcessRecord proc = startProcessLocked(app.processName, app, 11143 false, 0, "backup", hostingName, false, false); 11144 if (proc == null) { 11145 Slog.e(TAG, "Unable to start backup agent process " + r); 11146 return false; 11147 } 11148 11149 r.app = proc; 11150 mBackupTarget = r; 11151 mBackupAppName = app.packageName; 11152 11153 // Try not to kill the process during backup 11154 updateOomAdjLocked(proc); 11155 11156 // If the process is already attached, schedule the creation of the backup agent now. 11157 // If it is not yet live, this will be done when it attaches to the framework. 11158 if (proc.thread != null) { 11159 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11160 try { 11161 proc.thread.scheduleCreateBackupAgent(app, 11162 compatibilityInfoForPackageLocked(app), backupMode); 11163 } catch (RemoteException e) { 11164 // Will time out on the backup manager side 11165 } 11166 } else { 11167 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11168 } 11169 // Invariants: at this point, the target app process exists and the application 11170 // is either already running or in the process of coming up. mBackupTarget and 11171 // mBackupAppName describe the app, so that when it binds back to the AM we 11172 // know that it's scheduled for a backup-agent operation. 11173 } 11174 11175 return true; 11176 } 11177 11178 // A backup agent has just come up 11179 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11180 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11181 + " = " + agent); 11182 11183 synchronized(this) { 11184 if (!agentPackageName.equals(mBackupAppName)) { 11185 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11186 return; 11187 } 11188 } 11189 11190 long oldIdent = Binder.clearCallingIdentity(); 11191 try { 11192 IBackupManager bm = IBackupManager.Stub.asInterface( 11193 ServiceManager.getService(Context.BACKUP_SERVICE)); 11194 bm.agentConnected(agentPackageName, agent); 11195 } catch (RemoteException e) { 11196 // can't happen; the backup manager service is local 11197 } catch (Exception e) { 11198 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11199 e.printStackTrace(); 11200 } finally { 11201 Binder.restoreCallingIdentity(oldIdent); 11202 } 11203 } 11204 11205 // done with this agent 11206 public void unbindBackupAgent(ApplicationInfo appInfo) { 11207 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11208 if (appInfo == null) { 11209 Slog.w(TAG, "unbind backup agent for null app"); 11210 return; 11211 } 11212 11213 synchronized(this) { 11214 if (mBackupAppName == null) { 11215 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11216 return; 11217 } 11218 11219 if (!mBackupAppName.equals(appInfo.packageName)) { 11220 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11221 return; 11222 } 11223 11224 ProcessRecord proc = mBackupTarget.app; 11225 mBackupTarget = null; 11226 mBackupAppName = null; 11227 11228 // Not backing this app up any more; reset its OOM adjustment 11229 updateOomAdjLocked(proc); 11230 11231 // If the app crashed during backup, 'thread' will be null here 11232 if (proc.thread != null) { 11233 try { 11234 proc.thread.scheduleDestroyBackupAgent(appInfo, 11235 compatibilityInfoForPackageLocked(appInfo)); 11236 } catch (Exception e) { 11237 Slog.e(TAG, "Exception when unbinding backup agent:"); 11238 e.printStackTrace(); 11239 } 11240 } 11241 } 11242 } 11243 // ========================================================= 11244 // BROADCASTS 11245 // ========================================================= 11246 11247 private final List getStickiesLocked(String action, IntentFilter filter, 11248 List cur, int userId) { 11249 final ContentResolver resolver = mContext.getContentResolver(); 11250 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11251 if (stickies == null) { 11252 return cur; 11253 } 11254 final ArrayList<Intent> list = stickies.get(action); 11255 if (list == null) { 11256 return cur; 11257 } 11258 int N = list.size(); 11259 for (int i=0; i<N; i++) { 11260 Intent intent = list.get(i); 11261 if (filter.match(resolver, intent, true, TAG) >= 0) { 11262 if (cur == null) { 11263 cur = new ArrayList<Intent>(); 11264 } 11265 cur.add(intent); 11266 } 11267 } 11268 return cur; 11269 } 11270 11271 boolean isPendingBroadcastProcessLocked(int pid) { 11272 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11273 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11274 } 11275 11276 void skipPendingBroadcastLocked(int pid) { 11277 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11278 for (BroadcastQueue queue : mBroadcastQueues) { 11279 queue.skipPendingBroadcastLocked(pid); 11280 } 11281 } 11282 11283 // The app just attached; send any pending broadcasts that it should receive 11284 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11285 boolean didSomething = false; 11286 for (BroadcastQueue queue : mBroadcastQueues) { 11287 didSomething |= queue.sendPendingBroadcastsLocked(app); 11288 } 11289 return didSomething; 11290 } 11291 11292 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11293 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11294 enforceNotIsolatedCaller("registerReceiver"); 11295 int callingUid; 11296 int callingPid; 11297 synchronized(this) { 11298 ProcessRecord callerApp = null; 11299 if (caller != null) { 11300 callerApp = getRecordForAppLocked(caller); 11301 if (callerApp == null) { 11302 throw new SecurityException( 11303 "Unable to find app for caller " + caller 11304 + " (pid=" + Binder.getCallingPid() 11305 + ") when registering receiver " + receiver); 11306 } 11307 if (callerApp.info.uid != Process.SYSTEM_UID && 11308 !callerApp.pkgList.contains(callerPackage)) { 11309 throw new SecurityException("Given caller package " + callerPackage 11310 + " is not running in process " + callerApp); 11311 } 11312 callingUid = callerApp.info.uid; 11313 callingPid = callerApp.pid; 11314 } else { 11315 callerPackage = null; 11316 callingUid = Binder.getCallingUid(); 11317 callingPid = Binder.getCallingPid(); 11318 } 11319 11320 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11321 true, true, "registerReceiver", callerPackage); 11322 11323 List allSticky = null; 11324 11325 // Look for any matching sticky broadcasts... 11326 Iterator actions = filter.actionsIterator(); 11327 if (actions != null) { 11328 while (actions.hasNext()) { 11329 String action = (String)actions.next(); 11330 allSticky = getStickiesLocked(action, filter, allSticky, 11331 UserHandle.USER_ALL); 11332 allSticky = getStickiesLocked(action, filter, allSticky, 11333 UserHandle.getUserId(callingUid)); 11334 } 11335 } else { 11336 allSticky = getStickiesLocked(null, filter, allSticky, 11337 UserHandle.USER_ALL); 11338 allSticky = getStickiesLocked(null, filter, allSticky, 11339 UserHandle.getUserId(callingUid)); 11340 } 11341 11342 // The first sticky in the list is returned directly back to 11343 // the client. 11344 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11345 11346 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11347 + ": " + sticky); 11348 11349 if (receiver == null) { 11350 return sticky; 11351 } 11352 11353 ReceiverList rl 11354 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11355 if (rl == null) { 11356 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11357 userId, receiver); 11358 if (rl.app != null) { 11359 rl.app.receivers.add(rl); 11360 } else { 11361 try { 11362 receiver.asBinder().linkToDeath(rl, 0); 11363 } catch (RemoteException e) { 11364 return sticky; 11365 } 11366 rl.linkedToDeath = true; 11367 } 11368 mRegisteredReceivers.put(receiver.asBinder(), rl); 11369 } else if (rl.uid != callingUid) { 11370 throw new IllegalArgumentException( 11371 "Receiver requested to register for uid " + callingUid 11372 + " was previously registered for uid " + rl.uid); 11373 } else if (rl.pid != callingPid) { 11374 throw new IllegalArgumentException( 11375 "Receiver requested to register for pid " + callingPid 11376 + " was previously registered for pid " + rl.pid); 11377 } else if (rl.userId != userId) { 11378 throw new IllegalArgumentException( 11379 "Receiver requested to register for user " + userId 11380 + " was previously registered for user " + rl.userId); 11381 } 11382 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11383 permission, callingUid, userId); 11384 rl.add(bf); 11385 if (!bf.debugCheck()) { 11386 Slog.w(TAG, "==> For Dynamic broadast"); 11387 } 11388 mReceiverResolver.addFilter(bf); 11389 11390 // Enqueue broadcasts for all existing stickies that match 11391 // this filter. 11392 if (allSticky != null) { 11393 ArrayList receivers = new ArrayList(); 11394 receivers.add(bf); 11395 11396 int N = allSticky.size(); 11397 for (int i=0; i<N; i++) { 11398 Intent intent = (Intent)allSticky.get(i); 11399 BroadcastQueue queue = broadcastQueueForIntent(intent); 11400 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11401 null, -1, -1, null, receivers, null, 0, null, null, 11402 false, true, true, -1); 11403 queue.enqueueParallelBroadcastLocked(r); 11404 queue.scheduleBroadcastsLocked(); 11405 } 11406 } 11407 11408 return sticky; 11409 } 11410 } 11411 11412 public void unregisterReceiver(IIntentReceiver receiver) { 11413 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11414 11415 final long origId = Binder.clearCallingIdentity(); 11416 try { 11417 boolean doTrim = false; 11418 11419 synchronized(this) { 11420 ReceiverList rl 11421 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11422 if (rl != null) { 11423 if (rl.curBroadcast != null) { 11424 BroadcastRecord r = rl.curBroadcast; 11425 final boolean doNext = finishReceiverLocked( 11426 receiver.asBinder(), r.resultCode, r.resultData, 11427 r.resultExtras, r.resultAbort, true); 11428 if (doNext) { 11429 doTrim = true; 11430 r.queue.processNextBroadcast(false); 11431 } 11432 } 11433 11434 if (rl.app != null) { 11435 rl.app.receivers.remove(rl); 11436 } 11437 removeReceiverLocked(rl); 11438 if (rl.linkedToDeath) { 11439 rl.linkedToDeath = false; 11440 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11441 } 11442 } 11443 } 11444 11445 // If we actually concluded any broadcasts, we might now be able 11446 // to trim the recipients' apps from our working set 11447 if (doTrim) { 11448 trimApplications(); 11449 return; 11450 } 11451 11452 } finally { 11453 Binder.restoreCallingIdentity(origId); 11454 } 11455 } 11456 11457 void removeReceiverLocked(ReceiverList rl) { 11458 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11459 int N = rl.size(); 11460 for (int i=0; i<N; i++) { 11461 mReceiverResolver.removeFilter(rl.get(i)); 11462 } 11463 } 11464 11465 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11466 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11467 ProcessRecord r = mLruProcesses.get(i); 11468 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11469 try { 11470 r.thread.dispatchPackageBroadcast(cmd, packages); 11471 } catch (RemoteException ex) { 11472 } 11473 } 11474 } 11475 } 11476 11477 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11478 int[] users) { 11479 List<ResolveInfo> receivers = null; 11480 try { 11481 HashSet<ComponentName> singleUserReceivers = null; 11482 boolean scannedFirstReceivers = false; 11483 for (int user : users) { 11484 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11485 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11486 if (user != 0 && newReceivers != null) { 11487 // If this is not the primary user, we need to check for 11488 // any receivers that should be filtered out. 11489 for (int i=0; i<newReceivers.size(); i++) { 11490 ResolveInfo ri = newReceivers.get(i); 11491 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11492 newReceivers.remove(i); 11493 i--; 11494 } 11495 } 11496 } 11497 if (newReceivers != null && newReceivers.size() == 0) { 11498 newReceivers = null; 11499 } 11500 if (receivers == null) { 11501 receivers = newReceivers; 11502 } else if (newReceivers != null) { 11503 // We need to concatenate the additional receivers 11504 // found with what we have do far. This would be easy, 11505 // but we also need to de-dup any receivers that are 11506 // singleUser. 11507 if (!scannedFirstReceivers) { 11508 // Collect any single user receivers we had already retrieved. 11509 scannedFirstReceivers = true; 11510 for (int i=0; i<receivers.size(); i++) { 11511 ResolveInfo ri = receivers.get(i); 11512 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11513 ComponentName cn = new ComponentName( 11514 ri.activityInfo.packageName, ri.activityInfo.name); 11515 if (singleUserReceivers == null) { 11516 singleUserReceivers = new HashSet<ComponentName>(); 11517 } 11518 singleUserReceivers.add(cn); 11519 } 11520 } 11521 } 11522 // Add the new results to the existing results, tracking 11523 // and de-dupping single user receivers. 11524 for (int i=0; i<newReceivers.size(); i++) { 11525 ResolveInfo ri = newReceivers.get(i); 11526 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11527 ComponentName cn = new ComponentName( 11528 ri.activityInfo.packageName, ri.activityInfo.name); 11529 if (singleUserReceivers == null) { 11530 singleUserReceivers = new HashSet<ComponentName>(); 11531 } 11532 if (!singleUserReceivers.contains(cn)) { 11533 singleUserReceivers.add(cn); 11534 receivers.add(ri); 11535 } 11536 } else { 11537 receivers.add(ri); 11538 } 11539 } 11540 } 11541 } 11542 } catch (RemoteException ex) { 11543 // pm is in same process, this will never happen. 11544 } 11545 return receivers; 11546 } 11547 11548 private final int broadcastIntentLocked(ProcessRecord callerApp, 11549 String callerPackage, Intent intent, String resolvedType, 11550 IIntentReceiver resultTo, int resultCode, String resultData, 11551 Bundle map, String requiredPermission, 11552 boolean ordered, boolean sticky, int callingPid, int callingUid, 11553 int userId) { 11554 intent = new Intent(intent); 11555 11556 // By default broadcasts do not go to stopped apps. 11557 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11558 11559 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11560 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11561 + " ordered=" + ordered + " userid=" + userId); 11562 if ((resultTo != null) && !ordered) { 11563 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11564 } 11565 11566 userId = handleIncomingUser(callingPid, callingUid, userId, 11567 true, false, "broadcast", callerPackage); 11568 11569 // Make sure that the user who is receiving this broadcast is started. 11570 // If not, we will just skip it. 11571 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11572 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11573 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11574 Slog.w(TAG, "Skipping broadcast of " + intent 11575 + ": user " + userId + " is stopped"); 11576 return ActivityManager.BROADCAST_SUCCESS; 11577 } 11578 } 11579 11580 /* 11581 * Prevent non-system code (defined here to be non-persistent 11582 * processes) from sending protected broadcasts. 11583 */ 11584 int callingAppId = UserHandle.getAppId(callingUid); 11585 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11586 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11587 callingUid == 0) { 11588 // Always okay. 11589 } else if (callerApp == null || !callerApp.persistent) { 11590 try { 11591 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11592 intent.getAction())) { 11593 String msg = "Permission Denial: not allowed to send broadcast " 11594 + intent.getAction() + " from pid=" 11595 + callingPid + ", uid=" + callingUid; 11596 Slog.w(TAG, msg); 11597 throw new SecurityException(msg); 11598 } 11599 } catch (RemoteException e) { 11600 Slog.w(TAG, "Remote exception", e); 11601 return ActivityManager.BROADCAST_SUCCESS; 11602 } 11603 } 11604 11605 // Handle special intents: if this broadcast is from the package 11606 // manager about a package being removed, we need to remove all of 11607 // its activities from the history stack. 11608 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11609 intent.getAction()); 11610 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11611 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11612 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11613 || uidRemoved) { 11614 if (checkComponentPermission( 11615 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11616 callingPid, callingUid, -1, true) 11617 == PackageManager.PERMISSION_GRANTED) { 11618 if (uidRemoved) { 11619 final Bundle intentExtras = intent.getExtras(); 11620 final int uid = intentExtras != null 11621 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11622 if (uid >= 0) { 11623 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11624 synchronized (bs) { 11625 bs.removeUidStatsLocked(uid); 11626 } 11627 } 11628 } else { 11629 // If resources are unavailable just force stop all 11630 // those packages and flush the attribute cache as well. 11631 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11632 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11633 if (list != null && (list.length > 0)) { 11634 for (String pkg : list) { 11635 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11636 } 11637 sendPackageBroadcastLocked( 11638 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11639 } 11640 } else { 11641 Uri data = intent.getData(); 11642 String ssp; 11643 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11644 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11645 forceStopPackageLocked(ssp, 11646 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11647 false, userId); 11648 } 11649 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11650 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11651 new String[] {ssp}, userId); 11652 } 11653 } 11654 } 11655 } 11656 } else { 11657 String msg = "Permission Denial: " + intent.getAction() 11658 + " broadcast from " + callerPackage + " (pid=" + callingPid 11659 + ", uid=" + callingUid + ")" 11660 + " requires " 11661 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11662 Slog.w(TAG, msg); 11663 throw new SecurityException(msg); 11664 } 11665 11666 // Special case for adding a package: by default turn on compatibility 11667 // mode. 11668 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11669 Uri data = intent.getData(); 11670 String ssp; 11671 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11672 mCompatModePackages.handlePackageAddedLocked(ssp, 11673 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11674 } 11675 } 11676 11677 /* 11678 * If this is the time zone changed action, queue up a message that will reset the timezone 11679 * of all currently running processes. This message will get queued up before the broadcast 11680 * happens. 11681 */ 11682 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11683 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11684 } 11685 11686 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11687 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11688 } 11689 11690 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11691 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11692 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11693 } 11694 11695 // Add to the sticky list if requested. 11696 if (sticky) { 11697 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11698 callingPid, callingUid) 11699 != PackageManager.PERMISSION_GRANTED) { 11700 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11701 + callingPid + ", uid=" + callingUid 11702 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11703 Slog.w(TAG, msg); 11704 throw new SecurityException(msg); 11705 } 11706 if (requiredPermission != null) { 11707 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11708 + " and enforce permission " + requiredPermission); 11709 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11710 } 11711 if (intent.getComponent() != null) { 11712 throw new SecurityException( 11713 "Sticky broadcasts can't target a specific component"); 11714 } 11715 // We use userId directly here, since the "all" target is maintained 11716 // as a separate set of sticky broadcasts. 11717 if (userId != UserHandle.USER_ALL) { 11718 // But first, if this is not a broadcast to all users, then 11719 // make sure it doesn't conflict with an existing broadcast to 11720 // all users. 11721 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11722 UserHandle.USER_ALL); 11723 if (stickies != null) { 11724 ArrayList<Intent> list = stickies.get(intent.getAction()); 11725 if (list != null) { 11726 int N = list.size(); 11727 int i; 11728 for (i=0; i<N; i++) { 11729 if (intent.filterEquals(list.get(i))) { 11730 throw new IllegalArgumentException( 11731 "Sticky broadcast " + intent + " for user " 11732 + userId + " conflicts with existing global broadcast"); 11733 } 11734 } 11735 } 11736 } 11737 } 11738 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11739 if (stickies == null) { 11740 stickies = new HashMap<String, ArrayList<Intent>>(); 11741 mStickyBroadcasts.put(userId, stickies); 11742 } 11743 ArrayList<Intent> list = stickies.get(intent.getAction()); 11744 if (list == null) { 11745 list = new ArrayList<Intent>(); 11746 stickies.put(intent.getAction(), list); 11747 } 11748 int N = list.size(); 11749 int i; 11750 for (i=0; i<N; i++) { 11751 if (intent.filterEquals(list.get(i))) { 11752 // This sticky already exists, replace it. 11753 list.set(i, new Intent(intent)); 11754 break; 11755 } 11756 } 11757 if (i >= N) { 11758 list.add(new Intent(intent)); 11759 } 11760 } 11761 11762 int[] users; 11763 if (userId == UserHandle.USER_ALL) { 11764 // Caller wants broadcast to go to all started users. 11765 users = mStartedUserArray; 11766 } else { 11767 // Caller wants broadcast to go to one specific user. 11768 users = new int[] {userId}; 11769 } 11770 11771 // Figure out who all will receive this broadcast. 11772 List receivers = null; 11773 List<BroadcastFilter> registeredReceivers = null; 11774 // Need to resolve the intent to interested receivers... 11775 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11776 == 0) { 11777 receivers = collectReceiverComponents(intent, resolvedType, users); 11778 } 11779 if (intent.getComponent() == null) { 11780 registeredReceivers = mReceiverResolver.queryIntent(intent, 11781 resolvedType, false, userId); 11782 } 11783 11784 final boolean replacePending = 11785 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11786 11787 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11788 + " replacePending=" + replacePending); 11789 11790 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11791 if (!ordered && NR > 0) { 11792 // If we are not serializing this broadcast, then send the 11793 // registered receivers separately so they don't wait for the 11794 // components to be launched. 11795 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11796 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11797 callerPackage, callingPid, callingUid, requiredPermission, 11798 registeredReceivers, resultTo, resultCode, resultData, map, 11799 ordered, sticky, false, userId); 11800 if (DEBUG_BROADCAST) Slog.v( 11801 TAG, "Enqueueing parallel broadcast " + r); 11802 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11803 if (!replaced) { 11804 queue.enqueueParallelBroadcastLocked(r); 11805 queue.scheduleBroadcastsLocked(); 11806 } 11807 registeredReceivers = null; 11808 NR = 0; 11809 } 11810 11811 // Merge into one list. 11812 int ir = 0; 11813 if (receivers != null) { 11814 // A special case for PACKAGE_ADDED: do not allow the package 11815 // being added to see this broadcast. This prevents them from 11816 // using this as a back door to get run as soon as they are 11817 // installed. Maybe in the future we want to have a special install 11818 // broadcast or such for apps, but we'd like to deliberately make 11819 // this decision. 11820 String skipPackages[] = null; 11821 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11822 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11823 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11824 Uri data = intent.getData(); 11825 if (data != null) { 11826 String pkgName = data.getSchemeSpecificPart(); 11827 if (pkgName != null) { 11828 skipPackages = new String[] { pkgName }; 11829 } 11830 } 11831 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11832 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11833 } 11834 if (skipPackages != null && (skipPackages.length > 0)) { 11835 for (String skipPackage : skipPackages) { 11836 if (skipPackage != null) { 11837 int NT = receivers.size(); 11838 for (int it=0; it<NT; it++) { 11839 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11840 if (curt.activityInfo.packageName.equals(skipPackage)) { 11841 receivers.remove(it); 11842 it--; 11843 NT--; 11844 } 11845 } 11846 } 11847 } 11848 } 11849 11850 int NT = receivers != null ? receivers.size() : 0; 11851 int it = 0; 11852 ResolveInfo curt = null; 11853 BroadcastFilter curr = null; 11854 while (it < NT && ir < NR) { 11855 if (curt == null) { 11856 curt = (ResolveInfo)receivers.get(it); 11857 } 11858 if (curr == null) { 11859 curr = registeredReceivers.get(ir); 11860 } 11861 if (curr.getPriority() >= curt.priority) { 11862 // Insert this broadcast record into the final list. 11863 receivers.add(it, curr); 11864 ir++; 11865 curr = null; 11866 it++; 11867 NT++; 11868 } else { 11869 // Skip to the next ResolveInfo in the final list. 11870 it++; 11871 curt = null; 11872 } 11873 } 11874 } 11875 while (ir < NR) { 11876 if (receivers == null) { 11877 receivers = new ArrayList(); 11878 } 11879 receivers.add(registeredReceivers.get(ir)); 11880 ir++; 11881 } 11882 11883 if ((receivers != null && receivers.size() > 0) 11884 || resultTo != null) { 11885 BroadcastQueue queue = broadcastQueueForIntent(intent); 11886 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11887 callerPackage, callingPid, callingUid, requiredPermission, 11888 receivers, resultTo, resultCode, resultData, map, ordered, 11889 sticky, false, userId); 11890 if (DEBUG_BROADCAST) Slog.v( 11891 TAG, "Enqueueing ordered broadcast " + r 11892 + ": prev had " + queue.mOrderedBroadcasts.size()); 11893 if (DEBUG_BROADCAST) { 11894 int seq = r.intent.getIntExtra("seq", -1); 11895 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11896 } 11897 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11898 if (!replaced) { 11899 queue.enqueueOrderedBroadcastLocked(r); 11900 queue.scheduleBroadcastsLocked(); 11901 } 11902 } 11903 11904 return ActivityManager.BROADCAST_SUCCESS; 11905 } 11906 11907 final Intent verifyBroadcastLocked(Intent intent) { 11908 // Refuse possible leaked file descriptors 11909 if (intent != null && intent.hasFileDescriptors() == true) { 11910 throw new IllegalArgumentException("File descriptors passed in Intent"); 11911 } 11912 11913 int flags = intent.getFlags(); 11914 11915 if (!mProcessesReady) { 11916 // if the caller really truly claims to know what they're doing, go 11917 // ahead and allow the broadcast without launching any receivers 11918 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11919 intent = new Intent(intent); 11920 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11921 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11922 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11923 + " before boot completion"); 11924 throw new IllegalStateException("Cannot broadcast before boot completed"); 11925 } 11926 } 11927 11928 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11929 throw new IllegalArgumentException( 11930 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11931 } 11932 11933 return intent; 11934 } 11935 11936 public final int broadcastIntent(IApplicationThread caller, 11937 Intent intent, String resolvedType, IIntentReceiver resultTo, 11938 int resultCode, String resultData, Bundle map, 11939 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11940 enforceNotIsolatedCaller("broadcastIntent"); 11941 synchronized(this) { 11942 intent = verifyBroadcastLocked(intent); 11943 11944 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11945 final int callingPid = Binder.getCallingPid(); 11946 final int callingUid = Binder.getCallingUid(); 11947 final long origId = Binder.clearCallingIdentity(); 11948 int res = broadcastIntentLocked(callerApp, 11949 callerApp != null ? callerApp.info.packageName : null, 11950 intent, resolvedType, resultTo, 11951 resultCode, resultData, map, requiredPermission, serialized, sticky, 11952 callingPid, callingUid, userId); 11953 Binder.restoreCallingIdentity(origId); 11954 return res; 11955 } 11956 } 11957 11958 int broadcastIntentInPackage(String packageName, int uid, 11959 Intent intent, String resolvedType, IIntentReceiver resultTo, 11960 int resultCode, String resultData, Bundle map, 11961 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11962 synchronized(this) { 11963 intent = verifyBroadcastLocked(intent); 11964 11965 final long origId = Binder.clearCallingIdentity(); 11966 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11967 resultTo, resultCode, resultData, map, requiredPermission, 11968 serialized, sticky, -1, uid, userId); 11969 Binder.restoreCallingIdentity(origId); 11970 return res; 11971 } 11972 } 11973 11974 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11975 // Refuse possible leaked file descriptors 11976 if (intent != null && intent.hasFileDescriptors() == true) { 11977 throw new IllegalArgumentException("File descriptors passed in Intent"); 11978 } 11979 11980 userId = handleIncomingUser(Binder.getCallingPid(), 11981 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11982 11983 synchronized(this) { 11984 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11985 != PackageManager.PERMISSION_GRANTED) { 11986 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11987 + Binder.getCallingPid() 11988 + ", uid=" + Binder.getCallingUid() 11989 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11990 Slog.w(TAG, msg); 11991 throw new SecurityException(msg); 11992 } 11993 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11994 if (stickies != null) { 11995 ArrayList<Intent> list = stickies.get(intent.getAction()); 11996 if (list != null) { 11997 int N = list.size(); 11998 int i; 11999 for (i=0; i<N; i++) { 12000 if (intent.filterEquals(list.get(i))) { 12001 list.remove(i); 12002 break; 12003 } 12004 } 12005 if (list.size() <= 0) { 12006 stickies.remove(intent.getAction()); 12007 } 12008 } 12009 if (stickies.size() <= 0) { 12010 mStickyBroadcasts.remove(userId); 12011 } 12012 } 12013 } 12014 } 12015 12016 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12017 String resultData, Bundle resultExtras, boolean resultAbort, 12018 boolean explicit) { 12019 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 12020 if (r == null) { 12021 Slog.w(TAG, "finishReceiver called but not found on queue"); 12022 return false; 12023 } 12024 12025 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 12026 explicit); 12027 } 12028 12029 public void finishReceiver(IBinder who, int resultCode, String resultData, 12030 Bundle resultExtras, boolean resultAbort) { 12031 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12032 12033 // Refuse possible leaked file descriptors 12034 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12035 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12036 } 12037 12038 final long origId = Binder.clearCallingIdentity(); 12039 try { 12040 boolean doNext = false; 12041 BroadcastRecord r = null; 12042 12043 synchronized(this) { 12044 r = broadcastRecordForReceiverLocked(who); 12045 if (r != null) { 12046 doNext = r.queue.finishReceiverLocked(r, resultCode, 12047 resultData, resultExtras, resultAbort, true); 12048 } 12049 } 12050 12051 if (doNext) { 12052 r.queue.processNextBroadcast(false); 12053 } 12054 trimApplications(); 12055 } finally { 12056 Binder.restoreCallingIdentity(origId); 12057 } 12058 } 12059 12060 // ========================================================= 12061 // INSTRUMENTATION 12062 // ========================================================= 12063 12064 public boolean startInstrumentation(ComponentName className, 12065 String profileFile, int flags, Bundle arguments, 12066 IInstrumentationWatcher watcher, int userId) { 12067 enforceNotIsolatedCaller("startInstrumentation"); 12068 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 12069 userId, false, true, "startInstrumentation", null); 12070 // Refuse possible leaked file descriptors 12071 if (arguments != null && arguments.hasFileDescriptors()) { 12072 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12073 } 12074 12075 synchronized(this) { 12076 InstrumentationInfo ii = null; 12077 ApplicationInfo ai = null; 12078 try { 12079 ii = mContext.getPackageManager().getInstrumentationInfo( 12080 className, STOCK_PM_FLAGS); 12081 ai = AppGlobals.getPackageManager().getApplicationInfo( 12082 ii.targetPackage, STOCK_PM_FLAGS, userId); 12083 } catch (PackageManager.NameNotFoundException e) { 12084 } catch (RemoteException e) { 12085 } 12086 if (ii == null) { 12087 reportStartInstrumentationFailure(watcher, className, 12088 "Unable to find instrumentation info for: " + className); 12089 return false; 12090 } 12091 if (ai == null) { 12092 reportStartInstrumentationFailure(watcher, className, 12093 "Unable to find instrumentation target package: " + ii.targetPackage); 12094 return false; 12095 } 12096 12097 int match = mContext.getPackageManager().checkSignatures( 12098 ii.targetPackage, ii.packageName); 12099 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12100 String msg = "Permission Denial: starting instrumentation " 12101 + className + " from pid=" 12102 + Binder.getCallingPid() 12103 + ", uid=" + Binder.getCallingPid() 12104 + " not allowed because package " + ii.packageName 12105 + " does not have a signature matching the target " 12106 + ii.targetPackage; 12107 reportStartInstrumentationFailure(watcher, className, msg); 12108 throw new SecurityException(msg); 12109 } 12110 12111 final long origId = Binder.clearCallingIdentity(); 12112 // Instrumentation can kill and relaunch even persistent processes 12113 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12114 ProcessRecord app = addAppLocked(ai, false); 12115 app.instrumentationClass = className; 12116 app.instrumentationInfo = ai; 12117 app.instrumentationProfileFile = profileFile; 12118 app.instrumentationArguments = arguments; 12119 app.instrumentationWatcher = watcher; 12120 app.instrumentationResultClass = className; 12121 Binder.restoreCallingIdentity(origId); 12122 } 12123 12124 return true; 12125 } 12126 12127 /** 12128 * Report errors that occur while attempting to start Instrumentation. Always writes the 12129 * error to the logs, but if somebody is watching, send the report there too. This enables 12130 * the "am" command to report errors with more information. 12131 * 12132 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12133 * @param cn The component name of the instrumentation. 12134 * @param report The error report. 12135 */ 12136 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12137 ComponentName cn, String report) { 12138 Slog.w(TAG, report); 12139 try { 12140 if (watcher != null) { 12141 Bundle results = new Bundle(); 12142 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12143 results.putString("Error", report); 12144 watcher.instrumentationStatus(cn, -1, results); 12145 } 12146 } catch (RemoteException e) { 12147 Slog.w(TAG, e); 12148 } 12149 } 12150 12151 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12152 if (app.instrumentationWatcher != null) { 12153 try { 12154 // NOTE: IInstrumentationWatcher *must* be oneway here 12155 app.instrumentationWatcher.instrumentationFinished( 12156 app.instrumentationClass, 12157 resultCode, 12158 results); 12159 } catch (RemoteException e) { 12160 } 12161 } 12162 app.instrumentationWatcher = null; 12163 app.instrumentationClass = null; 12164 app.instrumentationInfo = null; 12165 app.instrumentationProfileFile = null; 12166 app.instrumentationArguments = null; 12167 12168 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12169 } 12170 12171 public void finishInstrumentation(IApplicationThread target, 12172 int resultCode, Bundle results) { 12173 int userId = UserHandle.getCallingUserId(); 12174 // Refuse possible leaked file descriptors 12175 if (results != null && results.hasFileDescriptors()) { 12176 throw new IllegalArgumentException("File descriptors passed in Intent"); 12177 } 12178 12179 synchronized(this) { 12180 ProcessRecord app = getRecordForAppLocked(target); 12181 if (app == null) { 12182 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12183 return; 12184 } 12185 final long origId = Binder.clearCallingIdentity(); 12186 finishInstrumentationLocked(app, resultCode, results); 12187 Binder.restoreCallingIdentity(origId); 12188 } 12189 } 12190 12191 // ========================================================= 12192 // CONFIGURATION 12193 // ========================================================= 12194 12195 public ConfigurationInfo getDeviceConfigurationInfo() { 12196 ConfigurationInfo config = new ConfigurationInfo(); 12197 synchronized (this) { 12198 config.reqTouchScreen = mConfiguration.touchscreen; 12199 config.reqKeyboardType = mConfiguration.keyboard; 12200 config.reqNavigation = mConfiguration.navigation; 12201 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12202 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12203 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12204 } 12205 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12206 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12207 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12208 } 12209 config.reqGlEsVersion = GL_ES_VERSION; 12210 } 12211 return config; 12212 } 12213 12214 public Configuration getConfiguration() { 12215 Configuration ci; 12216 synchronized(this) { 12217 ci = new Configuration(mConfiguration); 12218 } 12219 return ci; 12220 } 12221 12222 public void updatePersistentConfiguration(Configuration values) { 12223 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12224 "updateConfiguration()"); 12225 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12226 "updateConfiguration()"); 12227 if (values == null) { 12228 throw new NullPointerException("Configuration must not be null"); 12229 } 12230 12231 synchronized(this) { 12232 final long origId = Binder.clearCallingIdentity(); 12233 updateConfigurationLocked(values, null, true, false); 12234 Binder.restoreCallingIdentity(origId); 12235 } 12236 } 12237 12238 public void updateConfiguration(Configuration values) { 12239 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12240 "updateConfiguration()"); 12241 12242 synchronized(this) { 12243 if (values == null && mWindowManager != null) { 12244 // sentinel: fetch the current configuration from the window manager 12245 values = mWindowManager.computeNewConfiguration(); 12246 } 12247 12248 if (mWindowManager != null) { 12249 mProcessList.applyDisplaySize(mWindowManager); 12250 } 12251 12252 final long origId = Binder.clearCallingIdentity(); 12253 if (values != null) { 12254 Settings.System.clearConfiguration(values); 12255 } 12256 updateConfigurationLocked(values, null, false, false); 12257 Binder.restoreCallingIdentity(origId); 12258 } 12259 } 12260 12261 /** 12262 * Do either or both things: (1) change the current configuration, and (2) 12263 * make sure the given activity is running with the (now) current 12264 * configuration. Returns true if the activity has been left running, or 12265 * false if <var>starting</var> is being destroyed to match the new 12266 * configuration. 12267 * @param persistent TODO 12268 */ 12269 boolean updateConfigurationLocked(Configuration values, 12270 ActivityRecord starting, boolean persistent, boolean initLocale) { 12271 // do nothing if we are headless 12272 if (mHeadless) return true; 12273 12274 int changes = 0; 12275 12276 boolean kept = true; 12277 12278 if (values != null) { 12279 Configuration newConfig = new Configuration(mConfiguration); 12280 changes = newConfig.updateFrom(values); 12281 if (changes != 0) { 12282 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12283 Slog.i(TAG, "Updating configuration to: " + values); 12284 } 12285 12286 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12287 12288 if (values.locale != null && !initLocale) { 12289 saveLocaleLocked(values.locale, 12290 !values.locale.equals(mConfiguration.locale), 12291 values.userSetLocale); 12292 } 12293 12294 mConfigurationSeq++; 12295 if (mConfigurationSeq <= 0) { 12296 mConfigurationSeq = 1; 12297 } 12298 newConfig.seq = mConfigurationSeq; 12299 mConfiguration = newConfig; 12300 Slog.i(TAG, "Config changed: " + newConfig); 12301 12302 final Configuration configCopy = new Configuration(mConfiguration); 12303 12304 // TODO: If our config changes, should we auto dismiss any currently 12305 // showing dialogs? 12306 mShowDialogs = shouldShowDialogs(newConfig); 12307 12308 AttributeCache ac = AttributeCache.instance(); 12309 if (ac != null) { 12310 ac.updateConfiguration(configCopy); 12311 } 12312 12313 // Make sure all resources in our process are updated 12314 // right now, so that anyone who is going to retrieve 12315 // resource values after we return will be sure to get 12316 // the new ones. This is especially important during 12317 // boot, where the first config change needs to guarantee 12318 // all resources have that config before following boot 12319 // code is executed. 12320 mSystemThread.applyConfigurationToResources(configCopy); 12321 12322 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12323 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12324 msg.obj = new Configuration(configCopy); 12325 mHandler.sendMessage(msg); 12326 } 12327 12328 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12329 ProcessRecord app = mLruProcesses.get(i); 12330 try { 12331 if (app.thread != null) { 12332 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12333 + app.processName + " new config " + mConfiguration); 12334 app.thread.scheduleConfigurationChanged(configCopy); 12335 } 12336 } catch (Exception e) { 12337 } 12338 } 12339 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12340 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12341 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12342 | Intent.FLAG_RECEIVER_FOREGROUND); 12343 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12344 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12345 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12346 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12347 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12348 broadcastIntentLocked(null, null, intent, 12349 null, null, 0, null, null, 12350 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12351 } 12352 } 12353 } 12354 12355 if (changes != 0 && starting == null) { 12356 // If the configuration changed, and the caller is not already 12357 // in the process of starting an activity, then find the top 12358 // activity to check if its configuration needs to change. 12359 starting = mMainStack.topRunningActivityLocked(null); 12360 } 12361 12362 if (starting != null) { 12363 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12364 // And we need to make sure at this point that all other activities 12365 // are made visible with the correct configuration. 12366 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12367 } 12368 12369 if (values != null && mWindowManager != null) { 12370 mWindowManager.setNewConfiguration(mConfiguration); 12371 } 12372 12373 return kept; 12374 } 12375 12376 /** 12377 * Decide based on the configuration whether we should shouw the ANR, 12378 * crash, etc dialogs. The idea is that if there is no affordnace to 12379 * press the on-screen buttons, we shouldn't show the dialog. 12380 * 12381 * A thought: SystemUI might also want to get told about this, the Power 12382 * dialog / global actions also might want different behaviors. 12383 */ 12384 private static final boolean shouldShowDialogs(Configuration config) { 12385 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12386 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12387 } 12388 12389 /** 12390 * Save the locale. You must be inside a synchronized (this) block. 12391 */ 12392 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12393 if(isDiff) { 12394 SystemProperties.set("user.language", l.getLanguage()); 12395 SystemProperties.set("user.region", l.getCountry()); 12396 } 12397 12398 if(isPersist) { 12399 SystemProperties.set("persist.sys.language", l.getLanguage()); 12400 SystemProperties.set("persist.sys.country", l.getCountry()); 12401 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12402 } 12403 } 12404 12405 @Override 12406 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12407 ActivityRecord srec = ActivityRecord.forToken(token); 12408 return srec != null && srec.task.affinity != null && 12409 srec.task.affinity.equals(destAffinity); 12410 } 12411 12412 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12413 Intent resultData) { 12414 ComponentName dest = destIntent.getComponent(); 12415 12416 synchronized (this) { 12417 ActivityRecord srec = ActivityRecord.forToken(token); 12418 if (srec == null) { 12419 return false; 12420 } 12421 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12422 final int start = history.indexOf(srec); 12423 if (start < 0) { 12424 // Current activity is not in history stack; do nothing. 12425 return false; 12426 } 12427 int finishTo = start - 1; 12428 ActivityRecord parent = null; 12429 boolean foundParentInTask = false; 12430 if (dest != null) { 12431 TaskRecord tr = srec.task; 12432 for (int i = start - 1; i >= 0; i--) { 12433 ActivityRecord r = history.get(i); 12434 if (tr != r.task) { 12435 // Couldn't find parent in the same task; stop at the one above this. 12436 // (Root of current task; in-app "home" behavior) 12437 // Always at least finish the current activity. 12438 finishTo = Math.min(start - 1, i + 1); 12439 parent = history.get(finishTo); 12440 break; 12441 } else if (r.info.packageName.equals(dest.getPackageName()) && 12442 r.info.name.equals(dest.getClassName())) { 12443 finishTo = i; 12444 parent = r; 12445 foundParentInTask = true; 12446 break; 12447 } 12448 } 12449 } 12450 12451 if (mController != null) { 12452 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12453 if (next != null) { 12454 // ask watcher if this is allowed 12455 boolean resumeOK = true; 12456 try { 12457 resumeOK = mController.activityResuming(next.packageName); 12458 } catch (RemoteException e) { 12459 mController = null; 12460 } 12461 12462 if (!resumeOK) { 12463 return false; 12464 } 12465 } 12466 } 12467 final long origId = Binder.clearCallingIdentity(); 12468 for (int i = start; i > finishTo; i--) { 12469 ActivityRecord r = history.get(i); 12470 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12471 "navigate-up", true); 12472 // Only return the supplied result for the first activity finished 12473 resultCode = Activity.RESULT_CANCELED; 12474 resultData = null; 12475 } 12476 12477 if (parent != null && foundParentInTask) { 12478 final int parentLaunchMode = parent.info.launchMode; 12479 final int destIntentFlags = destIntent.getFlags(); 12480 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12481 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12482 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12483 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12484 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12485 } else { 12486 try { 12487 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12488 destIntent.getComponent(), 0, srec.userId); 12489 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12490 null, aInfo, parent.appToken, null, 12491 0, -1, parent.launchedFromUid, 0, null, true, null); 12492 foundParentInTask = res == ActivityManager.START_SUCCESS; 12493 } catch (RemoteException e) { 12494 foundParentInTask = false; 12495 } 12496 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12497 resultData, "navigate-up", true); 12498 } 12499 } 12500 Binder.restoreCallingIdentity(origId); 12501 return foundParentInTask; 12502 } 12503 } 12504 12505 public int getLaunchedFromUid(IBinder activityToken) { 12506 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12507 if (srec == null) { 12508 return -1; 12509 } 12510 return srec.launchedFromUid; 12511 } 12512 12513 // ========================================================= 12514 // LIFETIME MANAGEMENT 12515 // ========================================================= 12516 12517 // Returns which broadcast queue the app is the current [or imminent] receiver 12518 // on, or 'null' if the app is not an active broadcast recipient. 12519 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12520 BroadcastRecord r = app.curReceiver; 12521 if (r != null) { 12522 return r.queue; 12523 } 12524 12525 // It's not the current receiver, but it might be starting up to become one 12526 synchronized (this) { 12527 for (BroadcastQueue queue : mBroadcastQueues) { 12528 r = queue.mPendingBroadcast; 12529 if (r != null && r.curApp == app) { 12530 // found it; report which queue it's in 12531 return queue; 12532 } 12533 } 12534 } 12535 12536 return null; 12537 } 12538 12539 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, 12540 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12541 if (mAdjSeq == app.adjSeq) { 12542 // This adjustment has already been computed. If we are calling 12543 // from the top, we may have already computed our adjustment with 12544 // an earlier hidden adjustment that isn't really for us... if 12545 // so, use the new hidden adjustment. 12546 if (!recursed && app.hidden) { 12547 if (app.hasActivities) { 12548 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12549 } else if (app.hasClientActivities) { 12550 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12551 } else { 12552 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12553 } 12554 } 12555 return app.curRawAdj; 12556 } 12557 12558 if (app.thread == null) { 12559 app.adjSeq = mAdjSeq; 12560 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12561 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12562 } 12563 12564 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12565 app.adjSource = null; 12566 app.adjTarget = null; 12567 app.empty = false; 12568 app.hidden = false; 12569 app.hasClientActivities = false; 12570 12571 final int activitiesSize = app.activities.size(); 12572 12573 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12574 // The max adjustment doesn't allow this app to be anything 12575 // below foreground, so it is not worth doing work for it. 12576 app.adjType = "fixed"; 12577 app.adjSeq = mAdjSeq; 12578 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12579 app.hasActivities = false; 12580 app.foregroundActivities = false; 12581 app.keeping = true; 12582 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12583 // System process can do UI, and when they do we want to have 12584 // them trim their memory after the user leaves the UI. To 12585 // facilitate this, here we need to determine whether or not it 12586 // is currently showing UI. 12587 app.systemNoUi = true; 12588 if (app == TOP_APP) { 12589 app.systemNoUi = false; 12590 app.hasActivities = true; 12591 } else if (activitiesSize > 0) { 12592 for (int j = 0; j < activitiesSize; j++) { 12593 final ActivityRecord r = app.activities.get(j); 12594 if (r.visible) { 12595 app.systemNoUi = false; 12596 } 12597 if (r.app == app) { 12598 app.hasActivities = true; 12599 } 12600 } 12601 } 12602 return (app.curAdj=app.maxAdj); 12603 } 12604 12605 app.keeping = false; 12606 app.systemNoUi = false; 12607 app.hasActivities = false; 12608 12609 // Determine the importance of the process, starting with most 12610 // important to least, and assign an appropriate OOM adjustment. 12611 int adj; 12612 int schedGroup; 12613 boolean foregroundActivities = false; 12614 boolean interesting = false; 12615 BroadcastQueue queue; 12616 if (app == TOP_APP) { 12617 // The last app on the list is the foreground app. 12618 adj = ProcessList.FOREGROUND_APP_ADJ; 12619 schedGroup = Process.THREAD_GROUP_DEFAULT; 12620 app.adjType = "top-activity"; 12621 foregroundActivities = true; 12622 interesting = true; 12623 app.hasActivities = true; 12624 } else if (app.instrumentationClass != null) { 12625 // Don't want to kill running instrumentation. 12626 adj = ProcessList.FOREGROUND_APP_ADJ; 12627 schedGroup = Process.THREAD_GROUP_DEFAULT; 12628 app.adjType = "instrumentation"; 12629 interesting = true; 12630 } else if ((queue = isReceivingBroadcast(app)) != null) { 12631 // An app that is currently receiving a broadcast also 12632 // counts as being in the foreground for OOM killer purposes. 12633 // It's placed in a sched group based on the nature of the 12634 // broadcast as reflected by which queue it's active in. 12635 adj = ProcessList.FOREGROUND_APP_ADJ; 12636 schedGroup = (queue == mFgBroadcastQueue) 12637 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12638 app.adjType = "broadcast"; 12639 } else if (app.executingServices.size() > 0) { 12640 // An app that is currently executing a service callback also 12641 // counts as being in the foreground. 12642 adj = ProcessList.FOREGROUND_APP_ADJ; 12643 schedGroup = Process.THREAD_GROUP_DEFAULT; 12644 app.adjType = "exec-service"; 12645 } else { 12646 // Assume process is hidden (has activities); we will correct 12647 // later if this is not the case. 12648 adj = hiddenAdj; 12649 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12650 app.hidden = true; 12651 app.adjType = "bg-act"; 12652 } 12653 12654 boolean hasStoppingActivities = false; 12655 12656 // Examine all activities if not already foreground. 12657 if (!foregroundActivities && activitiesSize > 0) { 12658 for (int j = 0; j < activitiesSize; j++) { 12659 final ActivityRecord r = app.activities.get(j); 12660 if (r.visible) { 12661 // App has a visible activity; only upgrade adjustment. 12662 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12663 adj = ProcessList.VISIBLE_APP_ADJ; 12664 app.adjType = "visible"; 12665 } 12666 schedGroup = Process.THREAD_GROUP_DEFAULT; 12667 app.hidden = false; 12668 app.hasActivities = true; 12669 foregroundActivities = true; 12670 break; 12671 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12672 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12673 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12674 app.adjType = "pausing"; 12675 } 12676 app.hidden = false; 12677 foregroundActivities = true; 12678 } else if (r.state == ActivityState.STOPPING) { 12679 // We will apply the actual adjustment later, because 12680 // we want to allow this process to immediately go through 12681 // any memory trimming that is in effect. 12682 app.hidden = false; 12683 foregroundActivities = true; 12684 hasStoppingActivities = true; 12685 } 12686 if (r.app == app) { 12687 app.hasActivities = true; 12688 } 12689 } 12690 } 12691 12692 if (adj == hiddenAdj && !app.hasActivities) { 12693 if (app.hasClientActivities) { 12694 adj = clientHiddenAdj; 12695 app.adjType = "bg-client-act"; 12696 } else { 12697 // Whoops, this process is completely empty as far as we know 12698 // at this point. 12699 adj = emptyAdj; 12700 app.empty = true; 12701 app.adjType = "bg-empty"; 12702 } 12703 } 12704 12705 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12706 if (app.foregroundServices) { 12707 // The user is aware of this app, so make it visible. 12708 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12709 app.hidden = false; 12710 app.adjType = "fg-service"; 12711 schedGroup = Process.THREAD_GROUP_DEFAULT; 12712 } else if (app.forcingToForeground != null) { 12713 // The user is aware of this app, so make it visible. 12714 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12715 app.hidden = false; 12716 app.adjType = "force-fg"; 12717 app.adjSource = app.forcingToForeground; 12718 schedGroup = Process.THREAD_GROUP_DEFAULT; 12719 } 12720 } 12721 12722 if (app.foregroundServices) { 12723 interesting = true; 12724 } 12725 12726 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12727 // We don't want to kill the current heavy-weight process. 12728 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12729 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12730 app.hidden = false; 12731 app.adjType = "heavy"; 12732 } 12733 12734 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12735 // This process is hosting what we currently consider to be the 12736 // home app, so we don't want to let it go into the background. 12737 adj = ProcessList.HOME_APP_ADJ; 12738 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12739 app.hidden = false; 12740 app.adjType = "home"; 12741 } 12742 12743 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12744 && app.activities.size() > 0) { 12745 // This was the previous process that showed UI to the user. 12746 // We want to try to keep it around more aggressively, to give 12747 // a good experience around switching between two apps. 12748 adj = ProcessList.PREVIOUS_APP_ADJ; 12749 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12750 app.hidden = false; 12751 app.adjType = "previous"; 12752 } 12753 12754 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12755 + " reason=" + app.adjType); 12756 12757 // By default, we use the computed adjustment. It may be changed if 12758 // there are applications dependent on our services or providers, but 12759 // this gives us a baseline and makes sure we don't get into an 12760 // infinite recursion. 12761 app.adjSeq = mAdjSeq; 12762 app.curRawAdj = app.nonStoppingAdj = adj; 12763 12764 if (mBackupTarget != null && app == mBackupTarget.app) { 12765 // If possible we want to avoid killing apps while they're being backed up 12766 if (adj > ProcessList.BACKUP_APP_ADJ) { 12767 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12768 adj = ProcessList.BACKUP_APP_ADJ; 12769 app.adjType = "backup"; 12770 app.hidden = false; 12771 } 12772 } 12773 12774 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12775 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12776 final long now = SystemClock.uptimeMillis(); 12777 // This process is more important if the top activity is 12778 // bound to the service. 12779 Iterator<ServiceRecord> jt = app.services.iterator(); 12780 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12781 ServiceRecord s = jt.next(); 12782 if (s.startRequested) { 12783 if (app.hasShownUi && app != mHomeProcess) { 12784 // If this process has shown some UI, let it immediately 12785 // go to the LRU list because it may be pretty heavy with 12786 // UI stuff. We'll tag it with a label just to help 12787 // debug and understand what is going on. 12788 if (adj > ProcessList.SERVICE_ADJ) { 12789 app.adjType = "started-bg-ui-services"; 12790 } 12791 } else { 12792 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12793 // This service has seen some activity within 12794 // recent memory, so we will keep its process ahead 12795 // of the background processes. 12796 if (adj > ProcessList.SERVICE_ADJ) { 12797 adj = ProcessList.SERVICE_ADJ; 12798 app.adjType = "started-services"; 12799 app.hidden = false; 12800 } 12801 } 12802 // If we have let the service slide into the background 12803 // state, still have some text describing what it is doing 12804 // even though the service no longer has an impact. 12805 if (adj > ProcessList.SERVICE_ADJ) { 12806 app.adjType = "started-bg-services"; 12807 } 12808 } 12809 // Don't kill this process because it is doing work; it 12810 // has said it is doing work. 12811 app.keeping = true; 12812 } 12813 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12814 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12815 Iterator<ArrayList<ConnectionRecord>> kt 12816 = s.connections.values().iterator(); 12817 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12818 ArrayList<ConnectionRecord> clist = kt.next(); 12819 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12820 // XXX should compute this based on the max of 12821 // all connected clients. 12822 ConnectionRecord cr = clist.get(i); 12823 if (cr.binding.client == app) { 12824 // Binding to ourself is not interesting. 12825 continue; 12826 } 12827 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12828 ProcessRecord client = cr.binding.client; 12829 int clientAdj = adj; 12830 int myHiddenAdj = hiddenAdj; 12831 if (myHiddenAdj > client.hiddenAdj) { 12832 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12833 myHiddenAdj = client.hiddenAdj; 12834 } else { 12835 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12836 } 12837 } 12838 int myClientHiddenAdj = clientHiddenAdj; 12839 if (myClientHiddenAdj > client.clientHiddenAdj) { 12840 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12841 myClientHiddenAdj = client.clientHiddenAdj; 12842 } else { 12843 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12844 } 12845 } 12846 int myEmptyAdj = emptyAdj; 12847 if (myEmptyAdj > client.emptyAdj) { 12848 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12849 myEmptyAdj = client.emptyAdj; 12850 } else { 12851 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12852 } 12853 } 12854 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12855 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12856 String adjType = null; 12857 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12858 // Not doing bind OOM management, so treat 12859 // this guy more like a started service. 12860 if (app.hasShownUi && app != mHomeProcess) { 12861 // If this process has shown some UI, let it immediately 12862 // go to the LRU list because it may be pretty heavy with 12863 // UI stuff. We'll tag it with a label just to help 12864 // debug and understand what is going on. 12865 if (adj > clientAdj) { 12866 adjType = "bound-bg-ui-services"; 12867 } 12868 app.hidden = false; 12869 clientAdj = adj; 12870 } else { 12871 if (now >= (s.lastActivity 12872 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12873 // This service has not seen activity within 12874 // recent memory, so allow it to drop to the 12875 // LRU list if there is no other reason to keep 12876 // it around. We'll also tag it with a label just 12877 // to help debug and undertand what is going on. 12878 if (adj > clientAdj) { 12879 adjType = "bound-bg-services"; 12880 } 12881 clientAdj = adj; 12882 } 12883 } 12884 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12885 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12886 // If this connection is keeping the service 12887 // created, then we want to try to better follow 12888 // its memory management semantics for activities. 12889 // That is, if it is sitting in the background 12890 // LRU list as a hidden process (with activities), 12891 // we don't want the service it is connected to 12892 // to go into the empty LRU and quickly get killed, 12893 // because I'll we'll do is just end up restarting 12894 // the service. 12895 app.hasClientActivities |= client.hasActivities; 12896 } 12897 } 12898 if (adj > clientAdj) { 12899 // If this process has recently shown UI, and 12900 // the process that is binding to it is less 12901 // important than being visible, then we don't 12902 // care about the binding as much as we care 12903 // about letting this process get into the LRU 12904 // list to be killed and restarted if needed for 12905 // memory. 12906 if (app.hasShownUi && app != mHomeProcess 12907 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12908 adjType = "bound-bg-ui-services"; 12909 } else { 12910 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12911 |Context.BIND_IMPORTANT)) != 0) { 12912 adj = clientAdj; 12913 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12914 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12915 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12916 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12917 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12918 adj = clientAdj; 12919 } else { 12920 app.pendingUiClean = true; 12921 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12922 adj = ProcessList.VISIBLE_APP_ADJ; 12923 } 12924 } 12925 if (!client.hidden) { 12926 app.hidden = false; 12927 } 12928 if (client.keeping) { 12929 app.keeping = true; 12930 } 12931 adjType = "service"; 12932 } 12933 } 12934 if (adjType != null) { 12935 app.adjType = adjType; 12936 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12937 .REASON_SERVICE_IN_USE; 12938 app.adjSource = cr.binding.client; 12939 app.adjSourceOom = clientAdj; 12940 app.adjTarget = s.name; 12941 } 12942 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12943 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12944 schedGroup = Process.THREAD_GROUP_DEFAULT; 12945 } 12946 } 12947 } 12948 final ActivityRecord a = cr.activity; 12949 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12950 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12951 (a.visible || a.state == ActivityState.RESUMED 12952 || a.state == ActivityState.PAUSING)) { 12953 adj = ProcessList.FOREGROUND_APP_ADJ; 12954 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12955 schedGroup = Process.THREAD_GROUP_DEFAULT; 12956 } 12957 app.hidden = false; 12958 app.adjType = "service"; 12959 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12960 .REASON_SERVICE_IN_USE; 12961 app.adjSource = a; 12962 app.adjSourceOom = adj; 12963 app.adjTarget = s.name; 12964 } 12965 } 12966 } 12967 } 12968 } 12969 } 12970 12971 // Finally, if this process has active services running in it, we 12972 // would like to avoid killing it unless it would prevent the current 12973 // application from running. By default we put the process in 12974 // with the rest of the background processes; as we scan through 12975 // its services we may bump it up from there. 12976 if (adj > hiddenAdj) { 12977 adj = hiddenAdj; 12978 app.hidden = false; 12979 app.adjType = "bg-services"; 12980 } 12981 } 12982 12983 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12984 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12985 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12986 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12987 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12988 ContentProviderRecord cpr = jt.next(); 12989 for (int i = cpr.connections.size()-1; 12990 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12991 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12992 i--) { 12993 ContentProviderConnection conn = cpr.connections.get(i); 12994 ProcessRecord client = conn.client; 12995 if (client == app) { 12996 // Being our own client is not interesting. 12997 continue; 12998 } 12999 int myHiddenAdj = hiddenAdj; 13000 if (myHiddenAdj > client.hiddenAdj) { 13001 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 13002 myHiddenAdj = client.hiddenAdj; 13003 } else { 13004 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13005 } 13006 } 13007 int myClientHiddenAdj = clientHiddenAdj; 13008 if (myClientHiddenAdj > client.clientHiddenAdj) { 13009 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 13010 myClientHiddenAdj = client.clientHiddenAdj; 13011 } else { 13012 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 13013 } 13014 } 13015 int myEmptyAdj = emptyAdj; 13016 if (myEmptyAdj > client.emptyAdj) { 13017 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 13018 myEmptyAdj = client.emptyAdj; 13019 } else { 13020 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 13021 } 13022 } 13023 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 13024 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 13025 if (adj > clientAdj) { 13026 if (app.hasShownUi && app != mHomeProcess 13027 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13028 app.adjType = "bg-ui-provider"; 13029 } else { 13030 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 13031 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 13032 app.adjType = "provider"; 13033 } 13034 if (!client.hidden) { 13035 app.hidden = false; 13036 } 13037 if (client.keeping) { 13038 app.keeping = true; 13039 } 13040 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13041 .REASON_PROVIDER_IN_USE; 13042 app.adjSource = client; 13043 app.adjSourceOom = clientAdj; 13044 app.adjTarget = cpr.name; 13045 } 13046 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13047 schedGroup = Process.THREAD_GROUP_DEFAULT; 13048 } 13049 } 13050 // If the provider has external (non-framework) process 13051 // dependencies, ensure that its adjustment is at least 13052 // FOREGROUND_APP_ADJ. 13053 if (cpr.hasExternalProcessHandles()) { 13054 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 13055 adj = ProcessList.FOREGROUND_APP_ADJ; 13056 schedGroup = Process.THREAD_GROUP_DEFAULT; 13057 app.hidden = false; 13058 app.keeping = true; 13059 app.adjType = "provider"; 13060 app.adjTarget = cpr.name; 13061 } 13062 } 13063 } 13064 } 13065 13066 if (adj == ProcessList.SERVICE_ADJ) { 13067 if (doingAll) { 13068 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 13069 mNewNumServiceProcs++; 13070 } 13071 if (app.serviceb) { 13072 adj = ProcessList.SERVICE_B_ADJ; 13073 } 13074 } else { 13075 app.serviceb = false; 13076 } 13077 13078 app.nonStoppingAdj = adj; 13079 13080 if (hasStoppingActivities) { 13081 // Only upgrade adjustment. 13082 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13083 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13084 app.adjType = "stopping"; 13085 } 13086 } 13087 13088 app.curRawAdj = adj; 13089 13090 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13091 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13092 if (adj > app.maxAdj) { 13093 adj = app.maxAdj; 13094 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13095 schedGroup = Process.THREAD_GROUP_DEFAULT; 13096 } 13097 } 13098 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13099 app.keeping = true; 13100 } 13101 13102 if (app.hasAboveClient) { 13103 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13104 // then we need to drop its adjustment to be lower than the service's 13105 // in order to honor the request. We want to drop it by one adjustment 13106 // level... but there is special meaning applied to various levels so 13107 // we will skip some of them. 13108 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13109 // System process will not get dropped, ever 13110 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13111 adj = ProcessList.VISIBLE_APP_ADJ; 13112 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13113 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13114 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13115 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13116 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13117 adj++; 13118 } 13119 } 13120 13121 int importance = app.memImportance; 13122 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13123 app.curAdj = adj; 13124 app.curSchedGroup = schedGroup; 13125 if (!interesting) { 13126 // For this reporting, if there is not something explicitly 13127 // interesting in this process then we will push it to the 13128 // background importance. 13129 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13130 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13131 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13132 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13133 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13134 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13135 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13136 } else if (adj >= ProcessList.SERVICE_ADJ) { 13137 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13138 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13139 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13140 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13141 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13142 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13143 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13144 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13145 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13146 } else { 13147 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13148 } 13149 } 13150 13151 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13152 if (foregroundActivities != app.foregroundActivities) { 13153 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13154 } 13155 if (changes != 0) { 13156 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13157 app.memImportance = importance; 13158 app.foregroundActivities = foregroundActivities; 13159 int i = mPendingProcessChanges.size()-1; 13160 ProcessChangeItem item = null; 13161 while (i >= 0) { 13162 item = mPendingProcessChanges.get(i); 13163 if (item.pid == app.pid) { 13164 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13165 break; 13166 } 13167 i--; 13168 } 13169 if (i < 0) { 13170 // No existing item in pending changes; need a new one. 13171 final int NA = mAvailProcessChanges.size(); 13172 if (NA > 0) { 13173 item = mAvailProcessChanges.remove(NA-1); 13174 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13175 } else { 13176 item = new ProcessChangeItem(); 13177 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13178 } 13179 item.changes = 0; 13180 item.pid = app.pid; 13181 item.uid = app.info.uid; 13182 if (mPendingProcessChanges.size() == 0) { 13183 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13184 "*** Enqueueing dispatch processes changed!"); 13185 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13186 } 13187 mPendingProcessChanges.add(item); 13188 } 13189 item.changes |= changes; 13190 item.importance = importance; 13191 item.foregroundActivities = foregroundActivities; 13192 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13193 + Integer.toHexString(System.identityHashCode(item)) 13194 + " " + app.toShortString() + ": changes=" + item.changes 13195 + " importance=" + item.importance 13196 + " foreground=" + item.foregroundActivities 13197 + " type=" + app.adjType + " source=" + app.adjSource 13198 + " target=" + app.adjTarget); 13199 } 13200 13201 return app.curRawAdj; 13202 } 13203 13204 /** 13205 * Ask a given process to GC right now. 13206 */ 13207 final void performAppGcLocked(ProcessRecord app) { 13208 try { 13209 app.lastRequestedGc = SystemClock.uptimeMillis(); 13210 if (app.thread != null) { 13211 if (app.reportLowMemory) { 13212 app.reportLowMemory = false; 13213 app.thread.scheduleLowMemory(); 13214 } else { 13215 app.thread.processInBackground(); 13216 } 13217 } 13218 } catch (Exception e) { 13219 // whatever. 13220 } 13221 } 13222 13223 /** 13224 * Returns true if things are idle enough to perform GCs. 13225 */ 13226 private final boolean canGcNowLocked() { 13227 boolean processingBroadcasts = false; 13228 for (BroadcastQueue q : mBroadcastQueues) { 13229 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13230 processingBroadcasts = true; 13231 } 13232 } 13233 return !processingBroadcasts 13234 && (mSleeping || (mMainStack.mResumedActivity != null && 13235 mMainStack.mResumedActivity.idle)); 13236 } 13237 13238 /** 13239 * Perform GCs on all processes that are waiting for it, but only 13240 * if things are idle. 13241 */ 13242 final void performAppGcsLocked() { 13243 final int N = mProcessesToGc.size(); 13244 if (N <= 0) { 13245 return; 13246 } 13247 if (canGcNowLocked()) { 13248 while (mProcessesToGc.size() > 0) { 13249 ProcessRecord proc = mProcessesToGc.remove(0); 13250 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13251 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13252 <= SystemClock.uptimeMillis()) { 13253 // To avoid spamming the system, we will GC processes one 13254 // at a time, waiting a few seconds between each. 13255 performAppGcLocked(proc); 13256 scheduleAppGcsLocked(); 13257 return; 13258 } else { 13259 // It hasn't been long enough since we last GCed this 13260 // process... put it in the list to wait for its time. 13261 addProcessToGcListLocked(proc); 13262 break; 13263 } 13264 } 13265 } 13266 13267 scheduleAppGcsLocked(); 13268 } 13269 } 13270 13271 /** 13272 * If all looks good, perform GCs on all processes waiting for them. 13273 */ 13274 final void performAppGcsIfAppropriateLocked() { 13275 if (canGcNowLocked()) { 13276 performAppGcsLocked(); 13277 return; 13278 } 13279 // Still not idle, wait some more. 13280 scheduleAppGcsLocked(); 13281 } 13282 13283 /** 13284 * Schedule the execution of all pending app GCs. 13285 */ 13286 final void scheduleAppGcsLocked() { 13287 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13288 13289 if (mProcessesToGc.size() > 0) { 13290 // Schedule a GC for the time to the next process. 13291 ProcessRecord proc = mProcessesToGc.get(0); 13292 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13293 13294 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13295 long now = SystemClock.uptimeMillis(); 13296 if (when < (now+GC_TIMEOUT)) { 13297 when = now + GC_TIMEOUT; 13298 } 13299 mHandler.sendMessageAtTime(msg, when); 13300 } 13301 } 13302 13303 /** 13304 * Add a process to the array of processes waiting to be GCed. Keeps the 13305 * list in sorted order by the last GC time. The process can't already be 13306 * on the list. 13307 */ 13308 final void addProcessToGcListLocked(ProcessRecord proc) { 13309 boolean added = false; 13310 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13311 if (mProcessesToGc.get(i).lastRequestedGc < 13312 proc.lastRequestedGc) { 13313 added = true; 13314 mProcessesToGc.add(i+1, proc); 13315 break; 13316 } 13317 } 13318 if (!added) { 13319 mProcessesToGc.add(0, proc); 13320 } 13321 } 13322 13323 /** 13324 * Set up to ask a process to GC itself. This will either do it 13325 * immediately, or put it on the list of processes to gc the next 13326 * time things are idle. 13327 */ 13328 final void scheduleAppGcLocked(ProcessRecord app) { 13329 long now = SystemClock.uptimeMillis(); 13330 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13331 return; 13332 } 13333 if (!mProcessesToGc.contains(app)) { 13334 addProcessToGcListLocked(app); 13335 scheduleAppGcsLocked(); 13336 } 13337 } 13338 13339 final void checkExcessivePowerUsageLocked(boolean doKills) { 13340 updateCpuStatsNow(); 13341 13342 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13343 boolean doWakeKills = doKills; 13344 boolean doCpuKills = doKills; 13345 if (mLastPowerCheckRealtime == 0) { 13346 doWakeKills = false; 13347 } 13348 if (mLastPowerCheckUptime == 0) { 13349 doCpuKills = false; 13350 } 13351 if (stats.isScreenOn()) { 13352 doWakeKills = false; 13353 } 13354 final long curRealtime = SystemClock.elapsedRealtime(); 13355 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13356 final long curUptime = SystemClock.uptimeMillis(); 13357 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13358 mLastPowerCheckRealtime = curRealtime; 13359 mLastPowerCheckUptime = curUptime; 13360 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13361 doWakeKills = false; 13362 } 13363 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13364 doCpuKills = false; 13365 } 13366 int i = mLruProcesses.size(); 13367 while (i > 0) { 13368 i--; 13369 ProcessRecord app = mLruProcesses.get(i); 13370 if (!app.keeping) { 13371 long wtime; 13372 synchronized (stats) { 13373 wtime = stats.getProcessWakeTime(app.info.uid, 13374 app.pid, curRealtime); 13375 } 13376 long wtimeUsed = wtime - app.lastWakeTime; 13377 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13378 if (DEBUG_POWER) { 13379 StringBuilder sb = new StringBuilder(128); 13380 sb.append("Wake for "); 13381 app.toShortString(sb); 13382 sb.append(": over "); 13383 TimeUtils.formatDuration(realtimeSince, sb); 13384 sb.append(" used "); 13385 TimeUtils.formatDuration(wtimeUsed, sb); 13386 sb.append(" ("); 13387 sb.append((wtimeUsed*100)/realtimeSince); 13388 sb.append("%)"); 13389 Slog.i(TAG, sb.toString()); 13390 sb.setLength(0); 13391 sb.append("CPU for "); 13392 app.toShortString(sb); 13393 sb.append(": over "); 13394 TimeUtils.formatDuration(uptimeSince, sb); 13395 sb.append(" used "); 13396 TimeUtils.formatDuration(cputimeUsed, sb); 13397 sb.append(" ("); 13398 sb.append((cputimeUsed*100)/uptimeSince); 13399 sb.append("%)"); 13400 Slog.i(TAG, sb.toString()); 13401 } 13402 // If a process has held a wake lock for more 13403 // than 50% of the time during this period, 13404 // that sounds bad. Kill! 13405 if (doWakeKills && realtimeSince > 0 13406 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13407 synchronized (stats) { 13408 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13409 realtimeSince, wtimeUsed); 13410 } 13411 Slog.w(TAG, "Excessive wake lock in " + app.processName 13412 + " (pid " + app.pid + "): held " + wtimeUsed 13413 + " during " + realtimeSince); 13414 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13415 app.processName, app.setAdj, "excessive wake lock"); 13416 Process.killProcessQuiet(app.pid); 13417 } else if (doCpuKills && uptimeSince > 0 13418 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13419 synchronized (stats) { 13420 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13421 uptimeSince, cputimeUsed); 13422 } 13423 Slog.w(TAG, "Excessive CPU in " + app.processName 13424 + " (pid " + app.pid + "): used " + cputimeUsed 13425 + " during " + uptimeSince); 13426 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13427 app.processName, app.setAdj, "excessive cpu"); 13428 Process.killProcessQuiet(app.pid); 13429 } else { 13430 app.lastWakeTime = wtime; 13431 app.lastCpuTime = app.curCpuTime; 13432 } 13433 } 13434 } 13435 } 13436 13437 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13438 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13439 app.hiddenAdj = hiddenAdj; 13440 app.clientHiddenAdj = clientHiddenAdj; 13441 app.emptyAdj = emptyAdj; 13442 13443 if (app.thread == null) { 13444 return false; 13445 } 13446 13447 final boolean wasKeeping = app.keeping; 13448 13449 boolean success = true; 13450 13451 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13452 13453 if (app.curRawAdj != app.setRawAdj) { 13454 if (wasKeeping && !app.keeping) { 13455 // This app is no longer something we want to keep. Note 13456 // its current wake lock time to later know to kill it if 13457 // it is not behaving well. 13458 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13459 synchronized (stats) { 13460 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13461 app.pid, SystemClock.elapsedRealtime()); 13462 } 13463 app.lastCpuTime = app.curCpuTime; 13464 } 13465 13466 app.setRawAdj = app.curRawAdj; 13467 } 13468 13469 if (app.curAdj != app.setAdj) { 13470 if (Process.setOomAdj(app.pid, app.curAdj)) { 13471 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13472 TAG, "Set " + app.pid + " " + app.processName + 13473 " adj " + app.curAdj + ": " + app.adjType); 13474 app.setAdj = app.curAdj; 13475 } else { 13476 success = false; 13477 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13478 } 13479 } 13480 if (app.setSchedGroup != app.curSchedGroup) { 13481 app.setSchedGroup = app.curSchedGroup; 13482 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13483 "Setting process group of " + app.processName 13484 + " to " + app.curSchedGroup); 13485 if (app.waitingToKill != null && 13486 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13487 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13488 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13489 app.processName, app.setAdj, app.waitingToKill); 13490 app.killedBackground = true; 13491 Process.killProcessQuiet(app.pid); 13492 success = false; 13493 } else { 13494 if (true) { 13495 long oldId = Binder.clearCallingIdentity(); 13496 try { 13497 Process.setProcessGroup(app.pid, app.curSchedGroup); 13498 } catch (Exception e) { 13499 Slog.w(TAG, "Failed setting process group of " + app.pid 13500 + " to " + app.curSchedGroup); 13501 e.printStackTrace(); 13502 } finally { 13503 Binder.restoreCallingIdentity(oldId); 13504 } 13505 } else { 13506 if (app.thread != null) { 13507 try { 13508 app.thread.setSchedulingGroup(app.curSchedGroup); 13509 } catch (RemoteException e) { 13510 } 13511 } 13512 } 13513 } 13514 } 13515 return success; 13516 } 13517 13518 private final ActivityRecord resumedAppLocked() { 13519 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13520 if (resumedActivity == null || resumedActivity.app == null) { 13521 resumedActivity = mMainStack.mPausingActivity; 13522 if (resumedActivity == null || resumedActivity.app == null) { 13523 resumedActivity = mMainStack.topRunningActivityLocked(null); 13524 } 13525 } 13526 return resumedActivity; 13527 } 13528 13529 final boolean updateOomAdjLocked(ProcessRecord app) { 13530 final ActivityRecord TOP_ACT = resumedAppLocked(); 13531 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13532 int curAdj = app.curAdj; 13533 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13534 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13535 13536 mAdjSeq++; 13537 13538 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13539 app.emptyAdj, TOP_APP, false); 13540 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13541 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13542 if (nowHidden != wasHidden) { 13543 // Changed to/from hidden state, so apps after it in the LRU 13544 // list may also be changed. 13545 updateOomAdjLocked(); 13546 } 13547 return success; 13548 } 13549 13550 final void updateOomAdjLocked() { 13551 final ActivityRecord TOP_ACT = resumedAppLocked(); 13552 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13553 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13554 13555 if (false) { 13556 RuntimeException e = new RuntimeException(); 13557 e.fillInStackTrace(); 13558 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13559 } 13560 13561 mAdjSeq++; 13562 mNewNumServiceProcs = 0; 13563 13564 final int emptyProcessLimit; 13565 final int hiddenProcessLimit; 13566 if (mProcessLimit <= 0) { 13567 emptyProcessLimit = hiddenProcessLimit = 0; 13568 } else if (mProcessLimit == 1) { 13569 emptyProcessLimit = 1; 13570 hiddenProcessLimit = 0; 13571 } else { 13572 emptyProcessLimit = (mProcessLimit*2)/3; 13573 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13574 } 13575 13576 // Let's determine how many processes we have running vs. 13577 // how many slots we have for background processes; we may want 13578 // to put multiple processes in a slot of there are enough of 13579 // them. 13580 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13581 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13582 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13583 if (numEmptyProcs > hiddenProcessLimit) { 13584 // If there are more empty processes than our limit on hidden 13585 // processes, then use the hidden process limit for the factor. 13586 // This ensures that the really old empty processes get pushed 13587 // down to the bottom, so if we are running low on memory we will 13588 // have a better chance at keeping around more hidden processes 13589 // instead of a gazillion empty processes. 13590 numEmptyProcs = hiddenProcessLimit; 13591 } 13592 int emptyFactor = numEmptyProcs/numSlots; 13593 if (emptyFactor < 1) emptyFactor = 1; 13594 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13595 if (hiddenFactor < 1) hiddenFactor = 1; 13596 int stepHidden = 0; 13597 int stepEmpty = 0; 13598 int numHidden = 0; 13599 int numEmpty = 0; 13600 int numTrimming = 0; 13601 13602 mNumNonHiddenProcs = 0; 13603 mNumHiddenProcs = 0; 13604 13605 // First update the OOM adjustment for each of the 13606 // application processes based on their current state. 13607 int i = mLruProcesses.size(); 13608 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13609 int nextHiddenAdj = curHiddenAdj+1; 13610 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13611 int nextEmptyAdj = curEmptyAdj+2; 13612 int curClientHiddenAdj = curEmptyAdj; 13613 while (i > 0) { 13614 i--; 13615 ProcessRecord app = mLruProcesses.get(i); 13616 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13617 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13618 if (!app.killedBackground) { 13619 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13620 // This process was assigned as a hidden process... step the 13621 // hidden level. 13622 mNumHiddenProcs++; 13623 if (curHiddenAdj != nextHiddenAdj) { 13624 stepHidden++; 13625 if (stepHidden >= hiddenFactor) { 13626 stepHidden = 0; 13627 curHiddenAdj = nextHiddenAdj; 13628 nextHiddenAdj += 2; 13629 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13630 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13631 } 13632 if (curClientHiddenAdj <= curHiddenAdj) { 13633 curClientHiddenAdj = curHiddenAdj + 1; 13634 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13635 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13636 } 13637 } 13638 } 13639 } 13640 numHidden++; 13641 if (numHidden > hiddenProcessLimit) { 13642 Slog.i(TAG, "No longer want " + app.processName 13643 + " (pid " + app.pid + "): hidden #" + numHidden); 13644 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13645 app.processName, app.setAdj, "too many background"); 13646 app.killedBackground = true; 13647 Process.killProcessQuiet(app.pid); 13648 } 13649 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13650 // This process has a client that has activities. We will have 13651 // given it the current hidden adj; here we will just leave it 13652 // without stepping the hidden adj. 13653 curClientHiddenAdj++; 13654 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13655 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13656 } 13657 } else { 13658 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13659 // This process was assigned as an empty process... step the 13660 // empty level. 13661 if (curEmptyAdj != nextEmptyAdj) { 13662 stepEmpty++; 13663 if (stepEmpty >= emptyFactor) { 13664 stepEmpty = 0; 13665 curEmptyAdj = nextEmptyAdj; 13666 nextEmptyAdj += 2; 13667 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13668 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13669 } 13670 } 13671 } 13672 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13673 mNumNonHiddenProcs++; 13674 } 13675 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13676 && !app.hasClientActivities) { 13677 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13678 && app.lastActivityTime < oldTime) { 13679 Slog.i(TAG, "No longer want " + app.processName 13680 + " (pid " + app.pid + "): empty for " 13681 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13682 / 1000) + "s"); 13683 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13684 app.processName, app.setAdj, "old background process"); 13685 app.killedBackground = true; 13686 Process.killProcessQuiet(app.pid); 13687 } else { 13688 numEmpty++; 13689 if (numEmpty > emptyProcessLimit) { 13690 Slog.i(TAG, "No longer want " + app.processName 13691 + " (pid " + app.pid + "): empty #" + numEmpty); 13692 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13693 app.processName, app.setAdj, "too many background"); 13694 app.killedBackground = true; 13695 Process.killProcessQuiet(app.pid); 13696 } 13697 } 13698 } 13699 } 13700 if (app.isolated && app.services.size() <= 0) { 13701 // If this is an isolated process, and there are no 13702 // services running in it, then the process is no longer 13703 // needed. We agressively kill these because we can by 13704 // definition not re-use the same process again, and it is 13705 // good to avoid having whatever code was running in them 13706 // left sitting around after no longer needed. 13707 Slog.i(TAG, "Isolated process " + app.processName 13708 + " (pid " + app.pid + ") no longer needed"); 13709 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13710 app.processName, app.setAdj, "isolated not needed"); 13711 app.killedBackground = true; 13712 Process.killProcessQuiet(app.pid); 13713 } 13714 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13715 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13716 && !app.killedBackground) { 13717 numTrimming++; 13718 } 13719 } 13720 } 13721 13722 mNumServiceProcs = mNewNumServiceProcs; 13723 13724 // Now determine the memory trimming level of background processes. 13725 // Unfortunately we need to start at the back of the list to do this 13726 // properly. We only do this if the number of background apps we 13727 // are managing to keep around is less than half the maximum we desire; 13728 // if we are keeping a good number around, we'll let them use whatever 13729 // memory they want. 13730 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13731 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13732 final int numHiddenAndEmpty = numHidden + numEmpty; 13733 final int N = mLruProcesses.size(); 13734 int factor = numTrimming/3; 13735 int minFactor = 2; 13736 if (mHomeProcess != null) minFactor++; 13737 if (mPreviousProcess != null) minFactor++; 13738 if (factor < minFactor) factor = minFactor; 13739 int step = 0; 13740 int fgTrimLevel; 13741 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13742 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13743 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13744 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13745 } else { 13746 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13747 } 13748 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13749 for (i=0; i<N; i++) { 13750 ProcessRecord app = mLruProcesses.get(i); 13751 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13752 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13753 && !app.killedBackground) { 13754 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13755 try { 13756 app.thread.scheduleTrimMemory(curLevel); 13757 } catch (RemoteException e) { 13758 } 13759 if (false) { 13760 // For now we won't do this; our memory trimming seems 13761 // to be good enough at this point that destroying 13762 // activities causes more harm than good. 13763 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13764 && app != mHomeProcess && app != mPreviousProcess) { 13765 // Need to do this on its own message because the stack may not 13766 // be in a consistent state at this point. 13767 // For these apps we will also finish their activities 13768 // to help them free memory. 13769 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13770 } 13771 } 13772 } 13773 app.trimMemoryLevel = curLevel; 13774 step++; 13775 if (step >= factor) { 13776 step = 0; 13777 switch (curLevel) { 13778 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13779 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13780 break; 13781 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13782 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13783 break; 13784 } 13785 } 13786 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13787 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13788 && app.thread != null) { 13789 try { 13790 app.thread.scheduleTrimMemory( 13791 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13792 } catch (RemoteException e) { 13793 } 13794 } 13795 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13796 } else { 13797 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13798 && app.pendingUiClean) { 13799 // If this application is now in the background and it 13800 // had done UI, then give it the special trim level to 13801 // have it free UI resources. 13802 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13803 if (app.trimMemoryLevel < level && app.thread != null) { 13804 try { 13805 app.thread.scheduleTrimMemory(level); 13806 } catch (RemoteException e) { 13807 } 13808 } 13809 app.pendingUiClean = false; 13810 } 13811 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13812 try { 13813 app.thread.scheduleTrimMemory(fgTrimLevel); 13814 } catch (RemoteException e) { 13815 } 13816 } 13817 app.trimMemoryLevel = fgTrimLevel; 13818 } 13819 } 13820 } else { 13821 final int N = mLruProcesses.size(); 13822 for (i=0; i<N; i++) { 13823 ProcessRecord app = mLruProcesses.get(i); 13824 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13825 && app.pendingUiClean) { 13826 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13827 && app.thread != null) { 13828 try { 13829 app.thread.scheduleTrimMemory( 13830 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13831 } catch (RemoteException e) { 13832 } 13833 } 13834 app.pendingUiClean = false; 13835 } 13836 app.trimMemoryLevel = 0; 13837 } 13838 } 13839 13840 if (mAlwaysFinishActivities) { 13841 // Need to do this on its own message because the stack may not 13842 // be in a consistent state at this point. 13843 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13844 } 13845 } 13846 13847 final void trimApplications() { 13848 synchronized (this) { 13849 int i; 13850 13851 // First remove any unused application processes whose package 13852 // has been removed. 13853 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13854 final ProcessRecord app = mRemovedProcesses.get(i); 13855 if (app.activities.size() == 0 13856 && app.curReceiver == null && app.services.size() == 0) { 13857 Slog.i( 13858 TAG, "Exiting empty application process " 13859 + app.processName + " (" 13860 + (app.thread != null ? app.thread.asBinder() : null) 13861 + ")\n"); 13862 if (app.pid > 0 && app.pid != MY_PID) { 13863 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13864 app.processName, app.setAdj, "empty"); 13865 Process.killProcessQuiet(app.pid); 13866 } else { 13867 try { 13868 app.thread.scheduleExit(); 13869 } catch (Exception e) { 13870 // Ignore exceptions. 13871 } 13872 } 13873 cleanUpApplicationRecordLocked(app, false, true, -1); 13874 mRemovedProcesses.remove(i); 13875 13876 if (app.persistent) { 13877 if (app.persistent) { 13878 addAppLocked(app.info, false); 13879 } 13880 } 13881 } 13882 } 13883 13884 // Now update the oom adj for all processes. 13885 updateOomAdjLocked(); 13886 } 13887 } 13888 13889 /** This method sends the specified signal to each of the persistent apps */ 13890 public void signalPersistentProcesses(int sig) throws RemoteException { 13891 if (sig != Process.SIGNAL_USR1) { 13892 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13893 } 13894 13895 synchronized (this) { 13896 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13897 != PackageManager.PERMISSION_GRANTED) { 13898 throw new SecurityException("Requires permission " 13899 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13900 } 13901 13902 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13903 ProcessRecord r = mLruProcesses.get(i); 13904 if (r.thread != null && r.persistent) { 13905 Process.sendSignal(r.pid, sig); 13906 } 13907 } 13908 } 13909 } 13910 13911 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13912 if (proc == null || proc == mProfileProc) { 13913 proc = mProfileProc; 13914 path = mProfileFile; 13915 profileType = mProfileType; 13916 clearProfilerLocked(); 13917 } 13918 if (proc == null) { 13919 return; 13920 } 13921 try { 13922 proc.thread.profilerControl(false, path, null, profileType); 13923 } catch (RemoteException e) { 13924 throw new IllegalStateException("Process disappeared"); 13925 } 13926 } 13927 13928 private void clearProfilerLocked() { 13929 if (mProfileFd != null) { 13930 try { 13931 mProfileFd.close(); 13932 } catch (IOException e) { 13933 } 13934 } 13935 mProfileApp = null; 13936 mProfileProc = null; 13937 mProfileFile = null; 13938 mProfileType = 0; 13939 mAutoStopProfiler = false; 13940 } 13941 13942 public boolean profileControl(String process, int userId, boolean start, 13943 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13944 13945 try { 13946 synchronized (this) { 13947 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13948 // its own permission. 13949 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13950 != PackageManager.PERMISSION_GRANTED) { 13951 throw new SecurityException("Requires permission " 13952 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13953 } 13954 13955 if (start && fd == null) { 13956 throw new IllegalArgumentException("null fd"); 13957 } 13958 13959 ProcessRecord proc = null; 13960 if (process != null) { 13961 proc = findProcessLocked(process, userId, "profileControl"); 13962 } 13963 13964 if (start && (proc == null || proc.thread == null)) { 13965 throw new IllegalArgumentException("Unknown process: " + process); 13966 } 13967 13968 if (start) { 13969 stopProfilerLocked(null, null, 0); 13970 setProfileApp(proc.info, proc.processName, path, fd, false); 13971 mProfileProc = proc; 13972 mProfileType = profileType; 13973 try { 13974 fd = fd.dup(); 13975 } catch (IOException e) { 13976 fd = null; 13977 } 13978 proc.thread.profilerControl(start, path, fd, profileType); 13979 fd = null; 13980 mProfileFd = null; 13981 } else { 13982 stopProfilerLocked(proc, path, profileType); 13983 if (fd != null) { 13984 try { 13985 fd.close(); 13986 } catch (IOException e) { 13987 } 13988 } 13989 } 13990 13991 return true; 13992 } 13993 } catch (RemoteException e) { 13994 throw new IllegalStateException("Process disappeared"); 13995 } finally { 13996 if (fd != null) { 13997 try { 13998 fd.close(); 13999 } catch (IOException e) { 14000 } 14001 } 14002 } 14003 } 14004 14005 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 14006 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14007 userId, true, true, callName, null); 14008 ProcessRecord proc = null; 14009 try { 14010 int pid = Integer.parseInt(process); 14011 synchronized (mPidsSelfLocked) { 14012 proc = mPidsSelfLocked.get(pid); 14013 } 14014 } catch (NumberFormatException e) { 14015 } 14016 14017 if (proc == null) { 14018 HashMap<String, SparseArray<ProcessRecord>> all 14019 = mProcessNames.getMap(); 14020 SparseArray<ProcessRecord> procs = all.get(process); 14021 if (procs != null && procs.size() > 0) { 14022 proc = procs.valueAt(0); 14023 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 14024 for (int i=1; i<procs.size(); i++) { 14025 ProcessRecord thisProc = procs.valueAt(i); 14026 if (thisProc.userId == userId) { 14027 proc = thisProc; 14028 break; 14029 } 14030 } 14031 } 14032 } 14033 } 14034 14035 return proc; 14036 } 14037 14038 public boolean dumpHeap(String process, int userId, boolean managed, 14039 String path, ParcelFileDescriptor fd) throws RemoteException { 14040 14041 try { 14042 synchronized (this) { 14043 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14044 // its own permission (same as profileControl). 14045 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14046 != PackageManager.PERMISSION_GRANTED) { 14047 throw new SecurityException("Requires permission " 14048 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14049 } 14050 14051 if (fd == null) { 14052 throw new IllegalArgumentException("null fd"); 14053 } 14054 14055 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 14056 if (proc == null || proc.thread == null) { 14057 throw new IllegalArgumentException("Unknown process: " + process); 14058 } 14059 14060 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 14061 if (!isDebuggable) { 14062 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14063 throw new SecurityException("Process not debuggable: " + proc); 14064 } 14065 } 14066 14067 proc.thread.dumpHeap(managed, path, fd); 14068 fd = null; 14069 return true; 14070 } 14071 } catch (RemoteException e) { 14072 throw new IllegalStateException("Process disappeared"); 14073 } finally { 14074 if (fd != null) { 14075 try { 14076 fd.close(); 14077 } catch (IOException e) { 14078 } 14079 } 14080 } 14081 } 14082 14083 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14084 public void monitor() { 14085 synchronized (this) { } 14086 } 14087 14088 void onCoreSettingsChange(Bundle settings) { 14089 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14090 ProcessRecord processRecord = mLruProcesses.get(i); 14091 try { 14092 if (processRecord.thread != null) { 14093 processRecord.thread.setCoreSettings(settings); 14094 } 14095 } catch (RemoteException re) { 14096 /* ignore */ 14097 } 14098 } 14099 } 14100 14101 // Multi-user methods 14102 14103 @Override 14104 public boolean switchUser(int userId) { 14105 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14106 != PackageManager.PERMISSION_GRANTED) { 14107 String msg = "Permission Denial: switchUser() from pid=" 14108 + Binder.getCallingPid() 14109 + ", uid=" + Binder.getCallingUid() 14110 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14111 Slog.w(TAG, msg); 14112 throw new SecurityException(msg); 14113 } 14114 14115 final long ident = Binder.clearCallingIdentity(); 14116 try { 14117 synchronized (this) { 14118 final int oldUserId = mCurrentUserId; 14119 if (oldUserId == userId) { 14120 return true; 14121 } 14122 14123 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14124 if (userInfo == null) { 14125 Slog.w(TAG, "No user info for user #" + userId); 14126 return false; 14127 } 14128 14129 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14130 R.anim.screen_user_enter); 14131 14132 boolean needStart = false; 14133 14134 // If the user we are switching to is not currently started, then 14135 // we need to start it now. 14136 if (mStartedUsers.get(userId) == null) { 14137 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14138 updateStartedUserArrayLocked(); 14139 needStart = true; 14140 } 14141 14142 mCurrentUserId = userId; 14143 mCurrentUserArray = new int[] { userId }; 14144 final Integer userIdInt = Integer.valueOf(userId); 14145 mUserLru.remove(userIdInt); 14146 mUserLru.add(userIdInt); 14147 14148 mWindowManager.setCurrentUser(userId); 14149 14150 // Once the internal notion of the active user has switched, we lock the device 14151 // with the option to show the user switcher on the keyguard. 14152 mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS); 14153 14154 final UserStartedState uss = mStartedUsers.get(userId); 14155 14156 // Make sure user is in the started state. If it is currently 14157 // stopping, we need to knock that off. 14158 if (uss.mState == UserStartedState.STATE_STOPPING) { 14159 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 14160 // so we can just fairly silently bring the user back from 14161 // the almost-dead. 14162 uss.mState = UserStartedState.STATE_RUNNING; 14163 updateStartedUserArrayLocked(); 14164 needStart = true; 14165 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 14166 // This means ACTION_SHUTDOWN has been sent, so we will 14167 // need to treat this as a new boot of the user. 14168 uss.mState = UserStartedState.STATE_BOOTING; 14169 updateStartedUserArrayLocked(); 14170 needStart = true; 14171 } 14172 14173 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14174 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14175 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14176 oldUserId, userId, uss)); 14177 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14178 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14179 if (needStart) { 14180 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14181 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14182 | Intent.FLAG_RECEIVER_FOREGROUND); 14183 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14184 broadcastIntentLocked(null, null, intent, 14185 null, null, 0, null, null, null, 14186 false, false, MY_PID, Process.SYSTEM_UID, userId); 14187 } 14188 14189 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14190 if (userId != 0) { 14191 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14192 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14193 broadcastIntentLocked(null, null, intent, null, 14194 new IIntentReceiver.Stub() { 14195 public void performReceive(Intent intent, int resultCode, 14196 String data, Bundle extras, boolean ordered, 14197 boolean sticky, int sendingUser) { 14198 userInitialized(uss); 14199 } 14200 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14201 userId); 14202 uss.initializing = true; 14203 } else { 14204 getUserManagerLocked().makeInitialized(userInfo.id); 14205 } 14206 } 14207 14208 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14209 if (!haveActivities) { 14210 startHomeActivityLocked(userId); 14211 } 14212 14213 getUserManagerLocked().userForeground(userId); 14214 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14215 if (needStart) { 14216 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 14217 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14218 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14219 broadcastIntentLocked(null, null, intent, 14220 null, new IIntentReceiver.Stub() { 14221 @Override 14222 public void performReceive(Intent intent, int resultCode, String data, 14223 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14224 throws RemoteException { 14225 } 14226 }, 0, null, null, 14227 android.Manifest.permission.INTERACT_ACROSS_USERS, 14228 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14229 } 14230 } 14231 } finally { 14232 Binder.restoreCallingIdentity(ident); 14233 } 14234 14235 return true; 14236 } 14237 14238 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14239 long ident = Binder.clearCallingIdentity(); 14240 try { 14241 Intent intent; 14242 if (oldUserId >= 0) { 14243 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14245 | Intent.FLAG_RECEIVER_FOREGROUND); 14246 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14247 broadcastIntentLocked(null, null, intent, 14248 null, null, 0, null, null, null, 14249 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14250 } 14251 if (newUserId >= 0) { 14252 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14253 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14254 | Intent.FLAG_RECEIVER_FOREGROUND); 14255 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14256 broadcastIntentLocked(null, null, intent, 14257 null, null, 0, null, null, null, 14258 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14259 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14260 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14261 | Intent.FLAG_RECEIVER_FOREGROUND); 14262 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14263 broadcastIntentLocked(null, null, intent, 14264 null, null, 0, null, null, 14265 android.Manifest.permission.MANAGE_USERS, 14266 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14267 } 14268 } finally { 14269 Binder.restoreCallingIdentity(ident); 14270 } 14271 } 14272 14273 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14274 final int newUserId) { 14275 final int N = mUserSwitchObservers.beginBroadcast(); 14276 if (N > 0) { 14277 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14278 int mCount = 0; 14279 @Override 14280 public void sendResult(Bundle data) throws RemoteException { 14281 synchronized (ActivityManagerService.this) { 14282 if (mCurUserSwitchCallback == this) { 14283 mCount++; 14284 if (mCount == N) { 14285 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14286 } 14287 } 14288 } 14289 } 14290 }; 14291 synchronized (this) { 14292 uss.switching = true; 14293 mCurUserSwitchCallback = callback; 14294 } 14295 for (int i=0; i<N; i++) { 14296 try { 14297 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14298 newUserId, callback); 14299 } catch (RemoteException e) { 14300 } 14301 } 14302 } else { 14303 synchronized (this) { 14304 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14305 } 14306 } 14307 mUserSwitchObservers.finishBroadcast(); 14308 } 14309 14310 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14311 synchronized (this) { 14312 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14313 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14314 } 14315 } 14316 14317 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14318 mCurUserSwitchCallback = null; 14319 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14320 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14321 oldUserId, newUserId, uss)); 14322 } 14323 14324 void userInitialized(UserStartedState uss) { 14325 synchronized (ActivityManagerService.this) { 14326 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14327 uss.initializing = false; 14328 completeSwitchAndInitalizeLocked(uss); 14329 } 14330 } 14331 14332 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14333 final int N = mUserSwitchObservers.beginBroadcast(); 14334 for (int i=0; i<N; i++) { 14335 try { 14336 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14337 } catch (RemoteException e) { 14338 } 14339 } 14340 mUserSwitchObservers.finishBroadcast(); 14341 synchronized (this) { 14342 uss.switching = false; 14343 completeSwitchAndInitalizeLocked(uss); 14344 } 14345 } 14346 14347 void completeSwitchAndInitalizeLocked(UserStartedState uss) { 14348 if (!uss.switching && !uss.initializing) { 14349 mWindowManager.stopFreezingScreen(); 14350 } 14351 } 14352 14353 void finishUserSwitch(UserStartedState uss) { 14354 synchronized (this) { 14355 if (uss.mState == UserStartedState.STATE_BOOTING 14356 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14357 uss.mState = UserStartedState.STATE_RUNNING; 14358 final int userId = uss.mHandle.getIdentifier(); 14359 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14360 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14361 broadcastIntentLocked(null, null, intent, 14362 null, null, 0, null, null, 14363 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14364 false, false, MY_PID, Process.SYSTEM_UID, userId); 14365 } 14366 int num = mUserLru.size(); 14367 int i = 0; 14368 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14369 Integer oldUserId = mUserLru.get(i); 14370 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14371 if (oldUss == null) { 14372 // Shouldn't happen, but be sane if it does. 14373 mUserLru.remove(i); 14374 num--; 14375 continue; 14376 } 14377 if (oldUss.mState == UserStartedState.STATE_STOPPING 14378 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 14379 // This user is already stopping, doesn't count. 14380 num--; 14381 i++; 14382 continue; 14383 } 14384 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14385 // Owner and current can't be stopped, but count as running. 14386 i++; 14387 continue; 14388 } 14389 // This is a user to be stopped. 14390 stopUserLocked(oldUserId, null); 14391 num--; 14392 i++; 14393 } 14394 } 14395 } 14396 14397 @Override 14398 public int stopUser(final int userId, final IStopUserCallback callback) { 14399 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14400 != PackageManager.PERMISSION_GRANTED) { 14401 String msg = "Permission Denial: switchUser() from pid=" 14402 + Binder.getCallingPid() 14403 + ", uid=" + Binder.getCallingUid() 14404 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14405 Slog.w(TAG, msg); 14406 throw new SecurityException(msg); 14407 } 14408 if (userId <= 0) { 14409 throw new IllegalArgumentException("Can't stop primary user " + userId); 14410 } 14411 synchronized (this) { 14412 return stopUserLocked(userId, callback); 14413 } 14414 } 14415 14416 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14417 if (mCurrentUserId == userId) { 14418 return ActivityManager.USER_OP_IS_CURRENT; 14419 } 14420 14421 final UserStartedState uss = mStartedUsers.get(userId); 14422 if (uss == null) { 14423 // User is not started, nothing to do... but we do need to 14424 // callback if requested. 14425 if (callback != null) { 14426 mHandler.post(new Runnable() { 14427 @Override 14428 public void run() { 14429 try { 14430 callback.userStopped(userId); 14431 } catch (RemoteException e) { 14432 } 14433 } 14434 }); 14435 } 14436 return ActivityManager.USER_OP_SUCCESS; 14437 } 14438 14439 if (callback != null) { 14440 uss.mStopCallbacks.add(callback); 14441 } 14442 14443 if (uss.mState != UserStartedState.STATE_STOPPING 14444 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14445 uss.mState = UserStartedState.STATE_STOPPING; 14446 updateStartedUserArrayLocked(); 14447 14448 long ident = Binder.clearCallingIdentity(); 14449 try { 14450 // We are going to broadcast ACTION_USER_STOPPING and then 14451 // once that is down send a final ACTION_SHUTDOWN and then 14452 // stop the user. 14453 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 14454 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14455 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14456 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 14457 // This is the result receiver for the final shutdown broadcast. 14458 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 14459 @Override 14460 public void performReceive(Intent intent, int resultCode, String data, 14461 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14462 finishUserStop(uss); 14463 } 14464 }; 14465 // This is the result receiver for the initial stopping broadcast. 14466 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 14467 @Override 14468 public void performReceive(Intent intent, int resultCode, String data, 14469 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14470 // On to the next. 14471 synchronized (ActivityManagerService.this) { 14472 if (uss.mState != UserStartedState.STATE_STOPPING) { 14473 // Whoops, we are being started back up. Abort, abort! 14474 return; 14475 } 14476 uss.mState = UserStartedState.STATE_SHUTDOWN; 14477 } 14478 broadcastIntentLocked(null, null, shutdownIntent, 14479 null, shutdownReceiver, 0, null, null, null, 14480 true, false, MY_PID, Process.SYSTEM_UID, userId); 14481 } 14482 }; 14483 // Kick things off. 14484 broadcastIntentLocked(null, null, stoppingIntent, 14485 null, stoppingReceiver, 0, null, null, 14486 android.Manifest.permission.INTERACT_ACROSS_USERS, 14487 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14488 } finally { 14489 Binder.restoreCallingIdentity(ident); 14490 } 14491 } 14492 14493 return ActivityManager.USER_OP_SUCCESS; 14494 } 14495 14496 void finishUserStop(UserStartedState uss) { 14497 final int userId = uss.mHandle.getIdentifier(); 14498 boolean stopped; 14499 ArrayList<IStopUserCallback> callbacks; 14500 synchronized (this) { 14501 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14502 if (mStartedUsers.get(userId) != uss) { 14503 stopped = false; 14504 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 14505 stopped = false; 14506 } else { 14507 stopped = true; 14508 // User can no longer run. 14509 mStartedUsers.remove(userId); 14510 mUserLru.remove(Integer.valueOf(userId)); 14511 updateStartedUserArrayLocked(); 14512 14513 // Clean up all state and processes associated with the user. 14514 // Kill all the processes for the user. 14515 forceStopUserLocked(userId); 14516 } 14517 } 14518 14519 for (int i=0; i<callbacks.size(); i++) { 14520 try { 14521 if (stopped) callbacks.get(i).userStopped(userId); 14522 else callbacks.get(i).userStopAborted(userId); 14523 } catch (RemoteException e) { 14524 } 14525 } 14526 } 14527 14528 @Override 14529 public UserInfo getCurrentUser() { 14530 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14531 != PackageManager.PERMISSION_GRANTED) && ( 14532 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14533 != PackageManager.PERMISSION_GRANTED)) { 14534 String msg = "Permission Denial: getCurrentUser() from pid=" 14535 + Binder.getCallingPid() 14536 + ", uid=" + Binder.getCallingUid() 14537 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14538 Slog.w(TAG, msg); 14539 throw new SecurityException(msg); 14540 } 14541 synchronized (this) { 14542 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14543 } 14544 } 14545 14546 int getCurrentUserIdLocked() { 14547 return mCurrentUserId; 14548 } 14549 14550 @Override 14551 public boolean isUserRunning(int userId, boolean orStopped) { 14552 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14553 != PackageManager.PERMISSION_GRANTED) { 14554 String msg = "Permission Denial: isUserRunning() from pid=" 14555 + Binder.getCallingPid() 14556 + ", uid=" + Binder.getCallingUid() 14557 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14558 Slog.w(TAG, msg); 14559 throw new SecurityException(msg); 14560 } 14561 synchronized (this) { 14562 return isUserRunningLocked(userId, orStopped); 14563 } 14564 } 14565 14566 boolean isUserRunningLocked(int userId, boolean orStopped) { 14567 UserStartedState state = mStartedUsers.get(userId); 14568 if (state == null) { 14569 return false; 14570 } 14571 if (orStopped) { 14572 return true; 14573 } 14574 return state.mState != UserStartedState.STATE_STOPPING 14575 && state.mState != UserStartedState.STATE_SHUTDOWN; 14576 } 14577 14578 @Override 14579 public int[] getRunningUserIds() { 14580 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14581 != PackageManager.PERMISSION_GRANTED) { 14582 String msg = "Permission Denial: isUserRunning() from pid=" 14583 + Binder.getCallingPid() 14584 + ", uid=" + Binder.getCallingUid() 14585 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14586 Slog.w(TAG, msg); 14587 throw new SecurityException(msg); 14588 } 14589 synchronized (this) { 14590 return mStartedUserArray; 14591 } 14592 } 14593 14594 private void updateStartedUserArrayLocked() { 14595 int num = 0; 14596 for (int i=0; i<mStartedUsers.size(); i++) { 14597 UserStartedState uss = mStartedUsers.valueAt(i); 14598 // This list does not include stopping users. 14599 if (uss.mState != UserStartedState.STATE_STOPPING 14600 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14601 num++; 14602 } 14603 } 14604 mStartedUserArray = new int[num]; 14605 num = 0; 14606 for (int i=0; i<mStartedUsers.size(); i++) { 14607 UserStartedState uss = mStartedUsers.valueAt(i); 14608 if (uss.mState != UserStartedState.STATE_STOPPING 14609 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 14610 mStartedUserArray[num] = mStartedUsers.keyAt(i); 14611 num++; 14612 } 14613 } 14614 } 14615 14616 @Override 14617 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14618 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14619 != PackageManager.PERMISSION_GRANTED) { 14620 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14621 + Binder.getCallingPid() 14622 + ", uid=" + Binder.getCallingUid() 14623 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14624 Slog.w(TAG, msg); 14625 throw new SecurityException(msg); 14626 } 14627 14628 mUserSwitchObservers.register(observer); 14629 } 14630 14631 @Override 14632 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14633 mUserSwitchObservers.unregister(observer); 14634 } 14635 14636 private boolean userExists(int userId) { 14637 if (userId == 0) { 14638 return true; 14639 } 14640 UserManagerService ums = getUserManagerLocked(); 14641 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14642 } 14643 14644 int[] getUsersLocked() { 14645 UserManagerService ums = getUserManagerLocked(); 14646 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14647 } 14648 14649 UserManagerService getUserManagerLocked() { 14650 if (mUserManager == null) { 14651 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14652 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14653 } 14654 return mUserManager; 14655 } 14656 14657 private void checkValidCaller(int uid, int userId) { 14658 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14659 14660 throw new SecurityException("Caller uid=" + uid 14661 + " is not privileged to communicate with user=" + userId); 14662 } 14663 14664 private int applyUserId(int uid, int userId) { 14665 return UserHandle.getUid(userId, uid); 14666 } 14667 14668 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14669 if (info == null) return null; 14670 ApplicationInfo newInfo = new ApplicationInfo(info); 14671 newInfo.uid = applyUserId(info.uid, userId); 14672 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14673 + info.packageName; 14674 return newInfo; 14675 } 14676 14677 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14678 if (aInfo == null 14679 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14680 return aInfo; 14681 } 14682 14683 ActivityInfo info = new ActivityInfo(aInfo); 14684 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14685 return info; 14686 } 14687} 14688