ActivityManagerService.java revision 15491c6a728131e322c45bc440500a8a78e4a410
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Collections; 151import java.util.Comparator; 152import java.util.HashMap; 153import java.util.HashSet; 154import java.util.Iterator; 155import java.util.List; 156import java.util.Locale; 157import java.util.Map; 158import java.util.Set; 159import java.util.concurrent.atomic.AtomicBoolean; 160import java.util.concurrent.atomic.AtomicLong; 161 162public final class ActivityManagerService extends ActivityManagerNative 163 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 164 private static final String USER_DATA_DIR = "/data/user/"; 165 static final String TAG = "ActivityManager"; 166 static final String TAG_MU = "ActivityManagerServiceMU"; 167 static final boolean DEBUG = false; 168 static final boolean localLOGV = DEBUG; 169 static final boolean DEBUG_SWITCH = localLOGV || false; 170 static final boolean DEBUG_TASKS = localLOGV || false; 171 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 172 static final boolean DEBUG_PAUSE = localLOGV || false; 173 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 174 static final boolean DEBUG_TRANSITION = localLOGV || false; 175 static final boolean DEBUG_BROADCAST = localLOGV || false; 176 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 177 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_SERVICE = localLOGV || false; 179 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 180 static final boolean DEBUG_VISBILITY = localLOGV || false; 181 static final boolean DEBUG_PROCESSES = localLOGV || false; 182 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 183 static final boolean DEBUG_PROVIDER = localLOGV || false; 184 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 185 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 186 static final boolean DEBUG_RESULTS = localLOGV || false; 187 static final boolean DEBUG_BACKUP = localLOGV || false; 188 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 189 static final boolean DEBUG_POWER = localLOGV || false; 190 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 191 static final boolean DEBUG_MU = localLOGV || false; 192 static final boolean VALIDATE_TOKENS = false; 193 static final boolean SHOW_ACTIVITY_START_TIME = true; 194 195 // Control over CPU and battery monitoring. 196 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 197 static final boolean MONITOR_CPU_USAGE = true; 198 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 199 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 200 static final boolean MONITOR_THREAD_CPU_USAGE = false; 201 202 // The flags that are set for all calls we make to the package manager. 203 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 204 205 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 206 207 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 208 209 // Maximum number of recent tasks that we can remember. 210 static final int MAX_RECENT_TASKS = 20; 211 212 // Amount of time after a call to stopAppSwitches() during which we will 213 // prevent further untrusted switches from happening. 214 static final long APP_SWITCH_DELAY_TIME = 5*1000; 215 216 // How long we wait for a launched process to attach to the activity manager 217 // before we decide it's never going to come up for real. 218 static final int PROC_START_TIMEOUT = 10*1000; 219 220 // How long we wait for a launched process to attach to the activity manager 221 // before we decide it's never going to come up for real, when the process was 222 // started with a wrapper for instrumentation (such as Valgrind) because it 223 // could take much longer than usual. 224 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 225 226 // How long to wait after going idle before forcing apps to GC. 227 static final int GC_TIMEOUT = 5*1000; 228 229 // The minimum amount of time between successive GC requests for a process. 230 static final int GC_MIN_INTERVAL = 60*1000; 231 232 // The rate at which we check for apps using excessive power -- 15 mins. 233 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 234 235 // The minimum sample duration we will allow before deciding we have 236 // enough data on wake locks to start killing things. 237 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 238 239 // The minimum sample duration we will allow before deciding we have 240 // enough data on CPU usage to start killing things. 241 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 242 243 // How long we allow a receiver to run before giving up on it. 244 static final int BROADCAST_FG_TIMEOUT = 10*1000; 245 static final int BROADCAST_BG_TIMEOUT = 60*1000; 246 247 // How long we wait until we timeout on key dispatching. 248 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 249 250 // How long we wait until we timeout on key dispatching during instrumentation. 251 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 252 253 // Amount of time we wait for observers to handle a user switch before 254 // giving up on them and unfreezing the screen. 255 static final int USER_SWITCH_TIMEOUT = 2*1000; 256 257 static final int MY_PID = Process.myPid(); 258 259 static final String[] EMPTY_STRING_ARRAY = new String[0]; 260 261 public ActivityStack mMainStack; 262 263 private final boolean mHeadless; 264 265 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 266 // default actuion automatically. Important for devices without direct input 267 // devices. 268 private boolean mShowDialogs = true; 269 270 /** 271 * Description of a request to start a new activity, which has been held 272 * due to app switches being disabled. 273 */ 274 static class PendingActivityLaunch { 275 ActivityRecord r; 276 ActivityRecord sourceRecord; 277 int startFlags; 278 } 279 280 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 281 = new ArrayList<PendingActivityLaunch>(); 282 283 284 BroadcastQueue mFgBroadcastQueue; 285 BroadcastQueue mBgBroadcastQueue; 286 // Convenient for easy iteration over the queues. Foreground is first 287 // so that dispatch of foreground broadcasts gets precedence. 288 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 289 290 BroadcastQueue broadcastQueueForIntent(Intent intent) { 291 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 292 if (DEBUG_BACKGROUND_BROADCAST) { 293 Slog.i(TAG, "Broadcast intent " + intent + " on " 294 + (isFg ? "foreground" : "background") 295 + " queue"); 296 } 297 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 298 } 299 300 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 301 for (BroadcastQueue queue : mBroadcastQueues) { 302 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 303 if (r != null) { 304 return r; 305 } 306 } 307 return null; 308 } 309 310 /** 311 * Activity we have told the window manager to have key focus. 312 */ 313 ActivityRecord mFocusedActivity = null; 314 /** 315 * List of intents that were used to start the most recent tasks. 316 */ 317 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 318 319 /** 320 * Process management. 321 */ 322 final ProcessList mProcessList = new ProcessList(); 323 324 /** 325 * All of the applications we currently have running organized by name. 326 * The keys are strings of the application package name (as 327 * returned by the package manager), and the keys are ApplicationRecord 328 * objects. 329 */ 330 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 331 332 /** 333 * The currently running isolated processes. 334 */ 335 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 336 337 /** 338 * Counter for assigning isolated process uids, to avoid frequently reusing the 339 * same ones. 340 */ 341 int mNextIsolatedProcessUid = 0; 342 343 /** 344 * The currently running heavy-weight process, if any. 345 */ 346 ProcessRecord mHeavyWeightProcess = null; 347 348 /** 349 * The last time that various processes have crashed. 350 */ 351 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 352 353 /** 354 * Set of applications that we consider to be bad, and will reject 355 * incoming broadcasts from (which the user has no control over). 356 * Processes are added to this set when they have crashed twice within 357 * a minimum amount of time; they are removed from it when they are 358 * later restarted (hopefully due to some user action). The value is the 359 * time it was added to the list. 360 */ 361 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 362 363 /** 364 * All of the processes we currently have running organized by pid. 365 * The keys are the pid running the application. 366 * 367 * <p>NOTE: This object is protected by its own lock, NOT the global 368 * activity manager lock! 369 */ 370 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 371 372 /** 373 * All of the processes that have been forced to be foreground. The key 374 * is the pid of the caller who requested it (we hold a death 375 * link on it). 376 */ 377 abstract class ForegroundToken implements IBinder.DeathRecipient { 378 int pid; 379 IBinder token; 380 } 381 final SparseArray<ForegroundToken> mForegroundProcesses 382 = new SparseArray<ForegroundToken>(); 383 384 /** 385 * List of records for processes that someone had tried to start before the 386 * system was ready. We don't start them at that point, but ensure they 387 * are started by the time booting is complete. 388 */ 389 final ArrayList<ProcessRecord> mProcessesOnHold 390 = new ArrayList<ProcessRecord>(); 391 392 /** 393 * List of persistent applications that are in the process 394 * of being started. 395 */ 396 final ArrayList<ProcessRecord> mPersistentStartingProcesses 397 = new ArrayList<ProcessRecord>(); 398 399 /** 400 * Processes that are being forcibly torn down. 401 */ 402 final ArrayList<ProcessRecord> mRemovedProcesses 403 = new ArrayList<ProcessRecord>(); 404 405 /** 406 * List of running applications, sorted by recent usage. 407 * The first entry in the list is the least recently used. 408 * It contains ApplicationRecord objects. This list does NOT include 409 * any persistent application records (since we never want to exit them). 410 */ 411 final ArrayList<ProcessRecord> mLruProcesses 412 = new ArrayList<ProcessRecord>(); 413 414 /** 415 * List of processes that should gc as soon as things are idle. 416 */ 417 final ArrayList<ProcessRecord> mProcessesToGc 418 = new ArrayList<ProcessRecord>(); 419 420 /** 421 * This is the process holding what we currently consider to be 422 * the "home" activity. 423 */ 424 ProcessRecord mHomeProcess; 425 426 /** 427 * This is the process holding the activity the user last visited that 428 * is in a different process from the one they are currently in. 429 */ 430 ProcessRecord mPreviousProcess; 431 432 /** 433 * The time at which the previous process was last visible. 434 */ 435 long mPreviousProcessVisibleTime; 436 437 /** 438 * Which uses have been started, so are allowed to run code. 439 */ 440 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 441 442 /** 443 * LRU list of history of current users. Most recently current is at the end. 444 */ 445 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 446 447 /** 448 * Registered observers of the user switching mechanics. 449 */ 450 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 451 = new RemoteCallbackList<IUserSwitchObserver>(); 452 453 /** 454 * Currently active user switch. 455 */ 456 Object mCurUserSwitchCallback; 457 458 /** 459 * Packages that the user has asked to have run in screen size 460 * compatibility mode instead of filling the screen. 461 */ 462 final CompatModePackages mCompatModePackages; 463 464 /** 465 * Set of PendingResultRecord objects that are currently active. 466 */ 467 final HashSet mPendingResultRecords = new HashSet(); 468 469 /** 470 * Set of IntentSenderRecord objects that are currently active. 471 */ 472 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 473 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 474 475 /** 476 * Fingerprints (hashCode()) of stack traces that we've 477 * already logged DropBox entries for. Guarded by itself. If 478 * something (rogue user app) forces this over 479 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 480 */ 481 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 482 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 483 484 /** 485 * Strict Mode background batched logging state. 486 * 487 * The string buffer is guarded by itself, and its lock is also 488 * used to determine if another batched write is already 489 * in-flight. 490 */ 491 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 492 493 /** 494 * Keeps track of all IIntentReceivers that have been registered for 495 * broadcasts. Hash keys are the receiver IBinder, hash value is 496 * a ReceiverList. 497 */ 498 final HashMap mRegisteredReceivers = new HashMap(); 499 500 /** 501 * Resolver for broadcast intents to registered receivers. 502 * Holds BroadcastFilter (subclass of IntentFilter). 503 */ 504 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 505 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 506 @Override 507 protected boolean allowFilterResult( 508 BroadcastFilter filter, List<BroadcastFilter> dest) { 509 IBinder target = filter.receiverList.receiver.asBinder(); 510 for (int i=dest.size()-1; i>=0; i--) { 511 if (dest.get(i).receiverList.receiver.asBinder() == target) { 512 return false; 513 } 514 } 515 return true; 516 } 517 518 @Override 519 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 520 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 521 || userId == filter.owningUserId) { 522 return super.newResult(filter, match, userId); 523 } 524 return null; 525 } 526 527 @Override 528 protected BroadcastFilter[] newArray(int size) { 529 return new BroadcastFilter[size]; 530 } 531 532 @Override 533 protected String packageForFilter(BroadcastFilter filter) { 534 return filter.packageName; 535 } 536 }; 537 538 /** 539 * State of all active sticky broadcasts per user. Keys are the action of the 540 * sticky Intent, values are an ArrayList of all broadcasted intents with 541 * that action (which should usually be one). The SparseArray is keyed 542 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 543 * for stickies that are sent to all users. 544 */ 545 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 546 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 547 548 final ActiveServices mServices; 549 550 /** 551 * Backup/restore process management 552 */ 553 String mBackupAppName = null; 554 BackupRecord mBackupTarget = null; 555 556 /** 557 * List of PendingThumbnailsRecord objects of clients who are still 558 * waiting to receive all of the thumbnails for a task. 559 */ 560 final ArrayList mPendingThumbnails = new ArrayList(); 561 562 /** 563 * List of HistoryRecord objects that have been finished and must 564 * still report back to a pending thumbnail receiver. 565 */ 566 final ArrayList mCancelledThumbnails = new ArrayList(); 567 568 final ProviderMap mProviderMap; 569 570 /** 571 * List of content providers who have clients waiting for them. The 572 * application is currently being launched and the provider will be 573 * removed from this list once it is published. 574 */ 575 final ArrayList<ContentProviderRecord> mLaunchingProviders 576 = new ArrayList<ContentProviderRecord>(); 577 578 /** 579 * Global set of specific Uri permissions that have been granted. 580 */ 581 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 582 = new SparseArray<HashMap<Uri, UriPermission>>(); 583 584 CoreSettingsObserver mCoreSettingsObserver; 585 586 /** 587 * Thread-local storage used to carry caller permissions over through 588 * indirect content-provider access. 589 * @see #ActivityManagerService.openContentUri() 590 */ 591 private class Identity { 592 public int pid; 593 public int uid; 594 595 Identity(int _pid, int _uid) { 596 pid = _pid; 597 uid = _uid; 598 } 599 } 600 601 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 602 603 /** 604 * All information we have collected about the runtime performance of 605 * any user id that can impact battery performance. 606 */ 607 final BatteryStatsService mBatteryStatsService; 608 609 /** 610 * information about component usage 611 */ 612 final UsageStatsService mUsageStatsService; 613 614 /** 615 * Current configuration information. HistoryRecord objects are given 616 * a reference to this object to indicate which configuration they are 617 * currently running in, so this object must be kept immutable. 618 */ 619 Configuration mConfiguration = new Configuration(); 620 621 /** 622 * Current sequencing integer of the configuration, for skipping old 623 * configurations. 624 */ 625 int mConfigurationSeq = 0; 626 627 /** 628 * Hardware-reported OpenGLES version. 629 */ 630 final int GL_ES_VERSION; 631 632 /** 633 * List of initialization arguments to pass to all processes when binding applications to them. 634 * For example, references to the commonly used services. 635 */ 636 HashMap<String, IBinder> mAppBindArgs; 637 638 /** 639 * Temporary to avoid allocations. Protected by main lock. 640 */ 641 final StringBuilder mStringBuilder = new StringBuilder(256); 642 643 /** 644 * Used to control how we initialize the service. 645 */ 646 boolean mStartRunning = false; 647 ComponentName mTopComponent; 648 String mTopAction; 649 String mTopData; 650 boolean mProcessesReady = false; 651 boolean mSystemReady = false; 652 boolean mBooting = false; 653 boolean mWaitingUpdate = false; 654 boolean mDidUpdate = false; 655 boolean mOnBattery = false; 656 boolean mLaunchWarningShown = false; 657 658 Context mContext; 659 660 int mFactoryTest; 661 662 boolean mCheckedForSetup; 663 664 /** 665 * The time at which we will allow normal application switches again, 666 * after a call to {@link #stopAppSwitches()}. 667 */ 668 long mAppSwitchesAllowedTime; 669 670 /** 671 * This is set to true after the first switch after mAppSwitchesAllowedTime 672 * is set; any switches after that will clear the time. 673 */ 674 boolean mDidAppSwitch; 675 676 /** 677 * Last time (in realtime) at which we checked for power usage. 678 */ 679 long mLastPowerCheckRealtime; 680 681 /** 682 * Last time (in uptime) at which we checked for power usage. 683 */ 684 long mLastPowerCheckUptime; 685 686 /** 687 * Set while we are wanting to sleep, to prevent any 688 * activities from being started/resumed. 689 */ 690 boolean mSleeping = false; 691 692 /** 693 * State of external calls telling us if the device is asleep. 694 */ 695 boolean mWentToSleep = false; 696 697 /** 698 * State of external call telling us if the lock screen is shown. 699 */ 700 boolean mLockScreenShown = false; 701 702 /** 703 * Set if we are shutting down the system, similar to sleeping. 704 */ 705 boolean mShuttingDown = false; 706 707 /** 708 * Task identifier that activities are currently being started 709 * in. Incremented each time a new task is created. 710 * todo: Replace this with a TokenSpace class that generates non-repeating 711 * integers that won't wrap. 712 */ 713 int mCurTask = 1; 714 715 /** 716 * Current sequence id for oom_adj computation traversal. 717 */ 718 int mAdjSeq = 0; 719 720 /** 721 * Current sequence id for process LRU updating. 722 */ 723 int mLruSeq = 0; 724 725 /** 726 * Keep track of the non-hidden/empty process we last found, to help 727 * determine how to distribute hidden/empty processes next time. 728 */ 729 int mNumNonHiddenProcs = 0; 730 731 /** 732 * Keep track of the number of hidden procs, to balance oom adj 733 * distribution between those and empty procs. 734 */ 735 int mNumHiddenProcs = 0; 736 737 /** 738 * Keep track of the number of service processes we last found, to 739 * determine on the next iteration which should be B services. 740 */ 741 int mNumServiceProcs = 0; 742 int mNewNumServiceProcs = 0; 743 744 /** 745 * System monitoring: number of processes that died since the last 746 * N procs were started. 747 */ 748 int[] mProcDeaths = new int[20]; 749 750 /** 751 * This is set if we had to do a delayed dexopt of an app before launching 752 * it, to increasing the ANR timeouts in that case. 753 */ 754 boolean mDidDexOpt; 755 756 String mDebugApp = null; 757 boolean mWaitForDebugger = false; 758 boolean mDebugTransient = false; 759 String mOrigDebugApp = null; 760 boolean mOrigWaitForDebugger = false; 761 boolean mAlwaysFinishActivities = false; 762 IActivityController mController = null; 763 String mProfileApp = null; 764 ProcessRecord mProfileProc = null; 765 String mProfileFile; 766 ParcelFileDescriptor mProfileFd; 767 int mProfileType = 0; 768 boolean mAutoStopProfiler = false; 769 String mOpenGlTraceApp = null; 770 771 static class ProcessChangeItem { 772 static final int CHANGE_ACTIVITIES = 1<<0; 773 static final int CHANGE_IMPORTANCE= 1<<1; 774 int changes; 775 int uid; 776 int pid; 777 int importance; 778 boolean foregroundActivities; 779 } 780 781 final RemoteCallbackList<IProcessObserver> mProcessObservers 782 = new RemoteCallbackList<IProcessObserver>(); 783 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 784 785 final ArrayList<ProcessChangeItem> mPendingProcessChanges 786 = new ArrayList<ProcessChangeItem>(); 787 final ArrayList<ProcessChangeItem> mAvailProcessChanges 788 = new ArrayList<ProcessChangeItem>(); 789 790 /** 791 * Callback of last caller to {@link #requestPss}. 792 */ 793 Runnable mRequestPssCallback; 794 795 /** 796 * Remaining processes for which we are waiting results from the last 797 * call to {@link #requestPss}. 798 */ 799 final ArrayList<ProcessRecord> mRequestPssList 800 = new ArrayList<ProcessRecord>(); 801 802 /** 803 * Runtime statistics collection thread. This object's lock is used to 804 * protect all related state. 805 */ 806 final Thread mProcessStatsThread; 807 808 /** 809 * Used to collect process stats when showing not responding dialog. 810 * Protected by mProcessStatsThread. 811 */ 812 final ProcessStats mProcessStats = new ProcessStats( 813 MONITOR_THREAD_CPU_USAGE); 814 final AtomicLong mLastCpuTime = new AtomicLong(0); 815 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 816 817 long mLastWriteTime = 0; 818 819 /** 820 * Set to true after the system has finished booting. 821 */ 822 boolean mBooted = false; 823 824 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 825 int mProcessLimitOverride = -1; 826 827 WindowManagerService mWindowManager; 828 829 static ActivityManagerService mSelf; 830 static ActivityThread mSystemThread; 831 832 private int mCurrentUserId; 833 private UserManagerService mUserManager; 834 835 private final class AppDeathRecipient implements IBinder.DeathRecipient { 836 final ProcessRecord mApp; 837 final int mPid; 838 final IApplicationThread mAppThread; 839 840 AppDeathRecipient(ProcessRecord app, int pid, 841 IApplicationThread thread) { 842 if (localLOGV) Slog.v( 843 TAG, "New death recipient " + this 844 + " for thread " + thread.asBinder()); 845 mApp = app; 846 mPid = pid; 847 mAppThread = thread; 848 } 849 850 public void binderDied() { 851 if (localLOGV) Slog.v( 852 TAG, "Death received in " + this 853 + " for thread " + mAppThread.asBinder()); 854 synchronized(ActivityManagerService.this) { 855 appDiedLocked(mApp, mPid, mAppThread); 856 } 857 } 858 } 859 860 static final int SHOW_ERROR_MSG = 1; 861 static final int SHOW_NOT_RESPONDING_MSG = 2; 862 static final int SHOW_FACTORY_ERROR_MSG = 3; 863 static final int UPDATE_CONFIGURATION_MSG = 4; 864 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 865 static final int WAIT_FOR_DEBUGGER_MSG = 6; 866 static final int SERVICE_TIMEOUT_MSG = 12; 867 static final int UPDATE_TIME_ZONE = 13; 868 static final int SHOW_UID_ERROR_MSG = 14; 869 static final int IM_FEELING_LUCKY_MSG = 15; 870 static final int PROC_START_TIMEOUT_MSG = 20; 871 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 872 static final int KILL_APPLICATION_MSG = 22; 873 static final int FINALIZE_PENDING_INTENT_MSG = 23; 874 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 875 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 876 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 877 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 878 static final int CLEAR_DNS_CACHE = 28; 879 static final int UPDATE_HTTP_PROXY = 29; 880 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 881 static final int DISPATCH_PROCESSES_CHANGED = 31; 882 static final int DISPATCH_PROCESS_DIED = 32; 883 static final int REPORT_MEM_USAGE = 33; 884 static final int REPORT_USER_SWITCH_MSG = 34; 885 static final int CONTINUE_USER_SWITCH_MSG = 35; 886 static final int USER_SWITCH_TIMEOUT_MSG = 36; 887 888 static final int FIRST_ACTIVITY_STACK_MSG = 100; 889 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 890 static final int FIRST_COMPAT_MODE_MSG = 300; 891 892 AlertDialog mUidAlert; 893 CompatModeDialog mCompatModeDialog; 894 long mLastMemUsageReportTime = 0; 895 896 final Handler mHandler = new Handler() { 897 //public Handler() { 898 // if (localLOGV) Slog.v(TAG, "Handler started!"); 899 //} 900 901 public void handleMessage(Message msg) { 902 switch (msg.what) { 903 case SHOW_ERROR_MSG: { 904 HashMap data = (HashMap) msg.obj; 905 synchronized (ActivityManagerService.this) { 906 ProcessRecord proc = (ProcessRecord)data.get("app"); 907 if (proc != null && proc.crashDialog != null) { 908 Slog.e(TAG, "App already has crash dialog: " + proc); 909 return; 910 } 911 AppErrorResult res = (AppErrorResult) data.get("result"); 912 if (mShowDialogs && !mSleeping && !mShuttingDown) { 913 Dialog d = new AppErrorDialog(mContext, res, proc); 914 d.show(); 915 proc.crashDialog = d; 916 } else { 917 // The device is asleep, so just pretend that the user 918 // saw a crash dialog and hit "force quit". 919 res.set(0); 920 } 921 } 922 923 ensureBootCompleted(); 924 } break; 925 case SHOW_NOT_RESPONDING_MSG: { 926 synchronized (ActivityManagerService.this) { 927 HashMap data = (HashMap) msg.obj; 928 ProcessRecord proc = (ProcessRecord)data.get("app"); 929 if (proc != null && proc.anrDialog != null) { 930 Slog.e(TAG, "App already has anr dialog: " + proc); 931 return; 932 } 933 934 Intent intent = new Intent("android.intent.action.ANR"); 935 if (!mProcessesReady) { 936 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 937 | Intent.FLAG_RECEIVER_FOREGROUND); 938 } 939 broadcastIntentLocked(null, null, intent, 940 null, null, 0, null, null, null, 941 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 942 943 if (mShowDialogs) { 944 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 945 mContext, proc, (ActivityRecord)data.get("activity")); 946 d.show(); 947 proc.anrDialog = d; 948 } else { 949 // Just kill the app if there is no dialog to be shown. 950 killAppAtUsersRequest(proc, null); 951 } 952 } 953 954 ensureBootCompleted(); 955 } break; 956 case SHOW_STRICT_MODE_VIOLATION_MSG: { 957 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 958 synchronized (ActivityManagerService.this) { 959 ProcessRecord proc = (ProcessRecord) data.get("app"); 960 if (proc == null) { 961 Slog.e(TAG, "App not found when showing strict mode dialog."); 962 break; 963 } 964 if (proc.crashDialog != null) { 965 Slog.e(TAG, "App already has strict mode dialog: " + proc); 966 return; 967 } 968 AppErrorResult res = (AppErrorResult) data.get("result"); 969 if (mShowDialogs && !mSleeping && !mShuttingDown) { 970 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 971 d.show(); 972 proc.crashDialog = d; 973 } else { 974 // The device is asleep, so just pretend that the user 975 // saw a crash dialog and hit "force quit". 976 res.set(0); 977 } 978 } 979 ensureBootCompleted(); 980 } break; 981 case SHOW_FACTORY_ERROR_MSG: { 982 Dialog d = new FactoryErrorDialog( 983 mContext, msg.getData().getCharSequence("msg")); 984 d.show(); 985 ensureBootCompleted(); 986 } break; 987 case UPDATE_CONFIGURATION_MSG: { 988 final ContentResolver resolver = mContext.getContentResolver(); 989 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 990 } break; 991 case GC_BACKGROUND_PROCESSES_MSG: { 992 synchronized (ActivityManagerService.this) { 993 performAppGcsIfAppropriateLocked(); 994 } 995 } break; 996 case WAIT_FOR_DEBUGGER_MSG: { 997 synchronized (ActivityManagerService.this) { 998 ProcessRecord app = (ProcessRecord)msg.obj; 999 if (msg.arg1 != 0) { 1000 if (!app.waitedForDebugger) { 1001 Dialog d = new AppWaitingForDebuggerDialog( 1002 ActivityManagerService.this, 1003 mContext, app); 1004 app.waitDialog = d; 1005 app.waitedForDebugger = true; 1006 d.show(); 1007 } 1008 } else { 1009 if (app.waitDialog != null) { 1010 app.waitDialog.dismiss(); 1011 app.waitDialog = null; 1012 } 1013 } 1014 } 1015 } break; 1016 case SERVICE_TIMEOUT_MSG: { 1017 if (mDidDexOpt) { 1018 mDidDexOpt = false; 1019 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1020 nmsg.obj = msg.obj; 1021 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1022 return; 1023 } 1024 mServices.serviceTimeout((ProcessRecord)msg.obj); 1025 } break; 1026 case UPDATE_TIME_ZONE: { 1027 synchronized (ActivityManagerService.this) { 1028 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1029 ProcessRecord r = mLruProcesses.get(i); 1030 if (r.thread != null) { 1031 try { 1032 r.thread.updateTimeZone(); 1033 } catch (RemoteException ex) { 1034 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1035 } 1036 } 1037 } 1038 } 1039 } break; 1040 case CLEAR_DNS_CACHE: { 1041 synchronized (ActivityManagerService.this) { 1042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1043 ProcessRecord r = mLruProcesses.get(i); 1044 if (r.thread != null) { 1045 try { 1046 r.thread.clearDnsCache(); 1047 } catch (RemoteException ex) { 1048 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1049 } 1050 } 1051 } 1052 } 1053 } break; 1054 case UPDATE_HTTP_PROXY: { 1055 ProxyProperties proxy = (ProxyProperties)msg.obj; 1056 String host = ""; 1057 String port = ""; 1058 String exclList = ""; 1059 if (proxy != null) { 1060 host = proxy.getHost(); 1061 port = Integer.toString(proxy.getPort()); 1062 exclList = proxy.getExclusionList(); 1063 } 1064 synchronized (ActivityManagerService.this) { 1065 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1066 ProcessRecord r = mLruProcesses.get(i); 1067 if (r.thread != null) { 1068 try { 1069 r.thread.setHttpProxy(host, port, exclList); 1070 } catch (RemoteException ex) { 1071 Slog.w(TAG, "Failed to update http proxy for: " + 1072 r.info.processName); 1073 } 1074 } 1075 } 1076 } 1077 } break; 1078 case SHOW_UID_ERROR_MSG: { 1079 String title = "System UIDs Inconsistent"; 1080 String text = "UIDs on the system are inconsistent, you need to wipe your" 1081 + " data partition or your device will be unstable."; 1082 Log.e(TAG, title + ": " + text); 1083 if (mShowDialogs) { 1084 // XXX This is a temporary dialog, no need to localize. 1085 AlertDialog d = new BaseErrorDialog(mContext); 1086 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1087 d.setCancelable(false); 1088 d.setTitle(title); 1089 d.setMessage(text); 1090 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1091 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1092 mUidAlert = d; 1093 d.show(); 1094 } 1095 } break; 1096 case IM_FEELING_LUCKY_MSG: { 1097 if (mUidAlert != null) { 1098 mUidAlert.dismiss(); 1099 mUidAlert = null; 1100 } 1101 } break; 1102 case PROC_START_TIMEOUT_MSG: { 1103 if (mDidDexOpt) { 1104 mDidDexOpt = false; 1105 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1106 nmsg.obj = msg.obj; 1107 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1108 return; 1109 } 1110 ProcessRecord app = (ProcessRecord)msg.obj; 1111 synchronized (ActivityManagerService.this) { 1112 processStartTimedOutLocked(app); 1113 } 1114 } break; 1115 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1116 synchronized (ActivityManagerService.this) { 1117 doPendingActivityLaunchesLocked(true); 1118 } 1119 } break; 1120 case KILL_APPLICATION_MSG: { 1121 synchronized (ActivityManagerService.this) { 1122 int appid = msg.arg1; 1123 boolean restart = (msg.arg2 == 1); 1124 String pkg = (String) msg.obj; 1125 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1126 UserHandle.USER_ALL); 1127 } 1128 } break; 1129 case FINALIZE_PENDING_INTENT_MSG: { 1130 ((PendingIntentRecord)msg.obj).completeFinalize(); 1131 } break; 1132 case POST_HEAVY_NOTIFICATION_MSG: { 1133 INotificationManager inm = NotificationManager.getService(); 1134 if (inm == null) { 1135 return; 1136 } 1137 1138 ActivityRecord root = (ActivityRecord)msg.obj; 1139 ProcessRecord process = root.app; 1140 if (process == null) { 1141 return; 1142 } 1143 1144 try { 1145 Context context = mContext.createPackageContext(process.info.packageName, 0); 1146 String text = mContext.getString(R.string.heavy_weight_notification, 1147 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1148 Notification notification = new Notification(); 1149 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1150 notification.when = 0; 1151 notification.flags = Notification.FLAG_ONGOING_EVENT; 1152 notification.tickerText = text; 1153 notification.defaults = 0; // please be quiet 1154 notification.sound = null; 1155 notification.vibrate = null; 1156 notification.setLatestEventInfo(context, text, 1157 mContext.getText(R.string.heavy_weight_notification_detail), 1158 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1159 PendingIntent.FLAG_CANCEL_CURRENT, null, 1160 new UserHandle(root.userId))); 1161 1162 try { 1163 int[] outId = new int[1]; 1164 inm.enqueueNotificationWithTag("android", null, 1165 R.string.heavy_weight_notification, 1166 notification, outId, root.userId); 1167 } catch (RuntimeException e) { 1168 Slog.w(ActivityManagerService.TAG, 1169 "Error showing notification for heavy-weight app", e); 1170 } catch (RemoteException e) { 1171 } 1172 } catch (NameNotFoundException e) { 1173 Slog.w(TAG, "Unable to create context for heavy notification", e); 1174 } 1175 } break; 1176 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1177 INotificationManager inm = NotificationManager.getService(); 1178 if (inm == null) { 1179 return; 1180 } 1181 try { 1182 inm.cancelNotificationWithTag("android", null, 1183 R.string.heavy_weight_notification, msg.arg1); 1184 } catch (RuntimeException e) { 1185 Slog.w(ActivityManagerService.TAG, 1186 "Error canceling notification for service", e); 1187 } catch (RemoteException e) { 1188 } 1189 } break; 1190 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1191 synchronized (ActivityManagerService.this) { 1192 checkExcessivePowerUsageLocked(true); 1193 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1194 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1195 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1196 } 1197 } break; 1198 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1199 synchronized (ActivityManagerService.this) { 1200 ActivityRecord ar = (ActivityRecord)msg.obj; 1201 if (mCompatModeDialog != null) { 1202 if (mCompatModeDialog.mAppInfo.packageName.equals( 1203 ar.info.applicationInfo.packageName)) { 1204 return; 1205 } 1206 mCompatModeDialog.dismiss(); 1207 mCompatModeDialog = null; 1208 } 1209 if (ar != null && false) { 1210 if (mCompatModePackages.getPackageAskCompatModeLocked( 1211 ar.packageName)) { 1212 int mode = mCompatModePackages.computeCompatModeLocked( 1213 ar.info.applicationInfo); 1214 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1215 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1216 mCompatModeDialog = new CompatModeDialog( 1217 ActivityManagerService.this, mContext, 1218 ar.info.applicationInfo); 1219 mCompatModeDialog.show(); 1220 } 1221 } 1222 } 1223 } 1224 break; 1225 } 1226 case DISPATCH_PROCESSES_CHANGED: { 1227 dispatchProcessesChanged(); 1228 break; 1229 } 1230 case DISPATCH_PROCESS_DIED: { 1231 final int pid = msg.arg1; 1232 final int uid = msg.arg2; 1233 dispatchProcessDied(pid, uid); 1234 break; 1235 } 1236 case REPORT_MEM_USAGE: { 1237 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1238 if (!isDebuggable) { 1239 return; 1240 } 1241 synchronized (ActivityManagerService.this) { 1242 long now = SystemClock.uptimeMillis(); 1243 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1244 // Don't report more than every 5 minutes to somewhat 1245 // avoid spamming. 1246 return; 1247 } 1248 mLastMemUsageReportTime = now; 1249 } 1250 Thread thread = new Thread() { 1251 @Override public void run() { 1252 StringBuilder dropBuilder = new StringBuilder(1024); 1253 StringBuilder logBuilder = new StringBuilder(1024); 1254 StringWriter oomSw = new StringWriter(); 1255 PrintWriter oomPw = new PrintWriter(oomSw); 1256 StringWriter catSw = new StringWriter(); 1257 PrintWriter catPw = new PrintWriter(catSw); 1258 String[] emptyArgs = new String[] { }; 1259 StringBuilder tag = new StringBuilder(128); 1260 StringBuilder stack = new StringBuilder(128); 1261 tag.append("Low on memory -- "); 1262 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1263 tag, stack); 1264 dropBuilder.append(stack); 1265 dropBuilder.append('\n'); 1266 dropBuilder.append('\n'); 1267 String oomString = oomSw.toString(); 1268 dropBuilder.append(oomString); 1269 dropBuilder.append('\n'); 1270 logBuilder.append(oomString); 1271 try { 1272 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1273 "procrank", }); 1274 final InputStreamReader converter = new InputStreamReader( 1275 proc.getInputStream()); 1276 BufferedReader in = new BufferedReader(converter); 1277 String line; 1278 while (true) { 1279 line = in.readLine(); 1280 if (line == null) { 1281 break; 1282 } 1283 if (line.length() > 0) { 1284 logBuilder.append(line); 1285 logBuilder.append('\n'); 1286 } 1287 dropBuilder.append(line); 1288 dropBuilder.append('\n'); 1289 } 1290 converter.close(); 1291 } catch (IOException e) { 1292 } 1293 synchronized (ActivityManagerService.this) { 1294 catPw.println(); 1295 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1296 catPw.println(); 1297 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1298 false, false, null); 1299 catPw.println(); 1300 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1301 } 1302 dropBuilder.append(catSw.toString()); 1303 addErrorToDropBox("lowmem", null, "system_server", null, 1304 null, tag.toString(), dropBuilder.toString(), null, null); 1305 Slog.i(TAG, logBuilder.toString()); 1306 synchronized (ActivityManagerService.this) { 1307 long now = SystemClock.uptimeMillis(); 1308 if (mLastMemUsageReportTime < now) { 1309 mLastMemUsageReportTime = now; 1310 } 1311 } 1312 } 1313 }; 1314 thread.start(); 1315 break; 1316 } 1317 case REPORT_USER_SWITCH_MSG: { 1318 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1319 break; 1320 } 1321 case CONTINUE_USER_SWITCH_MSG: { 1322 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1323 break; 1324 } 1325 case USER_SWITCH_TIMEOUT_MSG: { 1326 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1327 break; 1328 } 1329 } 1330 } 1331 }; 1332 1333 public static void setSystemProcess() { 1334 try { 1335 ActivityManagerService m = mSelf; 1336 1337 ServiceManager.addService("activity", m, true); 1338 ServiceManager.addService("meminfo", new MemBinder(m)); 1339 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1340 ServiceManager.addService("dbinfo", new DbBinder(m)); 1341 if (MONITOR_CPU_USAGE) { 1342 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1343 } 1344 ServiceManager.addService("permission", new PermissionController(m)); 1345 1346 ApplicationInfo info = 1347 mSelf.mContext.getPackageManager().getApplicationInfo( 1348 "android", STOCK_PM_FLAGS); 1349 mSystemThread.installSystemApplicationInfo(info); 1350 1351 synchronized (mSelf) { 1352 ProcessRecord app = mSelf.newProcessRecordLocked( 1353 mSystemThread.getApplicationThread(), info, 1354 info.processName, false); 1355 app.persistent = true; 1356 app.pid = MY_PID; 1357 app.maxAdj = ProcessList.SYSTEM_ADJ; 1358 mSelf.mProcessNames.put(app.processName, app.uid, app); 1359 synchronized (mSelf.mPidsSelfLocked) { 1360 mSelf.mPidsSelfLocked.put(app.pid, app); 1361 } 1362 mSelf.updateLruProcessLocked(app, true, true); 1363 } 1364 } catch (PackageManager.NameNotFoundException e) { 1365 throw new RuntimeException( 1366 "Unable to find android system package", e); 1367 } 1368 } 1369 1370 public void setWindowManager(WindowManagerService wm) { 1371 mWindowManager = wm; 1372 } 1373 1374 public static final Context main(int factoryTest) { 1375 AThread thr = new AThread(); 1376 thr.start(); 1377 1378 synchronized (thr) { 1379 while (thr.mService == null) { 1380 try { 1381 thr.wait(); 1382 } catch (InterruptedException e) { 1383 } 1384 } 1385 } 1386 1387 ActivityManagerService m = thr.mService; 1388 mSelf = m; 1389 ActivityThread at = ActivityThread.systemMain(); 1390 mSystemThread = at; 1391 Context context = at.getSystemContext(); 1392 context.setTheme(android.R.style.Theme_Holo); 1393 m.mContext = context; 1394 m.mFactoryTest = factoryTest; 1395 m.mMainStack = new ActivityStack(m, context, true); 1396 1397 m.mBatteryStatsService.publish(context); 1398 m.mUsageStatsService.publish(context); 1399 1400 synchronized (thr) { 1401 thr.mReady = true; 1402 thr.notifyAll(); 1403 } 1404 1405 m.startRunning(null, null, null, null); 1406 1407 return context; 1408 } 1409 1410 public static ActivityManagerService self() { 1411 return mSelf; 1412 } 1413 1414 static class AThread extends Thread { 1415 ActivityManagerService mService; 1416 boolean mReady = false; 1417 1418 public AThread() { 1419 super("ActivityManager"); 1420 } 1421 1422 public void run() { 1423 Looper.prepare(); 1424 1425 android.os.Process.setThreadPriority( 1426 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1427 android.os.Process.setCanSelfBackground(false); 1428 1429 ActivityManagerService m = new ActivityManagerService(); 1430 1431 synchronized (this) { 1432 mService = m; 1433 notifyAll(); 1434 } 1435 1436 synchronized (this) { 1437 while (!mReady) { 1438 try { 1439 wait(); 1440 } catch (InterruptedException e) { 1441 } 1442 } 1443 } 1444 1445 // For debug builds, log event loop stalls to dropbox for analysis. 1446 if (StrictMode.conditionallyEnableDebugLogging()) { 1447 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1448 } 1449 1450 Looper.loop(); 1451 } 1452 } 1453 1454 static class MemBinder extends Binder { 1455 ActivityManagerService mActivityManagerService; 1456 MemBinder(ActivityManagerService activityManagerService) { 1457 mActivityManagerService = activityManagerService; 1458 } 1459 1460 @Override 1461 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1462 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1463 != PackageManager.PERMISSION_GRANTED) { 1464 pw.println("Permission Denial: can't dump meminfo from from pid=" 1465 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1466 + " without permission " + android.Manifest.permission.DUMP); 1467 return; 1468 } 1469 1470 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1471 false, null, null, null); 1472 } 1473 } 1474 1475 static class GraphicsBinder extends Binder { 1476 ActivityManagerService mActivityManagerService; 1477 GraphicsBinder(ActivityManagerService activityManagerService) { 1478 mActivityManagerService = activityManagerService; 1479 } 1480 1481 @Override 1482 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1483 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1484 != PackageManager.PERMISSION_GRANTED) { 1485 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1486 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1487 + " without permission " + android.Manifest.permission.DUMP); 1488 return; 1489 } 1490 1491 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1492 } 1493 } 1494 1495 static class DbBinder extends Binder { 1496 ActivityManagerService mActivityManagerService; 1497 DbBinder(ActivityManagerService activityManagerService) { 1498 mActivityManagerService = activityManagerService; 1499 } 1500 1501 @Override 1502 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1503 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1504 != PackageManager.PERMISSION_GRANTED) { 1505 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1506 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1507 + " without permission " + android.Manifest.permission.DUMP); 1508 return; 1509 } 1510 1511 mActivityManagerService.dumpDbInfo(fd, pw, args); 1512 } 1513 } 1514 1515 static class CpuBinder extends Binder { 1516 ActivityManagerService mActivityManagerService; 1517 CpuBinder(ActivityManagerService activityManagerService) { 1518 mActivityManagerService = activityManagerService; 1519 } 1520 1521 @Override 1522 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1523 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1524 != PackageManager.PERMISSION_GRANTED) { 1525 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1526 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1527 + " without permission " + android.Manifest.permission.DUMP); 1528 return; 1529 } 1530 1531 synchronized (mActivityManagerService.mProcessStatsThread) { 1532 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1533 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1534 SystemClock.uptimeMillis())); 1535 } 1536 } 1537 } 1538 1539 private ActivityManagerService() { 1540 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1541 1542 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1543 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1544 mBroadcastQueues[0] = mFgBroadcastQueue; 1545 mBroadcastQueues[1] = mBgBroadcastQueue; 1546 1547 mServices = new ActiveServices(this); 1548 mProviderMap = new ProviderMap(this); 1549 1550 File dataDir = Environment.getDataDirectory(); 1551 File systemDir = new File(dataDir, "system"); 1552 systemDir.mkdirs(); 1553 mBatteryStatsService = new BatteryStatsService(new File( 1554 systemDir, "batterystats.bin").toString()); 1555 mBatteryStatsService.getActiveStatistics().readLocked(); 1556 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1557 mOnBattery = DEBUG_POWER ? true 1558 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1559 mBatteryStatsService.getActiveStatistics().setCallback(this); 1560 1561 mUsageStatsService = new UsageStatsService(new File( 1562 systemDir, "usagestats").toString()); 1563 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1564 1565 // User 0 is the first and only user that runs at boot. 1566 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1567 mUserLru.add(Integer.valueOf(0)); 1568 1569 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1570 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1571 1572 mConfiguration.setToDefaults(); 1573 mConfiguration.setLocale(Locale.getDefault()); 1574 1575 mConfigurationSeq = mConfiguration.seq = 1; 1576 mProcessStats.init(); 1577 1578 mCompatModePackages = new CompatModePackages(this, systemDir); 1579 1580 // Add ourself to the Watchdog monitors. 1581 Watchdog.getInstance().addMonitor(this); 1582 1583 mProcessStatsThread = new Thread("ProcessStats") { 1584 public void run() { 1585 while (true) { 1586 try { 1587 try { 1588 synchronized(this) { 1589 final long now = SystemClock.uptimeMillis(); 1590 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1591 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1592 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1593 // + ", write delay=" + nextWriteDelay); 1594 if (nextWriteDelay < nextCpuDelay) { 1595 nextCpuDelay = nextWriteDelay; 1596 } 1597 if (nextCpuDelay > 0) { 1598 mProcessStatsMutexFree.set(true); 1599 this.wait(nextCpuDelay); 1600 } 1601 } 1602 } catch (InterruptedException e) { 1603 } 1604 updateCpuStatsNow(); 1605 } catch (Exception e) { 1606 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1607 } 1608 } 1609 } 1610 }; 1611 mProcessStatsThread.start(); 1612 } 1613 1614 @Override 1615 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1616 throws RemoteException { 1617 if (code == SYSPROPS_TRANSACTION) { 1618 // We need to tell all apps about the system property change. 1619 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1620 synchronized(this) { 1621 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1622 final int NA = apps.size(); 1623 for (int ia=0; ia<NA; ia++) { 1624 ProcessRecord app = apps.valueAt(ia); 1625 if (app.thread != null) { 1626 procs.add(app.thread.asBinder()); 1627 } 1628 } 1629 } 1630 } 1631 1632 int N = procs.size(); 1633 for (int i=0; i<N; i++) { 1634 Parcel data2 = Parcel.obtain(); 1635 try { 1636 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1637 } catch (RemoteException e) { 1638 } 1639 data2.recycle(); 1640 } 1641 } 1642 try { 1643 return super.onTransact(code, data, reply, flags); 1644 } catch (RuntimeException e) { 1645 // The activity manager only throws security exceptions, so let's 1646 // log all others. 1647 if (!(e instanceof SecurityException)) { 1648 Slog.e(TAG, "Activity Manager Crash", e); 1649 } 1650 throw e; 1651 } 1652 } 1653 1654 void updateCpuStats() { 1655 final long now = SystemClock.uptimeMillis(); 1656 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1657 return; 1658 } 1659 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1660 synchronized (mProcessStatsThread) { 1661 mProcessStatsThread.notify(); 1662 } 1663 } 1664 } 1665 1666 void updateCpuStatsNow() { 1667 synchronized (mProcessStatsThread) { 1668 mProcessStatsMutexFree.set(false); 1669 final long now = SystemClock.uptimeMillis(); 1670 boolean haveNewCpuStats = false; 1671 1672 if (MONITOR_CPU_USAGE && 1673 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1674 mLastCpuTime.set(now); 1675 haveNewCpuStats = true; 1676 mProcessStats.update(); 1677 //Slog.i(TAG, mProcessStats.printCurrentState()); 1678 //Slog.i(TAG, "Total CPU usage: " 1679 // + mProcessStats.getTotalCpuPercent() + "%"); 1680 1681 // Slog the cpu usage if the property is set. 1682 if ("true".equals(SystemProperties.get("events.cpu"))) { 1683 int user = mProcessStats.getLastUserTime(); 1684 int system = mProcessStats.getLastSystemTime(); 1685 int iowait = mProcessStats.getLastIoWaitTime(); 1686 int irq = mProcessStats.getLastIrqTime(); 1687 int softIrq = mProcessStats.getLastSoftIrqTime(); 1688 int idle = mProcessStats.getLastIdleTime(); 1689 1690 int total = user + system + iowait + irq + softIrq + idle; 1691 if (total == 0) total = 1; 1692 1693 EventLog.writeEvent(EventLogTags.CPU, 1694 ((user+system+iowait+irq+softIrq) * 100) / total, 1695 (user * 100) / total, 1696 (system * 100) / total, 1697 (iowait * 100) / total, 1698 (irq * 100) / total, 1699 (softIrq * 100) / total); 1700 } 1701 } 1702 1703 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1704 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1705 synchronized(bstats) { 1706 synchronized(mPidsSelfLocked) { 1707 if (haveNewCpuStats) { 1708 if (mOnBattery) { 1709 int perc = bstats.startAddingCpuLocked(); 1710 int totalUTime = 0; 1711 int totalSTime = 0; 1712 final int N = mProcessStats.countStats(); 1713 for (int i=0; i<N; i++) { 1714 ProcessStats.Stats st = mProcessStats.getStats(i); 1715 if (!st.working) { 1716 continue; 1717 } 1718 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1719 int otherUTime = (st.rel_utime*perc)/100; 1720 int otherSTime = (st.rel_stime*perc)/100; 1721 totalUTime += otherUTime; 1722 totalSTime += otherSTime; 1723 if (pr != null) { 1724 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1725 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1726 st.rel_stime-otherSTime); 1727 ps.addSpeedStepTimes(cpuSpeedTimes); 1728 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1729 } else { 1730 BatteryStatsImpl.Uid.Proc ps = 1731 bstats.getProcessStatsLocked(st.name, st.pid); 1732 if (ps != null) { 1733 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1734 st.rel_stime-otherSTime); 1735 ps.addSpeedStepTimes(cpuSpeedTimes); 1736 } 1737 } 1738 } 1739 bstats.finishAddingCpuLocked(perc, totalUTime, 1740 totalSTime, cpuSpeedTimes); 1741 } 1742 } 1743 } 1744 1745 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1746 mLastWriteTime = now; 1747 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1748 } 1749 } 1750 } 1751 } 1752 1753 @Override 1754 public void batteryNeedsCpuUpdate() { 1755 updateCpuStatsNow(); 1756 } 1757 1758 @Override 1759 public void batteryPowerChanged(boolean onBattery) { 1760 // When plugging in, update the CPU stats first before changing 1761 // the plug state. 1762 updateCpuStatsNow(); 1763 synchronized (this) { 1764 synchronized(mPidsSelfLocked) { 1765 mOnBattery = DEBUG_POWER ? true : onBattery; 1766 } 1767 } 1768 } 1769 1770 /** 1771 * Initialize the application bind args. These are passed to each 1772 * process when the bindApplication() IPC is sent to the process. They're 1773 * lazily setup to make sure the services are running when they're asked for. 1774 */ 1775 private HashMap<String, IBinder> getCommonServicesLocked() { 1776 if (mAppBindArgs == null) { 1777 mAppBindArgs = new HashMap<String, IBinder>(); 1778 1779 // Setup the application init args 1780 mAppBindArgs.put("package", ServiceManager.getService("package")); 1781 mAppBindArgs.put("window", ServiceManager.getService("window")); 1782 mAppBindArgs.put(Context.ALARM_SERVICE, 1783 ServiceManager.getService(Context.ALARM_SERVICE)); 1784 } 1785 return mAppBindArgs; 1786 } 1787 1788 final void setFocusedActivityLocked(ActivityRecord r) { 1789 if (mFocusedActivity != r) { 1790 mFocusedActivity = r; 1791 if (r != null) { 1792 mWindowManager.setFocusedApp(r.appToken, true); 1793 } 1794 } 1795 } 1796 1797 private final void updateLruProcessInternalLocked(ProcessRecord app, 1798 boolean updateActivityTime, int bestPos) { 1799 // put it on the LRU to keep track of when it should be exited. 1800 int lrui = mLruProcesses.indexOf(app); 1801 if (lrui >= 0) mLruProcesses.remove(lrui); 1802 1803 int i = mLruProcesses.size()-1; 1804 int skipTop = 0; 1805 1806 app.lruSeq = mLruSeq; 1807 1808 // compute the new weight for this process. 1809 if (updateActivityTime) { 1810 app.lastActivityTime = SystemClock.uptimeMillis(); 1811 } 1812 if (app.activities.size() > 0) { 1813 // If this process has activities, we more strongly want to keep 1814 // it around. 1815 app.lruWeight = app.lastActivityTime; 1816 } else if (app.pubProviders.size() > 0) { 1817 // If this process contains content providers, we want to keep 1818 // it a little more strongly. 1819 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1820 // Also don't let it kick out the first few "real" hidden processes. 1821 skipTop = ProcessList.MIN_HIDDEN_APPS; 1822 } else { 1823 // If this process doesn't have activities, we less strongly 1824 // want to keep it around, and generally want to avoid getting 1825 // in front of any very recently used activities. 1826 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1827 // Also don't let it kick out the first few "real" hidden processes. 1828 skipTop = ProcessList.MIN_HIDDEN_APPS; 1829 } 1830 1831 while (i >= 0) { 1832 ProcessRecord p = mLruProcesses.get(i); 1833 // If this app shouldn't be in front of the first N background 1834 // apps, then skip over that many that are currently hidden. 1835 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1836 skipTop--; 1837 } 1838 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1839 mLruProcesses.add(i+1, app); 1840 break; 1841 } 1842 i--; 1843 } 1844 if (i < 0) { 1845 mLruProcesses.add(0, app); 1846 } 1847 1848 // If the app is currently using a content provider or service, 1849 // bump those processes as well. 1850 if (app.connections.size() > 0) { 1851 for (ConnectionRecord cr : app.connections) { 1852 if (cr.binding != null && cr.binding.service != null 1853 && cr.binding.service.app != null 1854 && cr.binding.service.app.lruSeq != mLruSeq) { 1855 updateLruProcessInternalLocked(cr.binding.service.app, 1856 updateActivityTime, i+1); 1857 } 1858 } 1859 } 1860 for (int j=app.conProviders.size()-1; j>=0; j--) { 1861 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1862 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1863 updateLruProcessInternalLocked(cpr.proc, 1864 updateActivityTime, i+1); 1865 } 1866 } 1867 } 1868 1869 final void updateLruProcessLocked(ProcessRecord app, 1870 boolean oomAdj, boolean updateActivityTime) { 1871 mLruSeq++; 1872 updateLruProcessInternalLocked(app, updateActivityTime, 0); 1873 1874 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1875 if (oomAdj) { 1876 updateOomAdjLocked(); 1877 } 1878 } 1879 1880 final ProcessRecord getProcessRecordLocked( 1881 String processName, int uid) { 1882 if (uid == Process.SYSTEM_UID) { 1883 // The system gets to run in any process. If there are multiple 1884 // processes with the same uid, just pick the first (this 1885 // should never happen). 1886 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1887 processName); 1888 if (procs == null) return null; 1889 final int N = procs.size(); 1890 for (int i = 0; i < N; i++) { 1891 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1892 } 1893 } 1894 ProcessRecord proc = mProcessNames.get(processName, uid); 1895 return proc; 1896 } 1897 1898 void ensurePackageDexOpt(String packageName) { 1899 IPackageManager pm = AppGlobals.getPackageManager(); 1900 try { 1901 if (pm.performDexOpt(packageName)) { 1902 mDidDexOpt = true; 1903 } 1904 } catch (RemoteException e) { 1905 } 1906 } 1907 1908 boolean isNextTransitionForward() { 1909 int transit = mWindowManager.getPendingAppTransition(); 1910 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1911 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1912 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1913 } 1914 1915 final ProcessRecord startProcessLocked(String processName, 1916 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1917 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1918 boolean isolated) { 1919 ProcessRecord app; 1920 if (!isolated) { 1921 app = getProcessRecordLocked(processName, info.uid); 1922 } else { 1923 // If this is an isolated process, it can't re-use an existing process. 1924 app = null; 1925 } 1926 // We don't have to do anything more if: 1927 // (1) There is an existing application record; and 1928 // (2) The caller doesn't think it is dead, OR there is no thread 1929 // object attached to it so we know it couldn't have crashed; and 1930 // (3) There is a pid assigned to it, so it is either starting or 1931 // already running. 1932 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1933 + " app=" + app + " knownToBeDead=" + knownToBeDead 1934 + " thread=" + (app != null ? app.thread : null) 1935 + " pid=" + (app != null ? app.pid : -1)); 1936 if (app != null && app.pid > 0) { 1937 if (!knownToBeDead || app.thread == null) { 1938 // We already have the app running, or are waiting for it to 1939 // come up (we have a pid but not yet its thread), so keep it. 1940 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1941 // If this is a new package in the process, add the package to the list 1942 app.addPackage(info.packageName); 1943 return app; 1944 } else { 1945 // An application record is attached to a previous process, 1946 // clean it up now. 1947 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1948 handleAppDiedLocked(app, true, true); 1949 } 1950 } 1951 1952 String hostingNameStr = hostingName != null 1953 ? hostingName.flattenToShortString() : null; 1954 1955 if (!isolated) { 1956 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1957 // If we are in the background, then check to see if this process 1958 // is bad. If so, we will just silently fail. 1959 if (mBadProcesses.get(info.processName, info.uid) != null) { 1960 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1961 + "/" + info.processName); 1962 return null; 1963 } 1964 } else { 1965 // When the user is explicitly starting a process, then clear its 1966 // crash count so that we won't make it bad until they see at 1967 // least one crash dialog again, and make the process good again 1968 // if it had been bad. 1969 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1970 + "/" + info.processName); 1971 mProcessCrashTimes.remove(info.processName, info.uid); 1972 if (mBadProcesses.get(info.processName, info.uid) != null) { 1973 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1974 info.processName); 1975 mBadProcesses.remove(info.processName, info.uid); 1976 if (app != null) { 1977 app.bad = false; 1978 } 1979 } 1980 } 1981 } 1982 1983 if (app == null) { 1984 app = newProcessRecordLocked(null, info, processName, isolated); 1985 if (app == null) { 1986 Slog.w(TAG, "Failed making new process record for " 1987 + processName + "/" + info.uid + " isolated=" + isolated); 1988 return null; 1989 } 1990 mProcessNames.put(processName, app.uid, app); 1991 if (isolated) { 1992 mIsolatedProcesses.put(app.uid, app); 1993 } 1994 } else { 1995 // If this is a new package in the process, add the package to the list 1996 app.addPackage(info.packageName); 1997 } 1998 1999 // If the system is not ready yet, then hold off on starting this 2000 // process until it is. 2001 if (!mProcessesReady 2002 && !isAllowedWhileBooting(info) 2003 && !allowWhileBooting) { 2004 if (!mProcessesOnHold.contains(app)) { 2005 mProcessesOnHold.add(app); 2006 } 2007 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2008 return app; 2009 } 2010 2011 startProcessLocked(app, hostingType, hostingNameStr); 2012 return (app.pid != 0) ? app : null; 2013 } 2014 2015 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2016 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2017 } 2018 2019 private final void startProcessLocked(ProcessRecord app, 2020 String hostingType, String hostingNameStr) { 2021 if (app.pid > 0 && app.pid != MY_PID) { 2022 synchronized (mPidsSelfLocked) { 2023 mPidsSelfLocked.remove(app.pid); 2024 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2025 } 2026 app.setPid(0); 2027 } 2028 2029 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2030 "startProcessLocked removing on hold: " + app); 2031 mProcessesOnHold.remove(app); 2032 2033 updateCpuStats(); 2034 2035 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2036 mProcDeaths[0] = 0; 2037 2038 try { 2039 int uid = app.uid; 2040 2041 int[] gids = null; 2042 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2043 if (!app.isolated) { 2044 int[] permGids = null; 2045 try { 2046 final PackageManager pm = mContext.getPackageManager(); 2047 permGids = pm.getPackageGids(app.info.packageName); 2048 2049 if (Environment.isExternalStorageEmulated()) { 2050 if (pm.checkPermission( 2051 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2052 app.info.packageName) == PERMISSION_GRANTED) { 2053 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2054 } else { 2055 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2056 } 2057 } 2058 } catch (PackageManager.NameNotFoundException e) { 2059 Slog.w(TAG, "Unable to retrieve gids", e); 2060 } 2061 2062 /* 2063 * Add shared application GID so applications can share some 2064 * resources like shared libraries 2065 */ 2066 if (permGids == null) { 2067 gids = new int[1]; 2068 } else { 2069 gids = new int[permGids.length + 1]; 2070 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2071 } 2072 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2073 } 2074 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2075 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2076 && mTopComponent != null 2077 && app.processName.equals(mTopComponent.getPackageName())) { 2078 uid = 0; 2079 } 2080 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2081 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2082 uid = 0; 2083 } 2084 } 2085 int debugFlags = 0; 2086 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2087 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2088 // Also turn on CheckJNI for debuggable apps. It's quite 2089 // awkward to turn on otherwise. 2090 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2091 } 2092 // Run the app in safe mode if its manifest requests so or the 2093 // system is booted in safe mode. 2094 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2095 Zygote.systemInSafeMode == true) { 2096 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2097 } 2098 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2099 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2100 } 2101 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2102 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2103 } 2104 if ("1".equals(SystemProperties.get("debug.assert"))) { 2105 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2106 } 2107 2108 // Start the process. It will either succeed and return a result containing 2109 // the PID of the new process, or else throw a RuntimeException. 2110 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2111 app.processName, uid, uid, gids, debugFlags, mountExternal, 2112 app.info.targetSdkVersion, null, null); 2113 2114 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2115 synchronized (bs) { 2116 if (bs.isOnBattery()) { 2117 app.batteryStats.incStartsLocked(); 2118 } 2119 } 2120 2121 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2122 app.processName, hostingType, 2123 hostingNameStr != null ? hostingNameStr : ""); 2124 2125 if (app.persistent) { 2126 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2127 } 2128 2129 StringBuilder buf = mStringBuilder; 2130 buf.setLength(0); 2131 buf.append("Start proc "); 2132 buf.append(app.processName); 2133 buf.append(" for "); 2134 buf.append(hostingType); 2135 if (hostingNameStr != null) { 2136 buf.append(" "); 2137 buf.append(hostingNameStr); 2138 } 2139 buf.append(": pid="); 2140 buf.append(startResult.pid); 2141 buf.append(" uid="); 2142 buf.append(uid); 2143 buf.append(" gids={"); 2144 if (gids != null) { 2145 for (int gi=0; gi<gids.length; gi++) { 2146 if (gi != 0) buf.append(", "); 2147 buf.append(gids[gi]); 2148 2149 } 2150 } 2151 buf.append("}"); 2152 Slog.i(TAG, buf.toString()); 2153 app.setPid(startResult.pid); 2154 app.usingWrapper = startResult.usingWrapper; 2155 app.removed = false; 2156 synchronized (mPidsSelfLocked) { 2157 this.mPidsSelfLocked.put(startResult.pid, app); 2158 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2159 msg.obj = app; 2160 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2161 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2162 } 2163 } catch (RuntimeException e) { 2164 // XXX do better error recovery. 2165 app.setPid(0); 2166 Slog.e(TAG, "Failure starting process " + app.processName, e); 2167 } 2168 } 2169 2170 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2171 if (resumed) { 2172 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2173 } else { 2174 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2175 } 2176 } 2177 2178 boolean startHomeActivityLocked(int userId) { 2179 if (mHeadless) { 2180 // Added because none of the other calls to ensureBootCompleted seem to fire 2181 // when running headless. 2182 ensureBootCompleted(); 2183 return false; 2184 } 2185 2186 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2187 && mTopAction == null) { 2188 // We are running in factory test mode, but unable to find 2189 // the factory test app, so just sit around displaying the 2190 // error message and don't try to start anything. 2191 return false; 2192 } 2193 Intent intent = new Intent( 2194 mTopAction, 2195 mTopData != null ? Uri.parse(mTopData) : null); 2196 intent.setComponent(mTopComponent); 2197 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2198 intent.addCategory(Intent.CATEGORY_HOME); 2199 } 2200 ActivityInfo aInfo = 2201 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2202 if (aInfo != null) { 2203 intent.setComponent(new ComponentName( 2204 aInfo.applicationInfo.packageName, aInfo.name)); 2205 // Don't do this if the home app is currently being 2206 // instrumented. 2207 aInfo = new ActivityInfo(aInfo); 2208 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2209 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2210 aInfo.applicationInfo.uid); 2211 if (app == null || app.instrumentationClass == null) { 2212 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2213 mMainStack.startActivityLocked(null, intent, null, aInfo, 2214 null, null, 0, 0, 0, 0, null, false, null); 2215 } 2216 } 2217 2218 return true; 2219 } 2220 2221 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2222 ActivityInfo ai = null; 2223 ComponentName comp = intent.getComponent(); 2224 try { 2225 if (comp != null) { 2226 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2227 } else { 2228 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2229 intent, 2230 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2231 flags, userId); 2232 2233 if (info != null) { 2234 ai = info.activityInfo; 2235 } 2236 } 2237 } catch (RemoteException e) { 2238 // ignore 2239 } 2240 2241 return ai; 2242 } 2243 2244 /** 2245 * Starts the "new version setup screen" if appropriate. 2246 */ 2247 void startSetupActivityLocked() { 2248 // Only do this once per boot. 2249 if (mCheckedForSetup) { 2250 return; 2251 } 2252 2253 // We will show this screen if the current one is a different 2254 // version than the last one shown, and we are not running in 2255 // low-level factory test mode. 2256 final ContentResolver resolver = mContext.getContentResolver(); 2257 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2258 Settings.Secure.getInt(resolver, 2259 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2260 mCheckedForSetup = true; 2261 2262 // See if we should be showing the platform update setup UI. 2263 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2264 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2265 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2266 2267 // We don't allow third party apps to replace this. 2268 ResolveInfo ri = null; 2269 for (int i=0; ris != null && i<ris.size(); i++) { 2270 if ((ris.get(i).activityInfo.applicationInfo.flags 2271 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2272 ri = ris.get(i); 2273 break; 2274 } 2275 } 2276 2277 if (ri != null) { 2278 String vers = ri.activityInfo.metaData != null 2279 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2280 : null; 2281 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2282 vers = ri.activityInfo.applicationInfo.metaData.getString( 2283 Intent.METADATA_SETUP_VERSION); 2284 } 2285 String lastVers = Settings.Secure.getString( 2286 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2287 if (vers != null && !vers.equals(lastVers)) { 2288 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2289 intent.setComponent(new ComponentName( 2290 ri.activityInfo.packageName, ri.activityInfo.name)); 2291 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2292 null, null, 0, 0, 0, 0, null, false, null); 2293 } 2294 } 2295 } 2296 } 2297 2298 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2299 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2300 } 2301 2302 void enforceNotIsolatedCaller(String caller) { 2303 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2304 throw new SecurityException("Isolated process not allowed to call " + caller); 2305 } 2306 } 2307 2308 public int getFrontActivityScreenCompatMode() { 2309 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2310 synchronized (this) { 2311 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2312 } 2313 } 2314 2315 public void setFrontActivityScreenCompatMode(int mode) { 2316 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2317 "setFrontActivityScreenCompatMode"); 2318 synchronized (this) { 2319 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2320 } 2321 } 2322 2323 public int getPackageScreenCompatMode(String packageName) { 2324 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2325 synchronized (this) { 2326 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2327 } 2328 } 2329 2330 public void setPackageScreenCompatMode(String packageName, int mode) { 2331 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2332 "setPackageScreenCompatMode"); 2333 synchronized (this) { 2334 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2335 } 2336 } 2337 2338 public boolean getPackageAskScreenCompat(String packageName) { 2339 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2340 synchronized (this) { 2341 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2342 } 2343 } 2344 2345 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2346 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2347 "setPackageAskScreenCompat"); 2348 synchronized (this) { 2349 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2350 } 2351 } 2352 2353 void reportResumedActivityLocked(ActivityRecord r) { 2354 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2355 updateUsageStats(r, true); 2356 } 2357 2358 private void dispatchProcessesChanged() { 2359 int N; 2360 synchronized (this) { 2361 N = mPendingProcessChanges.size(); 2362 if (mActiveProcessChanges.length < N) { 2363 mActiveProcessChanges = new ProcessChangeItem[N]; 2364 } 2365 mPendingProcessChanges.toArray(mActiveProcessChanges); 2366 mAvailProcessChanges.addAll(mPendingProcessChanges); 2367 mPendingProcessChanges.clear(); 2368 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2369 } 2370 int i = mProcessObservers.beginBroadcast(); 2371 while (i > 0) { 2372 i--; 2373 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2374 if (observer != null) { 2375 try { 2376 for (int j=0; j<N; j++) { 2377 ProcessChangeItem item = mActiveProcessChanges[j]; 2378 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2379 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2380 + item.pid + " uid=" + item.uid + ": " 2381 + item.foregroundActivities); 2382 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2383 item.foregroundActivities); 2384 } 2385 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2386 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2387 + item.pid + " uid=" + item.uid + ": " + item.importance); 2388 observer.onImportanceChanged(item.pid, item.uid, 2389 item.importance); 2390 } 2391 } 2392 } catch (RemoteException e) { 2393 } 2394 } 2395 } 2396 mProcessObservers.finishBroadcast(); 2397 } 2398 2399 private void dispatchProcessDied(int pid, int uid) { 2400 int i = mProcessObservers.beginBroadcast(); 2401 while (i > 0) { 2402 i--; 2403 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2404 if (observer != null) { 2405 try { 2406 observer.onProcessDied(pid, uid); 2407 } catch (RemoteException e) { 2408 } 2409 } 2410 } 2411 mProcessObservers.finishBroadcast(); 2412 } 2413 2414 final void doPendingActivityLaunchesLocked(boolean doResume) { 2415 final int N = mPendingActivityLaunches.size(); 2416 if (N <= 0) { 2417 return; 2418 } 2419 for (int i=0; i<N; i++) { 2420 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2421 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2422 pal.startFlags, doResume && i == (N-1), null); 2423 } 2424 mPendingActivityLaunches.clear(); 2425 } 2426 2427 public final int startActivity(IApplicationThread caller, 2428 Intent intent, String resolvedType, IBinder resultTo, 2429 String resultWho, int requestCode, int startFlags, 2430 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2431 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2432 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2433 } 2434 2435 public final int startActivityAsUser(IApplicationThread caller, 2436 Intent intent, String resolvedType, IBinder resultTo, 2437 String resultWho, int requestCode, int startFlags, 2438 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2439 enforceNotIsolatedCaller("startActivity"); 2440 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2441 false, true, "startActivity", null); 2442 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2443 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2444 null, null, options, userId); 2445 } 2446 2447 public final WaitResult startActivityAndWait(IApplicationThread caller, 2448 Intent intent, String resolvedType, IBinder resultTo, 2449 String resultWho, int requestCode, int startFlags, String profileFile, 2450 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2451 enforceNotIsolatedCaller("startActivityAndWait"); 2452 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2453 false, true, "startActivityAndWait", null); 2454 WaitResult res = new WaitResult(); 2455 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2456 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2457 res, null, options, UserHandle.getCallingUserId()); 2458 return res; 2459 } 2460 2461 public final int startActivityWithConfig(IApplicationThread caller, 2462 Intent intent, String resolvedType, IBinder resultTo, 2463 String resultWho, int requestCode, int startFlags, Configuration config, 2464 Bundle options, int userId) { 2465 enforceNotIsolatedCaller("startActivityWithConfig"); 2466 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2467 false, true, "startActivityWithConfig", null); 2468 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2469 resultTo, resultWho, requestCode, startFlags, 2470 null, null, null, config, options, userId); 2471 return ret; 2472 } 2473 2474 public int startActivityIntentSender(IApplicationThread caller, 2475 IntentSender intent, Intent fillInIntent, String resolvedType, 2476 IBinder resultTo, String resultWho, int requestCode, 2477 int flagsMask, int flagsValues, Bundle options) { 2478 enforceNotIsolatedCaller("startActivityIntentSender"); 2479 // Refuse possible leaked file descriptors 2480 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2481 throw new IllegalArgumentException("File descriptors passed in Intent"); 2482 } 2483 2484 IIntentSender sender = intent.getTarget(); 2485 if (!(sender instanceof PendingIntentRecord)) { 2486 throw new IllegalArgumentException("Bad PendingIntent object"); 2487 } 2488 2489 PendingIntentRecord pir = (PendingIntentRecord)sender; 2490 2491 synchronized (this) { 2492 // If this is coming from the currently resumed activity, it is 2493 // effectively saying that app switches are allowed at this point. 2494 if (mMainStack.mResumedActivity != null 2495 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2496 Binder.getCallingUid()) { 2497 mAppSwitchesAllowedTime = 0; 2498 } 2499 } 2500 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2501 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2502 return ret; 2503 } 2504 2505 public boolean startNextMatchingActivity(IBinder callingActivity, 2506 Intent intent, Bundle options) { 2507 // Refuse possible leaked file descriptors 2508 if (intent != null && intent.hasFileDescriptors() == true) { 2509 throw new IllegalArgumentException("File descriptors passed in Intent"); 2510 } 2511 2512 synchronized (this) { 2513 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2514 if (r == null) { 2515 ActivityOptions.abort(options); 2516 return false; 2517 } 2518 if (r.app == null || r.app.thread == null) { 2519 // The caller is not running... d'oh! 2520 ActivityOptions.abort(options); 2521 return false; 2522 } 2523 intent = new Intent(intent); 2524 // The caller is not allowed to change the data. 2525 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2526 // And we are resetting to find the next component... 2527 intent.setComponent(null); 2528 2529 ActivityInfo aInfo = null; 2530 try { 2531 List<ResolveInfo> resolves = 2532 AppGlobals.getPackageManager().queryIntentActivities( 2533 intent, r.resolvedType, 2534 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2535 UserHandle.getCallingUserId()); 2536 2537 // Look for the original activity in the list... 2538 final int N = resolves != null ? resolves.size() : 0; 2539 for (int i=0; i<N; i++) { 2540 ResolveInfo rInfo = resolves.get(i); 2541 if (rInfo.activityInfo.packageName.equals(r.packageName) 2542 && rInfo.activityInfo.name.equals(r.info.name)) { 2543 // We found the current one... the next matching is 2544 // after it. 2545 i++; 2546 if (i<N) { 2547 aInfo = resolves.get(i).activityInfo; 2548 } 2549 break; 2550 } 2551 } 2552 } catch (RemoteException e) { 2553 } 2554 2555 if (aInfo == null) { 2556 // Nobody who is next! 2557 ActivityOptions.abort(options); 2558 return false; 2559 } 2560 2561 intent.setComponent(new ComponentName( 2562 aInfo.applicationInfo.packageName, aInfo.name)); 2563 intent.setFlags(intent.getFlags()&~( 2564 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2565 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2566 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2567 Intent.FLAG_ACTIVITY_NEW_TASK)); 2568 2569 // Okay now we need to start the new activity, replacing the 2570 // currently running activity. This is a little tricky because 2571 // we want to start the new one as if the current one is finished, 2572 // but not finish the current one first so that there is no flicker. 2573 // And thus... 2574 final boolean wasFinishing = r.finishing; 2575 r.finishing = true; 2576 2577 // Propagate reply information over to the new activity. 2578 final ActivityRecord resultTo = r.resultTo; 2579 final String resultWho = r.resultWho; 2580 final int requestCode = r.requestCode; 2581 r.resultTo = null; 2582 if (resultTo != null) { 2583 resultTo.removeResultsLocked(r, resultWho, requestCode); 2584 } 2585 2586 final long origId = Binder.clearCallingIdentity(); 2587 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2588 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2589 resultWho, requestCode, -1, r.launchedFromUid, 0, 2590 options, false, null); 2591 Binder.restoreCallingIdentity(origId); 2592 2593 r.finishing = wasFinishing; 2594 if (res != ActivityManager.START_SUCCESS) { 2595 return false; 2596 } 2597 return true; 2598 } 2599 } 2600 2601 final int startActivityInPackage(int uid, 2602 Intent intent, String resolvedType, IBinder resultTo, 2603 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2604 2605 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2606 false, true, "startActivityInPackage", null); 2607 2608 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2609 resultTo, resultWho, requestCode, startFlags, 2610 null, null, null, null, options, userId); 2611 return ret; 2612 } 2613 2614 public final int startActivities(IApplicationThread caller, 2615 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2616 enforceNotIsolatedCaller("startActivities"); 2617 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2618 options, UserHandle.getCallingUserId()); 2619 return ret; 2620 } 2621 2622 final int startActivitiesInPackage(int uid, 2623 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2624 Bundle options, int userId) { 2625 2626 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2627 false, true, "startActivityInPackage", null); 2628 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2629 options, userId); 2630 return ret; 2631 } 2632 2633 final void addRecentTaskLocked(TaskRecord task) { 2634 int N = mRecentTasks.size(); 2635 // Quick case: check if the top-most recent task is the same. 2636 if (N > 0 && mRecentTasks.get(0) == task) { 2637 return; 2638 } 2639 // Remove any existing entries that are the same kind of task. 2640 for (int i=0; i<N; i++) { 2641 TaskRecord tr = mRecentTasks.get(i); 2642 if (task.userId == tr.userId 2643 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2644 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2645 mRecentTasks.remove(i); 2646 i--; 2647 N--; 2648 if (task.intent == null) { 2649 // If the new recent task we are adding is not fully 2650 // specified, then replace it with the existing recent task. 2651 task = tr; 2652 } 2653 } 2654 } 2655 if (N >= MAX_RECENT_TASKS) { 2656 mRecentTasks.remove(N-1); 2657 } 2658 mRecentTasks.add(0, task); 2659 } 2660 2661 public void setRequestedOrientation(IBinder token, 2662 int requestedOrientation) { 2663 synchronized (this) { 2664 ActivityRecord r = mMainStack.isInStackLocked(token); 2665 if (r == null) { 2666 return; 2667 } 2668 final long origId = Binder.clearCallingIdentity(); 2669 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2670 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2671 mConfiguration, 2672 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2673 if (config != null) { 2674 r.frozenBeforeDestroy = true; 2675 if (!updateConfigurationLocked(config, r, false, false)) { 2676 mMainStack.resumeTopActivityLocked(null); 2677 } 2678 } 2679 Binder.restoreCallingIdentity(origId); 2680 } 2681 } 2682 2683 public int getRequestedOrientation(IBinder token) { 2684 synchronized (this) { 2685 ActivityRecord r = mMainStack.isInStackLocked(token); 2686 if (r == null) { 2687 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2688 } 2689 return mWindowManager.getAppOrientation(r.appToken); 2690 } 2691 } 2692 2693 /** 2694 * This is the internal entry point for handling Activity.finish(). 2695 * 2696 * @param token The Binder token referencing the Activity we want to finish. 2697 * @param resultCode Result code, if any, from this Activity. 2698 * @param resultData Result data (Intent), if any, from this Activity. 2699 * 2700 * @return Returns true if the activity successfully finished, or false if it is still running. 2701 */ 2702 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2703 // Refuse possible leaked file descriptors 2704 if (resultData != null && resultData.hasFileDescriptors() == true) { 2705 throw new IllegalArgumentException("File descriptors passed in Intent"); 2706 } 2707 2708 synchronized(this) { 2709 if (mController != null) { 2710 // Find the first activity that is not finishing. 2711 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2712 if (next != null) { 2713 // ask watcher if this is allowed 2714 boolean resumeOK = true; 2715 try { 2716 resumeOK = mController.activityResuming(next.packageName); 2717 } catch (RemoteException e) { 2718 mController = null; 2719 } 2720 2721 if (!resumeOK) { 2722 return false; 2723 } 2724 } 2725 } 2726 final long origId = Binder.clearCallingIdentity(); 2727 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2728 resultData, "app-request", true); 2729 Binder.restoreCallingIdentity(origId); 2730 return res; 2731 } 2732 } 2733 2734 public final void finishHeavyWeightApp() { 2735 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2736 != PackageManager.PERMISSION_GRANTED) { 2737 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2738 + Binder.getCallingPid() 2739 + ", uid=" + Binder.getCallingUid() 2740 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2741 Slog.w(TAG, msg); 2742 throw new SecurityException(msg); 2743 } 2744 2745 synchronized(this) { 2746 if (mHeavyWeightProcess == null) { 2747 return; 2748 } 2749 2750 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2751 mHeavyWeightProcess.activities); 2752 for (int i=0; i<activities.size(); i++) { 2753 ActivityRecord r = activities.get(i); 2754 if (!r.finishing) { 2755 int index = mMainStack.indexOfTokenLocked(r.appToken); 2756 if (index >= 0) { 2757 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2758 null, "finish-heavy", true); 2759 } 2760 } 2761 } 2762 2763 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2764 mHeavyWeightProcess.userId, 0)); 2765 mHeavyWeightProcess = null; 2766 } 2767 } 2768 2769 public void crashApplication(int uid, int initialPid, String packageName, 2770 String message) { 2771 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2772 != PackageManager.PERMISSION_GRANTED) { 2773 String msg = "Permission Denial: crashApplication() from pid=" 2774 + Binder.getCallingPid() 2775 + ", uid=" + Binder.getCallingUid() 2776 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2777 Slog.w(TAG, msg); 2778 throw new SecurityException(msg); 2779 } 2780 2781 synchronized(this) { 2782 ProcessRecord proc = null; 2783 2784 // Figure out which process to kill. We don't trust that initialPid 2785 // still has any relation to current pids, so must scan through the 2786 // list. 2787 synchronized (mPidsSelfLocked) { 2788 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2789 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2790 if (p.uid != uid) { 2791 continue; 2792 } 2793 if (p.pid == initialPid) { 2794 proc = p; 2795 break; 2796 } 2797 for (String str : p.pkgList) { 2798 if (str.equals(packageName)) { 2799 proc = p; 2800 } 2801 } 2802 } 2803 } 2804 2805 if (proc == null) { 2806 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2807 + " initialPid=" + initialPid 2808 + " packageName=" + packageName); 2809 return; 2810 } 2811 2812 if (proc.thread != null) { 2813 if (proc.pid == Process.myPid()) { 2814 Log.w(TAG, "crashApplication: trying to crash self!"); 2815 return; 2816 } 2817 long ident = Binder.clearCallingIdentity(); 2818 try { 2819 proc.thread.scheduleCrash(message); 2820 } catch (RemoteException e) { 2821 } 2822 Binder.restoreCallingIdentity(ident); 2823 } 2824 } 2825 } 2826 2827 public final void finishSubActivity(IBinder token, String resultWho, 2828 int requestCode) { 2829 synchronized(this) { 2830 final long origId = Binder.clearCallingIdentity(); 2831 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2832 Binder.restoreCallingIdentity(origId); 2833 } 2834 } 2835 2836 public boolean finishActivityAffinity(IBinder token) { 2837 synchronized(this) { 2838 final long origId = Binder.clearCallingIdentity(); 2839 boolean res = mMainStack.finishActivityAffinityLocked(token); 2840 Binder.restoreCallingIdentity(origId); 2841 return res; 2842 } 2843 } 2844 2845 public boolean willActivityBeVisible(IBinder token) { 2846 synchronized(this) { 2847 int i; 2848 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2849 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2850 if (r.appToken == token) { 2851 return true; 2852 } 2853 if (r.fullscreen && !r.finishing) { 2854 return false; 2855 } 2856 } 2857 return true; 2858 } 2859 } 2860 2861 public void overridePendingTransition(IBinder token, String packageName, 2862 int enterAnim, int exitAnim) { 2863 synchronized(this) { 2864 ActivityRecord self = mMainStack.isInStackLocked(token); 2865 if (self == null) { 2866 return; 2867 } 2868 2869 final long origId = Binder.clearCallingIdentity(); 2870 2871 if (self.state == ActivityState.RESUMED 2872 || self.state == ActivityState.PAUSING) { 2873 mWindowManager.overridePendingAppTransition(packageName, 2874 enterAnim, exitAnim, null); 2875 } 2876 2877 Binder.restoreCallingIdentity(origId); 2878 } 2879 } 2880 2881 /** 2882 * Main function for removing an existing process from the activity manager 2883 * as a result of that process going away. Clears out all connections 2884 * to the process. 2885 */ 2886 private final void handleAppDiedLocked(ProcessRecord app, 2887 boolean restarting, boolean allowRestart) { 2888 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2889 if (!restarting) { 2890 mLruProcesses.remove(app); 2891 } 2892 2893 if (mProfileProc == app) { 2894 clearProfilerLocked(); 2895 } 2896 2897 // Just in case... 2898 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2899 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2900 mMainStack.mPausingActivity = null; 2901 } 2902 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2903 mMainStack.mLastPausedActivity = null; 2904 } 2905 2906 // Remove this application's activities from active lists. 2907 mMainStack.removeHistoryRecordsForAppLocked(app); 2908 2909 boolean atTop = true; 2910 boolean hasVisibleActivities = false; 2911 2912 // Clean out the history list. 2913 int i = mMainStack.mHistory.size(); 2914 if (localLOGV) Slog.v( 2915 TAG, "Removing app " + app + " from history with " + i + " entries"); 2916 while (i > 0) { 2917 i--; 2918 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2919 if (localLOGV) Slog.v( 2920 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2921 if (r.app == app) { 2922 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2923 if (ActivityStack.DEBUG_ADD_REMOVE) { 2924 RuntimeException here = new RuntimeException("here"); 2925 here.fillInStackTrace(); 2926 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2927 + ": haveState=" + r.haveState 2928 + " stateNotNeeded=" + r.stateNotNeeded 2929 + " finishing=" + r.finishing 2930 + " state=" + r.state, here); 2931 } 2932 if (!r.finishing) { 2933 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2934 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2935 System.identityHashCode(r), 2936 r.task.taskId, r.shortComponentName, 2937 "proc died without state saved"); 2938 } 2939 mMainStack.removeActivityFromHistoryLocked(r); 2940 2941 } else { 2942 // We have the current state for this activity, so 2943 // it can be restarted later when needed. 2944 if (localLOGV) Slog.v( 2945 TAG, "Keeping entry, setting app to null"); 2946 if (r.visible) { 2947 hasVisibleActivities = true; 2948 } 2949 r.app = null; 2950 r.nowVisible = false; 2951 if (!r.haveState) { 2952 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2953 "App died, clearing saved state of " + r); 2954 r.icicle = null; 2955 } 2956 } 2957 2958 r.stack.cleanUpActivityLocked(r, true, true); 2959 } 2960 atTop = false; 2961 } 2962 2963 app.activities.clear(); 2964 2965 if (app.instrumentationClass != null) { 2966 Slog.w(TAG, "Crash of app " + app.processName 2967 + " running instrumentation " + app.instrumentationClass); 2968 Bundle info = new Bundle(); 2969 info.putString("shortMsg", "Process crashed."); 2970 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2971 } 2972 2973 if (!restarting) { 2974 if (!mMainStack.resumeTopActivityLocked(null)) { 2975 // If there was nothing to resume, and we are not already 2976 // restarting this process, but there is a visible activity that 2977 // is hosted by the process... then make sure all visible 2978 // activities are running, taking care of restarting this 2979 // process. 2980 if (hasVisibleActivities) { 2981 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2982 } 2983 } 2984 } 2985 } 2986 2987 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2988 IBinder threadBinder = thread.asBinder(); 2989 // Find the application record. 2990 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2991 ProcessRecord rec = mLruProcesses.get(i); 2992 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2993 return i; 2994 } 2995 } 2996 return -1; 2997 } 2998 2999 final ProcessRecord getRecordForAppLocked( 3000 IApplicationThread thread) { 3001 if (thread == null) { 3002 return null; 3003 } 3004 3005 int appIndex = getLRURecordIndexForAppLocked(thread); 3006 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3007 } 3008 3009 final void appDiedLocked(ProcessRecord app, int pid, 3010 IApplicationThread thread) { 3011 3012 mProcDeaths[0]++; 3013 3014 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3015 synchronized (stats) { 3016 stats.noteProcessDiedLocked(app.info.uid, pid); 3017 } 3018 3019 // Clean up already done if the process has been re-started. 3020 if (app.pid == pid && app.thread != null && 3021 app.thread.asBinder() == thread.asBinder()) { 3022 if (!app.killedBackground) { 3023 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3024 + ") has died."); 3025 } 3026 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3027 if (localLOGV) Slog.v( 3028 TAG, "Dying app: " + app + ", pid: " + pid 3029 + ", thread: " + thread.asBinder()); 3030 boolean doLowMem = app.instrumentationClass == null; 3031 handleAppDiedLocked(app, false, true); 3032 3033 if (doLowMem) { 3034 // If there are no longer any background processes running, 3035 // and the app that died was not running instrumentation, 3036 // then tell everyone we are now low on memory. 3037 boolean haveBg = false; 3038 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3039 ProcessRecord rec = mLruProcesses.get(i); 3040 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3041 haveBg = true; 3042 break; 3043 } 3044 } 3045 3046 if (!haveBg) { 3047 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3048 long now = SystemClock.uptimeMillis(); 3049 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3050 ProcessRecord rec = mLruProcesses.get(i); 3051 if (rec != app && rec.thread != null && 3052 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3053 // The low memory report is overriding any current 3054 // state for a GC request. Make sure to do 3055 // heavy/important/visible/foreground processes first. 3056 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3057 rec.lastRequestedGc = 0; 3058 } else { 3059 rec.lastRequestedGc = rec.lastLowMemory; 3060 } 3061 rec.reportLowMemory = true; 3062 rec.lastLowMemory = now; 3063 mProcessesToGc.remove(rec); 3064 addProcessToGcListLocked(rec); 3065 } 3066 } 3067 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3068 scheduleAppGcsLocked(); 3069 } 3070 } 3071 } else if (app.pid != pid) { 3072 // A new process has already been started. 3073 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3074 + ") has died and restarted (pid " + app.pid + ")."); 3075 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3076 } else if (DEBUG_PROCESSES) { 3077 Slog.d(TAG, "Received spurious death notification for thread " 3078 + thread.asBinder()); 3079 } 3080 } 3081 3082 /** 3083 * If a stack trace dump file is configured, dump process stack traces. 3084 * @param clearTraces causes the dump file to be erased prior to the new 3085 * traces being written, if true; when false, the new traces will be 3086 * appended to any existing file content. 3087 * @param firstPids of dalvik VM processes to dump stack traces for first 3088 * @param lastPids of dalvik VM processes to dump stack traces for last 3089 * @param nativeProcs optional list of native process names to dump stack crawls 3090 * @return file containing stack traces, or null if no dump file is configured 3091 */ 3092 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3093 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3094 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3095 if (tracesPath == null || tracesPath.length() == 0) { 3096 return null; 3097 } 3098 3099 File tracesFile = new File(tracesPath); 3100 try { 3101 File tracesDir = tracesFile.getParentFile(); 3102 if (!tracesDir.exists()) { 3103 tracesFile.mkdirs(); 3104 if (!SELinux.restorecon(tracesDir)) { 3105 return null; 3106 } 3107 } 3108 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3109 3110 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3111 tracesFile.createNewFile(); 3112 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3113 } catch (IOException e) { 3114 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3115 return null; 3116 } 3117 3118 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3119 return tracesFile; 3120 } 3121 3122 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3123 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3124 // Use a FileObserver to detect when traces finish writing. 3125 // The order of traces is considered important to maintain for legibility. 3126 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3127 public synchronized void onEvent(int event, String path) { notify(); } 3128 }; 3129 3130 try { 3131 observer.startWatching(); 3132 3133 // First collect all of the stacks of the most important pids. 3134 if (firstPids != null) { 3135 try { 3136 int num = firstPids.size(); 3137 for (int i = 0; i < num; i++) { 3138 synchronized (observer) { 3139 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3140 observer.wait(200); // Wait for write-close, give up after 200msec 3141 } 3142 } 3143 } catch (InterruptedException e) { 3144 Log.wtf(TAG, e); 3145 } 3146 } 3147 3148 // Next measure CPU usage. 3149 if (processStats != null) { 3150 processStats.init(); 3151 System.gc(); 3152 processStats.update(); 3153 try { 3154 synchronized (processStats) { 3155 processStats.wait(500); // measure over 1/2 second. 3156 } 3157 } catch (InterruptedException e) { 3158 } 3159 processStats.update(); 3160 3161 // We'll take the stack crawls of just the top apps using CPU. 3162 final int N = processStats.countWorkingStats(); 3163 int numProcs = 0; 3164 for (int i=0; i<N && numProcs<5; i++) { 3165 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3166 if (lastPids.indexOfKey(stats.pid) >= 0) { 3167 numProcs++; 3168 try { 3169 synchronized (observer) { 3170 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3171 observer.wait(200); // Wait for write-close, give up after 200msec 3172 } 3173 } catch (InterruptedException e) { 3174 Log.wtf(TAG, e); 3175 } 3176 3177 } 3178 } 3179 } 3180 3181 } finally { 3182 observer.stopWatching(); 3183 } 3184 3185 if (nativeProcs != null) { 3186 int[] pids = Process.getPidsForCommands(nativeProcs); 3187 if (pids != null) { 3188 for (int pid : pids) { 3189 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3190 } 3191 } 3192 } 3193 } 3194 3195 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3196 if (true || IS_USER_BUILD) { 3197 return; 3198 } 3199 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3200 if (tracesPath == null || tracesPath.length() == 0) { 3201 return; 3202 } 3203 3204 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3205 StrictMode.allowThreadDiskWrites(); 3206 try { 3207 final File tracesFile = new File(tracesPath); 3208 final File tracesDir = tracesFile.getParentFile(); 3209 final File tracesTmp = new File(tracesDir, "__tmp__"); 3210 try { 3211 if (!tracesDir.exists()) { 3212 tracesFile.mkdirs(); 3213 if (!SELinux.restorecon(tracesDir.getPath())) { 3214 return; 3215 } 3216 } 3217 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3218 3219 if (tracesFile.exists()) { 3220 tracesTmp.delete(); 3221 tracesFile.renameTo(tracesTmp); 3222 } 3223 StringBuilder sb = new StringBuilder(); 3224 Time tobj = new Time(); 3225 tobj.set(System.currentTimeMillis()); 3226 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3227 sb.append(": "); 3228 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3229 sb.append(" since "); 3230 sb.append(msg); 3231 FileOutputStream fos = new FileOutputStream(tracesFile); 3232 fos.write(sb.toString().getBytes()); 3233 if (app == null) { 3234 fos.write("\n*** No application process!".getBytes()); 3235 } 3236 fos.close(); 3237 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3238 } catch (IOException e) { 3239 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3240 return; 3241 } 3242 3243 if (app != null) { 3244 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3245 firstPids.add(app.pid); 3246 dumpStackTraces(tracesPath, firstPids, null, null, null); 3247 } 3248 3249 File lastTracesFile = null; 3250 File curTracesFile = null; 3251 for (int i=9; i>=0; i--) { 3252 String name = String.format("slow%02d.txt", i); 3253 curTracesFile = new File(tracesDir, name); 3254 if (curTracesFile.exists()) { 3255 if (lastTracesFile != null) { 3256 curTracesFile.renameTo(lastTracesFile); 3257 } else { 3258 curTracesFile.delete(); 3259 } 3260 } 3261 lastTracesFile = curTracesFile; 3262 } 3263 tracesFile.renameTo(curTracesFile); 3264 if (tracesTmp.exists()) { 3265 tracesTmp.renameTo(tracesFile); 3266 } 3267 } finally { 3268 StrictMode.setThreadPolicy(oldPolicy); 3269 } 3270 } 3271 3272 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3273 ActivityRecord parent, final String annotation) { 3274 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3275 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3276 3277 if (mController != null) { 3278 try { 3279 // 0 == continue, -1 = kill process immediately 3280 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3281 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3282 } catch (RemoteException e) { 3283 mController = null; 3284 } 3285 } 3286 3287 long anrTime = SystemClock.uptimeMillis(); 3288 if (MONITOR_CPU_USAGE) { 3289 updateCpuStatsNow(); 3290 } 3291 3292 synchronized (this) { 3293 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3294 if (mShuttingDown) { 3295 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3296 return; 3297 } else if (app.notResponding) { 3298 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3299 return; 3300 } else if (app.crashing) { 3301 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3302 return; 3303 } 3304 3305 // In case we come through here for the same app before completing 3306 // this one, mark as anring now so we will bail out. 3307 app.notResponding = true; 3308 3309 // Log the ANR to the event log. 3310 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3311 annotation); 3312 3313 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3314 firstPids.add(app.pid); 3315 3316 int parentPid = app.pid; 3317 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3318 if (parentPid != app.pid) firstPids.add(parentPid); 3319 3320 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3321 3322 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3323 ProcessRecord r = mLruProcesses.get(i); 3324 if (r != null && r.thread != null) { 3325 int pid = r.pid; 3326 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3327 if (r.persistent) { 3328 firstPids.add(pid); 3329 } else { 3330 lastPids.put(pid, Boolean.TRUE); 3331 } 3332 } 3333 } 3334 } 3335 } 3336 3337 // Log the ANR to the main log. 3338 StringBuilder info = new StringBuilder(); 3339 info.setLength(0); 3340 info.append("ANR in ").append(app.processName); 3341 if (activity != null && activity.shortComponentName != null) { 3342 info.append(" (").append(activity.shortComponentName).append(")"); 3343 } 3344 info.append("\n"); 3345 if (annotation != null) { 3346 info.append("Reason: ").append(annotation).append("\n"); 3347 } 3348 if (parent != null && parent != activity) { 3349 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3350 } 3351 3352 final ProcessStats processStats = new ProcessStats(true); 3353 3354 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3355 3356 String cpuInfo = null; 3357 if (MONITOR_CPU_USAGE) { 3358 updateCpuStatsNow(); 3359 synchronized (mProcessStatsThread) { 3360 cpuInfo = mProcessStats.printCurrentState(anrTime); 3361 } 3362 info.append(processStats.printCurrentLoad()); 3363 info.append(cpuInfo); 3364 } 3365 3366 info.append(processStats.printCurrentState(anrTime)); 3367 3368 Slog.e(TAG, info.toString()); 3369 if (tracesFile == null) { 3370 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3371 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3372 } 3373 3374 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3375 cpuInfo, tracesFile, null); 3376 3377 if (mController != null) { 3378 try { 3379 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3380 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3381 if (res != 0) { 3382 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3383 return; 3384 } 3385 } catch (RemoteException e) { 3386 mController = null; 3387 } 3388 } 3389 3390 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3391 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3392 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3393 3394 synchronized (this) { 3395 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3396 Slog.w(TAG, "Killing " + app + ": background ANR"); 3397 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3398 app.processName, app.setAdj, "background ANR"); 3399 Process.killProcessQuiet(app.pid); 3400 return; 3401 } 3402 3403 // Set the app's notResponding state, and look up the errorReportReceiver 3404 makeAppNotRespondingLocked(app, 3405 activity != null ? activity.shortComponentName : null, 3406 annotation != null ? "ANR " + annotation : "ANR", 3407 info.toString()); 3408 3409 // Bring up the infamous App Not Responding dialog 3410 Message msg = Message.obtain(); 3411 HashMap map = new HashMap(); 3412 msg.what = SHOW_NOT_RESPONDING_MSG; 3413 msg.obj = map; 3414 map.put("app", app); 3415 if (activity != null) { 3416 map.put("activity", activity); 3417 } 3418 3419 mHandler.sendMessage(msg); 3420 } 3421 } 3422 3423 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3424 if (!mLaunchWarningShown) { 3425 mLaunchWarningShown = true; 3426 mHandler.post(new Runnable() { 3427 @Override 3428 public void run() { 3429 synchronized (ActivityManagerService.this) { 3430 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3431 d.show(); 3432 mHandler.postDelayed(new Runnable() { 3433 @Override 3434 public void run() { 3435 synchronized (ActivityManagerService.this) { 3436 d.dismiss(); 3437 mLaunchWarningShown = false; 3438 } 3439 } 3440 }, 4000); 3441 } 3442 } 3443 }); 3444 } 3445 } 3446 3447 public boolean clearApplicationUserData(final String packageName, 3448 final IPackageDataObserver observer, int userId) { 3449 enforceNotIsolatedCaller("clearApplicationUserData"); 3450 int uid = Binder.getCallingUid(); 3451 int pid = Binder.getCallingPid(); 3452 userId = handleIncomingUserLocked(pid, uid, 3453 userId, false, true, "clearApplicationUserData", null); 3454 long callingId = Binder.clearCallingIdentity(); 3455 try { 3456 IPackageManager pm = AppGlobals.getPackageManager(); 3457 int pkgUid = -1; 3458 synchronized(this) { 3459 try { 3460 pkgUid = pm.getPackageUid(packageName, userId); 3461 } catch (RemoteException e) { 3462 } 3463 if (pkgUid == -1) { 3464 Slog.w(TAG, "Invalid packageName:" + packageName); 3465 return false; 3466 } 3467 if (uid == pkgUid || checkComponentPermission( 3468 android.Manifest.permission.CLEAR_APP_USER_DATA, 3469 pid, uid, -1, true) 3470 == PackageManager.PERMISSION_GRANTED) { 3471 forceStopPackageLocked(packageName, pkgUid); 3472 } else { 3473 throw new SecurityException(pid+" does not have permission:"+ 3474 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3475 "for process:"+packageName); 3476 } 3477 } 3478 3479 try { 3480 //clear application user data 3481 pm.clearApplicationUserData(packageName, observer, userId); 3482 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3483 Uri.fromParts("package", packageName, null)); 3484 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3485 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3486 null, null, 0, null, null, null, false, false, userId); 3487 } catch (RemoteException e) { 3488 } 3489 } finally { 3490 Binder.restoreCallingIdentity(callingId); 3491 } 3492 return true; 3493 } 3494 3495 public void killBackgroundProcesses(final String packageName, int userId) { 3496 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3497 != PackageManager.PERMISSION_GRANTED && 3498 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3499 != PackageManager.PERMISSION_GRANTED) { 3500 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3501 + Binder.getCallingPid() 3502 + ", uid=" + Binder.getCallingUid() 3503 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3504 Slog.w(TAG, msg); 3505 throw new SecurityException(msg); 3506 } 3507 3508 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3509 userId, true, true, "killBackgroundProcesses", null); 3510 long callingId = Binder.clearCallingIdentity(); 3511 try { 3512 IPackageManager pm = AppGlobals.getPackageManager(); 3513 synchronized(this) { 3514 int appId = -1; 3515 try { 3516 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3517 } catch (RemoteException e) { 3518 } 3519 if (appId == -1) { 3520 Slog.w(TAG, "Invalid packageName: " + packageName); 3521 return; 3522 } 3523 killPackageProcessesLocked(packageName, appId, userId, 3524 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3525 } 3526 } finally { 3527 Binder.restoreCallingIdentity(callingId); 3528 } 3529 } 3530 3531 public void killAllBackgroundProcesses() { 3532 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3533 != PackageManager.PERMISSION_GRANTED) { 3534 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3535 + Binder.getCallingPid() 3536 + ", uid=" + Binder.getCallingUid() 3537 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3538 Slog.w(TAG, msg); 3539 throw new SecurityException(msg); 3540 } 3541 3542 long callingId = Binder.clearCallingIdentity(); 3543 try { 3544 synchronized(this) { 3545 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3546 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3547 final int NA = apps.size(); 3548 for (int ia=0; ia<NA; ia++) { 3549 ProcessRecord app = apps.valueAt(ia); 3550 if (app.persistent) { 3551 // we don't kill persistent processes 3552 continue; 3553 } 3554 if (app.removed) { 3555 procs.add(app); 3556 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3557 app.removed = true; 3558 procs.add(app); 3559 } 3560 } 3561 } 3562 3563 int N = procs.size(); 3564 for (int i=0; i<N; i++) { 3565 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3566 } 3567 } 3568 } finally { 3569 Binder.restoreCallingIdentity(callingId); 3570 } 3571 } 3572 3573 public void forceStopPackage(final String packageName, int userId) { 3574 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3575 != PackageManager.PERMISSION_GRANTED) { 3576 String msg = "Permission Denial: forceStopPackage() from pid=" 3577 + Binder.getCallingPid() 3578 + ", uid=" + Binder.getCallingUid() 3579 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3580 Slog.w(TAG, msg); 3581 throw new SecurityException(msg); 3582 } 3583 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3584 userId, true, true, "forceStopPackage", null); 3585 long callingId = Binder.clearCallingIdentity(); 3586 try { 3587 IPackageManager pm = AppGlobals.getPackageManager(); 3588 synchronized(this) { 3589 int[] users = userId == UserHandle.USER_ALL 3590 ? getUsersLocked() : new int[] { userId }; 3591 for (int user : users) { 3592 int pkgUid = -1; 3593 try { 3594 pkgUid = pm.getPackageUid(packageName, user); 3595 } catch (RemoteException e) { 3596 } 3597 if (pkgUid == -1) { 3598 Slog.w(TAG, "Invalid packageName: " + packageName); 3599 continue; 3600 } 3601 try { 3602 pm.setPackageStoppedState(packageName, true, user); 3603 } catch (RemoteException e) { 3604 } catch (IllegalArgumentException e) { 3605 Slog.w(TAG, "Failed trying to unstop package " 3606 + packageName + ": " + e); 3607 } 3608 if (isUserRunningLocked(user)) { 3609 forceStopPackageLocked(packageName, pkgUid); 3610 } 3611 } 3612 } 3613 } finally { 3614 Binder.restoreCallingIdentity(callingId); 3615 } 3616 } 3617 3618 /* 3619 * The pkg name and app id have to be specified. 3620 */ 3621 public void killApplicationWithAppId(String pkg, int appid) { 3622 if (pkg == null) { 3623 return; 3624 } 3625 // Make sure the uid is valid. 3626 if (appid < 0) { 3627 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3628 return; 3629 } 3630 int callerUid = Binder.getCallingUid(); 3631 // Only the system server can kill an application 3632 if (callerUid == Process.SYSTEM_UID) { 3633 // Post an aysnc message to kill the application 3634 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3635 msg.arg1 = appid; 3636 msg.arg2 = 0; 3637 msg.obj = pkg; 3638 mHandler.sendMessage(msg); 3639 } else { 3640 throw new SecurityException(callerUid + " cannot kill pkg: " + 3641 pkg); 3642 } 3643 } 3644 3645 public void closeSystemDialogs(String reason) { 3646 enforceNotIsolatedCaller("closeSystemDialogs"); 3647 3648 final int pid = Binder.getCallingPid(); 3649 final int uid = Binder.getCallingUid(); 3650 final long origId = Binder.clearCallingIdentity(); 3651 try { 3652 synchronized (this) { 3653 // Only allow this from foreground processes, so that background 3654 // applications can't abuse it to prevent system UI from being shown. 3655 if (uid >= Process.FIRST_APPLICATION_UID) { 3656 ProcessRecord proc; 3657 synchronized (mPidsSelfLocked) { 3658 proc = mPidsSelfLocked.get(pid); 3659 } 3660 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3661 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3662 + " from background process " + proc); 3663 return; 3664 } 3665 } 3666 closeSystemDialogsLocked(reason); 3667 } 3668 } finally { 3669 Binder.restoreCallingIdentity(origId); 3670 } 3671 } 3672 3673 void closeSystemDialogsLocked(String reason) { 3674 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3675 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3676 if (reason != null) { 3677 intent.putExtra("reason", reason); 3678 } 3679 mWindowManager.closeSystemDialogs(reason); 3680 3681 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3682 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3683 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3684 r.stack.finishActivityLocked(r, i, 3685 Activity.RESULT_CANCELED, null, "close-sys", true); 3686 } 3687 } 3688 3689 broadcastIntentLocked(null, null, intent, null, 3690 null, 0, null, null, null, false, false, -1, 3691 Process.SYSTEM_UID, UserHandle.USER_ALL); 3692 } 3693 3694 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3695 throws RemoteException { 3696 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3697 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3698 for (int i=pids.length-1; i>=0; i--) { 3699 infos[i] = new Debug.MemoryInfo(); 3700 Debug.getMemoryInfo(pids[i], infos[i]); 3701 } 3702 return infos; 3703 } 3704 3705 public long[] getProcessPss(int[] pids) throws RemoteException { 3706 enforceNotIsolatedCaller("getProcessPss"); 3707 long[] pss = new long[pids.length]; 3708 for (int i=pids.length-1; i>=0; i--) { 3709 pss[i] = Debug.getPss(pids[i]); 3710 } 3711 return pss; 3712 } 3713 3714 public void killApplicationProcess(String processName, int uid) { 3715 if (processName == null) { 3716 return; 3717 } 3718 3719 int callerUid = Binder.getCallingUid(); 3720 // Only the system server can kill an application 3721 if (callerUid == Process.SYSTEM_UID) { 3722 synchronized (this) { 3723 ProcessRecord app = getProcessRecordLocked(processName, uid); 3724 if (app != null && app.thread != null) { 3725 try { 3726 app.thread.scheduleSuicide(); 3727 } catch (RemoteException e) { 3728 // If the other end already died, then our work here is done. 3729 } 3730 } else { 3731 Slog.w(TAG, "Process/uid not found attempting kill of " 3732 + processName + " / " + uid); 3733 } 3734 } 3735 } else { 3736 throw new SecurityException(callerUid + " cannot kill app process: " + 3737 processName); 3738 } 3739 } 3740 3741 private void forceStopPackageLocked(final String packageName, int uid) { 3742 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3743 false, true, false, UserHandle.getUserId(uid)); 3744 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3745 Uri.fromParts("package", packageName, null)); 3746 if (!mProcessesReady) { 3747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3748 } 3749 intent.putExtra(Intent.EXTRA_UID, uid); 3750 broadcastIntentLocked(null, null, intent, 3751 null, null, 0, null, null, null, 3752 false, false, 3753 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3754 } 3755 3756 private void forceStopUserLocked(int userId) { 3757 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3758 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3759 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3760 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3761 broadcastIntentLocked(null, null, intent, 3762 null, null, 0, null, null, null, 3763 false, false, 3764 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3765 } 3766 3767 private final boolean killPackageProcessesLocked(String packageName, int appId, 3768 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3769 boolean doit, boolean evenPersistent, String reason) { 3770 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3771 3772 // Remove all processes this package may have touched: all with the 3773 // same UID (except for the system or root user), and all whose name 3774 // matches the package name. 3775 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3776 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3777 final int NA = apps.size(); 3778 for (int ia=0; ia<NA; ia++) { 3779 ProcessRecord app = apps.valueAt(ia); 3780 if (app.persistent && !evenPersistent) { 3781 // we don't kill persistent processes 3782 continue; 3783 } 3784 if (app.removed) { 3785 if (doit) { 3786 procs.add(app); 3787 } 3788 continue; 3789 } 3790 3791 // Skip process if it doesn't meet our oom adj requirement. 3792 if (app.setAdj < minOomAdj) { 3793 continue; 3794 } 3795 3796 // If no package is specified, we call all processes under the 3797 // give user id. 3798 if (packageName == null) { 3799 if (app.userId != userId) { 3800 continue; 3801 } 3802 // Package has been specified, we want to hit all processes 3803 // that match it. We need to qualify this by the processes 3804 // that are running under the specified app and user ID. 3805 } else { 3806 if (UserHandle.getAppId(app.uid) != appId) { 3807 continue; 3808 } 3809 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3810 continue; 3811 } 3812 if (!app.pkgList.contains(packageName)) { 3813 continue; 3814 } 3815 } 3816 3817 // Process has passed all conditions, kill it! 3818 if (!doit) { 3819 return true; 3820 } 3821 app.removed = true; 3822 procs.add(app); 3823 } 3824 } 3825 3826 int N = procs.size(); 3827 for (int i=0; i<N; i++) { 3828 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3829 } 3830 return N > 0; 3831 } 3832 3833 private final boolean forceStopPackageLocked(String name, int appId, 3834 boolean callerWillRestart, boolean purgeCache, boolean doit, 3835 boolean evenPersistent, int userId) { 3836 int i; 3837 int N; 3838 3839 if (userId == UserHandle.USER_ALL && name == null) { 3840 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3841 } 3842 3843 if (appId < 0 && name != null) { 3844 try { 3845 appId = UserHandle.getAppId( 3846 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3847 } catch (RemoteException e) { 3848 } 3849 } 3850 3851 if (doit) { 3852 if (name != null) { 3853 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3854 + " user=" + userId); 3855 } else { 3856 Slog.i(TAG, "Force stopping user " + userId); 3857 } 3858 3859 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3860 while (badApps.hasNext()) { 3861 SparseArray<Long> ba = badApps.next(); 3862 for (i=ba.size()-1; i>=0; i--) { 3863 boolean remove = false; 3864 final int entUid = ba.keyAt(i); 3865 if (name != null) { 3866 if (userId == UserHandle.USER_ALL) { 3867 if (UserHandle.getAppId(entUid) == appId) { 3868 remove = true; 3869 } 3870 } else { 3871 if (entUid == UserHandle.getUid(userId, appId)) { 3872 remove = true; 3873 } 3874 } 3875 } else if (UserHandle.getUserId(entUid) == userId) { 3876 remove = true; 3877 } 3878 if (remove) { 3879 ba.removeAt(i); 3880 } 3881 } 3882 if (ba.size() == 0) { 3883 badApps.remove(); 3884 } 3885 } 3886 } 3887 3888 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3889 -100, callerWillRestart, false, doit, evenPersistent, 3890 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3891 3892 TaskRecord lastTask = null; 3893 for (i=0; i<mMainStack.mHistory.size(); i++) { 3894 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3895 final boolean samePackage = r.packageName.equals(name) 3896 || (name == null && r.userId == userId); 3897 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3898 && (samePackage || r.task == lastTask) 3899 && (r.app == null || evenPersistent || !r.app.persistent)) { 3900 if (!doit) { 3901 if (r.finishing) { 3902 // If this activity is just finishing, then it is not 3903 // interesting as far as something to stop. 3904 continue; 3905 } 3906 return true; 3907 } 3908 didSomething = true; 3909 Slog.i(TAG, " Force finishing activity " + r); 3910 if (samePackage) { 3911 if (r.app != null) { 3912 r.app.removed = true; 3913 } 3914 r.app = null; 3915 } 3916 lastTask = r.task; 3917 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3918 null, "force-stop", true)) { 3919 i--; 3920 } 3921 } 3922 } 3923 3924 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3925 if (!doit) { 3926 return true; 3927 } 3928 didSomething = true; 3929 } 3930 3931 if (name == null) { 3932 // Remove all sticky broadcasts from this user. 3933 mStickyBroadcasts.remove(userId); 3934 } 3935 3936 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3937 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3938 userId, providers)) { 3939 if (!doit) { 3940 return true; 3941 } 3942 didSomething = true; 3943 } 3944 N = providers.size(); 3945 for (i=0; i<N; i++) { 3946 removeDyingProviderLocked(null, providers.get(i), true); 3947 } 3948 3949 if (mIntentSenderRecords.size() > 0) { 3950 Iterator<WeakReference<PendingIntentRecord>> it 3951 = mIntentSenderRecords.values().iterator(); 3952 while (it.hasNext()) { 3953 WeakReference<PendingIntentRecord> wpir = it.next(); 3954 if (wpir == null) { 3955 it.remove(); 3956 continue; 3957 } 3958 PendingIntentRecord pir = wpir.get(); 3959 if (pir == null) { 3960 it.remove(); 3961 continue; 3962 } 3963 if (name == null) { 3964 // Stopping user, remove all objects for the user. 3965 if (pir.key.userId != userId) { 3966 // Not the same user, skip it. 3967 continue; 3968 } 3969 } else { 3970 if (UserHandle.getAppId(pir.uid) != appId) { 3971 // Different app id, skip it. 3972 continue; 3973 } 3974 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3975 // Different user, skip it. 3976 continue; 3977 } 3978 if (!pir.key.packageName.equals(name)) { 3979 // Different package, skip it. 3980 continue; 3981 } 3982 } 3983 if (!doit) { 3984 return true; 3985 } 3986 didSomething = true; 3987 it.remove(); 3988 pir.canceled = true; 3989 if (pir.key.activity != null) { 3990 pir.key.activity.pendingResults.remove(pir.ref); 3991 } 3992 } 3993 } 3994 3995 if (doit) { 3996 if (purgeCache && name != null) { 3997 AttributeCache ac = AttributeCache.instance(); 3998 if (ac != null) { 3999 ac.removePackage(name); 4000 } 4001 } 4002 if (mBooted) { 4003 mMainStack.resumeTopActivityLocked(null); 4004 mMainStack.scheduleIdleLocked(); 4005 } 4006 } 4007 4008 return didSomething; 4009 } 4010 4011 private final boolean removeProcessLocked(ProcessRecord app, 4012 boolean callerWillRestart, boolean allowRestart, String reason) { 4013 final String name = app.processName; 4014 final int uid = app.uid; 4015 if (DEBUG_PROCESSES) Slog.d( 4016 TAG, "Force removing proc " + app.toShortString() + " (" + name 4017 + "/" + uid + ")"); 4018 4019 mProcessNames.remove(name, uid); 4020 mIsolatedProcesses.remove(app.uid); 4021 if (mHeavyWeightProcess == app) { 4022 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4023 mHeavyWeightProcess.userId, 0)); 4024 mHeavyWeightProcess = null; 4025 } 4026 boolean needRestart = false; 4027 if (app.pid > 0 && app.pid != MY_PID) { 4028 int pid = app.pid; 4029 synchronized (mPidsSelfLocked) { 4030 mPidsSelfLocked.remove(pid); 4031 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4032 } 4033 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4034 handleAppDiedLocked(app, true, allowRestart); 4035 mLruProcesses.remove(app); 4036 Process.killProcessQuiet(pid); 4037 4038 if (app.persistent && !app.isolated) { 4039 if (!callerWillRestart) { 4040 addAppLocked(app.info, false); 4041 } else { 4042 needRestart = true; 4043 } 4044 } 4045 } else { 4046 mRemovedProcesses.add(app); 4047 } 4048 4049 return needRestart; 4050 } 4051 4052 private final void processStartTimedOutLocked(ProcessRecord app) { 4053 final int pid = app.pid; 4054 boolean gone = false; 4055 synchronized (mPidsSelfLocked) { 4056 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4057 if (knownApp != null && knownApp.thread == null) { 4058 mPidsSelfLocked.remove(pid); 4059 gone = true; 4060 } 4061 } 4062 4063 if (gone) { 4064 Slog.w(TAG, "Process " + app + " failed to attach"); 4065 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4066 app.processName); 4067 mProcessNames.remove(app.processName, app.uid); 4068 mIsolatedProcesses.remove(app.uid); 4069 if (mHeavyWeightProcess == app) { 4070 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4071 mHeavyWeightProcess.userId, 0)); 4072 mHeavyWeightProcess = null; 4073 } 4074 // Take care of any launching providers waiting for this process. 4075 checkAppInLaunchingProvidersLocked(app, true); 4076 // Take care of any services that are waiting for the process. 4077 mServices.processStartTimedOutLocked(app); 4078 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4079 app.processName, app.setAdj, "start timeout"); 4080 Process.killProcessQuiet(pid); 4081 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4082 Slog.w(TAG, "Unattached app died before backup, skipping"); 4083 try { 4084 IBackupManager bm = IBackupManager.Stub.asInterface( 4085 ServiceManager.getService(Context.BACKUP_SERVICE)); 4086 bm.agentDisconnected(app.info.packageName); 4087 } catch (RemoteException e) { 4088 // Can't happen; the backup manager is local 4089 } 4090 } 4091 if (isPendingBroadcastProcessLocked(pid)) { 4092 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4093 skipPendingBroadcastLocked(pid); 4094 } 4095 } else { 4096 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4097 } 4098 } 4099 4100 private final boolean attachApplicationLocked(IApplicationThread thread, 4101 int pid) { 4102 4103 // Find the application record that is being attached... either via 4104 // the pid if we are running in multiple processes, or just pull the 4105 // next app record if we are emulating process with anonymous threads. 4106 ProcessRecord app; 4107 if (pid != MY_PID && pid >= 0) { 4108 synchronized (mPidsSelfLocked) { 4109 app = mPidsSelfLocked.get(pid); 4110 } 4111 } else { 4112 app = null; 4113 } 4114 4115 if (app == null) { 4116 Slog.w(TAG, "No pending application record for pid " + pid 4117 + " (IApplicationThread " + thread + "); dropping process"); 4118 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4119 if (pid > 0 && pid != MY_PID) { 4120 Process.killProcessQuiet(pid); 4121 } else { 4122 try { 4123 thread.scheduleExit(); 4124 } catch (Exception e) { 4125 // Ignore exceptions. 4126 } 4127 } 4128 return false; 4129 } 4130 4131 // If this application record is still attached to a previous 4132 // process, clean it up now. 4133 if (app.thread != null) { 4134 handleAppDiedLocked(app, true, true); 4135 } 4136 4137 // Tell the process all about itself. 4138 4139 if (localLOGV) Slog.v( 4140 TAG, "Binding process pid " + pid + " to record " + app); 4141 4142 String processName = app.processName; 4143 try { 4144 AppDeathRecipient adr = new AppDeathRecipient( 4145 app, pid, thread); 4146 thread.asBinder().linkToDeath(adr, 0); 4147 app.deathRecipient = adr; 4148 } catch (RemoteException e) { 4149 app.resetPackageList(); 4150 startProcessLocked(app, "link fail", processName); 4151 return false; 4152 } 4153 4154 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4155 4156 app.thread = thread; 4157 app.curAdj = app.setAdj = -100; 4158 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4159 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4160 app.forcingToForeground = null; 4161 app.foregroundServices = false; 4162 app.hasShownUi = false; 4163 app.debugging = false; 4164 4165 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4166 4167 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4168 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4169 4170 if (!normalMode) { 4171 Slog.i(TAG, "Launching preboot mode app: " + app); 4172 } 4173 4174 if (localLOGV) Slog.v( 4175 TAG, "New app record " + app 4176 + " thread=" + thread.asBinder() + " pid=" + pid); 4177 try { 4178 int testMode = IApplicationThread.DEBUG_OFF; 4179 if (mDebugApp != null && mDebugApp.equals(processName)) { 4180 testMode = mWaitForDebugger 4181 ? IApplicationThread.DEBUG_WAIT 4182 : IApplicationThread.DEBUG_ON; 4183 app.debugging = true; 4184 if (mDebugTransient) { 4185 mDebugApp = mOrigDebugApp; 4186 mWaitForDebugger = mOrigWaitForDebugger; 4187 } 4188 } 4189 String profileFile = app.instrumentationProfileFile; 4190 ParcelFileDescriptor profileFd = null; 4191 boolean profileAutoStop = false; 4192 if (mProfileApp != null && mProfileApp.equals(processName)) { 4193 mProfileProc = app; 4194 profileFile = mProfileFile; 4195 profileFd = mProfileFd; 4196 profileAutoStop = mAutoStopProfiler; 4197 } 4198 boolean enableOpenGlTrace = false; 4199 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4200 enableOpenGlTrace = true; 4201 mOpenGlTraceApp = null; 4202 } 4203 4204 // If the app is being launched for restore or full backup, set it up specially 4205 boolean isRestrictedBackupMode = false; 4206 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4207 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4208 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4209 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4210 } 4211 4212 ensurePackageDexOpt(app.instrumentationInfo != null 4213 ? app.instrumentationInfo.packageName 4214 : app.info.packageName); 4215 if (app.instrumentationClass != null) { 4216 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4217 } 4218 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4219 + processName + " with config " + mConfiguration); 4220 ApplicationInfo appInfo = app.instrumentationInfo != null 4221 ? app.instrumentationInfo : app.info; 4222 app.compat = compatibilityInfoForPackageLocked(appInfo); 4223 if (profileFd != null) { 4224 profileFd = profileFd.dup(); 4225 } 4226 thread.bindApplication(processName, appInfo, providers, 4227 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4228 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4229 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4230 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4231 mCoreSettingsObserver.getCoreSettingsLocked()); 4232 updateLruProcessLocked(app, false, true); 4233 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4234 } catch (Exception e) { 4235 // todo: Yikes! What should we do? For now we will try to 4236 // start another process, but that could easily get us in 4237 // an infinite loop of restarting processes... 4238 Slog.w(TAG, "Exception thrown during bind!", e); 4239 4240 app.resetPackageList(); 4241 app.unlinkDeathRecipient(); 4242 startProcessLocked(app, "bind fail", processName); 4243 return false; 4244 } 4245 4246 // Remove this record from the list of starting applications. 4247 mPersistentStartingProcesses.remove(app); 4248 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4249 "Attach application locked removing on hold: " + app); 4250 mProcessesOnHold.remove(app); 4251 4252 boolean badApp = false; 4253 boolean didSomething = false; 4254 4255 // See if the top visible activity is waiting to run in this process... 4256 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4257 if (hr != null && normalMode) { 4258 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4259 && processName.equals(hr.processName)) { 4260 try { 4261 if (mHeadless) { 4262 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4263 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4264 didSomething = true; 4265 } 4266 } catch (Exception e) { 4267 Slog.w(TAG, "Exception in new application when starting activity " 4268 + hr.intent.getComponent().flattenToShortString(), e); 4269 badApp = true; 4270 } 4271 } else { 4272 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4273 } 4274 } 4275 4276 // Find any services that should be running in this process... 4277 if (!badApp) { 4278 try { 4279 didSomething |= mServices.attachApplicationLocked(app, processName); 4280 } catch (Exception e) { 4281 badApp = true; 4282 } 4283 } 4284 4285 // Check if a next-broadcast receiver is in this process... 4286 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4287 try { 4288 didSomething = sendPendingBroadcastsLocked(app); 4289 } catch (Exception e) { 4290 // If the app died trying to launch the receiver we declare it 'bad' 4291 badApp = true; 4292 } 4293 } 4294 4295 // Check whether the next backup agent is in this process... 4296 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4297 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4298 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4299 try { 4300 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4301 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4302 mBackupTarget.backupMode); 4303 } catch (Exception e) { 4304 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4305 e.printStackTrace(); 4306 } 4307 } 4308 4309 if (badApp) { 4310 // todo: Also need to kill application to deal with all 4311 // kinds of exceptions. 4312 handleAppDiedLocked(app, false, true); 4313 return false; 4314 } 4315 4316 if (!didSomething) { 4317 updateOomAdjLocked(); 4318 } 4319 4320 return true; 4321 } 4322 4323 public final void attachApplication(IApplicationThread thread) { 4324 synchronized (this) { 4325 int callingPid = Binder.getCallingPid(); 4326 final long origId = Binder.clearCallingIdentity(); 4327 attachApplicationLocked(thread, callingPid); 4328 Binder.restoreCallingIdentity(origId); 4329 } 4330 } 4331 4332 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4333 final long origId = Binder.clearCallingIdentity(); 4334 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4335 if (stopProfiling) { 4336 synchronized (this) { 4337 if (mProfileProc == r.app) { 4338 if (mProfileFd != null) { 4339 try { 4340 mProfileFd.close(); 4341 } catch (IOException e) { 4342 } 4343 clearProfilerLocked(); 4344 } 4345 } 4346 } 4347 } 4348 Binder.restoreCallingIdentity(origId); 4349 } 4350 4351 void enableScreenAfterBoot() { 4352 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4353 SystemClock.uptimeMillis()); 4354 mWindowManager.enableScreenAfterBoot(); 4355 4356 synchronized (this) { 4357 updateEventDispatchingLocked(); 4358 } 4359 } 4360 4361 public void showBootMessage(final CharSequence msg, final boolean always) { 4362 enforceNotIsolatedCaller("showBootMessage"); 4363 mWindowManager.showBootMessage(msg, always); 4364 } 4365 4366 public void dismissKeyguardOnNextActivity() { 4367 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4368 final long token = Binder.clearCallingIdentity(); 4369 try { 4370 synchronized (this) { 4371 if (mLockScreenShown) { 4372 mLockScreenShown = false; 4373 comeOutOfSleepIfNeededLocked(); 4374 } 4375 mMainStack.dismissKeyguardOnNextActivityLocked(); 4376 } 4377 } finally { 4378 Binder.restoreCallingIdentity(token); 4379 } 4380 } 4381 4382 final void finishBooting() { 4383 IntentFilter pkgFilter = new IntentFilter(); 4384 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4385 pkgFilter.addDataScheme("package"); 4386 mContext.registerReceiver(new BroadcastReceiver() { 4387 @Override 4388 public void onReceive(Context context, Intent intent) { 4389 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4390 if (pkgs != null) { 4391 for (String pkg : pkgs) { 4392 synchronized (ActivityManagerService.this) { 4393 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4394 setResultCode(Activity.RESULT_OK); 4395 return; 4396 } 4397 } 4398 } 4399 } 4400 } 4401 }, pkgFilter); 4402 4403 synchronized (this) { 4404 // Ensure that any processes we had put on hold are now started 4405 // up. 4406 final int NP = mProcessesOnHold.size(); 4407 if (NP > 0) { 4408 ArrayList<ProcessRecord> procs = 4409 new ArrayList<ProcessRecord>(mProcessesOnHold); 4410 for (int ip=0; ip<NP; ip++) { 4411 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4412 + procs.get(ip)); 4413 startProcessLocked(procs.get(ip), "on-hold", null); 4414 } 4415 } 4416 4417 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4418 // Start looking for apps that are abusing wake locks. 4419 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4420 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4421 // Tell anyone interested that we are done booting! 4422 SystemProperties.set("sys.boot_completed", "1"); 4423 SystemProperties.set("dev.bootcomplete", "1"); 4424 for (int i=0; i<mStartedUsers.size(); i++) { 4425 UserStartedState uss = mStartedUsers.valueAt(i); 4426 if (uss.mState == UserStartedState.STATE_BOOTING) { 4427 uss.mState = UserStartedState.STATE_RUNNING; 4428 final int userId = mStartedUsers.keyAt(i); 4429 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4430 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4431 broadcastIntentLocked(null, null, intent, 4432 null, null, 0, null, null, 4433 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4434 false, false, MY_PID, Process.SYSTEM_UID, userId); 4435 } 4436 } 4437 } 4438 } 4439 } 4440 4441 final void ensureBootCompleted() { 4442 boolean booting; 4443 boolean enableScreen; 4444 synchronized (this) { 4445 booting = mBooting; 4446 mBooting = false; 4447 enableScreen = !mBooted; 4448 mBooted = true; 4449 } 4450 4451 if (booting) { 4452 finishBooting(); 4453 } 4454 4455 if (enableScreen) { 4456 enableScreenAfterBoot(); 4457 } 4458 } 4459 4460 public final void activityResumed(IBinder token) { 4461 final long origId = Binder.clearCallingIdentity(); 4462 mMainStack.activityResumed(token); 4463 Binder.restoreCallingIdentity(origId); 4464 } 4465 4466 public final void activityPaused(IBinder token) { 4467 final long origId = Binder.clearCallingIdentity(); 4468 mMainStack.activityPaused(token, false); 4469 Binder.restoreCallingIdentity(origId); 4470 } 4471 4472 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4473 CharSequence description) { 4474 if (localLOGV) Slog.v( 4475 TAG, "Activity stopped: token=" + token); 4476 4477 // Refuse possible leaked file descriptors 4478 if (icicle != null && icicle.hasFileDescriptors()) { 4479 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4480 } 4481 4482 ActivityRecord r = null; 4483 4484 final long origId = Binder.clearCallingIdentity(); 4485 4486 synchronized (this) { 4487 r = mMainStack.isInStackLocked(token); 4488 if (r != null) { 4489 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4490 } 4491 } 4492 4493 if (r != null) { 4494 sendPendingThumbnail(r, null, null, null, false); 4495 } 4496 4497 trimApplications(); 4498 4499 Binder.restoreCallingIdentity(origId); 4500 } 4501 4502 public final void activityDestroyed(IBinder token) { 4503 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4504 mMainStack.activityDestroyed(token); 4505 } 4506 4507 public String getCallingPackage(IBinder token) { 4508 synchronized (this) { 4509 ActivityRecord r = getCallingRecordLocked(token); 4510 return r != null && r.app != null ? r.info.packageName : null; 4511 } 4512 } 4513 4514 public ComponentName getCallingActivity(IBinder token) { 4515 synchronized (this) { 4516 ActivityRecord r = getCallingRecordLocked(token); 4517 return r != null ? r.intent.getComponent() : null; 4518 } 4519 } 4520 4521 private ActivityRecord getCallingRecordLocked(IBinder token) { 4522 ActivityRecord r = mMainStack.isInStackLocked(token); 4523 if (r == null) { 4524 return null; 4525 } 4526 return r.resultTo; 4527 } 4528 4529 public ComponentName getActivityClassForToken(IBinder token) { 4530 synchronized(this) { 4531 ActivityRecord r = mMainStack.isInStackLocked(token); 4532 if (r == null) { 4533 return null; 4534 } 4535 return r.intent.getComponent(); 4536 } 4537 } 4538 4539 public String getPackageForToken(IBinder token) { 4540 synchronized(this) { 4541 ActivityRecord r = mMainStack.isInStackLocked(token); 4542 if (r == null) { 4543 return null; 4544 } 4545 return r.packageName; 4546 } 4547 } 4548 4549 public IIntentSender getIntentSender(int type, 4550 String packageName, IBinder token, String resultWho, 4551 int requestCode, Intent[] intents, String[] resolvedTypes, 4552 int flags, Bundle options, int userId) { 4553 enforceNotIsolatedCaller("getIntentSender"); 4554 // Refuse possible leaked file descriptors 4555 if (intents != null) { 4556 if (intents.length < 1) { 4557 throw new IllegalArgumentException("Intents array length must be >= 1"); 4558 } 4559 for (int i=0; i<intents.length; i++) { 4560 Intent intent = intents[i]; 4561 if (intent != null) { 4562 if (intent.hasFileDescriptors()) { 4563 throw new IllegalArgumentException("File descriptors passed in Intent"); 4564 } 4565 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4566 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4567 throw new IllegalArgumentException( 4568 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4569 } 4570 intents[i] = new Intent(intent); 4571 } 4572 } 4573 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4574 throw new IllegalArgumentException( 4575 "Intent array length does not match resolvedTypes length"); 4576 } 4577 } 4578 if (options != null) { 4579 if (options.hasFileDescriptors()) { 4580 throw new IllegalArgumentException("File descriptors passed in options"); 4581 } 4582 } 4583 4584 synchronized(this) { 4585 int callingUid = Binder.getCallingUid(); 4586 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4587 false, true, "getIntentSender", null); 4588 try { 4589 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4590 int uid = AppGlobals.getPackageManager() 4591 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4592 if (!UserHandle.isSameApp(callingUid, uid)) { 4593 String msg = "Permission Denial: getIntentSender() from pid=" 4594 + Binder.getCallingPid() 4595 + ", uid=" + Binder.getCallingUid() 4596 + ", (need uid=" + uid + ")" 4597 + " is not allowed to send as package " + packageName; 4598 Slog.w(TAG, msg); 4599 throw new SecurityException(msg); 4600 } 4601 } 4602 4603 return getIntentSenderLocked(type, packageName, callingUid, userId, 4604 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4605 4606 } catch (RemoteException e) { 4607 throw new SecurityException(e); 4608 } 4609 } 4610 } 4611 4612 IIntentSender getIntentSenderLocked(int type, String packageName, 4613 int callingUid, int userId, IBinder token, String resultWho, 4614 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4615 Bundle options) { 4616 if (DEBUG_MU) 4617 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4618 ActivityRecord activity = null; 4619 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4620 activity = mMainStack.isInStackLocked(token); 4621 if (activity == null) { 4622 return null; 4623 } 4624 if (activity.finishing) { 4625 return null; 4626 } 4627 } 4628 4629 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4630 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4631 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4632 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4633 |PendingIntent.FLAG_UPDATE_CURRENT); 4634 4635 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4636 type, packageName, activity, resultWho, 4637 requestCode, intents, resolvedTypes, flags, options, userId); 4638 WeakReference<PendingIntentRecord> ref; 4639 ref = mIntentSenderRecords.get(key); 4640 PendingIntentRecord rec = ref != null ? ref.get() : null; 4641 if (rec != null) { 4642 if (!cancelCurrent) { 4643 if (updateCurrent) { 4644 if (rec.key.requestIntent != null) { 4645 rec.key.requestIntent.replaceExtras(intents != null ? 4646 intents[intents.length - 1] : null); 4647 } 4648 if (intents != null) { 4649 intents[intents.length-1] = rec.key.requestIntent; 4650 rec.key.allIntents = intents; 4651 rec.key.allResolvedTypes = resolvedTypes; 4652 } else { 4653 rec.key.allIntents = null; 4654 rec.key.allResolvedTypes = null; 4655 } 4656 } 4657 return rec; 4658 } 4659 rec.canceled = true; 4660 mIntentSenderRecords.remove(key); 4661 } 4662 if (noCreate) { 4663 return rec; 4664 } 4665 rec = new PendingIntentRecord(this, key, callingUid); 4666 mIntentSenderRecords.put(key, rec.ref); 4667 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4668 if (activity.pendingResults == null) { 4669 activity.pendingResults 4670 = new HashSet<WeakReference<PendingIntentRecord>>(); 4671 } 4672 activity.pendingResults.add(rec.ref); 4673 } 4674 return rec; 4675 } 4676 4677 public void cancelIntentSender(IIntentSender sender) { 4678 if (!(sender instanceof PendingIntentRecord)) { 4679 return; 4680 } 4681 synchronized(this) { 4682 PendingIntentRecord rec = (PendingIntentRecord)sender; 4683 try { 4684 int uid = AppGlobals.getPackageManager() 4685 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4686 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4687 String msg = "Permission Denial: cancelIntentSender() from pid=" 4688 + Binder.getCallingPid() 4689 + ", uid=" + Binder.getCallingUid() 4690 + " is not allowed to cancel packges " 4691 + rec.key.packageName; 4692 Slog.w(TAG, msg); 4693 throw new SecurityException(msg); 4694 } 4695 } catch (RemoteException e) { 4696 throw new SecurityException(e); 4697 } 4698 cancelIntentSenderLocked(rec, true); 4699 } 4700 } 4701 4702 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4703 rec.canceled = true; 4704 mIntentSenderRecords.remove(rec.key); 4705 if (cleanActivity && rec.key.activity != null) { 4706 rec.key.activity.pendingResults.remove(rec.ref); 4707 } 4708 } 4709 4710 public String getPackageForIntentSender(IIntentSender pendingResult) { 4711 if (!(pendingResult instanceof PendingIntentRecord)) { 4712 return null; 4713 } 4714 try { 4715 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4716 return res.key.packageName; 4717 } catch (ClassCastException e) { 4718 } 4719 return null; 4720 } 4721 4722 public int getUidForIntentSender(IIntentSender sender) { 4723 if (sender instanceof PendingIntentRecord) { 4724 try { 4725 PendingIntentRecord res = (PendingIntentRecord)sender; 4726 return res.uid; 4727 } catch (ClassCastException e) { 4728 } 4729 } 4730 return -1; 4731 } 4732 4733 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4734 if (!(pendingResult instanceof PendingIntentRecord)) { 4735 return false; 4736 } 4737 try { 4738 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4739 if (res.key.allIntents == null) { 4740 return false; 4741 } 4742 for (int i=0; i<res.key.allIntents.length; i++) { 4743 Intent intent = res.key.allIntents[i]; 4744 if (intent.getPackage() != null && intent.getComponent() != null) { 4745 return false; 4746 } 4747 } 4748 return true; 4749 } catch (ClassCastException e) { 4750 } 4751 return false; 4752 } 4753 4754 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4755 if (!(pendingResult instanceof PendingIntentRecord)) { 4756 return false; 4757 } 4758 try { 4759 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4760 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4761 return true; 4762 } 4763 return false; 4764 } catch (ClassCastException e) { 4765 } 4766 return false; 4767 } 4768 4769 public void setProcessLimit(int max) { 4770 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4771 "setProcessLimit()"); 4772 synchronized (this) { 4773 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4774 mProcessLimitOverride = max; 4775 } 4776 trimApplications(); 4777 } 4778 4779 public int getProcessLimit() { 4780 synchronized (this) { 4781 return mProcessLimitOverride; 4782 } 4783 } 4784 4785 void foregroundTokenDied(ForegroundToken token) { 4786 synchronized (ActivityManagerService.this) { 4787 synchronized (mPidsSelfLocked) { 4788 ForegroundToken cur 4789 = mForegroundProcesses.get(token.pid); 4790 if (cur != token) { 4791 return; 4792 } 4793 mForegroundProcesses.remove(token.pid); 4794 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4795 if (pr == null) { 4796 return; 4797 } 4798 pr.forcingToForeground = null; 4799 pr.foregroundServices = false; 4800 } 4801 updateOomAdjLocked(); 4802 } 4803 } 4804 4805 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4806 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4807 "setProcessForeground()"); 4808 synchronized(this) { 4809 boolean changed = false; 4810 4811 synchronized (mPidsSelfLocked) { 4812 ProcessRecord pr = mPidsSelfLocked.get(pid); 4813 if (pr == null && isForeground) { 4814 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4815 return; 4816 } 4817 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4818 if (oldToken != null) { 4819 oldToken.token.unlinkToDeath(oldToken, 0); 4820 mForegroundProcesses.remove(pid); 4821 if (pr != null) { 4822 pr.forcingToForeground = null; 4823 } 4824 changed = true; 4825 } 4826 if (isForeground && token != null) { 4827 ForegroundToken newToken = new ForegroundToken() { 4828 public void binderDied() { 4829 foregroundTokenDied(this); 4830 } 4831 }; 4832 newToken.pid = pid; 4833 newToken.token = token; 4834 try { 4835 token.linkToDeath(newToken, 0); 4836 mForegroundProcesses.put(pid, newToken); 4837 pr.forcingToForeground = token; 4838 changed = true; 4839 } catch (RemoteException e) { 4840 // If the process died while doing this, we will later 4841 // do the cleanup with the process death link. 4842 } 4843 } 4844 } 4845 4846 if (changed) { 4847 updateOomAdjLocked(); 4848 } 4849 } 4850 } 4851 4852 // ========================================================= 4853 // PERMISSIONS 4854 // ========================================================= 4855 4856 static class PermissionController extends IPermissionController.Stub { 4857 ActivityManagerService mActivityManagerService; 4858 PermissionController(ActivityManagerService activityManagerService) { 4859 mActivityManagerService = activityManagerService; 4860 } 4861 4862 public boolean checkPermission(String permission, int pid, int uid) { 4863 return mActivityManagerService.checkPermission(permission, pid, 4864 uid) == PackageManager.PERMISSION_GRANTED; 4865 } 4866 } 4867 4868 /** 4869 * This can be called with or without the global lock held. 4870 */ 4871 int checkComponentPermission(String permission, int pid, int uid, 4872 int owningUid, boolean exported) { 4873 // We might be performing an operation on behalf of an indirect binder 4874 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4875 // client identity accordingly before proceeding. 4876 Identity tlsIdentity = sCallerIdentity.get(); 4877 if (tlsIdentity != null) { 4878 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4879 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4880 uid = tlsIdentity.uid; 4881 pid = tlsIdentity.pid; 4882 } 4883 4884 if (pid == MY_PID) { 4885 return PackageManager.PERMISSION_GRANTED; 4886 } 4887 4888 return ActivityManager.checkComponentPermission(permission, uid, 4889 owningUid, exported); 4890 } 4891 4892 /** 4893 * As the only public entry point for permissions checking, this method 4894 * can enforce the semantic that requesting a check on a null global 4895 * permission is automatically denied. (Internally a null permission 4896 * string is used when calling {@link #checkComponentPermission} in cases 4897 * when only uid-based security is needed.) 4898 * 4899 * This can be called with or without the global lock held. 4900 */ 4901 public int checkPermission(String permission, int pid, int uid) { 4902 if (permission == null) { 4903 return PackageManager.PERMISSION_DENIED; 4904 } 4905 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4906 } 4907 4908 /** 4909 * Binder IPC calls go through the public entry point. 4910 * This can be called with or without the global lock held. 4911 */ 4912 int checkCallingPermission(String permission) { 4913 return checkPermission(permission, 4914 Binder.getCallingPid(), 4915 UserHandle.getAppId(Binder.getCallingUid())); 4916 } 4917 4918 /** 4919 * This can be called with or without the global lock held. 4920 */ 4921 void enforceCallingPermission(String permission, String func) { 4922 if (checkCallingPermission(permission) 4923 == PackageManager.PERMISSION_GRANTED) { 4924 return; 4925 } 4926 4927 String msg = "Permission Denial: " + func + " from pid=" 4928 + Binder.getCallingPid() 4929 + ", uid=" + Binder.getCallingUid() 4930 + " requires " + permission; 4931 Slog.w(TAG, msg); 4932 throw new SecurityException(msg); 4933 } 4934 4935 /** 4936 * Determine if UID is holding permissions required to access {@link Uri} in 4937 * the given {@link ProviderInfo}. Final permission checking is always done 4938 * in {@link ContentProvider}. 4939 */ 4940 private final boolean checkHoldingPermissionsLocked( 4941 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4942 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4943 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4944 4945 if (pi.applicationInfo.uid == uid) { 4946 return true; 4947 } else if (!pi.exported) { 4948 return false; 4949 } 4950 4951 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4952 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4953 try { 4954 // check if target holds top-level <provider> permissions 4955 if (!readMet && pi.readPermission != null 4956 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4957 readMet = true; 4958 } 4959 if (!writeMet && pi.writePermission != null 4960 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4961 writeMet = true; 4962 } 4963 4964 // track if unprotected read/write is allowed; any denied 4965 // <path-permission> below removes this ability 4966 boolean allowDefaultRead = pi.readPermission == null; 4967 boolean allowDefaultWrite = pi.writePermission == null; 4968 4969 // check if target holds any <path-permission> that match uri 4970 final PathPermission[] pps = pi.pathPermissions; 4971 if (pps != null) { 4972 final String path = uri.getPath(); 4973 int i = pps.length; 4974 while (i > 0 && (!readMet || !writeMet)) { 4975 i--; 4976 PathPermission pp = pps[i]; 4977 if (pp.match(path)) { 4978 if (!readMet) { 4979 final String pprperm = pp.getReadPermission(); 4980 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4981 + pprperm + " for " + pp.getPath() 4982 + ": match=" + pp.match(path) 4983 + " check=" + pm.checkUidPermission(pprperm, uid)); 4984 if (pprperm != null) { 4985 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4986 readMet = true; 4987 } else { 4988 allowDefaultRead = false; 4989 } 4990 } 4991 } 4992 if (!writeMet) { 4993 final String ppwperm = pp.getWritePermission(); 4994 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4995 + ppwperm + " for " + pp.getPath() 4996 + ": match=" + pp.match(path) 4997 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4998 if (ppwperm != null) { 4999 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5000 writeMet = true; 5001 } else { 5002 allowDefaultWrite = false; 5003 } 5004 } 5005 } 5006 } 5007 } 5008 } 5009 5010 // grant unprotected <provider> read/write, if not blocked by 5011 // <path-permission> above 5012 if (allowDefaultRead) readMet = true; 5013 if (allowDefaultWrite) writeMet = true; 5014 5015 } catch (RemoteException e) { 5016 return false; 5017 } 5018 5019 return readMet && writeMet; 5020 } 5021 5022 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5023 int modeFlags) { 5024 // Root gets to do everything. 5025 if (uid == 0) { 5026 return true; 5027 } 5028 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5029 if (perms == null) return false; 5030 UriPermission perm = perms.get(uri); 5031 if (perm == null) return false; 5032 return (modeFlags&perm.modeFlags) == modeFlags; 5033 } 5034 5035 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5036 enforceNotIsolatedCaller("checkUriPermission"); 5037 5038 // Another redirected-binder-call permissions check as in 5039 // {@link checkComponentPermission}. 5040 Identity tlsIdentity = sCallerIdentity.get(); 5041 if (tlsIdentity != null) { 5042 uid = tlsIdentity.uid; 5043 pid = tlsIdentity.pid; 5044 } 5045 5046 // Our own process gets to do everything. 5047 if (pid == MY_PID) { 5048 return PackageManager.PERMISSION_GRANTED; 5049 } 5050 synchronized(this) { 5051 return checkUriPermissionLocked(uri, uid, modeFlags) 5052 ? PackageManager.PERMISSION_GRANTED 5053 : PackageManager.PERMISSION_DENIED; 5054 } 5055 } 5056 5057 /** 5058 * Check if the targetPkg can be granted permission to access uri by 5059 * the callingUid using the given modeFlags. Throws a security exception 5060 * if callingUid is not allowed to do this. Returns the uid of the target 5061 * if the URI permission grant should be performed; returns -1 if it is not 5062 * needed (for example targetPkg already has permission to access the URI). 5063 * If you already know the uid of the target, you can supply it in 5064 * lastTargetUid else set that to -1. 5065 */ 5066 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5067 Uri uri, int modeFlags, int lastTargetUid) { 5068 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5069 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5070 if (modeFlags == 0) { 5071 return -1; 5072 } 5073 5074 if (targetPkg != null) { 5075 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5076 "Checking grant " + targetPkg + " permission to " + uri); 5077 } 5078 5079 final IPackageManager pm = AppGlobals.getPackageManager(); 5080 5081 // If this is not a content: uri, we can't do anything with it. 5082 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5083 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5084 "Can't grant URI permission for non-content URI: " + uri); 5085 return -1; 5086 } 5087 5088 String name = uri.getAuthority(); 5089 ProviderInfo pi = null; 5090 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5091 UserHandle.getUserId(callingUid)); 5092 if (cpr != null) { 5093 pi = cpr.info; 5094 } else { 5095 try { 5096 pi = pm.resolveContentProvider(name, 5097 PackageManager.GET_URI_PERMISSION_PATTERNS, 5098 UserHandle.getUserId(callingUid)); 5099 } catch (RemoteException ex) { 5100 } 5101 } 5102 if (pi == null) { 5103 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5104 return -1; 5105 } 5106 5107 int targetUid = lastTargetUid; 5108 if (targetUid < 0 && targetPkg != null) { 5109 try { 5110 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5111 if (targetUid < 0) { 5112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5113 "Can't grant URI permission no uid for: " + targetPkg); 5114 return -1; 5115 } 5116 } catch (RemoteException ex) { 5117 return -1; 5118 } 5119 } 5120 5121 if (targetUid >= 0) { 5122 // First... does the target actually need this permission? 5123 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5124 // No need to grant the target this permission. 5125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5126 "Target " + targetPkg + " already has full permission to " + uri); 5127 return -1; 5128 } 5129 } else { 5130 // First... there is no target package, so can anyone access it? 5131 boolean allowed = pi.exported; 5132 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5133 if (pi.readPermission != null) { 5134 allowed = false; 5135 } 5136 } 5137 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5138 if (pi.writePermission != null) { 5139 allowed = false; 5140 } 5141 } 5142 if (allowed) { 5143 return -1; 5144 } 5145 } 5146 5147 // Second... is the provider allowing granting of URI permissions? 5148 if (!pi.grantUriPermissions) { 5149 throw new SecurityException("Provider " + pi.packageName 5150 + "/" + pi.name 5151 + " does not allow granting of Uri permissions (uri " 5152 + uri + ")"); 5153 } 5154 if (pi.uriPermissionPatterns != null) { 5155 final int N = pi.uriPermissionPatterns.length; 5156 boolean allowed = false; 5157 for (int i=0; i<N; i++) { 5158 if (pi.uriPermissionPatterns[i] != null 5159 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5160 allowed = true; 5161 break; 5162 } 5163 } 5164 if (!allowed) { 5165 throw new SecurityException("Provider " + pi.packageName 5166 + "/" + pi.name 5167 + " does not allow granting of permission to path of Uri " 5168 + uri); 5169 } 5170 } 5171 5172 // Third... does the caller itself have permission to access 5173 // this uri? 5174 if (callingUid != Process.myUid()) { 5175 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5176 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5177 throw new SecurityException("Uid " + callingUid 5178 + " does not have permission to uri " + uri); 5179 } 5180 } 5181 } 5182 5183 return targetUid; 5184 } 5185 5186 public int checkGrantUriPermission(int callingUid, String targetPkg, 5187 Uri uri, int modeFlags) { 5188 enforceNotIsolatedCaller("checkGrantUriPermission"); 5189 synchronized(this) { 5190 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5191 } 5192 } 5193 5194 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5195 Uri uri, int modeFlags, UriPermissionOwner owner) { 5196 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5197 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5198 if (modeFlags == 0) { 5199 return; 5200 } 5201 5202 // So here we are: the caller has the assumed permission 5203 // to the uri, and the target doesn't. Let's now give this to 5204 // the target. 5205 5206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5207 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5208 5209 HashMap<Uri, UriPermission> targetUris 5210 = mGrantedUriPermissions.get(targetUid); 5211 if (targetUris == null) { 5212 targetUris = new HashMap<Uri, UriPermission>(); 5213 mGrantedUriPermissions.put(targetUid, targetUris); 5214 } 5215 5216 UriPermission perm = targetUris.get(uri); 5217 if (perm == null) { 5218 perm = new UriPermission(targetUid, uri); 5219 targetUris.put(uri, perm); 5220 } 5221 5222 perm.modeFlags |= modeFlags; 5223 if (owner == null) { 5224 perm.globalModeFlags |= modeFlags; 5225 } else { 5226 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5227 perm.readOwners.add(owner); 5228 owner.addReadPermission(perm); 5229 } 5230 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5231 perm.writeOwners.add(owner); 5232 owner.addWritePermission(perm); 5233 } 5234 } 5235 } 5236 5237 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5238 int modeFlags, UriPermissionOwner owner) { 5239 if (targetPkg == null) { 5240 throw new NullPointerException("targetPkg"); 5241 } 5242 5243 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5244 if (targetUid < 0) { 5245 return; 5246 } 5247 5248 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5249 } 5250 5251 static class NeededUriGrants extends ArrayList<Uri> { 5252 final String targetPkg; 5253 final int targetUid; 5254 final int flags; 5255 5256 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5257 targetPkg = _targetPkg; 5258 targetUid = _targetUid; 5259 flags = _flags; 5260 } 5261 } 5262 5263 /** 5264 * Like checkGrantUriPermissionLocked, but takes an Intent. 5265 */ 5266 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5267 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5268 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5269 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5270 + " clip=" + (intent != null ? intent.getClipData() : null) 5271 + " from " + intent + "; flags=0x" 5272 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5273 5274 if (targetPkg == null) { 5275 throw new NullPointerException("targetPkg"); 5276 } 5277 5278 if (intent == null) { 5279 return null; 5280 } 5281 Uri data = intent.getData(); 5282 ClipData clip = intent.getClipData(); 5283 if (data == null && clip == null) { 5284 return null; 5285 } 5286 if (data != null) { 5287 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5288 mode, needed != null ? needed.targetUid : -1); 5289 if (target > 0) { 5290 if (needed == null) { 5291 needed = new NeededUriGrants(targetPkg, target, mode); 5292 } 5293 needed.add(data); 5294 } 5295 } 5296 if (clip != null) { 5297 for (int i=0; i<clip.getItemCount(); i++) { 5298 Uri uri = clip.getItemAt(i).getUri(); 5299 if (uri != null) { 5300 int target = -1; 5301 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5302 mode, needed != null ? needed.targetUid : -1); 5303 if (target > 0) { 5304 if (needed == null) { 5305 needed = new NeededUriGrants(targetPkg, target, mode); 5306 } 5307 needed.add(uri); 5308 } 5309 } else { 5310 Intent clipIntent = clip.getItemAt(i).getIntent(); 5311 if (clipIntent != null) { 5312 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5313 callingUid, targetPkg, clipIntent, mode, needed); 5314 if (newNeeded != null) { 5315 needed = newNeeded; 5316 } 5317 } 5318 } 5319 } 5320 } 5321 5322 return needed; 5323 } 5324 5325 /** 5326 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5327 */ 5328 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5329 UriPermissionOwner owner) { 5330 if (needed != null) { 5331 for (int i=0; i<needed.size(); i++) { 5332 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5333 needed.get(i), needed.flags, owner); 5334 } 5335 } 5336 } 5337 5338 void grantUriPermissionFromIntentLocked(int callingUid, 5339 String targetPkg, Intent intent, UriPermissionOwner owner) { 5340 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5341 intent, intent != null ? intent.getFlags() : 0, null); 5342 if (needed == null) { 5343 return; 5344 } 5345 5346 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5347 } 5348 5349 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5350 Uri uri, int modeFlags) { 5351 enforceNotIsolatedCaller("grantUriPermission"); 5352 synchronized(this) { 5353 final ProcessRecord r = getRecordForAppLocked(caller); 5354 if (r == null) { 5355 throw new SecurityException("Unable to find app for caller " 5356 + caller 5357 + " when granting permission to uri " + uri); 5358 } 5359 if (targetPkg == null) { 5360 throw new IllegalArgumentException("null target"); 5361 } 5362 if (uri == null) { 5363 throw new IllegalArgumentException("null uri"); 5364 } 5365 5366 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5367 null); 5368 } 5369 } 5370 5371 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5372 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5373 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5374 HashMap<Uri, UriPermission> perms 5375 = mGrantedUriPermissions.get(perm.uid); 5376 if (perms != null) { 5377 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5378 "Removing " + perm.uid + " permission to " + perm.uri); 5379 perms.remove(perm.uri); 5380 if (perms.size() == 0) { 5381 mGrantedUriPermissions.remove(perm.uid); 5382 } 5383 } 5384 } 5385 } 5386 5387 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5388 int modeFlags) { 5389 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5390 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5391 if (modeFlags == 0) { 5392 return; 5393 } 5394 5395 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5396 "Revoking all granted permissions to " + uri); 5397 5398 final IPackageManager pm = AppGlobals.getPackageManager(); 5399 5400 final String authority = uri.getAuthority(); 5401 ProviderInfo pi = null; 5402 int userId = UserHandle.getUserId(callingUid); 5403 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5404 if (cpr != null) { 5405 pi = cpr.info; 5406 } else { 5407 try { 5408 pi = pm.resolveContentProvider(authority, 5409 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5410 } catch (RemoteException ex) { 5411 } 5412 } 5413 if (pi == null) { 5414 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5415 return; 5416 } 5417 5418 // Does the caller have this permission on the URI? 5419 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5420 // Right now, if you are not the original owner of the permission, 5421 // you are not allowed to revoke it. 5422 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5423 throw new SecurityException("Uid " + callingUid 5424 + " does not have permission to uri " + uri); 5425 //} 5426 } 5427 5428 // Go through all of the permissions and remove any that match. 5429 final List<String> SEGMENTS = uri.getPathSegments(); 5430 if (SEGMENTS != null) { 5431 final int NS = SEGMENTS.size(); 5432 int N = mGrantedUriPermissions.size(); 5433 for (int i=0; i<N; i++) { 5434 HashMap<Uri, UriPermission> perms 5435 = mGrantedUriPermissions.valueAt(i); 5436 Iterator<UriPermission> it = perms.values().iterator(); 5437 toploop: 5438 while (it.hasNext()) { 5439 UriPermission perm = it.next(); 5440 Uri targetUri = perm.uri; 5441 if (!authority.equals(targetUri.getAuthority())) { 5442 continue; 5443 } 5444 List<String> targetSegments = targetUri.getPathSegments(); 5445 if (targetSegments == null) { 5446 continue; 5447 } 5448 if (targetSegments.size() < NS) { 5449 continue; 5450 } 5451 for (int j=0; j<NS; j++) { 5452 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5453 continue toploop; 5454 } 5455 } 5456 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5457 "Revoking " + perm.uid + " permission to " + perm.uri); 5458 perm.clearModes(modeFlags); 5459 if (perm.modeFlags == 0) { 5460 it.remove(); 5461 } 5462 } 5463 if (perms.size() == 0) { 5464 mGrantedUriPermissions.remove( 5465 mGrantedUriPermissions.keyAt(i)); 5466 N--; 5467 i--; 5468 } 5469 } 5470 } 5471 } 5472 5473 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5474 int modeFlags) { 5475 enforceNotIsolatedCaller("revokeUriPermission"); 5476 synchronized(this) { 5477 final ProcessRecord r = getRecordForAppLocked(caller); 5478 if (r == null) { 5479 throw new SecurityException("Unable to find app for caller " 5480 + caller 5481 + " when revoking permission to uri " + uri); 5482 } 5483 if (uri == null) { 5484 Slog.w(TAG, "revokeUriPermission: null uri"); 5485 return; 5486 } 5487 5488 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5489 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5490 if (modeFlags == 0) { 5491 return; 5492 } 5493 5494 final IPackageManager pm = AppGlobals.getPackageManager(); 5495 5496 final String authority = uri.getAuthority(); 5497 ProviderInfo pi = null; 5498 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5499 if (cpr != null) { 5500 pi = cpr.info; 5501 } else { 5502 try { 5503 pi = pm.resolveContentProvider(authority, 5504 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5505 } catch (RemoteException ex) { 5506 } 5507 } 5508 if (pi == null) { 5509 Slog.w(TAG, "No content provider found for permission revoke: " 5510 + uri.toSafeString()); 5511 return; 5512 } 5513 5514 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5515 } 5516 } 5517 5518 @Override 5519 public IBinder newUriPermissionOwner(String name) { 5520 enforceNotIsolatedCaller("newUriPermissionOwner"); 5521 synchronized(this) { 5522 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5523 return owner.getExternalTokenLocked(); 5524 } 5525 } 5526 5527 @Override 5528 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5529 Uri uri, int modeFlags) { 5530 synchronized(this) { 5531 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5532 if (owner == null) { 5533 throw new IllegalArgumentException("Unknown owner: " + token); 5534 } 5535 if (fromUid != Binder.getCallingUid()) { 5536 if (Binder.getCallingUid() != Process.myUid()) { 5537 // Only system code can grant URI permissions on behalf 5538 // of other users. 5539 throw new SecurityException("nice try"); 5540 } 5541 } 5542 if (targetPkg == null) { 5543 throw new IllegalArgumentException("null target"); 5544 } 5545 if (uri == null) { 5546 throw new IllegalArgumentException("null uri"); 5547 } 5548 5549 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5550 } 5551 } 5552 5553 @Override 5554 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5555 synchronized(this) { 5556 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5557 if (owner == null) { 5558 throw new IllegalArgumentException("Unknown owner: " + token); 5559 } 5560 5561 if (uri == null) { 5562 owner.removeUriPermissionsLocked(mode); 5563 } else { 5564 owner.removeUriPermissionLocked(uri, mode); 5565 } 5566 } 5567 } 5568 5569 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5570 synchronized (this) { 5571 ProcessRecord app = 5572 who != null ? getRecordForAppLocked(who) : null; 5573 if (app == null) return; 5574 5575 Message msg = Message.obtain(); 5576 msg.what = WAIT_FOR_DEBUGGER_MSG; 5577 msg.obj = app; 5578 msg.arg1 = waiting ? 1 : 0; 5579 mHandler.sendMessage(msg); 5580 } 5581 } 5582 5583 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5584 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5585 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5586 outInfo.availMem = Process.getFreeMemory(); 5587 outInfo.totalMem = Process.getTotalMemory(); 5588 outInfo.threshold = homeAppMem; 5589 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5590 outInfo.hiddenAppThreshold = hiddenAppMem; 5591 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5592 ProcessList.SERVICE_ADJ); 5593 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5594 ProcessList.VISIBLE_APP_ADJ); 5595 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5596 ProcessList.FOREGROUND_APP_ADJ); 5597 } 5598 5599 // ========================================================= 5600 // TASK MANAGEMENT 5601 // ========================================================= 5602 5603 public List getTasks(int maxNum, int flags, 5604 IThumbnailReceiver receiver) { 5605 ArrayList list = new ArrayList(); 5606 5607 PendingThumbnailsRecord pending = null; 5608 IApplicationThread topThumbnail = null; 5609 ActivityRecord topRecord = null; 5610 5611 synchronized(this) { 5612 if (localLOGV) Slog.v( 5613 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5614 + ", receiver=" + receiver); 5615 5616 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5617 != PackageManager.PERMISSION_GRANTED) { 5618 if (receiver != null) { 5619 // If the caller wants to wait for pending thumbnails, 5620 // it ain't gonna get them. 5621 try { 5622 receiver.finished(); 5623 } catch (RemoteException ex) { 5624 } 5625 } 5626 String msg = "Permission Denial: getTasks() from pid=" 5627 + Binder.getCallingPid() 5628 + ", uid=" + Binder.getCallingUid() 5629 + " requires " + android.Manifest.permission.GET_TASKS; 5630 Slog.w(TAG, msg); 5631 throw new SecurityException(msg); 5632 } 5633 5634 int pos = mMainStack.mHistory.size()-1; 5635 ActivityRecord next = 5636 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5637 ActivityRecord top = null; 5638 TaskRecord curTask = null; 5639 int numActivities = 0; 5640 int numRunning = 0; 5641 while (pos >= 0 && maxNum > 0) { 5642 final ActivityRecord r = next; 5643 pos--; 5644 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5645 5646 // Initialize state for next task if needed. 5647 if (top == null || 5648 (top.state == ActivityState.INITIALIZING 5649 && top.task == r.task)) { 5650 top = r; 5651 curTask = r.task; 5652 numActivities = numRunning = 0; 5653 } 5654 5655 // Add 'r' into the current task. 5656 numActivities++; 5657 if (r.app != null && r.app.thread != null) { 5658 numRunning++; 5659 } 5660 5661 if (localLOGV) Slog.v( 5662 TAG, r.intent.getComponent().flattenToShortString() 5663 + ": task=" + r.task); 5664 5665 // If the next one is a different task, generate a new 5666 // TaskInfo entry for what we have. 5667 if (next == null || next.task != curTask) { 5668 ActivityManager.RunningTaskInfo ci 5669 = new ActivityManager.RunningTaskInfo(); 5670 ci.id = curTask.taskId; 5671 ci.baseActivity = r.intent.getComponent(); 5672 ci.topActivity = top.intent.getComponent(); 5673 if (top.thumbHolder != null) { 5674 ci.description = top.thumbHolder.lastDescription; 5675 } 5676 ci.numActivities = numActivities; 5677 ci.numRunning = numRunning; 5678 //System.out.println( 5679 // "#" + maxNum + ": " + " descr=" + ci.description); 5680 if (ci.thumbnail == null && receiver != null) { 5681 if (localLOGV) Slog.v( 5682 TAG, "State=" + top.state + "Idle=" + top.idle 5683 + " app=" + top.app 5684 + " thr=" + (top.app != null ? top.app.thread : null)); 5685 if (top.state == ActivityState.RESUMED 5686 || top.state == ActivityState.PAUSING) { 5687 if (top.idle && top.app != null 5688 && top.app.thread != null) { 5689 topRecord = top; 5690 topThumbnail = top.app.thread; 5691 } else { 5692 top.thumbnailNeeded = true; 5693 } 5694 } 5695 if (pending == null) { 5696 pending = new PendingThumbnailsRecord(receiver); 5697 } 5698 pending.pendingRecords.add(top); 5699 } 5700 list.add(ci); 5701 maxNum--; 5702 top = null; 5703 } 5704 } 5705 5706 if (pending != null) { 5707 mPendingThumbnails.add(pending); 5708 } 5709 } 5710 5711 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5712 5713 if (topThumbnail != null) { 5714 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5715 try { 5716 topThumbnail.requestThumbnail(topRecord.appToken); 5717 } catch (Exception e) { 5718 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5719 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5720 } 5721 } 5722 5723 if (pending == null && receiver != null) { 5724 // In this case all thumbnails were available and the client 5725 // is being asked to be told when the remaining ones come in... 5726 // which is unusually, since the top-most currently running 5727 // activity should never have a canned thumbnail! Oh well. 5728 try { 5729 receiver.finished(); 5730 } catch (RemoteException ex) { 5731 } 5732 } 5733 5734 return list; 5735 } 5736 5737 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5738 int flags, int userId) { 5739 final int callingUid = Binder.getCallingUid(); 5740 if (userId != UserHandle.getCallingUserId()) { 5741 // Check if the caller is holding permissions for cross-user requests. 5742 if (checkComponentPermission( 5743 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5744 Binder.getCallingPid(), callingUid, -1, true) 5745 != PackageManager.PERMISSION_GRANTED) { 5746 String msg = "Permission Denial: " 5747 + "Request to get recent tasks for user " + userId 5748 + " but is calling from user " + UserHandle.getUserId(callingUid) 5749 + "; this requires " 5750 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5751 Slog.w(TAG, msg); 5752 throw new SecurityException(msg); 5753 } else { 5754 if (userId == UserHandle.USER_CURRENT) { 5755 userId = mCurrentUserId; 5756 } 5757 } 5758 } 5759 5760 synchronized (this) { 5761 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5762 "getRecentTasks()"); 5763 final boolean detailed = checkCallingPermission( 5764 android.Manifest.permission.GET_DETAILED_TASKS) 5765 == PackageManager.PERMISSION_GRANTED; 5766 5767 IPackageManager pm = AppGlobals.getPackageManager(); 5768 5769 final int N = mRecentTasks.size(); 5770 ArrayList<ActivityManager.RecentTaskInfo> res 5771 = new ArrayList<ActivityManager.RecentTaskInfo>( 5772 maxNum < N ? maxNum : N); 5773 for (int i=0; i<N && maxNum > 0; i++) { 5774 TaskRecord tr = mRecentTasks.get(i); 5775 // Only add calling user's recent tasks 5776 if (tr.userId != userId) continue; 5777 // Return the entry if desired by the caller. We always return 5778 // the first entry, because callers always expect this to be the 5779 // foreground app. We may filter others if the caller has 5780 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5781 // we should exclude the entry. 5782 5783 if (i == 0 5784 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5785 || (tr.intent == null) 5786 || ((tr.intent.getFlags() 5787 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5788 ActivityManager.RecentTaskInfo rti 5789 = new ActivityManager.RecentTaskInfo(); 5790 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5791 rti.persistentId = tr.taskId; 5792 rti.baseIntent = new Intent( 5793 tr.intent != null ? tr.intent : tr.affinityIntent); 5794 if (!detailed) { 5795 rti.baseIntent.replaceExtras((Bundle)null); 5796 } 5797 rti.origActivity = tr.origActivity; 5798 rti.description = tr.lastDescription; 5799 5800 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5801 // Check whether this activity is currently available. 5802 try { 5803 if (rti.origActivity != null) { 5804 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5805 == null) { 5806 continue; 5807 } 5808 } else if (rti.baseIntent != null) { 5809 if (pm.queryIntentActivities(rti.baseIntent, 5810 null, 0, userId) == null) { 5811 continue; 5812 } 5813 } 5814 } catch (RemoteException e) { 5815 // Will never happen. 5816 } 5817 } 5818 5819 res.add(rti); 5820 maxNum--; 5821 } 5822 } 5823 return res; 5824 } 5825 } 5826 5827 private TaskRecord taskForIdLocked(int id) { 5828 final int N = mRecentTasks.size(); 5829 for (int i=0; i<N; i++) { 5830 TaskRecord tr = mRecentTasks.get(i); 5831 if (tr.taskId == id) { 5832 return tr; 5833 } 5834 } 5835 return null; 5836 } 5837 5838 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5839 synchronized (this) { 5840 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5841 "getTaskThumbnails()"); 5842 TaskRecord tr = taskForIdLocked(id); 5843 if (tr != null) { 5844 return mMainStack.getTaskThumbnailsLocked(tr); 5845 } 5846 } 5847 return null; 5848 } 5849 5850 public Bitmap getTaskTopThumbnail(int id) { 5851 synchronized (this) { 5852 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5853 "getTaskTopThumbnail()"); 5854 TaskRecord tr = taskForIdLocked(id); 5855 if (tr != null) { 5856 return mMainStack.getTaskTopThumbnailLocked(tr); 5857 } 5858 } 5859 return null; 5860 } 5861 5862 public boolean removeSubTask(int taskId, int subTaskIndex) { 5863 synchronized (this) { 5864 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5865 "removeSubTask()"); 5866 long ident = Binder.clearCallingIdentity(); 5867 try { 5868 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5869 true) != null; 5870 } finally { 5871 Binder.restoreCallingIdentity(ident); 5872 } 5873 } 5874 } 5875 5876 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5877 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5878 Intent baseIntent = new Intent( 5879 tr.intent != null ? tr.intent : tr.affinityIntent); 5880 ComponentName component = baseIntent.getComponent(); 5881 if (component == null) { 5882 Slog.w(TAG, "Now component for base intent of task: " + tr); 5883 return; 5884 } 5885 5886 // Find any running services associated with this app. 5887 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5888 5889 if (killProcesses) { 5890 // Find any running processes associated with this app. 5891 final String pkg = component.getPackageName(); 5892 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5893 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5894 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5895 for (int i=0; i<uids.size(); i++) { 5896 ProcessRecord proc = uids.valueAt(i); 5897 if (proc.userId != tr.userId) { 5898 continue; 5899 } 5900 if (!proc.pkgList.contains(pkg)) { 5901 continue; 5902 } 5903 procs.add(proc); 5904 } 5905 } 5906 5907 // Kill the running processes. 5908 for (int i=0; i<procs.size(); i++) { 5909 ProcessRecord pr = procs.get(i); 5910 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5911 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5912 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5913 pr.processName, pr.setAdj, "remove task"); 5914 pr.killedBackground = true; 5915 Process.killProcessQuiet(pr.pid); 5916 } else { 5917 pr.waitingToKill = "remove task"; 5918 } 5919 } 5920 } 5921 } 5922 5923 public boolean removeTask(int taskId, int flags) { 5924 synchronized (this) { 5925 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5926 "removeTask()"); 5927 long ident = Binder.clearCallingIdentity(); 5928 try { 5929 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5930 false); 5931 if (r != null) { 5932 mRecentTasks.remove(r.task); 5933 cleanUpRemovedTaskLocked(r.task, flags); 5934 return true; 5935 } else { 5936 TaskRecord tr = null; 5937 int i=0; 5938 while (i < mRecentTasks.size()) { 5939 TaskRecord t = mRecentTasks.get(i); 5940 if (t.taskId == taskId) { 5941 tr = t; 5942 break; 5943 } 5944 i++; 5945 } 5946 if (tr != null) { 5947 if (tr.numActivities <= 0) { 5948 // Caller is just removing a recent task that is 5949 // not actively running. That is easy! 5950 mRecentTasks.remove(i); 5951 cleanUpRemovedTaskLocked(tr, flags); 5952 return true; 5953 } else { 5954 Slog.w(TAG, "removeTask: task " + taskId 5955 + " does not have activities to remove, " 5956 + " but numActivities=" + tr.numActivities 5957 + ": " + tr); 5958 } 5959 } 5960 } 5961 } finally { 5962 Binder.restoreCallingIdentity(ident); 5963 } 5964 } 5965 return false; 5966 } 5967 5968 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5969 int j; 5970 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5971 TaskRecord jt = startTask; 5972 5973 // First look backwards 5974 for (j=startIndex-1; j>=0; j--) { 5975 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5976 if (r.task != jt) { 5977 jt = r.task; 5978 if (affinity.equals(jt.affinity)) { 5979 return j; 5980 } 5981 } 5982 } 5983 5984 // Now look forwards 5985 final int N = mMainStack.mHistory.size(); 5986 jt = startTask; 5987 for (j=startIndex+1; j<N; j++) { 5988 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5989 if (r.task != jt) { 5990 if (affinity.equals(jt.affinity)) { 5991 return j; 5992 } 5993 jt = r.task; 5994 } 5995 } 5996 5997 // Might it be at the top? 5998 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5999 return N-1; 6000 } 6001 6002 return -1; 6003 } 6004 6005 /** 6006 * TODO: Add mController hook 6007 */ 6008 public void moveTaskToFront(int task, int flags, Bundle options) { 6009 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6010 "moveTaskToFront()"); 6011 6012 synchronized(this) { 6013 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6014 Binder.getCallingUid(), "Task to front")) { 6015 ActivityOptions.abort(options); 6016 return; 6017 } 6018 final long origId = Binder.clearCallingIdentity(); 6019 try { 6020 TaskRecord tr = taskForIdLocked(task); 6021 if (tr != null) { 6022 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6023 mMainStack.mUserLeaving = true; 6024 } 6025 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6026 // Caller wants the home activity moved with it. To accomplish this, 6027 // we'll just move the home task to the top first. 6028 mMainStack.moveHomeToFrontLocked(); 6029 } 6030 mMainStack.moveTaskToFrontLocked(tr, null, options); 6031 return; 6032 } 6033 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6034 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6035 if (hr.task.taskId == task) { 6036 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6037 mMainStack.mUserLeaving = true; 6038 } 6039 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6040 // Caller wants the home activity moved with it. To accomplish this, 6041 // we'll just move the home task to the top first. 6042 mMainStack.moveHomeToFrontLocked(); 6043 } 6044 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6045 return; 6046 } 6047 } 6048 } finally { 6049 Binder.restoreCallingIdentity(origId); 6050 } 6051 ActivityOptions.abort(options); 6052 } 6053 } 6054 6055 public void moveTaskToBack(int task) { 6056 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6057 "moveTaskToBack()"); 6058 6059 synchronized(this) { 6060 if (mMainStack.mResumedActivity != null 6061 && mMainStack.mResumedActivity.task.taskId == task) { 6062 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6063 Binder.getCallingUid(), "Task to back")) { 6064 return; 6065 } 6066 } 6067 final long origId = Binder.clearCallingIdentity(); 6068 mMainStack.moveTaskToBackLocked(task, null); 6069 Binder.restoreCallingIdentity(origId); 6070 } 6071 } 6072 6073 /** 6074 * Moves an activity, and all of the other activities within the same task, to the bottom 6075 * of the history stack. The activity's order within the task is unchanged. 6076 * 6077 * @param token A reference to the activity we wish to move 6078 * @param nonRoot If false then this only works if the activity is the root 6079 * of a task; if true it will work for any activity in a task. 6080 * @return Returns true if the move completed, false if not. 6081 */ 6082 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6083 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6084 synchronized(this) { 6085 final long origId = Binder.clearCallingIdentity(); 6086 int taskId = getTaskForActivityLocked(token, !nonRoot); 6087 if (taskId >= 0) { 6088 return mMainStack.moveTaskToBackLocked(taskId, null); 6089 } 6090 Binder.restoreCallingIdentity(origId); 6091 } 6092 return false; 6093 } 6094 6095 public void moveTaskBackwards(int task) { 6096 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6097 "moveTaskBackwards()"); 6098 6099 synchronized(this) { 6100 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6101 Binder.getCallingUid(), "Task backwards")) { 6102 return; 6103 } 6104 final long origId = Binder.clearCallingIdentity(); 6105 moveTaskBackwardsLocked(task); 6106 Binder.restoreCallingIdentity(origId); 6107 } 6108 } 6109 6110 private final void moveTaskBackwardsLocked(int task) { 6111 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6112 } 6113 6114 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6115 synchronized(this) { 6116 return getTaskForActivityLocked(token, onlyRoot); 6117 } 6118 } 6119 6120 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6121 final int N = mMainStack.mHistory.size(); 6122 TaskRecord lastTask = null; 6123 for (int i=0; i<N; i++) { 6124 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6125 if (r.appToken == token) { 6126 if (!onlyRoot || lastTask != r.task) { 6127 return r.task.taskId; 6128 } 6129 return -1; 6130 } 6131 lastTask = r.task; 6132 } 6133 6134 return -1; 6135 } 6136 6137 // ========================================================= 6138 // THUMBNAILS 6139 // ========================================================= 6140 6141 public void reportThumbnail(IBinder token, 6142 Bitmap thumbnail, CharSequence description) { 6143 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6144 final long origId = Binder.clearCallingIdentity(); 6145 sendPendingThumbnail(null, token, thumbnail, description, true); 6146 Binder.restoreCallingIdentity(origId); 6147 } 6148 6149 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6150 Bitmap thumbnail, CharSequence description, boolean always) { 6151 TaskRecord task = null; 6152 ArrayList receivers = null; 6153 6154 //System.out.println("Send pending thumbnail: " + r); 6155 6156 synchronized(this) { 6157 if (r == null) { 6158 r = mMainStack.isInStackLocked(token); 6159 if (r == null) { 6160 return; 6161 } 6162 } 6163 if (thumbnail == null && r.thumbHolder != null) { 6164 thumbnail = r.thumbHolder.lastThumbnail; 6165 description = r.thumbHolder.lastDescription; 6166 } 6167 if (thumbnail == null && !always) { 6168 // If there is no thumbnail, and this entry is not actually 6169 // going away, then abort for now and pick up the next 6170 // thumbnail we get. 6171 return; 6172 } 6173 task = r.task; 6174 6175 int N = mPendingThumbnails.size(); 6176 int i=0; 6177 while (i<N) { 6178 PendingThumbnailsRecord pr = 6179 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6180 //System.out.println("Looking in " + pr.pendingRecords); 6181 if (pr.pendingRecords.remove(r)) { 6182 if (receivers == null) { 6183 receivers = new ArrayList(); 6184 } 6185 receivers.add(pr); 6186 if (pr.pendingRecords.size() == 0) { 6187 pr.finished = true; 6188 mPendingThumbnails.remove(i); 6189 N--; 6190 continue; 6191 } 6192 } 6193 i++; 6194 } 6195 } 6196 6197 if (receivers != null) { 6198 final int N = receivers.size(); 6199 for (int i=0; i<N; i++) { 6200 try { 6201 PendingThumbnailsRecord pr = 6202 (PendingThumbnailsRecord)receivers.get(i); 6203 pr.receiver.newThumbnail( 6204 task != null ? task.taskId : -1, thumbnail, description); 6205 if (pr.finished) { 6206 pr.receiver.finished(); 6207 } 6208 } catch (Exception e) { 6209 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6210 } 6211 } 6212 } 6213 } 6214 6215 // ========================================================= 6216 // CONTENT PROVIDERS 6217 // ========================================================= 6218 6219 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6220 List<ProviderInfo> providers = null; 6221 try { 6222 providers = AppGlobals.getPackageManager(). 6223 queryContentProviders(app.processName, app.uid, 6224 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6225 } catch (RemoteException ex) { 6226 } 6227 if (DEBUG_MU) 6228 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6229 int userId = app.userId; 6230 if (providers != null) { 6231 int N = providers.size(); 6232 for (int i=0; i<N; i++) { 6233 ProviderInfo cpi = 6234 (ProviderInfo)providers.get(i); 6235 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6236 cpi.name, cpi.flags); 6237 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6238 // This is a singleton provider, but a user besides the 6239 // default user is asking to initialize a process it runs 6240 // in... well, no, it doesn't actually run in this process, 6241 // it runs in the process of the default user. Get rid of it. 6242 providers.remove(i); 6243 N--; 6244 continue; 6245 } 6246 6247 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6248 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6249 if (cpr == null) { 6250 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6251 mProviderMap.putProviderByClass(comp, cpr); 6252 } 6253 if (DEBUG_MU) 6254 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6255 app.pubProviders.put(cpi.name, cpr); 6256 app.addPackage(cpi.applicationInfo.packageName); 6257 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6258 } 6259 } 6260 return providers; 6261 } 6262 6263 /** 6264 * Check if {@link ProcessRecord} has a possible chance at accessing the 6265 * given {@link ProviderInfo}. Final permission checking is always done 6266 * in {@link ContentProvider}. 6267 */ 6268 private final String checkContentProviderPermissionLocked( 6269 ProviderInfo cpi, ProcessRecord r) { 6270 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6271 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6272 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6273 cpi.applicationInfo.uid, cpi.exported) 6274 == PackageManager.PERMISSION_GRANTED) { 6275 return null; 6276 } 6277 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6278 cpi.applicationInfo.uid, cpi.exported) 6279 == PackageManager.PERMISSION_GRANTED) { 6280 return null; 6281 } 6282 6283 PathPermission[] pps = cpi.pathPermissions; 6284 if (pps != null) { 6285 int i = pps.length; 6286 while (i > 0) { 6287 i--; 6288 PathPermission pp = pps[i]; 6289 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6290 cpi.applicationInfo.uid, cpi.exported) 6291 == PackageManager.PERMISSION_GRANTED) { 6292 return null; 6293 } 6294 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6295 cpi.applicationInfo.uid, cpi.exported) 6296 == PackageManager.PERMISSION_GRANTED) { 6297 return null; 6298 } 6299 } 6300 } 6301 6302 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6303 if (perms != null) { 6304 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6305 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6306 return null; 6307 } 6308 } 6309 } 6310 6311 String msg; 6312 if (!cpi.exported) { 6313 msg = "Permission Denial: opening provider " + cpi.name 6314 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6315 + ", uid=" + callingUid + ") that is not exported from uid " 6316 + cpi.applicationInfo.uid; 6317 } else { 6318 msg = "Permission Denial: opening provider " + cpi.name 6319 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6320 + ", uid=" + callingUid + ") requires " 6321 + cpi.readPermission + " or " + cpi.writePermission; 6322 } 6323 Slog.w(TAG, msg); 6324 return msg; 6325 } 6326 6327 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6328 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6329 if (r != null) { 6330 for (int i=0; i<r.conProviders.size(); i++) { 6331 ContentProviderConnection conn = r.conProviders.get(i); 6332 if (conn.provider == cpr) { 6333 if (DEBUG_PROVIDER) Slog.v(TAG, 6334 "Adding provider requested by " 6335 + r.processName + " from process " 6336 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6337 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6338 if (stable) { 6339 conn.stableCount++; 6340 conn.numStableIncs++; 6341 } else { 6342 conn.unstableCount++; 6343 conn.numUnstableIncs++; 6344 } 6345 return conn; 6346 } 6347 } 6348 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6349 if (stable) { 6350 conn.stableCount = 1; 6351 conn.numStableIncs = 1; 6352 } else { 6353 conn.unstableCount = 1; 6354 conn.numUnstableIncs = 1; 6355 } 6356 cpr.connections.add(conn); 6357 r.conProviders.add(conn); 6358 return conn; 6359 } 6360 cpr.addExternalProcessHandleLocked(externalProcessToken); 6361 return null; 6362 } 6363 6364 boolean decProviderCountLocked(ContentProviderConnection conn, 6365 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6366 if (conn != null) { 6367 cpr = conn.provider; 6368 if (DEBUG_PROVIDER) Slog.v(TAG, 6369 "Removing provider requested by " 6370 + conn.client.processName + " from process " 6371 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6372 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6373 if (stable) { 6374 conn.stableCount--; 6375 } else { 6376 conn.unstableCount--; 6377 } 6378 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6379 cpr.connections.remove(conn); 6380 conn.client.conProviders.remove(conn); 6381 return true; 6382 } 6383 return false; 6384 } 6385 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6386 return false; 6387 } 6388 6389 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6390 String name, IBinder token, boolean stable, int userId) { 6391 ContentProviderRecord cpr; 6392 ContentProviderConnection conn = null; 6393 ProviderInfo cpi = null; 6394 6395 synchronized(this) { 6396 ProcessRecord r = null; 6397 if (caller != null) { 6398 r = getRecordForAppLocked(caller); 6399 if (r == null) { 6400 throw new SecurityException( 6401 "Unable to find app for caller " + caller 6402 + " (pid=" + Binder.getCallingPid() 6403 + ") when getting content provider " + name); 6404 } 6405 if (r.userId != userId) { 6406 throw new SecurityException("Calling requested user " + userId 6407 + " but app is user " + r.userId); 6408 } 6409 } 6410 6411 // First check if this content provider has been published... 6412 cpr = mProviderMap.getProviderByName(name, userId); 6413 boolean providerRunning = cpr != null; 6414 if (providerRunning) { 6415 cpi = cpr.info; 6416 String msg; 6417 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6418 throw new SecurityException(msg); 6419 } 6420 6421 if (r != null && cpr.canRunHere(r)) { 6422 // This provider has been published or is in the process 6423 // of being published... but it is also allowed to run 6424 // in the caller's process, so don't make a connection 6425 // and just let the caller instantiate its own instance. 6426 ContentProviderHolder holder = cpr.newHolder(null); 6427 // don't give caller the provider object, it needs 6428 // to make its own. 6429 holder.provider = null; 6430 return holder; 6431 } 6432 6433 final long origId = Binder.clearCallingIdentity(); 6434 6435 // In this case the provider instance already exists, so we can 6436 // return it right away. 6437 conn = incProviderCountLocked(r, cpr, token, stable); 6438 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6439 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6440 // If this is a perceptible app accessing the provider, 6441 // make sure to count it as being accessed and thus 6442 // back up on the LRU list. This is good because 6443 // content providers are often expensive to start. 6444 updateLruProcessLocked(cpr.proc, false, true); 6445 } 6446 } 6447 6448 if (cpr.proc != null) { 6449 if (false) { 6450 if (cpr.name.flattenToShortString().equals( 6451 "com.android.providers.calendar/.CalendarProvider2")) { 6452 Slog.v(TAG, "****************** KILLING " 6453 + cpr.name.flattenToShortString()); 6454 Process.killProcess(cpr.proc.pid); 6455 } 6456 } 6457 boolean success = updateOomAdjLocked(cpr.proc); 6458 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6459 // NOTE: there is still a race here where a signal could be 6460 // pending on the process even though we managed to update its 6461 // adj level. Not sure what to do about this, but at least 6462 // the race is now smaller. 6463 if (!success) { 6464 // Uh oh... it looks like the provider's process 6465 // has been killed on us. We need to wait for a new 6466 // process to be started, and make sure its death 6467 // doesn't kill our process. 6468 Slog.i(TAG, 6469 "Existing provider " + cpr.name.flattenToShortString() 6470 + " is crashing; detaching " + r); 6471 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6472 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6473 if (!lastRef) { 6474 // This wasn't the last ref our process had on 6475 // the provider... we have now been killed, bail. 6476 return null; 6477 } 6478 providerRunning = false; 6479 conn = null; 6480 } 6481 } 6482 6483 Binder.restoreCallingIdentity(origId); 6484 } 6485 6486 boolean singleton; 6487 if (!providerRunning) { 6488 try { 6489 cpi = AppGlobals.getPackageManager(). 6490 resolveContentProvider(name, 6491 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6492 } catch (RemoteException ex) { 6493 } 6494 if (cpi == null) { 6495 return null; 6496 } 6497 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6498 cpi.name, cpi.flags); 6499 if (singleton) { 6500 userId = 0; 6501 } 6502 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6503 6504 String msg; 6505 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6506 throw new SecurityException(msg); 6507 } 6508 6509 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6510 && !cpi.processName.equals("system")) { 6511 // If this content provider does not run in the system 6512 // process, and the system is not yet ready to run other 6513 // processes, then fail fast instead of hanging. 6514 throw new IllegalArgumentException( 6515 "Attempt to launch content provider before system ready"); 6516 } 6517 6518 // Make sure that the user who owns this provider is started. If not, 6519 // we don't want to allow it to run. 6520 if (mStartedUsers.get(userId) == null) { 6521 Slog.w(TAG, "Unable to launch app " 6522 + cpi.applicationInfo.packageName + "/" 6523 + cpi.applicationInfo.uid + " for provider " 6524 + name + ": user " + userId + " is stopped"); 6525 return null; 6526 } 6527 6528 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6529 cpr = mProviderMap.getProviderByClass(comp, userId); 6530 final boolean firstClass = cpr == null; 6531 if (firstClass) { 6532 try { 6533 ApplicationInfo ai = 6534 AppGlobals.getPackageManager(). 6535 getApplicationInfo( 6536 cpi.applicationInfo.packageName, 6537 STOCK_PM_FLAGS, userId); 6538 if (ai == null) { 6539 Slog.w(TAG, "No package info for content provider " 6540 + cpi.name); 6541 return null; 6542 } 6543 ai = getAppInfoForUser(ai, userId); 6544 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6545 } catch (RemoteException ex) { 6546 // pm is in same process, this will never happen. 6547 } 6548 } 6549 6550 if (r != null && cpr.canRunHere(r)) { 6551 // If this is a multiprocess provider, then just return its 6552 // info and allow the caller to instantiate it. Only do 6553 // this if the provider is the same user as the caller's 6554 // process, or can run as root (so can be in any process). 6555 return cpr.newHolder(null); 6556 } 6557 6558 if (DEBUG_PROVIDER) { 6559 RuntimeException e = new RuntimeException("here"); 6560 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6561 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6562 } 6563 6564 // This is single process, and our app is now connecting to it. 6565 // See if we are already in the process of launching this 6566 // provider. 6567 final int N = mLaunchingProviders.size(); 6568 int i; 6569 for (i=0; i<N; i++) { 6570 if (mLaunchingProviders.get(i) == cpr) { 6571 break; 6572 } 6573 } 6574 6575 // If the provider is not already being launched, then get it 6576 // started. 6577 if (i >= N) { 6578 final long origId = Binder.clearCallingIdentity(); 6579 6580 try { 6581 // Content provider is now in use, its package can't be stopped. 6582 try { 6583 AppGlobals.getPackageManager().setPackageStoppedState( 6584 cpr.appInfo.packageName, false, userId); 6585 } catch (RemoteException e) { 6586 } catch (IllegalArgumentException e) { 6587 Slog.w(TAG, "Failed trying to unstop package " 6588 + cpr.appInfo.packageName + ": " + e); 6589 } 6590 6591 ProcessRecord proc = startProcessLocked(cpi.processName, 6592 cpr.appInfo, false, 0, "content provider", 6593 new ComponentName(cpi.applicationInfo.packageName, 6594 cpi.name), false, false); 6595 if (proc == null) { 6596 Slog.w(TAG, "Unable to launch app " 6597 + cpi.applicationInfo.packageName + "/" 6598 + cpi.applicationInfo.uid + " for provider " 6599 + name + ": process is bad"); 6600 return null; 6601 } 6602 cpr.launchingApp = proc; 6603 mLaunchingProviders.add(cpr); 6604 } finally { 6605 Binder.restoreCallingIdentity(origId); 6606 } 6607 } 6608 6609 // Make sure the provider is published (the same provider class 6610 // may be published under multiple names). 6611 if (firstClass) { 6612 mProviderMap.putProviderByClass(comp, cpr); 6613 } 6614 6615 mProviderMap.putProviderByName(name, cpr); 6616 conn = incProviderCountLocked(r, cpr, token, stable); 6617 if (conn != null) { 6618 conn.waiting = true; 6619 } 6620 } 6621 } 6622 6623 // Wait for the provider to be published... 6624 synchronized (cpr) { 6625 while (cpr.provider == null) { 6626 if (cpr.launchingApp == null) { 6627 Slog.w(TAG, "Unable to launch app " 6628 + cpi.applicationInfo.packageName + "/" 6629 + cpi.applicationInfo.uid + " for provider " 6630 + name + ": launching app became null"); 6631 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6632 cpi.applicationInfo.packageName, 6633 cpi.applicationInfo.uid, name); 6634 return null; 6635 } 6636 try { 6637 if (DEBUG_MU) { 6638 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6639 + cpr.launchingApp); 6640 } 6641 if (conn != null) { 6642 conn.waiting = true; 6643 } 6644 cpr.wait(); 6645 } catch (InterruptedException ex) { 6646 } finally { 6647 if (conn != null) { 6648 conn.waiting = false; 6649 } 6650 } 6651 } 6652 } 6653 return cpr != null ? cpr.newHolder(conn) : null; 6654 } 6655 6656 public final ContentProviderHolder getContentProvider( 6657 IApplicationThread caller, String name, boolean stable) { 6658 enforceNotIsolatedCaller("getContentProvider"); 6659 if (caller == null) { 6660 String msg = "null IApplicationThread when getting content provider " 6661 + name; 6662 Slog.w(TAG, msg); 6663 throw new SecurityException(msg); 6664 } 6665 6666 return getContentProviderImpl(caller, name, null, stable, 6667 UserHandle.getCallingUserId()); 6668 } 6669 6670 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6671 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6672 "Do not have permission in call getContentProviderExternal()"); 6673 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6674 } 6675 6676 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6677 IBinder token, int userId) { 6678 return getContentProviderImpl(null, name, token, true, userId); 6679 } 6680 6681 /** 6682 * Drop a content provider from a ProcessRecord's bookkeeping 6683 * @param cpr 6684 */ 6685 public void removeContentProvider(IBinder connection, boolean stable) { 6686 enforceNotIsolatedCaller("removeContentProvider"); 6687 synchronized (this) { 6688 ContentProviderConnection conn; 6689 try { 6690 conn = (ContentProviderConnection)connection; 6691 } catch (ClassCastException e) { 6692 String msg ="removeContentProvider: " + connection 6693 + " not a ContentProviderConnection"; 6694 Slog.w(TAG, msg); 6695 throw new IllegalArgumentException(msg); 6696 } 6697 if (conn == null) { 6698 throw new NullPointerException("connection is null"); 6699 } 6700 if (decProviderCountLocked(conn, null, null, stable)) { 6701 updateOomAdjLocked(); 6702 } 6703 } 6704 } 6705 6706 public void removeContentProviderExternal(String name, IBinder token) { 6707 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6708 "Do not have permission in call removeContentProviderExternal()"); 6709 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6710 } 6711 6712 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6713 synchronized (this) { 6714 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6715 if(cpr == null) { 6716 //remove from mProvidersByClass 6717 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6718 return; 6719 } 6720 6721 //update content provider record entry info 6722 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6723 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6724 if (localCpr.hasExternalProcessHandles()) { 6725 if (localCpr.removeExternalProcessHandleLocked(token)) { 6726 updateOomAdjLocked(); 6727 } else { 6728 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6729 + " with no external reference for token: " 6730 + token + "."); 6731 } 6732 } else { 6733 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6734 + " with no external references."); 6735 } 6736 } 6737 } 6738 6739 public final void publishContentProviders(IApplicationThread caller, 6740 List<ContentProviderHolder> providers) { 6741 if (providers == null) { 6742 return; 6743 } 6744 6745 enforceNotIsolatedCaller("publishContentProviders"); 6746 synchronized (this) { 6747 final ProcessRecord r = getRecordForAppLocked(caller); 6748 if (DEBUG_MU) 6749 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6750 if (r == null) { 6751 throw new SecurityException( 6752 "Unable to find app for caller " + caller 6753 + " (pid=" + Binder.getCallingPid() 6754 + ") when publishing content providers"); 6755 } 6756 6757 final long origId = Binder.clearCallingIdentity(); 6758 6759 final int N = providers.size(); 6760 for (int i=0; i<N; i++) { 6761 ContentProviderHolder src = providers.get(i); 6762 if (src == null || src.info == null || src.provider == null) { 6763 continue; 6764 } 6765 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6766 if (DEBUG_MU) 6767 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6768 if (dst != null) { 6769 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6770 mProviderMap.putProviderByClass(comp, dst); 6771 String names[] = dst.info.authority.split(";"); 6772 for (int j = 0; j < names.length; j++) { 6773 mProviderMap.putProviderByName(names[j], dst); 6774 } 6775 6776 int NL = mLaunchingProviders.size(); 6777 int j; 6778 for (j=0; j<NL; j++) { 6779 if (mLaunchingProviders.get(j) == dst) { 6780 mLaunchingProviders.remove(j); 6781 j--; 6782 NL--; 6783 } 6784 } 6785 synchronized (dst) { 6786 dst.provider = src.provider; 6787 dst.proc = r; 6788 dst.notifyAll(); 6789 } 6790 updateOomAdjLocked(r); 6791 } 6792 } 6793 6794 Binder.restoreCallingIdentity(origId); 6795 } 6796 } 6797 6798 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6799 ContentProviderConnection conn; 6800 try { 6801 conn = (ContentProviderConnection)connection; 6802 } catch (ClassCastException e) { 6803 String msg ="refContentProvider: " + connection 6804 + " not a ContentProviderConnection"; 6805 Slog.w(TAG, msg); 6806 throw new IllegalArgumentException(msg); 6807 } 6808 if (conn == null) { 6809 throw new NullPointerException("connection is null"); 6810 } 6811 6812 synchronized (this) { 6813 if (stable > 0) { 6814 conn.numStableIncs += stable; 6815 } 6816 stable = conn.stableCount + stable; 6817 if (stable < 0) { 6818 throw new IllegalStateException("stableCount < 0: " + stable); 6819 } 6820 6821 if (unstable > 0) { 6822 conn.numUnstableIncs += unstable; 6823 } 6824 unstable = conn.unstableCount + unstable; 6825 if (unstable < 0) { 6826 throw new IllegalStateException("unstableCount < 0: " + unstable); 6827 } 6828 6829 if ((stable+unstable) <= 0) { 6830 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6831 + stable + " unstable=" + unstable); 6832 } 6833 conn.stableCount = stable; 6834 conn.unstableCount = unstable; 6835 return !conn.dead; 6836 } 6837 } 6838 6839 public void unstableProviderDied(IBinder connection) { 6840 ContentProviderConnection conn; 6841 try { 6842 conn = (ContentProviderConnection)connection; 6843 } catch (ClassCastException e) { 6844 String msg ="refContentProvider: " + connection 6845 + " not a ContentProviderConnection"; 6846 Slog.w(TAG, msg); 6847 throw new IllegalArgumentException(msg); 6848 } 6849 if (conn == null) { 6850 throw new NullPointerException("connection is null"); 6851 } 6852 6853 // Safely retrieve the content provider associated with the connection. 6854 IContentProvider provider; 6855 synchronized (this) { 6856 provider = conn.provider.provider; 6857 } 6858 6859 if (provider == null) { 6860 // Um, yeah, we're way ahead of you. 6861 return; 6862 } 6863 6864 // Make sure the caller is being honest with us. 6865 if (provider.asBinder().pingBinder()) { 6866 // Er, no, still looks good to us. 6867 synchronized (this) { 6868 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6869 + " says " + conn + " died, but we don't agree"); 6870 return; 6871 } 6872 } 6873 6874 // Well look at that! It's dead! 6875 synchronized (this) { 6876 if (conn.provider.provider != provider) { 6877 // But something changed... good enough. 6878 return; 6879 } 6880 6881 ProcessRecord proc = conn.provider.proc; 6882 if (proc == null || proc.thread == null) { 6883 // Seems like the process is already cleaned up. 6884 return; 6885 } 6886 6887 // As far as we're concerned, this is just like receiving a 6888 // death notification... just a bit prematurely. 6889 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6890 + ") early provider death"); 6891 final long ident = Binder.clearCallingIdentity(); 6892 try { 6893 appDiedLocked(proc, proc.pid, proc.thread); 6894 } finally { 6895 Binder.restoreCallingIdentity(ident); 6896 } 6897 } 6898 } 6899 6900 public static final void installSystemProviders() { 6901 List<ProviderInfo> providers; 6902 synchronized (mSelf) { 6903 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6904 providers = mSelf.generateApplicationProvidersLocked(app); 6905 if (providers != null) { 6906 for (int i=providers.size()-1; i>=0; i--) { 6907 ProviderInfo pi = (ProviderInfo)providers.get(i); 6908 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6909 Slog.w(TAG, "Not installing system proc provider " + pi.name 6910 + ": not system .apk"); 6911 providers.remove(i); 6912 } 6913 } 6914 } 6915 } 6916 if (providers != null) { 6917 mSystemThread.installSystemProviders(providers); 6918 } 6919 6920 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6921 6922 mSelf.mUsageStatsService.monitorPackages(); 6923 } 6924 6925 /** 6926 * Allows app to retrieve the MIME type of a URI without having permission 6927 * to access its content provider. 6928 * 6929 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6930 * 6931 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6932 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6933 */ 6934 public String getProviderMimeType(Uri uri, int userId) { 6935 enforceNotIsolatedCaller("getProviderMimeType"); 6936 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6937 userId, false, true, "getProviderMimeType", null); 6938 final String name = uri.getAuthority(); 6939 final long ident = Binder.clearCallingIdentity(); 6940 ContentProviderHolder holder = null; 6941 6942 try { 6943 holder = getContentProviderExternalUnchecked(name, null, userId); 6944 if (holder != null) { 6945 return holder.provider.getType(uri); 6946 } 6947 } catch (RemoteException e) { 6948 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6949 return null; 6950 } finally { 6951 if (holder != null) { 6952 removeContentProviderExternalUnchecked(name, null, userId); 6953 } 6954 Binder.restoreCallingIdentity(ident); 6955 } 6956 6957 return null; 6958 } 6959 6960 // ========================================================= 6961 // GLOBAL MANAGEMENT 6962 // ========================================================= 6963 6964 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6965 ApplicationInfo info, String customProcess, boolean isolated) { 6966 String proc = customProcess != null ? customProcess : info.processName; 6967 BatteryStatsImpl.Uid.Proc ps = null; 6968 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6969 int uid = info.uid; 6970 if (isolated) { 6971 int userId = UserHandle.getUserId(uid); 6972 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6973 uid = 0; 6974 while (true) { 6975 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6976 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6977 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6978 } 6979 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6980 mNextIsolatedProcessUid++; 6981 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6982 // No process for this uid, use it. 6983 break; 6984 } 6985 stepsLeft--; 6986 if (stepsLeft <= 0) { 6987 return null; 6988 } 6989 } 6990 } 6991 synchronized (stats) { 6992 ps = stats.getProcessStatsLocked(info.uid, proc); 6993 } 6994 return new ProcessRecord(ps, thread, info, proc, uid); 6995 } 6996 6997 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6998 ProcessRecord app; 6999 if (!isolated) { 7000 app = getProcessRecordLocked(info.processName, info.uid); 7001 } else { 7002 app = null; 7003 } 7004 7005 if (app == null) { 7006 app = newProcessRecordLocked(null, info, null, isolated); 7007 mProcessNames.put(info.processName, app.uid, app); 7008 if (isolated) { 7009 mIsolatedProcesses.put(app.uid, app); 7010 } 7011 updateLruProcessLocked(app, true, true); 7012 } 7013 7014 // This package really, really can not be stopped. 7015 try { 7016 AppGlobals.getPackageManager().setPackageStoppedState( 7017 info.packageName, false, UserHandle.getUserId(app.uid)); 7018 } catch (RemoteException e) { 7019 } catch (IllegalArgumentException e) { 7020 Slog.w(TAG, "Failed trying to unstop package " 7021 + info.packageName + ": " + e); 7022 } 7023 7024 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7025 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7026 app.persistent = true; 7027 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7028 } 7029 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7030 mPersistentStartingProcesses.add(app); 7031 startProcessLocked(app, "added application", app.processName); 7032 } 7033 7034 return app; 7035 } 7036 7037 public void unhandledBack() { 7038 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7039 "unhandledBack()"); 7040 7041 synchronized(this) { 7042 int count = mMainStack.mHistory.size(); 7043 if (DEBUG_SWITCH) Slog.d( 7044 TAG, "Performing unhandledBack(): stack size = " + count); 7045 if (count > 1) { 7046 final long origId = Binder.clearCallingIdentity(); 7047 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7048 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7049 Binder.restoreCallingIdentity(origId); 7050 } 7051 } 7052 } 7053 7054 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7055 enforceNotIsolatedCaller("openContentUri"); 7056 final int userId = UserHandle.getCallingUserId(); 7057 String name = uri.getAuthority(); 7058 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7059 ParcelFileDescriptor pfd = null; 7060 if (cph != null) { 7061 // We record the binder invoker's uid in thread-local storage before 7062 // going to the content provider to open the file. Later, in the code 7063 // that handles all permissions checks, we look for this uid and use 7064 // that rather than the Activity Manager's own uid. The effect is that 7065 // we do the check against the caller's permissions even though it looks 7066 // to the content provider like the Activity Manager itself is making 7067 // the request. 7068 sCallerIdentity.set(new Identity( 7069 Binder.getCallingPid(), Binder.getCallingUid())); 7070 try { 7071 pfd = cph.provider.openFile(uri, "r"); 7072 } catch (FileNotFoundException e) { 7073 // do nothing; pfd will be returned null 7074 } finally { 7075 // Ensure that whatever happens, we clean up the identity state 7076 sCallerIdentity.remove(); 7077 } 7078 7079 // We've got the fd now, so we're done with the provider. 7080 removeContentProviderExternalUnchecked(name, null, userId); 7081 } else { 7082 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7083 } 7084 return pfd; 7085 } 7086 7087 // Actually is sleeping or shutting down or whatever else in the future 7088 // is an inactive state. 7089 public boolean isSleeping() { 7090 return mSleeping || mShuttingDown; 7091 } 7092 7093 public void goingToSleep() { 7094 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7095 != PackageManager.PERMISSION_GRANTED) { 7096 throw new SecurityException("Requires permission " 7097 + android.Manifest.permission.DEVICE_POWER); 7098 } 7099 7100 synchronized(this) { 7101 mWentToSleep = true; 7102 updateEventDispatchingLocked(); 7103 7104 if (!mSleeping) { 7105 mSleeping = true; 7106 mMainStack.stopIfSleepingLocked(); 7107 7108 // Initialize the wake times of all processes. 7109 checkExcessivePowerUsageLocked(false); 7110 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7111 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7112 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7113 } 7114 } 7115 } 7116 7117 public boolean shutdown(int timeout) { 7118 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7119 != PackageManager.PERMISSION_GRANTED) { 7120 throw new SecurityException("Requires permission " 7121 + android.Manifest.permission.SHUTDOWN); 7122 } 7123 7124 boolean timedout = false; 7125 7126 synchronized(this) { 7127 mShuttingDown = true; 7128 updateEventDispatchingLocked(); 7129 7130 if (mMainStack.mResumedActivity != null) { 7131 mMainStack.stopIfSleepingLocked(); 7132 final long endTime = System.currentTimeMillis() + timeout; 7133 while (mMainStack.mResumedActivity != null 7134 || mMainStack.mPausingActivity != null) { 7135 long delay = endTime - System.currentTimeMillis(); 7136 if (delay <= 0) { 7137 Slog.w(TAG, "Activity manager shutdown timed out"); 7138 timedout = true; 7139 break; 7140 } 7141 try { 7142 this.wait(); 7143 } catch (InterruptedException e) { 7144 } 7145 } 7146 } 7147 } 7148 7149 mUsageStatsService.shutdown(); 7150 mBatteryStatsService.shutdown(); 7151 7152 return timedout; 7153 } 7154 7155 public final void activitySlept(IBinder token) { 7156 if (localLOGV) Slog.v( 7157 TAG, "Activity slept: token=" + token); 7158 7159 ActivityRecord r = null; 7160 7161 final long origId = Binder.clearCallingIdentity(); 7162 7163 synchronized (this) { 7164 r = mMainStack.isInStackLocked(token); 7165 if (r != null) { 7166 mMainStack.activitySleptLocked(r); 7167 } 7168 } 7169 7170 Binder.restoreCallingIdentity(origId); 7171 } 7172 7173 private void comeOutOfSleepIfNeededLocked() { 7174 if (!mWentToSleep && !mLockScreenShown) { 7175 if (mSleeping) { 7176 mSleeping = false; 7177 mMainStack.awakeFromSleepingLocked(); 7178 mMainStack.resumeTopActivityLocked(null); 7179 } 7180 } 7181 } 7182 7183 public void wakingUp() { 7184 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7185 != PackageManager.PERMISSION_GRANTED) { 7186 throw new SecurityException("Requires permission " 7187 + android.Manifest.permission.DEVICE_POWER); 7188 } 7189 7190 synchronized(this) { 7191 mWentToSleep = false; 7192 updateEventDispatchingLocked(); 7193 comeOutOfSleepIfNeededLocked(); 7194 } 7195 } 7196 7197 private void updateEventDispatchingLocked() { 7198 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7199 } 7200 7201 public void setLockScreenShown(boolean shown) { 7202 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7203 != PackageManager.PERMISSION_GRANTED) { 7204 throw new SecurityException("Requires permission " 7205 + android.Manifest.permission.DEVICE_POWER); 7206 } 7207 7208 synchronized(this) { 7209 mLockScreenShown = shown; 7210 comeOutOfSleepIfNeededLocked(); 7211 } 7212 } 7213 7214 public void stopAppSwitches() { 7215 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7216 != PackageManager.PERMISSION_GRANTED) { 7217 throw new SecurityException("Requires permission " 7218 + android.Manifest.permission.STOP_APP_SWITCHES); 7219 } 7220 7221 synchronized(this) { 7222 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7223 + APP_SWITCH_DELAY_TIME; 7224 mDidAppSwitch = false; 7225 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7226 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7227 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7228 } 7229 } 7230 7231 public void resumeAppSwitches() { 7232 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7233 != PackageManager.PERMISSION_GRANTED) { 7234 throw new SecurityException("Requires permission " 7235 + android.Manifest.permission.STOP_APP_SWITCHES); 7236 } 7237 7238 synchronized(this) { 7239 // Note that we don't execute any pending app switches... we will 7240 // let those wait until either the timeout, or the next start 7241 // activity request. 7242 mAppSwitchesAllowedTime = 0; 7243 } 7244 } 7245 7246 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7247 String name) { 7248 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7249 return true; 7250 } 7251 7252 final int perm = checkComponentPermission( 7253 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7254 callingUid, -1, true); 7255 if (perm == PackageManager.PERMISSION_GRANTED) { 7256 return true; 7257 } 7258 7259 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7260 return false; 7261 } 7262 7263 public void setDebugApp(String packageName, boolean waitForDebugger, 7264 boolean persistent) { 7265 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7266 "setDebugApp()"); 7267 7268 // Note that this is not really thread safe if there are multiple 7269 // callers into it at the same time, but that's not a situation we 7270 // care about. 7271 if (persistent) { 7272 final ContentResolver resolver = mContext.getContentResolver(); 7273 Settings.System.putString( 7274 resolver, Settings.System.DEBUG_APP, 7275 packageName); 7276 Settings.System.putInt( 7277 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7278 waitForDebugger ? 1 : 0); 7279 } 7280 7281 synchronized (this) { 7282 if (!persistent) { 7283 mOrigDebugApp = mDebugApp; 7284 mOrigWaitForDebugger = mWaitForDebugger; 7285 } 7286 mDebugApp = packageName; 7287 mWaitForDebugger = waitForDebugger; 7288 mDebugTransient = !persistent; 7289 if (packageName != null) { 7290 final long origId = Binder.clearCallingIdentity(); 7291 forceStopPackageLocked(packageName, -1, false, false, true, true, 7292 UserHandle.USER_ALL); 7293 Binder.restoreCallingIdentity(origId); 7294 } 7295 } 7296 } 7297 7298 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7299 synchronized (this) { 7300 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7301 if (!isDebuggable) { 7302 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7303 throw new SecurityException("Process not debuggable: " + app.packageName); 7304 } 7305 } 7306 7307 mOpenGlTraceApp = processName; 7308 } 7309 } 7310 7311 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7312 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7313 synchronized (this) { 7314 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7315 if (!isDebuggable) { 7316 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7317 throw new SecurityException("Process not debuggable: " + app.packageName); 7318 } 7319 } 7320 mProfileApp = processName; 7321 mProfileFile = profileFile; 7322 if (mProfileFd != null) { 7323 try { 7324 mProfileFd.close(); 7325 } catch (IOException e) { 7326 } 7327 mProfileFd = null; 7328 } 7329 mProfileFd = profileFd; 7330 mProfileType = 0; 7331 mAutoStopProfiler = autoStopProfiler; 7332 } 7333 } 7334 7335 public void setAlwaysFinish(boolean enabled) { 7336 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7337 "setAlwaysFinish()"); 7338 7339 Settings.System.putInt( 7340 mContext.getContentResolver(), 7341 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7342 7343 synchronized (this) { 7344 mAlwaysFinishActivities = enabled; 7345 } 7346 } 7347 7348 public void setActivityController(IActivityController controller) { 7349 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7350 "setActivityController()"); 7351 synchronized (this) { 7352 mController = controller; 7353 } 7354 } 7355 7356 public boolean isUserAMonkey() { 7357 // For now the fact that there is a controller implies 7358 // we have a monkey. 7359 synchronized (this) { 7360 return mController != null; 7361 } 7362 } 7363 7364 public void registerProcessObserver(IProcessObserver observer) { 7365 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7366 "registerProcessObserver()"); 7367 synchronized (this) { 7368 mProcessObservers.register(observer); 7369 } 7370 } 7371 7372 public void unregisterProcessObserver(IProcessObserver observer) { 7373 synchronized (this) { 7374 mProcessObservers.unregister(observer); 7375 } 7376 } 7377 7378 public void setImmersive(IBinder token, boolean immersive) { 7379 synchronized(this) { 7380 ActivityRecord r = mMainStack.isInStackLocked(token); 7381 if (r == null) { 7382 throw new IllegalArgumentException(); 7383 } 7384 r.immersive = immersive; 7385 } 7386 } 7387 7388 public boolean isImmersive(IBinder token) { 7389 synchronized (this) { 7390 ActivityRecord r = mMainStack.isInStackLocked(token); 7391 if (r == null) { 7392 throw new IllegalArgumentException(); 7393 } 7394 return r.immersive; 7395 } 7396 } 7397 7398 public boolean isTopActivityImmersive() { 7399 enforceNotIsolatedCaller("startActivity"); 7400 synchronized (this) { 7401 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7402 return (r != null) ? r.immersive : false; 7403 } 7404 } 7405 7406 public final void enterSafeMode() { 7407 synchronized(this) { 7408 // It only makes sense to do this before the system is ready 7409 // and started launching other packages. 7410 if (!mSystemReady) { 7411 try { 7412 AppGlobals.getPackageManager().enterSafeMode(); 7413 } catch (RemoteException e) { 7414 } 7415 } 7416 } 7417 } 7418 7419 public final void showSafeModeOverlay() { 7420 View v = LayoutInflater.from(mContext).inflate( 7421 com.android.internal.R.layout.safe_mode, null); 7422 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7423 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7424 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7425 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7426 lp.gravity = Gravity.BOTTOM | Gravity.START; 7427 lp.format = v.getBackground().getOpacity(); 7428 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7429 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7430 ((WindowManager)mContext.getSystemService( 7431 Context.WINDOW_SERVICE)).addView(v, lp); 7432 } 7433 7434 public void noteWakeupAlarm(IIntentSender sender) { 7435 if (!(sender instanceof PendingIntentRecord)) { 7436 return; 7437 } 7438 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7439 synchronized (stats) { 7440 if (mBatteryStatsService.isOnBattery()) { 7441 mBatteryStatsService.enforceCallingPermission(); 7442 PendingIntentRecord rec = (PendingIntentRecord)sender; 7443 int MY_UID = Binder.getCallingUid(); 7444 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7445 BatteryStatsImpl.Uid.Pkg pkg = 7446 stats.getPackageStatsLocked(uid, rec.key.packageName); 7447 pkg.incWakeupsLocked(); 7448 } 7449 } 7450 } 7451 7452 public boolean killPids(int[] pids, String pReason, boolean secure) { 7453 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7454 throw new SecurityException("killPids only available to the system"); 7455 } 7456 String reason = (pReason == null) ? "Unknown" : pReason; 7457 // XXX Note: don't acquire main activity lock here, because the window 7458 // manager calls in with its locks held. 7459 7460 boolean killed = false; 7461 synchronized (mPidsSelfLocked) { 7462 int[] types = new int[pids.length]; 7463 int worstType = 0; 7464 for (int i=0; i<pids.length; i++) { 7465 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7466 if (proc != null) { 7467 int type = proc.setAdj; 7468 types[i] = type; 7469 if (type > worstType) { 7470 worstType = type; 7471 } 7472 } 7473 } 7474 7475 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7476 // then constrain it so we will kill all hidden procs. 7477 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7478 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7479 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7480 } 7481 7482 // If this is not a secure call, don't let it kill processes that 7483 // are important. 7484 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7485 worstType = ProcessList.SERVICE_ADJ; 7486 } 7487 7488 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7489 for (int i=0; i<pids.length; i++) { 7490 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7491 if (proc == null) { 7492 continue; 7493 } 7494 int adj = proc.setAdj; 7495 if (adj >= worstType && !proc.killedBackground) { 7496 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7497 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7498 proc.processName, adj, reason); 7499 killed = true; 7500 proc.killedBackground = true; 7501 Process.killProcessQuiet(pids[i]); 7502 } 7503 } 7504 } 7505 return killed; 7506 } 7507 7508 @Override 7509 public boolean killProcessesBelowForeground(String reason) { 7510 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7511 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7512 } 7513 7514 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7515 } 7516 7517 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7518 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7519 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7520 } 7521 7522 boolean killed = false; 7523 synchronized (mPidsSelfLocked) { 7524 final int size = mPidsSelfLocked.size(); 7525 for (int i = 0; i < size; i++) { 7526 final int pid = mPidsSelfLocked.keyAt(i); 7527 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7528 if (proc == null) continue; 7529 7530 final int adj = proc.setAdj; 7531 if (adj > belowAdj && !proc.killedBackground) { 7532 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7533 EventLog.writeEvent( 7534 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7535 killed = true; 7536 proc.killedBackground = true; 7537 Process.killProcessQuiet(pid); 7538 } 7539 } 7540 } 7541 return killed; 7542 } 7543 7544 public final void startRunning(String pkg, String cls, String action, 7545 String data) { 7546 synchronized(this) { 7547 if (mStartRunning) { 7548 return; 7549 } 7550 mStartRunning = true; 7551 mTopComponent = pkg != null && cls != null 7552 ? new ComponentName(pkg, cls) : null; 7553 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7554 mTopData = data; 7555 if (!mSystemReady) { 7556 return; 7557 } 7558 } 7559 7560 systemReady(null); 7561 } 7562 7563 private void retrieveSettings() { 7564 final ContentResolver resolver = mContext.getContentResolver(); 7565 String debugApp = Settings.System.getString( 7566 resolver, Settings.System.DEBUG_APP); 7567 boolean waitForDebugger = Settings.System.getInt( 7568 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7569 boolean alwaysFinishActivities = Settings.System.getInt( 7570 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7571 7572 Configuration configuration = new Configuration(); 7573 Settings.System.getConfiguration(resolver, configuration); 7574 7575 synchronized (this) { 7576 mDebugApp = mOrigDebugApp = debugApp; 7577 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7578 mAlwaysFinishActivities = alwaysFinishActivities; 7579 // This happens before any activities are started, so we can 7580 // change mConfiguration in-place. 7581 updateConfigurationLocked(configuration, null, false, true); 7582 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7583 } 7584 } 7585 7586 public boolean testIsSystemReady() { 7587 // no need to synchronize(this) just to read & return the value 7588 return mSystemReady; 7589 } 7590 7591 private static File getCalledPreBootReceiversFile() { 7592 File dataDir = Environment.getDataDirectory(); 7593 File systemDir = new File(dataDir, "system"); 7594 File fname = new File(systemDir, "called_pre_boots.dat"); 7595 return fname; 7596 } 7597 7598 static final int LAST_DONE_VERSION = 10000; 7599 7600 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7601 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7602 File file = getCalledPreBootReceiversFile(); 7603 FileInputStream fis = null; 7604 try { 7605 fis = new FileInputStream(file); 7606 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7607 int fvers = dis.readInt(); 7608 if (fvers == LAST_DONE_VERSION) { 7609 String vers = dis.readUTF(); 7610 String codename = dis.readUTF(); 7611 String build = dis.readUTF(); 7612 if (android.os.Build.VERSION.RELEASE.equals(vers) 7613 && android.os.Build.VERSION.CODENAME.equals(codename) 7614 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7615 int num = dis.readInt(); 7616 while (num > 0) { 7617 num--; 7618 String pkg = dis.readUTF(); 7619 String cls = dis.readUTF(); 7620 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7621 } 7622 } 7623 } 7624 } catch (FileNotFoundException e) { 7625 } catch (IOException e) { 7626 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7627 } finally { 7628 if (fis != null) { 7629 try { 7630 fis.close(); 7631 } catch (IOException e) { 7632 } 7633 } 7634 } 7635 return lastDoneReceivers; 7636 } 7637 7638 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7639 File file = getCalledPreBootReceiversFile(); 7640 FileOutputStream fos = null; 7641 DataOutputStream dos = null; 7642 try { 7643 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7644 fos = new FileOutputStream(file); 7645 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7646 dos.writeInt(LAST_DONE_VERSION); 7647 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7648 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7649 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7650 dos.writeInt(list.size()); 7651 for (int i=0; i<list.size(); i++) { 7652 dos.writeUTF(list.get(i).getPackageName()); 7653 dos.writeUTF(list.get(i).getClassName()); 7654 } 7655 } catch (IOException e) { 7656 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7657 file.delete(); 7658 } finally { 7659 FileUtils.sync(fos); 7660 if (dos != null) { 7661 try { 7662 dos.close(); 7663 } catch (IOException e) { 7664 // TODO Auto-generated catch block 7665 e.printStackTrace(); 7666 } 7667 } 7668 } 7669 } 7670 7671 public void systemReady(final Runnable goingCallback) { 7672 synchronized(this) { 7673 if (mSystemReady) { 7674 if (goingCallback != null) goingCallback.run(); 7675 return; 7676 } 7677 7678 // Check to see if there are any update receivers to run. 7679 if (!mDidUpdate) { 7680 if (mWaitingUpdate) { 7681 return; 7682 } 7683 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7684 List<ResolveInfo> ris = null; 7685 try { 7686 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7687 intent, null, 0, 0); 7688 } catch (RemoteException e) { 7689 } 7690 if (ris != null) { 7691 for (int i=ris.size()-1; i>=0; i--) { 7692 if ((ris.get(i).activityInfo.applicationInfo.flags 7693 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7694 ris.remove(i); 7695 } 7696 } 7697 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7698 7699 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7700 7701 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7702 for (int i=0; i<ris.size(); i++) { 7703 ActivityInfo ai = ris.get(i).activityInfo; 7704 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7705 if (lastDoneReceivers.contains(comp)) { 7706 ris.remove(i); 7707 i--; 7708 } 7709 } 7710 7711 final int[] users = getUsersLocked(); 7712 for (int i=0; i<ris.size(); i++) { 7713 ActivityInfo ai = ris.get(i).activityInfo; 7714 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7715 doneReceivers.add(comp); 7716 intent.setComponent(comp); 7717 for (int j=0; j<users.length; j++) { 7718 IIntentReceiver finisher = null; 7719 if (i == ris.size()-1 && j == users.length-1) { 7720 finisher = new IIntentReceiver.Stub() { 7721 public void performReceive(Intent intent, int resultCode, 7722 String data, Bundle extras, boolean ordered, 7723 boolean sticky, int sendingUser) { 7724 // The raw IIntentReceiver interface is called 7725 // with the AM lock held, so redispatch to 7726 // execute our code without the lock. 7727 mHandler.post(new Runnable() { 7728 public void run() { 7729 synchronized (ActivityManagerService.this) { 7730 mDidUpdate = true; 7731 } 7732 writeLastDonePreBootReceivers(doneReceivers); 7733 showBootMessage(mContext.getText( 7734 R.string.android_upgrading_complete), 7735 false); 7736 systemReady(goingCallback); 7737 } 7738 }); 7739 } 7740 }; 7741 } 7742 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7743 + " for user " + users[j]); 7744 broadcastIntentLocked(null, null, intent, null, finisher, 7745 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7746 users[j]); 7747 if (finisher != null) { 7748 mWaitingUpdate = true; 7749 } 7750 } 7751 } 7752 } 7753 if (mWaitingUpdate) { 7754 return; 7755 } 7756 mDidUpdate = true; 7757 } 7758 7759 mSystemReady = true; 7760 if (!mStartRunning) { 7761 return; 7762 } 7763 } 7764 7765 ArrayList<ProcessRecord> procsToKill = null; 7766 synchronized(mPidsSelfLocked) { 7767 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7768 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7769 if (!isAllowedWhileBooting(proc.info)){ 7770 if (procsToKill == null) { 7771 procsToKill = new ArrayList<ProcessRecord>(); 7772 } 7773 procsToKill.add(proc); 7774 } 7775 } 7776 } 7777 7778 synchronized(this) { 7779 if (procsToKill != null) { 7780 for (int i=procsToKill.size()-1; i>=0; i--) { 7781 ProcessRecord proc = procsToKill.get(i); 7782 Slog.i(TAG, "Removing system update proc: " + proc); 7783 removeProcessLocked(proc, true, false, "system update done"); 7784 } 7785 } 7786 7787 // Now that we have cleaned up any update processes, we 7788 // are ready to start launching real processes and know that 7789 // we won't trample on them any more. 7790 mProcessesReady = true; 7791 } 7792 7793 Slog.i(TAG, "System now ready"); 7794 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7795 SystemClock.uptimeMillis()); 7796 7797 synchronized(this) { 7798 // Make sure we have no pre-ready processes sitting around. 7799 7800 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7801 ResolveInfo ri = mContext.getPackageManager() 7802 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7803 STOCK_PM_FLAGS); 7804 CharSequence errorMsg = null; 7805 if (ri != null) { 7806 ActivityInfo ai = ri.activityInfo; 7807 ApplicationInfo app = ai.applicationInfo; 7808 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7809 mTopAction = Intent.ACTION_FACTORY_TEST; 7810 mTopData = null; 7811 mTopComponent = new ComponentName(app.packageName, 7812 ai.name); 7813 } else { 7814 errorMsg = mContext.getResources().getText( 7815 com.android.internal.R.string.factorytest_not_system); 7816 } 7817 } else { 7818 errorMsg = mContext.getResources().getText( 7819 com.android.internal.R.string.factorytest_no_action); 7820 } 7821 if (errorMsg != null) { 7822 mTopAction = null; 7823 mTopData = null; 7824 mTopComponent = null; 7825 Message msg = Message.obtain(); 7826 msg.what = SHOW_FACTORY_ERROR_MSG; 7827 msg.getData().putCharSequence("msg", errorMsg); 7828 mHandler.sendMessage(msg); 7829 } 7830 } 7831 } 7832 7833 retrieveSettings(); 7834 7835 if (goingCallback != null) goingCallback.run(); 7836 7837 synchronized (this) { 7838 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7839 try { 7840 List apps = AppGlobals.getPackageManager(). 7841 getPersistentApplications(STOCK_PM_FLAGS); 7842 if (apps != null) { 7843 int N = apps.size(); 7844 int i; 7845 for (i=0; i<N; i++) { 7846 ApplicationInfo info 7847 = (ApplicationInfo)apps.get(i); 7848 if (info != null && 7849 !info.packageName.equals("android")) { 7850 addAppLocked(info, false); 7851 } 7852 } 7853 } 7854 } catch (RemoteException ex) { 7855 // pm is in same process, this will never happen. 7856 } 7857 } 7858 7859 // Start up initial activity. 7860 mBooting = true; 7861 7862 try { 7863 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7864 Message msg = Message.obtain(); 7865 msg.what = SHOW_UID_ERROR_MSG; 7866 mHandler.sendMessage(msg); 7867 } 7868 } catch (RemoteException e) { 7869 } 7870 7871 long ident = Binder.clearCallingIdentity(); 7872 try { 7873 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7874 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7875 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7876 broadcastIntentLocked(null, null, intent, 7877 null, null, 0, null, null, null, 7878 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7879 } finally { 7880 Binder.restoreCallingIdentity(ident); 7881 } 7882 mMainStack.resumeTopActivityLocked(null); 7883 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7884 } 7885 } 7886 7887 private boolean makeAppCrashingLocked(ProcessRecord app, 7888 String shortMsg, String longMsg, String stackTrace) { 7889 app.crashing = true; 7890 app.crashingReport = generateProcessError(app, 7891 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7892 startAppProblemLocked(app); 7893 app.stopFreezingAllLocked(); 7894 return handleAppCrashLocked(app); 7895 } 7896 7897 private void makeAppNotRespondingLocked(ProcessRecord app, 7898 String activity, String shortMsg, String longMsg) { 7899 app.notResponding = true; 7900 app.notRespondingReport = generateProcessError(app, 7901 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7902 activity, shortMsg, longMsg, null); 7903 startAppProblemLocked(app); 7904 app.stopFreezingAllLocked(); 7905 } 7906 7907 /** 7908 * Generate a process error record, suitable for attachment to a ProcessRecord. 7909 * 7910 * @param app The ProcessRecord in which the error occurred. 7911 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7912 * ActivityManager.AppErrorStateInfo 7913 * @param activity The activity associated with the crash, if known. 7914 * @param shortMsg Short message describing the crash. 7915 * @param longMsg Long message describing the crash. 7916 * @param stackTrace Full crash stack trace, may be null. 7917 * 7918 * @return Returns a fully-formed AppErrorStateInfo record. 7919 */ 7920 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7921 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7922 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7923 7924 report.condition = condition; 7925 report.processName = app.processName; 7926 report.pid = app.pid; 7927 report.uid = app.info.uid; 7928 report.tag = activity; 7929 report.shortMsg = shortMsg; 7930 report.longMsg = longMsg; 7931 report.stackTrace = stackTrace; 7932 7933 return report; 7934 } 7935 7936 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7937 synchronized (this) { 7938 app.crashing = false; 7939 app.crashingReport = null; 7940 app.notResponding = false; 7941 app.notRespondingReport = null; 7942 if (app.anrDialog == fromDialog) { 7943 app.anrDialog = null; 7944 } 7945 if (app.waitDialog == fromDialog) { 7946 app.waitDialog = null; 7947 } 7948 if (app.pid > 0 && app.pid != MY_PID) { 7949 handleAppCrashLocked(app); 7950 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7951 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7952 app.processName, app.setAdj, "user's request after error"); 7953 Process.killProcessQuiet(app.pid); 7954 } 7955 } 7956 } 7957 7958 private boolean handleAppCrashLocked(ProcessRecord app) { 7959 if (mHeadless) { 7960 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7961 return false; 7962 } 7963 long now = SystemClock.uptimeMillis(); 7964 7965 Long crashTime; 7966 if (!app.isolated) { 7967 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7968 } else { 7969 crashTime = null; 7970 } 7971 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7972 // This process loses! 7973 Slog.w(TAG, "Process " + app.info.processName 7974 + " has crashed too many times: killing!"); 7975 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7976 app.info.processName, app.uid); 7977 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7978 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7979 if (r.app == app) { 7980 Slog.w(TAG, " Force finishing activity " 7981 + r.intent.getComponent().flattenToShortString()); 7982 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7983 null, "crashed", false); 7984 } 7985 } 7986 if (!app.persistent) { 7987 // We don't want to start this process again until the user 7988 // explicitly does so... but for persistent process, we really 7989 // need to keep it running. If a persistent process is actually 7990 // repeatedly crashing, then badness for everyone. 7991 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7992 app.info.processName); 7993 if (!app.isolated) { 7994 // XXX We don't have a way to mark isolated processes 7995 // as bad, since they don't have a peristent identity. 7996 mBadProcesses.put(app.info.processName, app.uid, now); 7997 mProcessCrashTimes.remove(app.info.processName, app.uid); 7998 } 7999 app.bad = true; 8000 app.removed = true; 8001 // Don't let services in this process be restarted and potentially 8002 // annoy the user repeatedly. Unless it is persistent, since those 8003 // processes run critical code. 8004 removeProcessLocked(app, false, false, "crash"); 8005 mMainStack.resumeTopActivityLocked(null); 8006 return false; 8007 } 8008 mMainStack.resumeTopActivityLocked(null); 8009 } else { 8010 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8011 if (r != null && r.app == app) { 8012 // If the top running activity is from this crashing 8013 // process, then terminate it to avoid getting in a loop. 8014 Slog.w(TAG, " Force finishing activity " 8015 + r.intent.getComponent().flattenToShortString()); 8016 int index = mMainStack.indexOfActivityLocked(r); 8017 r.stack.finishActivityLocked(r, index, 8018 Activity.RESULT_CANCELED, null, "crashed", false); 8019 // Also terminate any activities below it that aren't yet 8020 // stopped, to avoid a situation where one will get 8021 // re-start our crashing activity once it gets resumed again. 8022 index--; 8023 if (index >= 0) { 8024 r = (ActivityRecord)mMainStack.mHistory.get(index); 8025 if (r.state == ActivityState.RESUMED 8026 || r.state == ActivityState.PAUSING 8027 || r.state == ActivityState.PAUSED) { 8028 if (!r.isHomeActivity || mHomeProcess != r.app) { 8029 Slog.w(TAG, " Force finishing activity " 8030 + r.intent.getComponent().flattenToShortString()); 8031 r.stack.finishActivityLocked(r, index, 8032 Activity.RESULT_CANCELED, null, "crashed", false); 8033 } 8034 } 8035 } 8036 } 8037 } 8038 8039 // Bump up the crash count of any services currently running in the proc. 8040 if (app.services.size() != 0) { 8041 // Any services running in the application need to be placed 8042 // back in the pending list. 8043 Iterator<ServiceRecord> it = app.services.iterator(); 8044 while (it.hasNext()) { 8045 ServiceRecord sr = it.next(); 8046 sr.crashCount++; 8047 } 8048 } 8049 8050 // If the crashing process is what we consider to be the "home process" and it has been 8051 // replaced by a third-party app, clear the package preferred activities from packages 8052 // with a home activity running in the process to prevent a repeatedly crashing app 8053 // from blocking the user to manually clear the list. 8054 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8055 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8056 Iterator it = mHomeProcess.activities.iterator(); 8057 while (it.hasNext()) { 8058 ActivityRecord r = (ActivityRecord)it.next(); 8059 if (r.isHomeActivity) { 8060 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8061 try { 8062 ActivityThread.getPackageManager() 8063 .clearPackagePreferredActivities(r.packageName); 8064 } catch (RemoteException c) { 8065 // pm is in same process, this will never happen. 8066 } 8067 } 8068 } 8069 } 8070 8071 if (!app.isolated) { 8072 // XXX Can't keep track of crash times for isolated processes, 8073 // because they don't have a perisistent identity. 8074 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8075 } 8076 8077 return true; 8078 } 8079 8080 void startAppProblemLocked(ProcessRecord app) { 8081 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8082 mContext, app.info.packageName, app.info.flags); 8083 skipCurrentReceiverLocked(app); 8084 } 8085 8086 void skipCurrentReceiverLocked(ProcessRecord app) { 8087 for (BroadcastQueue queue : mBroadcastQueues) { 8088 queue.skipCurrentReceiverLocked(app); 8089 } 8090 } 8091 8092 /** 8093 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8094 * The application process will exit immediately after this call returns. 8095 * @param app object of the crashing app, null for the system server 8096 * @param crashInfo describing the exception 8097 */ 8098 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8099 ProcessRecord r = findAppProcess(app, "Crash"); 8100 final String processName = app == null ? "system_server" 8101 : (r == null ? "unknown" : r.processName); 8102 8103 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8104 processName, 8105 r == null ? -1 : r.info.flags, 8106 crashInfo.exceptionClassName, 8107 crashInfo.exceptionMessage, 8108 crashInfo.throwFileName, 8109 crashInfo.throwLineNumber); 8110 8111 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8112 8113 crashApplication(r, crashInfo); 8114 } 8115 8116 public void handleApplicationStrictModeViolation( 8117 IBinder app, 8118 int violationMask, 8119 StrictMode.ViolationInfo info) { 8120 ProcessRecord r = findAppProcess(app, "StrictMode"); 8121 if (r == null) { 8122 return; 8123 } 8124 8125 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8126 Integer stackFingerprint = info.hashCode(); 8127 boolean logIt = true; 8128 synchronized (mAlreadyLoggedViolatedStacks) { 8129 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8130 logIt = false; 8131 // TODO: sub-sample into EventLog for these, with 8132 // the info.durationMillis? Then we'd get 8133 // the relative pain numbers, without logging all 8134 // the stack traces repeatedly. We'd want to do 8135 // likewise in the client code, which also does 8136 // dup suppression, before the Binder call. 8137 } else { 8138 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8139 mAlreadyLoggedViolatedStacks.clear(); 8140 } 8141 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8142 } 8143 } 8144 if (logIt) { 8145 logStrictModeViolationToDropBox(r, info); 8146 } 8147 } 8148 8149 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8150 AppErrorResult result = new AppErrorResult(); 8151 synchronized (this) { 8152 final long origId = Binder.clearCallingIdentity(); 8153 8154 Message msg = Message.obtain(); 8155 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8156 HashMap<String, Object> data = new HashMap<String, Object>(); 8157 data.put("result", result); 8158 data.put("app", r); 8159 data.put("violationMask", violationMask); 8160 data.put("info", info); 8161 msg.obj = data; 8162 mHandler.sendMessage(msg); 8163 8164 Binder.restoreCallingIdentity(origId); 8165 } 8166 int res = result.get(); 8167 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8168 } 8169 } 8170 8171 // Depending on the policy in effect, there could be a bunch of 8172 // these in quick succession so we try to batch these together to 8173 // minimize disk writes, number of dropbox entries, and maximize 8174 // compression, by having more fewer, larger records. 8175 private void logStrictModeViolationToDropBox( 8176 ProcessRecord process, 8177 StrictMode.ViolationInfo info) { 8178 if (info == null) { 8179 return; 8180 } 8181 final boolean isSystemApp = process == null || 8182 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8183 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8184 final String processName = process == null ? "unknown" : process.processName; 8185 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8186 final DropBoxManager dbox = (DropBoxManager) 8187 mContext.getSystemService(Context.DROPBOX_SERVICE); 8188 8189 // Exit early if the dropbox isn't configured to accept this report type. 8190 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8191 8192 boolean bufferWasEmpty; 8193 boolean needsFlush; 8194 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8195 synchronized (sb) { 8196 bufferWasEmpty = sb.length() == 0; 8197 appendDropBoxProcessHeaders(process, processName, sb); 8198 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8199 sb.append("System-App: ").append(isSystemApp).append("\n"); 8200 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8201 if (info.violationNumThisLoop != 0) { 8202 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8203 } 8204 if (info.numAnimationsRunning != 0) { 8205 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8206 } 8207 if (info.broadcastIntentAction != null) { 8208 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8209 } 8210 if (info.durationMillis != -1) { 8211 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8212 } 8213 if (info.numInstances != -1) { 8214 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8215 } 8216 if (info.tags != null) { 8217 for (String tag : info.tags) { 8218 sb.append("Span-Tag: ").append(tag).append("\n"); 8219 } 8220 } 8221 sb.append("\n"); 8222 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8223 sb.append(info.crashInfo.stackTrace); 8224 } 8225 sb.append("\n"); 8226 8227 // Only buffer up to ~64k. Various logging bits truncate 8228 // things at 128k. 8229 needsFlush = (sb.length() > 64 * 1024); 8230 } 8231 8232 // Flush immediately if the buffer's grown too large, or this 8233 // is a non-system app. Non-system apps are isolated with a 8234 // different tag & policy and not batched. 8235 // 8236 // Batching is useful during internal testing with 8237 // StrictMode settings turned up high. Without batching, 8238 // thousands of separate files could be created on boot. 8239 if (!isSystemApp || needsFlush) { 8240 new Thread("Error dump: " + dropboxTag) { 8241 @Override 8242 public void run() { 8243 String report; 8244 synchronized (sb) { 8245 report = sb.toString(); 8246 sb.delete(0, sb.length()); 8247 sb.trimToSize(); 8248 } 8249 if (report.length() != 0) { 8250 dbox.addText(dropboxTag, report); 8251 } 8252 } 8253 }.start(); 8254 return; 8255 } 8256 8257 // System app batching: 8258 if (!bufferWasEmpty) { 8259 // An existing dropbox-writing thread is outstanding, so 8260 // we don't need to start it up. The existing thread will 8261 // catch the buffer appends we just did. 8262 return; 8263 } 8264 8265 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8266 // (After this point, we shouldn't access AMS internal data structures.) 8267 new Thread("Error dump: " + dropboxTag) { 8268 @Override 8269 public void run() { 8270 // 5 second sleep to let stacks arrive and be batched together 8271 try { 8272 Thread.sleep(5000); // 5 seconds 8273 } catch (InterruptedException e) {} 8274 8275 String errorReport; 8276 synchronized (mStrictModeBuffer) { 8277 errorReport = mStrictModeBuffer.toString(); 8278 if (errorReport.length() == 0) { 8279 return; 8280 } 8281 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8282 mStrictModeBuffer.trimToSize(); 8283 } 8284 dbox.addText(dropboxTag, errorReport); 8285 } 8286 }.start(); 8287 } 8288 8289 /** 8290 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8291 * @param app object of the crashing app, null for the system server 8292 * @param tag reported by the caller 8293 * @param crashInfo describing the context of the error 8294 * @return true if the process should exit immediately (WTF is fatal) 8295 */ 8296 public boolean handleApplicationWtf(IBinder app, String tag, 8297 ApplicationErrorReport.CrashInfo crashInfo) { 8298 ProcessRecord r = findAppProcess(app, "WTF"); 8299 final String processName = app == null ? "system_server" 8300 : (r == null ? "unknown" : r.processName); 8301 8302 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8303 processName, 8304 r == null ? -1 : r.info.flags, 8305 tag, crashInfo.exceptionMessage); 8306 8307 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8308 8309 if (r != null && r.pid != Process.myPid() && 8310 Settings.Secure.getInt(mContext.getContentResolver(), 8311 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8312 crashApplication(r, crashInfo); 8313 return true; 8314 } else { 8315 return false; 8316 } 8317 } 8318 8319 /** 8320 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8321 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8322 */ 8323 private ProcessRecord findAppProcess(IBinder app, String reason) { 8324 if (app == null) { 8325 return null; 8326 } 8327 8328 synchronized (this) { 8329 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8330 final int NA = apps.size(); 8331 for (int ia=0; ia<NA; ia++) { 8332 ProcessRecord p = apps.valueAt(ia); 8333 if (p.thread != null && p.thread.asBinder() == app) { 8334 return p; 8335 } 8336 } 8337 } 8338 8339 Slog.w(TAG, "Can't find mystery application for " + reason 8340 + " from pid=" + Binder.getCallingPid() 8341 + " uid=" + Binder.getCallingUid() + ": " + app); 8342 return null; 8343 } 8344 } 8345 8346 /** 8347 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8348 * to append various headers to the dropbox log text. 8349 */ 8350 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8351 StringBuilder sb) { 8352 // Watchdog thread ends up invoking this function (with 8353 // a null ProcessRecord) to add the stack file to dropbox. 8354 // Do not acquire a lock on this (am) in such cases, as it 8355 // could cause a potential deadlock, if and when watchdog 8356 // is invoked due to unavailability of lock on am and it 8357 // would prevent watchdog from killing system_server. 8358 if (process == null) { 8359 sb.append("Process: ").append(processName).append("\n"); 8360 return; 8361 } 8362 // Note: ProcessRecord 'process' is guarded by the service 8363 // instance. (notably process.pkgList, which could otherwise change 8364 // concurrently during execution of this method) 8365 synchronized (this) { 8366 sb.append("Process: ").append(processName).append("\n"); 8367 int flags = process.info.flags; 8368 IPackageManager pm = AppGlobals.getPackageManager(); 8369 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8370 for (String pkg : process.pkgList) { 8371 sb.append("Package: ").append(pkg); 8372 try { 8373 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8374 if (pi != null) { 8375 sb.append(" v").append(pi.versionCode); 8376 if (pi.versionName != null) { 8377 sb.append(" (").append(pi.versionName).append(")"); 8378 } 8379 } 8380 } catch (RemoteException e) { 8381 Slog.e(TAG, "Error getting package info: " + pkg, e); 8382 } 8383 sb.append("\n"); 8384 } 8385 } 8386 } 8387 8388 private static String processClass(ProcessRecord process) { 8389 if (process == null || process.pid == MY_PID) { 8390 return "system_server"; 8391 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8392 return "system_app"; 8393 } else { 8394 return "data_app"; 8395 } 8396 } 8397 8398 /** 8399 * Write a description of an error (crash, WTF, ANR) to the drop box. 8400 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8401 * @param process which caused the error, null means the system server 8402 * @param activity which triggered the error, null if unknown 8403 * @param parent activity related to the error, null if unknown 8404 * @param subject line related to the error, null if absent 8405 * @param report in long form describing the error, null if absent 8406 * @param logFile to include in the report, null if none 8407 * @param crashInfo giving an application stack trace, null if absent 8408 */ 8409 public void addErrorToDropBox(String eventType, 8410 ProcessRecord process, String processName, ActivityRecord activity, 8411 ActivityRecord parent, String subject, 8412 final String report, final File logFile, 8413 final ApplicationErrorReport.CrashInfo crashInfo) { 8414 // NOTE -- this must never acquire the ActivityManagerService lock, 8415 // otherwise the watchdog may be prevented from resetting the system. 8416 8417 final String dropboxTag = processClass(process) + "_" + eventType; 8418 final DropBoxManager dbox = (DropBoxManager) 8419 mContext.getSystemService(Context.DROPBOX_SERVICE); 8420 8421 // Exit early if the dropbox isn't configured to accept this report type. 8422 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8423 8424 final StringBuilder sb = new StringBuilder(1024); 8425 appendDropBoxProcessHeaders(process, processName, sb); 8426 if (activity != null) { 8427 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8428 } 8429 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8430 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8431 } 8432 if (parent != null && parent != activity) { 8433 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8434 } 8435 if (subject != null) { 8436 sb.append("Subject: ").append(subject).append("\n"); 8437 } 8438 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8439 if (Debug.isDebuggerConnected()) { 8440 sb.append("Debugger: Connected\n"); 8441 } 8442 sb.append("\n"); 8443 8444 // Do the rest in a worker thread to avoid blocking the caller on I/O 8445 // (After this point, we shouldn't access AMS internal data structures.) 8446 Thread worker = new Thread("Error dump: " + dropboxTag) { 8447 @Override 8448 public void run() { 8449 if (report != null) { 8450 sb.append(report); 8451 } 8452 if (logFile != null) { 8453 try { 8454 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8455 } catch (IOException e) { 8456 Slog.e(TAG, "Error reading " + logFile, e); 8457 } 8458 } 8459 if (crashInfo != null && crashInfo.stackTrace != null) { 8460 sb.append(crashInfo.stackTrace); 8461 } 8462 8463 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8464 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8465 if (lines > 0) { 8466 sb.append("\n"); 8467 8468 // Merge several logcat streams, and take the last N lines 8469 InputStreamReader input = null; 8470 try { 8471 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8472 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8473 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8474 8475 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8476 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8477 input = new InputStreamReader(logcat.getInputStream()); 8478 8479 int num; 8480 char[] buf = new char[8192]; 8481 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8482 } catch (IOException e) { 8483 Slog.e(TAG, "Error running logcat", e); 8484 } finally { 8485 if (input != null) try { input.close(); } catch (IOException e) {} 8486 } 8487 } 8488 8489 dbox.addText(dropboxTag, sb.toString()); 8490 } 8491 }; 8492 8493 if (process == null) { 8494 // If process is null, we are being called from some internal code 8495 // and may be about to die -- run this synchronously. 8496 worker.run(); 8497 } else { 8498 worker.start(); 8499 } 8500 } 8501 8502 /** 8503 * Bring up the "unexpected error" dialog box for a crashing app. 8504 * Deal with edge cases (intercepts from instrumented applications, 8505 * ActivityController, error intent receivers, that sort of thing). 8506 * @param r the application crashing 8507 * @param crashInfo describing the failure 8508 */ 8509 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8510 long timeMillis = System.currentTimeMillis(); 8511 String shortMsg = crashInfo.exceptionClassName; 8512 String longMsg = crashInfo.exceptionMessage; 8513 String stackTrace = crashInfo.stackTrace; 8514 if (shortMsg != null && longMsg != null) { 8515 longMsg = shortMsg + ": " + longMsg; 8516 } else if (shortMsg != null) { 8517 longMsg = shortMsg; 8518 } 8519 8520 AppErrorResult result = new AppErrorResult(); 8521 synchronized (this) { 8522 if (mController != null) { 8523 try { 8524 String name = r != null ? r.processName : null; 8525 int pid = r != null ? r.pid : Binder.getCallingPid(); 8526 if (!mController.appCrashed(name, pid, 8527 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8528 Slog.w(TAG, "Force-killing crashed app " + name 8529 + " at watcher's request"); 8530 Process.killProcess(pid); 8531 return; 8532 } 8533 } catch (RemoteException e) { 8534 mController = null; 8535 } 8536 } 8537 8538 final long origId = Binder.clearCallingIdentity(); 8539 8540 // If this process is running instrumentation, finish it. 8541 if (r != null && r.instrumentationClass != null) { 8542 Slog.w(TAG, "Error in app " + r.processName 8543 + " running instrumentation " + r.instrumentationClass + ":"); 8544 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8545 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8546 Bundle info = new Bundle(); 8547 info.putString("shortMsg", shortMsg); 8548 info.putString("longMsg", longMsg); 8549 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8550 Binder.restoreCallingIdentity(origId); 8551 return; 8552 } 8553 8554 // If we can't identify the process or it's already exceeded its crash quota, 8555 // quit right away without showing a crash dialog. 8556 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8557 Binder.restoreCallingIdentity(origId); 8558 return; 8559 } 8560 8561 Message msg = Message.obtain(); 8562 msg.what = SHOW_ERROR_MSG; 8563 HashMap data = new HashMap(); 8564 data.put("result", result); 8565 data.put("app", r); 8566 msg.obj = data; 8567 mHandler.sendMessage(msg); 8568 8569 Binder.restoreCallingIdentity(origId); 8570 } 8571 8572 int res = result.get(); 8573 8574 Intent appErrorIntent = null; 8575 synchronized (this) { 8576 if (r != null && !r.isolated) { 8577 // XXX Can't keep track of crash time for isolated processes, 8578 // since they don't have a persistent identity. 8579 mProcessCrashTimes.put(r.info.processName, r.uid, 8580 SystemClock.uptimeMillis()); 8581 } 8582 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8583 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8584 } 8585 } 8586 8587 if (appErrorIntent != null) { 8588 try { 8589 mContext.startActivity(appErrorIntent); 8590 } catch (ActivityNotFoundException e) { 8591 Slog.w(TAG, "bug report receiver dissappeared", e); 8592 } 8593 } 8594 } 8595 8596 Intent createAppErrorIntentLocked(ProcessRecord r, 8597 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8598 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8599 if (report == null) { 8600 return null; 8601 } 8602 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8603 result.setComponent(r.errorReportReceiver); 8604 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8605 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8606 return result; 8607 } 8608 8609 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8610 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8611 if (r.errorReportReceiver == null) { 8612 return null; 8613 } 8614 8615 if (!r.crashing && !r.notResponding) { 8616 return null; 8617 } 8618 8619 ApplicationErrorReport report = new ApplicationErrorReport(); 8620 report.packageName = r.info.packageName; 8621 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8622 report.processName = r.processName; 8623 report.time = timeMillis; 8624 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8625 8626 if (r.crashing) { 8627 report.type = ApplicationErrorReport.TYPE_CRASH; 8628 report.crashInfo = crashInfo; 8629 } else if (r.notResponding) { 8630 report.type = ApplicationErrorReport.TYPE_ANR; 8631 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8632 8633 report.anrInfo.activity = r.notRespondingReport.tag; 8634 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8635 report.anrInfo.info = r.notRespondingReport.longMsg; 8636 } 8637 8638 return report; 8639 } 8640 8641 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8642 enforceNotIsolatedCaller("getProcessesInErrorState"); 8643 // assume our apps are happy - lazy create the list 8644 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8645 8646 final boolean allUsers = ActivityManager.checkUidPermission( 8647 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8648 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8649 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8650 8651 synchronized (this) { 8652 8653 // iterate across all processes 8654 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8655 ProcessRecord app = mLruProcesses.get(i); 8656 if (!allUsers && app.userId != userId) { 8657 continue; 8658 } 8659 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8660 // This one's in trouble, so we'll generate a report for it 8661 // crashes are higher priority (in case there's a crash *and* an anr) 8662 ActivityManager.ProcessErrorStateInfo report = null; 8663 if (app.crashing) { 8664 report = app.crashingReport; 8665 } else if (app.notResponding) { 8666 report = app.notRespondingReport; 8667 } 8668 8669 if (report != null) { 8670 if (errList == null) { 8671 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8672 } 8673 errList.add(report); 8674 } else { 8675 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8676 " crashing = " + app.crashing + 8677 " notResponding = " + app.notResponding); 8678 } 8679 } 8680 } 8681 } 8682 8683 return errList; 8684 } 8685 8686 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8687 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8688 if (currApp != null) { 8689 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8690 } 8691 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8692 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8693 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8694 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8695 if (currApp != null) { 8696 currApp.lru = 0; 8697 } 8698 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8699 } else if (adj >= ProcessList.SERVICE_ADJ) { 8700 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8701 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8702 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8703 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8704 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8705 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8706 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8707 } else { 8708 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8709 } 8710 } 8711 8712 private void fillInProcMemInfo(ProcessRecord app, 8713 ActivityManager.RunningAppProcessInfo outInfo) { 8714 outInfo.pid = app.pid; 8715 outInfo.uid = app.info.uid; 8716 if (mHeavyWeightProcess == app) { 8717 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8718 } 8719 if (app.persistent) { 8720 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8721 } 8722 if (app.hasActivities) { 8723 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8724 } 8725 outInfo.lastTrimLevel = app.trimMemoryLevel; 8726 int adj = app.curAdj; 8727 outInfo.importance = oomAdjToImportance(adj, outInfo); 8728 outInfo.importanceReasonCode = app.adjTypeCode; 8729 } 8730 8731 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8732 enforceNotIsolatedCaller("getRunningAppProcesses"); 8733 // Lazy instantiation of list 8734 List<ActivityManager.RunningAppProcessInfo> runList = null; 8735 final boolean allUsers = ActivityManager.checkUidPermission( 8736 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8737 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8738 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8739 synchronized (this) { 8740 // Iterate across all processes 8741 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8742 ProcessRecord app = mLruProcesses.get(i); 8743 if (!allUsers && app.userId != userId) { 8744 continue; 8745 } 8746 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8747 // Generate process state info for running application 8748 ActivityManager.RunningAppProcessInfo currApp = 8749 new ActivityManager.RunningAppProcessInfo(app.processName, 8750 app.pid, app.getPackageList()); 8751 fillInProcMemInfo(app, currApp); 8752 if (app.adjSource instanceof ProcessRecord) { 8753 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8754 currApp.importanceReasonImportance = oomAdjToImportance( 8755 app.adjSourceOom, null); 8756 } else if (app.adjSource instanceof ActivityRecord) { 8757 ActivityRecord r = (ActivityRecord)app.adjSource; 8758 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8759 } 8760 if (app.adjTarget instanceof ComponentName) { 8761 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8762 } 8763 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8764 // + " lru=" + currApp.lru); 8765 if (runList == null) { 8766 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8767 } 8768 runList.add(currApp); 8769 } 8770 } 8771 } 8772 return runList; 8773 } 8774 8775 public List<ApplicationInfo> getRunningExternalApplications() { 8776 enforceNotIsolatedCaller("getRunningExternalApplications"); 8777 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8778 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8779 if (runningApps != null && runningApps.size() > 0) { 8780 Set<String> extList = new HashSet<String>(); 8781 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8782 if (app.pkgList != null) { 8783 for (String pkg : app.pkgList) { 8784 extList.add(pkg); 8785 } 8786 } 8787 } 8788 IPackageManager pm = AppGlobals.getPackageManager(); 8789 for (String pkg : extList) { 8790 try { 8791 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8792 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8793 retList.add(info); 8794 } 8795 } catch (RemoteException e) { 8796 } 8797 } 8798 } 8799 return retList; 8800 } 8801 8802 @Override 8803 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8804 enforceNotIsolatedCaller("getMyMemoryState"); 8805 synchronized (this) { 8806 ProcessRecord proc; 8807 synchronized (mPidsSelfLocked) { 8808 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8809 } 8810 fillInProcMemInfo(proc, outInfo); 8811 } 8812 } 8813 8814 @Override 8815 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8816 if (checkCallingPermission(android.Manifest.permission.DUMP) 8817 != PackageManager.PERMISSION_GRANTED) { 8818 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8819 + Binder.getCallingPid() 8820 + ", uid=" + Binder.getCallingUid() 8821 + " without permission " 8822 + android.Manifest.permission.DUMP); 8823 return; 8824 } 8825 8826 boolean dumpAll = false; 8827 boolean dumpClient = false; 8828 String dumpPackage = null; 8829 8830 int opti = 0; 8831 while (opti < args.length) { 8832 String opt = args[opti]; 8833 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8834 break; 8835 } 8836 opti++; 8837 if ("-a".equals(opt)) { 8838 dumpAll = true; 8839 } else if ("-c".equals(opt)) { 8840 dumpClient = true; 8841 } else if ("-h".equals(opt)) { 8842 pw.println("Activity manager dump options:"); 8843 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8844 pw.println(" cmd may be one of:"); 8845 pw.println(" a[ctivities]: activity stack state"); 8846 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8847 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8848 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8849 pw.println(" o[om]: out of memory management"); 8850 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8851 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8852 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8853 pw.println(" service [COMP_SPEC]: service client-side state"); 8854 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8855 pw.println(" all: dump all activities"); 8856 pw.println(" top: dump the top activity"); 8857 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8858 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8859 pw.println(" a partial substring in a component name, a"); 8860 pw.println(" hex object identifier."); 8861 pw.println(" -a: include all available server state."); 8862 pw.println(" -c: include client state."); 8863 return; 8864 } else { 8865 pw.println("Unknown argument: " + opt + "; use -h for help"); 8866 } 8867 } 8868 8869 long origId = Binder.clearCallingIdentity(); 8870 boolean more = false; 8871 // Is the caller requesting to dump a particular piece of data? 8872 if (opti < args.length) { 8873 String cmd = args[opti]; 8874 opti++; 8875 if ("activities".equals(cmd) || "a".equals(cmd)) { 8876 synchronized (this) { 8877 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8878 } 8879 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8880 String[] newArgs; 8881 String name; 8882 if (opti >= args.length) { 8883 name = null; 8884 newArgs = EMPTY_STRING_ARRAY; 8885 } else { 8886 name = args[opti]; 8887 opti++; 8888 newArgs = new String[args.length - opti]; 8889 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8890 args.length - opti); 8891 } 8892 synchronized (this) { 8893 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8894 } 8895 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8896 String[] newArgs; 8897 String name; 8898 if (opti >= args.length) { 8899 name = null; 8900 newArgs = EMPTY_STRING_ARRAY; 8901 } else { 8902 name = args[opti]; 8903 opti++; 8904 newArgs = new String[args.length - opti]; 8905 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8906 args.length - opti); 8907 } 8908 synchronized (this) { 8909 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8910 } 8911 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8912 String[] newArgs; 8913 String name; 8914 if (opti >= args.length) { 8915 name = null; 8916 newArgs = EMPTY_STRING_ARRAY; 8917 } else { 8918 name = args[opti]; 8919 opti++; 8920 newArgs = new String[args.length - opti]; 8921 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8922 args.length - opti); 8923 } 8924 synchronized (this) { 8925 dumpProcessesLocked(fd, pw, args, opti, true, name); 8926 } 8927 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8928 synchronized (this) { 8929 dumpOomLocked(fd, pw, args, opti, true); 8930 } 8931 } else if ("provider".equals(cmd)) { 8932 String[] newArgs; 8933 String name; 8934 if (opti >= args.length) { 8935 name = null; 8936 newArgs = EMPTY_STRING_ARRAY; 8937 } else { 8938 name = args[opti]; 8939 opti++; 8940 newArgs = new String[args.length - opti]; 8941 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8942 } 8943 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8944 pw.println("No providers match: " + name); 8945 pw.println("Use -h for help."); 8946 } 8947 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8948 synchronized (this) { 8949 dumpProvidersLocked(fd, pw, args, opti, true, null); 8950 } 8951 } else if ("service".equals(cmd)) { 8952 String[] newArgs; 8953 String name; 8954 if (opti >= args.length) { 8955 name = null; 8956 newArgs = EMPTY_STRING_ARRAY; 8957 } else { 8958 name = args[opti]; 8959 opti++; 8960 newArgs = new String[args.length - opti]; 8961 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8962 args.length - opti); 8963 } 8964 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8965 pw.println("No services match: " + name); 8966 pw.println("Use -h for help."); 8967 } 8968 } else if ("package".equals(cmd)) { 8969 String[] newArgs; 8970 if (opti >= args.length) { 8971 pw.println("package: no package name specified"); 8972 pw.println("Use -h for help."); 8973 } else { 8974 dumpPackage = args[opti]; 8975 opti++; 8976 newArgs = new String[args.length - opti]; 8977 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8978 args.length - opti); 8979 args = newArgs; 8980 opti = 0; 8981 more = true; 8982 } 8983 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8984 synchronized (this) { 8985 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8986 } 8987 } else { 8988 // Dumping a single activity? 8989 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8990 pw.println("Bad activity command, or no activities match: " + cmd); 8991 pw.println("Use -h for help."); 8992 } 8993 } 8994 if (!more) { 8995 Binder.restoreCallingIdentity(origId); 8996 return; 8997 } 8998 } 8999 9000 // No piece of data specified, dump everything. 9001 synchronized (this) { 9002 boolean needSep; 9003 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9004 if (needSep) { 9005 pw.println(" "); 9006 } 9007 if (dumpAll) { 9008 pw.println("-------------------------------------------------------------------------------"); 9009 } 9010 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9011 if (needSep) { 9012 pw.println(" "); 9013 } 9014 if (dumpAll) { 9015 pw.println("-------------------------------------------------------------------------------"); 9016 } 9017 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9018 if (needSep) { 9019 pw.println(" "); 9020 } 9021 if (dumpAll) { 9022 pw.println("-------------------------------------------------------------------------------"); 9023 } 9024 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9025 if (needSep) { 9026 pw.println(" "); 9027 } 9028 if (dumpAll) { 9029 pw.println("-------------------------------------------------------------------------------"); 9030 } 9031 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9032 if (needSep) { 9033 pw.println(" "); 9034 } 9035 if (dumpAll) { 9036 pw.println("-------------------------------------------------------------------------------"); 9037 } 9038 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9039 } 9040 Binder.restoreCallingIdentity(origId); 9041 } 9042 9043 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9044 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9045 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9046 pw.println(" Main stack:"); 9047 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9048 dumpPackage); 9049 pw.println(" "); 9050 pw.println(" Running activities (most recent first):"); 9051 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9052 dumpPackage); 9053 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9054 pw.println(" "); 9055 pw.println(" Activities waiting for another to become visible:"); 9056 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9057 !dumpAll, false, dumpPackage); 9058 } 9059 if (mMainStack.mStoppingActivities.size() > 0) { 9060 pw.println(" "); 9061 pw.println(" Activities waiting to stop:"); 9062 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9063 !dumpAll, false, dumpPackage); 9064 } 9065 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9066 pw.println(" "); 9067 pw.println(" Activities waiting to sleep:"); 9068 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9069 !dumpAll, false, dumpPackage); 9070 } 9071 if (mMainStack.mFinishingActivities.size() > 0) { 9072 pw.println(" "); 9073 pw.println(" Activities waiting to finish:"); 9074 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9075 !dumpAll, false, dumpPackage); 9076 } 9077 9078 pw.println(" "); 9079 if (mMainStack.mPausingActivity != null) { 9080 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9081 } 9082 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9083 pw.println(" mFocusedActivity: " + mFocusedActivity); 9084 if (dumpAll) { 9085 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9086 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9087 pw.println(" mDismissKeyguardOnNextActivity: " 9088 + mMainStack.mDismissKeyguardOnNextActivity); 9089 } 9090 9091 if (mRecentTasks.size() > 0) { 9092 pw.println(); 9093 pw.println(" Recent tasks:"); 9094 9095 final int N = mRecentTasks.size(); 9096 for (int i=0; i<N; i++) { 9097 TaskRecord tr = mRecentTasks.get(i); 9098 if (dumpPackage != null) { 9099 if (tr.realActivity == null || 9100 !dumpPackage.equals(tr.realActivity)) { 9101 continue; 9102 } 9103 } 9104 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9105 pw.println(tr); 9106 if (dumpAll) { 9107 mRecentTasks.get(i).dump(pw, " "); 9108 } 9109 } 9110 } 9111 9112 if (dumpAll) { 9113 pw.println(" "); 9114 pw.println(" mCurTask: " + mCurTask); 9115 } 9116 9117 return true; 9118 } 9119 9120 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9121 int opti, boolean dumpAll, String dumpPackage) { 9122 boolean needSep = false; 9123 int numPers = 0; 9124 9125 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9126 9127 if (dumpAll) { 9128 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9129 final int NA = procs.size(); 9130 for (int ia=0; ia<NA; ia++) { 9131 ProcessRecord r = procs.valueAt(ia); 9132 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9133 continue; 9134 } 9135 if (!needSep) { 9136 pw.println(" All known processes:"); 9137 needSep = true; 9138 } 9139 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9140 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9141 pw.print(" "); pw.println(r); 9142 r.dump(pw, " "); 9143 if (r.persistent) { 9144 numPers++; 9145 } 9146 } 9147 } 9148 } 9149 9150 if (mIsolatedProcesses.size() > 0) { 9151 if (needSep) pw.println(" "); 9152 needSep = true; 9153 pw.println(" Isolated process list (sorted by uid):"); 9154 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9155 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9156 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9157 continue; 9158 } 9159 pw.println(String.format("%sIsolated #%2d: %s", 9160 " ", i, r.toString())); 9161 } 9162 } 9163 9164 if (mLruProcesses.size() > 0) { 9165 if (needSep) pw.println(" "); 9166 needSep = true; 9167 pw.println(" Process LRU list (sorted by oom_adj):"); 9168 dumpProcessOomList(pw, this, mLruProcesses, " ", 9169 "Proc", "PERS", false, dumpPackage); 9170 needSep = true; 9171 } 9172 9173 if (dumpAll) { 9174 synchronized (mPidsSelfLocked) { 9175 boolean printed = false; 9176 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9177 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9178 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9179 continue; 9180 } 9181 if (!printed) { 9182 if (needSep) pw.println(" "); 9183 needSep = true; 9184 pw.println(" PID mappings:"); 9185 printed = true; 9186 } 9187 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9188 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9189 } 9190 } 9191 } 9192 9193 if (mForegroundProcesses.size() > 0) { 9194 synchronized (mPidsSelfLocked) { 9195 boolean printed = false; 9196 for (int i=0; i<mForegroundProcesses.size(); i++) { 9197 ProcessRecord r = mPidsSelfLocked.get( 9198 mForegroundProcesses.valueAt(i).pid); 9199 if (dumpPackage != null && (r == null 9200 || !dumpPackage.equals(r.info.packageName))) { 9201 continue; 9202 } 9203 if (!printed) { 9204 if (needSep) pw.println(" "); 9205 needSep = true; 9206 pw.println(" Foreground Processes:"); 9207 printed = true; 9208 } 9209 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9210 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9211 } 9212 } 9213 } 9214 9215 if (mPersistentStartingProcesses.size() > 0) { 9216 if (needSep) pw.println(" "); 9217 needSep = true; 9218 pw.println(" Persisent processes that are starting:"); 9219 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9220 "Starting Norm", "Restarting PERS", dumpPackage); 9221 } 9222 9223 if (mRemovedProcesses.size() > 0) { 9224 if (needSep) pw.println(" "); 9225 needSep = true; 9226 pw.println(" Processes that are being removed:"); 9227 dumpProcessList(pw, this, mRemovedProcesses, " ", 9228 "Removed Norm", "Removed PERS", dumpPackage); 9229 } 9230 9231 if (mProcessesOnHold.size() > 0) { 9232 if (needSep) pw.println(" "); 9233 needSep = true; 9234 pw.println(" Processes that are on old until the system is ready:"); 9235 dumpProcessList(pw, this, mProcessesOnHold, " ", 9236 "OnHold Norm", "OnHold PERS", dumpPackage); 9237 } 9238 9239 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9240 9241 if (mProcessCrashTimes.getMap().size() > 0) { 9242 boolean printed = false; 9243 long now = SystemClock.uptimeMillis(); 9244 for (Map.Entry<String, SparseArray<Long>> procs 9245 : mProcessCrashTimes.getMap().entrySet()) { 9246 String pname = procs.getKey(); 9247 SparseArray<Long> uids = procs.getValue(); 9248 final int N = uids.size(); 9249 for (int i=0; i<N; i++) { 9250 int puid = uids.keyAt(i); 9251 ProcessRecord r = mProcessNames.get(pname, puid); 9252 if (dumpPackage != null && (r == null 9253 || !dumpPackage.equals(r.info.packageName))) { 9254 continue; 9255 } 9256 if (!printed) { 9257 if (needSep) pw.println(" "); 9258 needSep = true; 9259 pw.println(" Time since processes crashed:"); 9260 printed = true; 9261 } 9262 pw.print(" Process "); pw.print(pname); 9263 pw.print(" uid "); pw.print(puid); 9264 pw.print(": last crashed "); 9265 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9266 pw.println(" ago"); 9267 } 9268 } 9269 } 9270 9271 if (mBadProcesses.getMap().size() > 0) { 9272 boolean printed = false; 9273 for (Map.Entry<String, SparseArray<Long>> procs 9274 : mBadProcesses.getMap().entrySet()) { 9275 String pname = procs.getKey(); 9276 SparseArray<Long> uids = procs.getValue(); 9277 final int N = uids.size(); 9278 for (int i=0; i<N; i++) { 9279 int puid = uids.keyAt(i); 9280 ProcessRecord r = mProcessNames.get(pname, puid); 9281 if (dumpPackage != null && (r == null 9282 || !dumpPackage.equals(r.info.packageName))) { 9283 continue; 9284 } 9285 if (!printed) { 9286 if (needSep) pw.println(" "); 9287 needSep = true; 9288 pw.println(" Bad processes:"); 9289 } 9290 pw.print(" Bad process "); pw.print(pname); 9291 pw.print(" uid "); pw.print(puid); 9292 pw.print(": crashed at time "); 9293 pw.println(uids.valueAt(i)); 9294 } 9295 } 9296 } 9297 9298 pw.println(); 9299 pw.println(" mStartedUsers:"); 9300 for (int i=0; i<mStartedUsers.size(); i++) { 9301 UserStartedState uss = mStartedUsers.valueAt(i); 9302 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9303 pw.print(": "); uss.dump("", pw); 9304 } 9305 pw.print(" mUserLru: ["); 9306 for (int i=0; i<mUserLru.size(); i++) { 9307 if (i > 0) pw.print(", "); 9308 pw.print(mUserLru.get(i)); 9309 } 9310 pw.println("]"); 9311 pw.println(" mHomeProcess: " + mHomeProcess); 9312 pw.println(" mPreviousProcess: " + mPreviousProcess); 9313 if (dumpAll) { 9314 StringBuilder sb = new StringBuilder(128); 9315 sb.append(" mPreviousProcessVisibleTime: "); 9316 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9317 pw.println(sb); 9318 } 9319 if (mHeavyWeightProcess != null) { 9320 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9321 } 9322 pw.println(" mConfiguration: " + mConfiguration); 9323 if (dumpAll) { 9324 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9325 if (mCompatModePackages.getPackages().size() > 0) { 9326 boolean printed = false; 9327 for (Map.Entry<String, Integer> entry 9328 : mCompatModePackages.getPackages().entrySet()) { 9329 String pkg = entry.getKey(); 9330 int mode = entry.getValue(); 9331 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9332 continue; 9333 } 9334 if (!printed) { 9335 pw.println(" mScreenCompatPackages:"); 9336 printed = true; 9337 } 9338 pw.print(" "); pw.print(pkg); pw.print(": "); 9339 pw.print(mode); pw.println(); 9340 } 9341 } 9342 } 9343 if (mSleeping || mWentToSleep || mLockScreenShown) { 9344 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9345 + " mLockScreenShown " + mLockScreenShown); 9346 } 9347 if (mShuttingDown) { 9348 pw.println(" mShuttingDown=" + mShuttingDown); 9349 } 9350 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9351 || mOrigWaitForDebugger) { 9352 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9353 + " mDebugTransient=" + mDebugTransient 9354 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9355 } 9356 if (mOpenGlTraceApp != null) { 9357 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9358 } 9359 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9360 || mProfileFd != null) { 9361 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9362 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9363 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9364 + mAutoStopProfiler); 9365 } 9366 if (mAlwaysFinishActivities || mController != null) { 9367 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9368 + " mController=" + mController); 9369 } 9370 if (dumpAll) { 9371 pw.println(" Total persistent processes: " + numPers); 9372 pw.println(" mStartRunning=" + mStartRunning 9373 + " mProcessesReady=" + mProcessesReady 9374 + " mSystemReady=" + mSystemReady); 9375 pw.println(" mBooting=" + mBooting 9376 + " mBooted=" + mBooted 9377 + " mFactoryTest=" + mFactoryTest); 9378 pw.print(" mLastPowerCheckRealtime="); 9379 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9380 pw.println(""); 9381 pw.print(" mLastPowerCheckUptime="); 9382 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9383 pw.println(""); 9384 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9385 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9386 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9387 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9388 + " mNumHiddenProcs=" + mNumHiddenProcs 9389 + " mNumServiceProcs=" + mNumServiceProcs 9390 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9391 } 9392 9393 return true; 9394 } 9395 9396 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9397 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9398 if (mProcessesToGc.size() > 0) { 9399 boolean printed = false; 9400 long now = SystemClock.uptimeMillis(); 9401 for (int i=0; i<mProcessesToGc.size(); i++) { 9402 ProcessRecord proc = mProcessesToGc.get(i); 9403 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9404 continue; 9405 } 9406 if (!printed) { 9407 if (needSep) pw.println(" "); 9408 needSep = true; 9409 pw.println(" Processes that are waiting to GC:"); 9410 printed = true; 9411 } 9412 pw.print(" Process "); pw.println(proc); 9413 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9414 pw.print(", last gced="); 9415 pw.print(now-proc.lastRequestedGc); 9416 pw.print(" ms ago, last lowMem="); 9417 pw.print(now-proc.lastLowMemory); 9418 pw.println(" ms ago"); 9419 9420 } 9421 } 9422 return needSep; 9423 } 9424 9425 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9426 int opti, boolean dumpAll) { 9427 boolean needSep = false; 9428 9429 if (mLruProcesses.size() > 0) { 9430 if (needSep) pw.println(" "); 9431 needSep = true; 9432 pw.println(" OOM levels:"); 9433 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9434 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9435 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9436 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9437 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9438 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9439 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9440 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9441 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9442 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9443 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9444 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9445 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9446 9447 if (needSep) pw.println(" "); 9448 needSep = true; 9449 pw.println(" Process OOM control:"); 9450 dumpProcessOomList(pw, this, mLruProcesses, " ", 9451 "Proc", "PERS", true, null); 9452 needSep = true; 9453 } 9454 9455 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9456 9457 pw.println(); 9458 pw.println(" mHomeProcess: " + mHomeProcess); 9459 pw.println(" mPreviousProcess: " + mPreviousProcess); 9460 if (mHeavyWeightProcess != null) { 9461 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9462 } 9463 9464 return true; 9465 } 9466 9467 /** 9468 * There are three ways to call this: 9469 * - no provider specified: dump all the providers 9470 * - a flattened component name that matched an existing provider was specified as the 9471 * first arg: dump that one provider 9472 * - the first arg isn't the flattened component name of an existing provider: 9473 * dump all providers whose component contains the first arg as a substring 9474 */ 9475 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9476 int opti, boolean dumpAll) { 9477 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9478 } 9479 9480 static class ItemMatcher { 9481 ArrayList<ComponentName> components; 9482 ArrayList<String> strings; 9483 ArrayList<Integer> objects; 9484 boolean all; 9485 9486 ItemMatcher() { 9487 all = true; 9488 } 9489 9490 void build(String name) { 9491 ComponentName componentName = ComponentName.unflattenFromString(name); 9492 if (componentName != null) { 9493 if (components == null) { 9494 components = new ArrayList<ComponentName>(); 9495 } 9496 components.add(componentName); 9497 all = false; 9498 } else { 9499 int objectId = 0; 9500 // Not a '/' separated full component name; maybe an object ID? 9501 try { 9502 objectId = Integer.parseInt(name, 16); 9503 if (objects == null) { 9504 objects = new ArrayList<Integer>(); 9505 } 9506 objects.add(objectId); 9507 all = false; 9508 } catch (RuntimeException e) { 9509 // Not an integer; just do string match. 9510 if (strings == null) { 9511 strings = new ArrayList<String>(); 9512 } 9513 strings.add(name); 9514 all = false; 9515 } 9516 } 9517 } 9518 9519 int build(String[] args, int opti) { 9520 for (; opti<args.length; opti++) { 9521 String name = args[opti]; 9522 if ("--".equals(name)) { 9523 return opti+1; 9524 } 9525 build(name); 9526 } 9527 return opti; 9528 } 9529 9530 boolean match(Object object, ComponentName comp) { 9531 if (all) { 9532 return true; 9533 } 9534 if (components != null) { 9535 for (int i=0; i<components.size(); i++) { 9536 if (components.get(i).equals(comp)) { 9537 return true; 9538 } 9539 } 9540 } 9541 if (objects != null) { 9542 for (int i=0; i<objects.size(); i++) { 9543 if (System.identityHashCode(object) == objects.get(i)) { 9544 return true; 9545 } 9546 } 9547 } 9548 if (strings != null) { 9549 String flat = comp.flattenToString(); 9550 for (int i=0; i<strings.size(); i++) { 9551 if (flat.contains(strings.get(i))) { 9552 return true; 9553 } 9554 } 9555 } 9556 return false; 9557 } 9558 } 9559 9560 /** 9561 * There are three things that cmd can be: 9562 * - a flattened component name that matches an existing activity 9563 * - the cmd arg isn't the flattened component name of an existing activity: 9564 * dump all activity whose component contains the cmd as a substring 9565 * - A hex number of the ActivityRecord object instance. 9566 */ 9567 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9568 int opti, boolean dumpAll) { 9569 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9570 9571 if ("all".equals(name)) { 9572 synchronized (this) { 9573 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9574 activities.add(r1); 9575 } 9576 } 9577 } else if ("top".equals(name)) { 9578 synchronized (this) { 9579 final int N = mMainStack.mHistory.size(); 9580 if (N > 0) { 9581 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9582 } 9583 } 9584 } else { 9585 ItemMatcher matcher = new ItemMatcher(); 9586 matcher.build(name); 9587 9588 synchronized (this) { 9589 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9590 if (matcher.match(r1, r1.intent.getComponent())) { 9591 activities.add(r1); 9592 } 9593 } 9594 } 9595 } 9596 9597 if (activities.size() <= 0) { 9598 return false; 9599 } 9600 9601 String[] newArgs = new String[args.length - opti]; 9602 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9603 9604 TaskRecord lastTask = null; 9605 boolean needSep = false; 9606 for (int i=activities.size()-1; i>=0; i--) { 9607 ActivityRecord r = (ActivityRecord)activities.get(i); 9608 if (needSep) { 9609 pw.println(); 9610 } 9611 needSep = true; 9612 synchronized (this) { 9613 if (lastTask != r.task) { 9614 lastTask = r.task; 9615 pw.print("TASK "); pw.print(lastTask.affinity); 9616 pw.print(" id="); pw.println(lastTask.taskId); 9617 if (dumpAll) { 9618 lastTask.dump(pw, " "); 9619 } 9620 } 9621 } 9622 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9623 } 9624 return true; 9625 } 9626 9627 /** 9628 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9629 * there is a thread associated with the activity. 9630 */ 9631 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9632 final ActivityRecord r, String[] args, boolean dumpAll) { 9633 String innerPrefix = prefix + " "; 9634 synchronized (this) { 9635 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9636 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9637 pw.print(" pid="); 9638 if (r.app != null) pw.println(r.app.pid); 9639 else pw.println("(not running)"); 9640 if (dumpAll) { 9641 r.dump(pw, innerPrefix); 9642 } 9643 } 9644 if (r.app != null && r.app.thread != null) { 9645 // flush anything that is already in the PrintWriter since the thread is going 9646 // to write to the file descriptor directly 9647 pw.flush(); 9648 try { 9649 TransferPipe tp = new TransferPipe(); 9650 try { 9651 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9652 r.appToken, innerPrefix, args); 9653 tp.go(fd); 9654 } finally { 9655 tp.kill(); 9656 } 9657 } catch (IOException e) { 9658 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9659 } catch (RemoteException e) { 9660 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9661 } 9662 } 9663 } 9664 9665 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9666 int opti, boolean dumpAll, String dumpPackage) { 9667 boolean needSep = false; 9668 boolean onlyHistory = false; 9669 9670 if ("history".equals(dumpPackage)) { 9671 onlyHistory = true; 9672 dumpPackage = null; 9673 } 9674 9675 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9676 if (!onlyHistory && dumpAll) { 9677 if (mRegisteredReceivers.size() > 0) { 9678 boolean printed = false; 9679 Iterator it = mRegisteredReceivers.values().iterator(); 9680 while (it.hasNext()) { 9681 ReceiverList r = (ReceiverList)it.next(); 9682 if (dumpPackage != null && (r.app == null || 9683 !dumpPackage.equals(r.app.info.packageName))) { 9684 continue; 9685 } 9686 if (!printed) { 9687 pw.println(" Registered Receivers:"); 9688 needSep = true; 9689 printed = true; 9690 } 9691 pw.print(" * "); pw.println(r); 9692 r.dump(pw, " "); 9693 } 9694 } 9695 9696 if (mReceiverResolver.dump(pw, needSep ? 9697 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9698 " ", dumpPackage, false)) { 9699 needSep = true; 9700 } 9701 } 9702 9703 for (BroadcastQueue q : mBroadcastQueues) { 9704 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9705 } 9706 9707 needSep = true; 9708 9709 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9710 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9711 if (needSep) { 9712 pw.println(); 9713 } 9714 needSep = true; 9715 pw.print(" Sticky broadcasts for user "); 9716 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9717 StringBuilder sb = new StringBuilder(128); 9718 for (Map.Entry<String, ArrayList<Intent>> ent 9719 : mStickyBroadcasts.valueAt(user).entrySet()) { 9720 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9721 if (dumpAll) { 9722 pw.println(":"); 9723 ArrayList<Intent> intents = ent.getValue(); 9724 final int N = intents.size(); 9725 for (int i=0; i<N; i++) { 9726 sb.setLength(0); 9727 sb.append(" Intent: "); 9728 intents.get(i).toShortString(sb, false, true, false, false); 9729 pw.println(sb.toString()); 9730 Bundle bundle = intents.get(i).getExtras(); 9731 if (bundle != null) { 9732 pw.print(" "); 9733 pw.println(bundle.toString()); 9734 } 9735 } 9736 } else { 9737 pw.println(""); 9738 } 9739 } 9740 } 9741 } 9742 9743 if (!onlyHistory && dumpAll) { 9744 pw.println(); 9745 for (BroadcastQueue queue : mBroadcastQueues) { 9746 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9747 + queue.mBroadcastsScheduled); 9748 } 9749 pw.println(" mHandler:"); 9750 mHandler.dump(new PrintWriterPrinter(pw), " "); 9751 needSep = true; 9752 } 9753 9754 return needSep; 9755 } 9756 9757 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9758 int opti, boolean dumpAll, String dumpPackage) { 9759 boolean needSep = true; 9760 9761 ItemMatcher matcher = new ItemMatcher(); 9762 matcher.build(args, opti); 9763 9764 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9765 9766 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9767 9768 if (mLaunchingProviders.size() > 0) { 9769 boolean printed = false; 9770 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9771 ContentProviderRecord r = mLaunchingProviders.get(i); 9772 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9773 continue; 9774 } 9775 if (!printed) { 9776 if (needSep) pw.println(" "); 9777 needSep = true; 9778 pw.println(" Launching content providers:"); 9779 printed = true; 9780 } 9781 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9782 pw.println(r); 9783 } 9784 } 9785 9786 if (mGrantedUriPermissions.size() > 0) { 9787 if (needSep) pw.println(); 9788 needSep = true; 9789 pw.println("Granted Uri Permissions:"); 9790 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9791 int uid = mGrantedUriPermissions.keyAt(i); 9792 HashMap<Uri, UriPermission> perms 9793 = mGrantedUriPermissions.valueAt(i); 9794 pw.print(" * UID "); pw.print(uid); 9795 pw.println(" holds:"); 9796 for (UriPermission perm : perms.values()) { 9797 pw.print(" "); pw.println(perm); 9798 if (dumpAll) { 9799 perm.dump(pw, " "); 9800 } 9801 } 9802 } 9803 needSep = true; 9804 } 9805 9806 return needSep; 9807 } 9808 9809 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9810 int opti, boolean dumpAll, String dumpPackage) { 9811 boolean needSep = false; 9812 9813 if (mIntentSenderRecords.size() > 0) { 9814 boolean printed = false; 9815 Iterator<WeakReference<PendingIntentRecord>> it 9816 = mIntentSenderRecords.values().iterator(); 9817 while (it.hasNext()) { 9818 WeakReference<PendingIntentRecord> ref = it.next(); 9819 PendingIntentRecord rec = ref != null ? ref.get(): null; 9820 if (dumpPackage != null && (rec == null 9821 || !dumpPackage.equals(rec.key.packageName))) { 9822 continue; 9823 } 9824 if (!printed) { 9825 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9826 printed = true; 9827 } 9828 needSep = true; 9829 if (rec != null) { 9830 pw.print(" * "); pw.println(rec); 9831 if (dumpAll) { 9832 rec.dump(pw, " "); 9833 } 9834 } else { 9835 pw.print(" * "); pw.println(ref); 9836 } 9837 } 9838 } 9839 9840 return needSep; 9841 } 9842 9843 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9844 String prefix, String label, boolean complete, boolean brief, boolean client, 9845 String dumpPackage) { 9846 TaskRecord lastTask = null; 9847 boolean needNL = false; 9848 final String innerPrefix = prefix + " "; 9849 final String[] args = new String[0]; 9850 for (int i=list.size()-1; i>=0; i--) { 9851 final ActivityRecord r = (ActivityRecord)list.get(i); 9852 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9853 continue; 9854 } 9855 final boolean full = !brief && (complete || !r.isInHistory()); 9856 if (needNL) { 9857 pw.println(" "); 9858 needNL = false; 9859 } 9860 if (lastTask != r.task) { 9861 lastTask = r.task; 9862 pw.print(prefix); 9863 pw.print(full ? "* " : " "); 9864 pw.println(lastTask); 9865 if (full) { 9866 lastTask.dump(pw, prefix + " "); 9867 } else if (complete) { 9868 // Complete + brief == give a summary. Isn't that obvious?!? 9869 if (lastTask.intent != null) { 9870 pw.print(prefix); pw.print(" "); 9871 pw.println(lastTask.intent.toInsecureStringWithClip()); 9872 } 9873 } 9874 } 9875 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9876 pw.print(" #"); pw.print(i); pw.print(": "); 9877 pw.println(r); 9878 if (full) { 9879 r.dump(pw, innerPrefix); 9880 } else if (complete) { 9881 // Complete + brief == give a summary. Isn't that obvious?!? 9882 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9883 if (r.app != null) { 9884 pw.print(innerPrefix); pw.println(r.app); 9885 } 9886 } 9887 if (client && r.app != null && r.app.thread != null) { 9888 // flush anything that is already in the PrintWriter since the thread is going 9889 // to write to the file descriptor directly 9890 pw.flush(); 9891 try { 9892 TransferPipe tp = new TransferPipe(); 9893 try { 9894 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9895 r.appToken, innerPrefix, args); 9896 // Short timeout, since blocking here can 9897 // deadlock with the application. 9898 tp.go(fd, 2000); 9899 } finally { 9900 tp.kill(); 9901 } 9902 } catch (IOException e) { 9903 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9904 } catch (RemoteException e) { 9905 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9906 } 9907 needNL = true; 9908 } 9909 } 9910 } 9911 9912 private static String buildOomTag(String prefix, String space, int val, int base) { 9913 if (val == base) { 9914 if (space == null) return prefix; 9915 return prefix + " "; 9916 } 9917 return prefix + "+" + Integer.toString(val-base); 9918 } 9919 9920 private static final int dumpProcessList(PrintWriter pw, 9921 ActivityManagerService service, List list, 9922 String prefix, String normalLabel, String persistentLabel, 9923 String dumpPackage) { 9924 int numPers = 0; 9925 final int N = list.size()-1; 9926 for (int i=N; i>=0; i--) { 9927 ProcessRecord r = (ProcessRecord)list.get(i); 9928 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9929 continue; 9930 } 9931 pw.println(String.format("%s%s #%2d: %s", 9932 prefix, (r.persistent ? persistentLabel : normalLabel), 9933 i, r.toString())); 9934 if (r.persistent) { 9935 numPers++; 9936 } 9937 } 9938 return numPers; 9939 } 9940 9941 private static final boolean dumpProcessOomList(PrintWriter pw, 9942 ActivityManagerService service, List<ProcessRecord> origList, 9943 String prefix, String normalLabel, String persistentLabel, 9944 boolean inclDetails, String dumpPackage) { 9945 9946 ArrayList<Pair<ProcessRecord, Integer>> list 9947 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9948 for (int i=0; i<origList.size(); i++) { 9949 ProcessRecord r = origList.get(i); 9950 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9951 continue; 9952 } 9953 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9954 } 9955 9956 if (list.size() <= 0) { 9957 return false; 9958 } 9959 9960 Comparator<Pair<ProcessRecord, Integer>> comparator 9961 = new Comparator<Pair<ProcessRecord, Integer>>() { 9962 @Override 9963 public int compare(Pair<ProcessRecord, Integer> object1, 9964 Pair<ProcessRecord, Integer> object2) { 9965 if (object1.first.setAdj != object2.first.setAdj) { 9966 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9967 } 9968 if (object1.second.intValue() != object2.second.intValue()) { 9969 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9970 } 9971 return 0; 9972 } 9973 }; 9974 9975 Collections.sort(list, comparator); 9976 9977 final long curRealtime = SystemClock.elapsedRealtime(); 9978 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9979 final long curUptime = SystemClock.uptimeMillis(); 9980 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9981 9982 for (int i=list.size()-1; i>=0; i--) { 9983 ProcessRecord r = list.get(i).first; 9984 String oomAdj; 9985 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9986 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9987 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9988 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9989 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9990 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9991 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9992 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9993 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9994 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9995 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9996 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9997 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9998 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9999 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10000 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10001 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10002 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10003 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10004 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10005 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10006 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10007 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10008 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10009 } else { 10010 oomAdj = Integer.toString(r.setAdj); 10011 } 10012 String schedGroup; 10013 switch (r.setSchedGroup) { 10014 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10015 schedGroup = "B"; 10016 break; 10017 case Process.THREAD_GROUP_DEFAULT: 10018 schedGroup = "F"; 10019 break; 10020 default: 10021 schedGroup = Integer.toString(r.setSchedGroup); 10022 break; 10023 } 10024 String foreground; 10025 if (r.foregroundActivities) { 10026 foreground = "A"; 10027 } else if (r.foregroundServices) { 10028 foreground = "S"; 10029 } else { 10030 foreground = " "; 10031 } 10032 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10033 prefix, (r.persistent ? persistentLabel : normalLabel), 10034 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10035 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10036 if (r.adjSource != null || r.adjTarget != null) { 10037 pw.print(prefix); 10038 pw.print(" "); 10039 if (r.adjTarget instanceof ComponentName) { 10040 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10041 } else if (r.adjTarget != null) { 10042 pw.print(r.adjTarget.toString()); 10043 } else { 10044 pw.print("{null}"); 10045 } 10046 pw.print("<="); 10047 if (r.adjSource instanceof ProcessRecord) { 10048 pw.print("Proc{"); 10049 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10050 pw.println("}"); 10051 } else if (r.adjSource != null) { 10052 pw.println(r.adjSource.toString()); 10053 } else { 10054 pw.println("{null}"); 10055 } 10056 } 10057 if (inclDetails) { 10058 pw.print(prefix); 10059 pw.print(" "); 10060 pw.print("oom: max="); pw.print(r.maxAdj); 10061 pw.print(" hidden="); pw.print(r.hiddenAdj); 10062 pw.print(" empty="); pw.print(r.emptyAdj); 10063 pw.print(" curRaw="); pw.print(r.curRawAdj); 10064 pw.print(" setRaw="); pw.print(r.setRawAdj); 10065 pw.print(" cur="); pw.print(r.curAdj); 10066 pw.print(" set="); pw.println(r.setAdj); 10067 pw.print(prefix); 10068 pw.print(" "); 10069 pw.print("keeping="); pw.print(r.keeping); 10070 pw.print(" hidden="); pw.print(r.hidden); 10071 pw.print(" empty="); pw.print(r.empty); 10072 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10073 10074 if (!r.keeping) { 10075 if (r.lastWakeTime != 0) { 10076 long wtime; 10077 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10078 synchronized (stats) { 10079 wtime = stats.getProcessWakeTime(r.info.uid, 10080 r.pid, curRealtime); 10081 } 10082 long timeUsed = wtime - r.lastWakeTime; 10083 pw.print(prefix); 10084 pw.print(" "); 10085 pw.print("keep awake over "); 10086 TimeUtils.formatDuration(realtimeSince, pw); 10087 pw.print(" used "); 10088 TimeUtils.formatDuration(timeUsed, pw); 10089 pw.print(" ("); 10090 pw.print((timeUsed*100)/realtimeSince); 10091 pw.println("%)"); 10092 } 10093 if (r.lastCpuTime != 0) { 10094 long timeUsed = r.curCpuTime - r.lastCpuTime; 10095 pw.print(prefix); 10096 pw.print(" "); 10097 pw.print("run cpu over "); 10098 TimeUtils.formatDuration(uptimeSince, pw); 10099 pw.print(" used "); 10100 TimeUtils.formatDuration(timeUsed, pw); 10101 pw.print(" ("); 10102 pw.print((timeUsed*100)/uptimeSince); 10103 pw.println("%)"); 10104 } 10105 } 10106 } 10107 } 10108 return true; 10109 } 10110 10111 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10112 ArrayList<ProcessRecord> procs; 10113 synchronized (this) { 10114 if (args != null && args.length > start 10115 && args[start].charAt(0) != '-') { 10116 procs = new ArrayList<ProcessRecord>(); 10117 int pid = -1; 10118 try { 10119 pid = Integer.parseInt(args[start]); 10120 } catch (NumberFormatException e) { 10121 10122 } 10123 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10124 ProcessRecord proc = mLruProcesses.get(i); 10125 if (proc.pid == pid) { 10126 procs.add(proc); 10127 } else if (proc.processName.equals(args[start])) { 10128 procs.add(proc); 10129 } 10130 } 10131 if (procs.size() <= 0) { 10132 pw.println("No process found for: " + args[start]); 10133 return null; 10134 } 10135 } else { 10136 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10137 } 10138 } 10139 return procs; 10140 } 10141 10142 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10143 PrintWriter pw, String[] args) { 10144 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10145 if (procs == null) { 10146 return; 10147 } 10148 10149 long uptime = SystemClock.uptimeMillis(); 10150 long realtime = SystemClock.elapsedRealtime(); 10151 pw.println("Applications Graphics Acceleration Info:"); 10152 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10153 10154 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10155 ProcessRecord r = procs.get(i); 10156 if (r.thread != null) { 10157 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10158 pw.flush(); 10159 try { 10160 TransferPipe tp = new TransferPipe(); 10161 try { 10162 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10163 tp.go(fd); 10164 } finally { 10165 tp.kill(); 10166 } 10167 } catch (IOException e) { 10168 pw.println("Failure while dumping the app: " + r); 10169 pw.flush(); 10170 } catch (RemoteException e) { 10171 pw.println("Got a RemoteException while dumping the app " + r); 10172 pw.flush(); 10173 } 10174 } 10175 } 10176 } 10177 10178 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10179 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10180 if (procs == null) { 10181 return; 10182 } 10183 10184 pw.println("Applications Database Info:"); 10185 10186 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10187 ProcessRecord r = procs.get(i); 10188 if (r.thread != null) { 10189 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10190 pw.flush(); 10191 try { 10192 TransferPipe tp = new TransferPipe(); 10193 try { 10194 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10195 tp.go(fd); 10196 } finally { 10197 tp.kill(); 10198 } 10199 } catch (IOException e) { 10200 pw.println("Failure while dumping the app: " + r); 10201 pw.flush(); 10202 } catch (RemoteException e) { 10203 pw.println("Got a RemoteException while dumping the app " + r); 10204 pw.flush(); 10205 } 10206 } 10207 } 10208 } 10209 10210 final static class MemItem { 10211 final String label; 10212 final String shortLabel; 10213 final long pss; 10214 final int id; 10215 ArrayList<MemItem> subitems; 10216 10217 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10218 label = _label; 10219 shortLabel = _shortLabel; 10220 pss = _pss; 10221 id = _id; 10222 } 10223 } 10224 10225 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10226 boolean sort) { 10227 if (sort) { 10228 Collections.sort(items, new Comparator<MemItem>() { 10229 @Override 10230 public int compare(MemItem lhs, MemItem rhs) { 10231 if (lhs.pss < rhs.pss) { 10232 return 1; 10233 } else if (lhs.pss > rhs.pss) { 10234 return -1; 10235 } 10236 return 0; 10237 } 10238 }); 10239 } 10240 10241 for (int i=0; i<items.size(); i++) { 10242 MemItem mi = items.get(i); 10243 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10244 if (mi.subitems != null) { 10245 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10246 } 10247 } 10248 } 10249 10250 // These are in KB. 10251 static final long[] DUMP_MEM_BUCKETS = new long[] { 10252 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10253 120*1024, 160*1024, 200*1024, 10254 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10255 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10256 }; 10257 10258 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10259 boolean stackLike) { 10260 int start = label.lastIndexOf('.'); 10261 if (start >= 0) start++; 10262 else start = 0; 10263 int end = label.length(); 10264 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10265 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10266 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10267 out.append(bucket); 10268 out.append(stackLike ? "MB." : "MB "); 10269 out.append(label, start, end); 10270 return; 10271 } 10272 } 10273 out.append(memKB/1024); 10274 out.append(stackLike ? "MB." : "MB "); 10275 out.append(label, start, end); 10276 } 10277 10278 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10279 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10280 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10281 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10282 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10283 }; 10284 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10285 "System", "Persistent", "Foreground", 10286 "Visible", "Perceptible", "Heavy Weight", 10287 "Backup", "A Services", "Home", "Previous", 10288 "B Services", "Background" 10289 }; 10290 10291 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10292 PrintWriter pw, String prefix, String[] args, boolean brief, 10293 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10294 boolean dumpAll = false; 10295 boolean oomOnly = false; 10296 10297 int opti = 0; 10298 while (opti < args.length) { 10299 String opt = args[opti]; 10300 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10301 break; 10302 } 10303 opti++; 10304 if ("-a".equals(opt)) { 10305 dumpAll = true; 10306 } else if ("--oom".equals(opt)) { 10307 oomOnly = true; 10308 } else if ("-h".equals(opt)) { 10309 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10310 pw.println(" -a: include all available information for each process."); 10311 pw.println(" --oom: only show processes organized by oom adj."); 10312 pw.println("If [process] is specified it can be the name or "); 10313 pw.println("pid of a specific process to dump."); 10314 return; 10315 } else { 10316 pw.println("Unknown argument: " + opt + "; use -h for help"); 10317 } 10318 } 10319 10320 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10321 if (procs == null) { 10322 return; 10323 } 10324 10325 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10326 long uptime = SystemClock.uptimeMillis(); 10327 long realtime = SystemClock.elapsedRealtime(); 10328 10329 if (procs.size() == 1 || isCheckinRequest) { 10330 dumpAll = true; 10331 } 10332 10333 if (isCheckinRequest) { 10334 // short checkin version 10335 pw.println(uptime + "," + realtime); 10336 pw.flush(); 10337 } else { 10338 pw.println("Applications Memory Usage (kB):"); 10339 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10340 } 10341 10342 String[] innerArgs = new String[args.length-opti]; 10343 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10344 10345 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10346 long nativePss=0, dalvikPss=0, otherPss=0; 10347 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10348 10349 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10350 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10351 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10352 10353 long totalPss = 0; 10354 10355 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10356 ProcessRecord r = procs.get(i); 10357 if (r.thread != null) { 10358 if (!isCheckinRequest && dumpAll) { 10359 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10360 pw.flush(); 10361 } 10362 Debug.MemoryInfo mi = null; 10363 if (dumpAll) { 10364 try { 10365 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10366 } catch (RemoteException e) { 10367 if (!isCheckinRequest) { 10368 pw.println("Got RemoteException!"); 10369 pw.flush(); 10370 } 10371 } 10372 } else { 10373 mi = new Debug.MemoryInfo(); 10374 Debug.getMemoryInfo(r.pid, mi); 10375 } 10376 10377 if (!isCheckinRequest && mi != null) { 10378 long myTotalPss = mi.getTotalPss(); 10379 totalPss += myTotalPss; 10380 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10381 r.processName, myTotalPss, 0); 10382 procMems.add(pssItem); 10383 10384 nativePss += mi.nativePss; 10385 dalvikPss += mi.dalvikPss; 10386 otherPss += mi.otherPss; 10387 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10388 long mem = mi.getOtherPss(j); 10389 miscPss[j] += mem; 10390 otherPss -= mem; 10391 } 10392 10393 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10394 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10395 || oomIndex == (oomPss.length-1)) { 10396 oomPss[oomIndex] += myTotalPss; 10397 if (oomProcs[oomIndex] == null) { 10398 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10399 } 10400 oomProcs[oomIndex].add(pssItem); 10401 break; 10402 } 10403 } 10404 } 10405 } 10406 } 10407 10408 if (!isCheckinRequest && procs.size() > 1) { 10409 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10410 10411 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10412 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10413 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10414 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10415 String label = Debug.MemoryInfo.getOtherLabel(j); 10416 catMems.add(new MemItem(label, label, miscPss[j], j)); 10417 } 10418 10419 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10420 for (int j=0; j<oomPss.length; j++) { 10421 if (oomPss[j] != 0) { 10422 String label = DUMP_MEM_OOM_LABEL[j]; 10423 MemItem item = new MemItem(label, label, oomPss[j], 10424 DUMP_MEM_OOM_ADJ[j]); 10425 item.subitems = oomProcs[j]; 10426 oomMems.add(item); 10427 } 10428 } 10429 10430 if (outTag != null || outStack != null) { 10431 if (outTag != null) { 10432 appendMemBucket(outTag, totalPss, "total", false); 10433 } 10434 if (outStack != null) { 10435 appendMemBucket(outStack, totalPss, "total", true); 10436 } 10437 boolean firstLine = true; 10438 for (int i=0; i<oomMems.size(); i++) { 10439 MemItem miCat = oomMems.get(i); 10440 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10441 continue; 10442 } 10443 if (miCat.id < ProcessList.SERVICE_ADJ 10444 || miCat.id == ProcessList.HOME_APP_ADJ 10445 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10446 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10447 outTag.append(" / "); 10448 } 10449 if (outStack != null) { 10450 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10451 if (firstLine) { 10452 outStack.append(":"); 10453 firstLine = false; 10454 } 10455 outStack.append("\n\t at "); 10456 } else { 10457 outStack.append("$"); 10458 } 10459 } 10460 for (int j=0; j<miCat.subitems.size(); j++) { 10461 MemItem mi = miCat.subitems.get(j); 10462 if (j > 0) { 10463 if (outTag != null) { 10464 outTag.append(" "); 10465 } 10466 if (outStack != null) { 10467 outStack.append("$"); 10468 } 10469 } 10470 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10471 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10472 } 10473 if (outStack != null) { 10474 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10475 } 10476 } 10477 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10478 outStack.append("("); 10479 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10480 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10481 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10482 outStack.append(":"); 10483 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10484 } 10485 } 10486 outStack.append(")"); 10487 } 10488 } 10489 } 10490 } 10491 10492 if (!brief && !oomOnly) { 10493 pw.println(); 10494 pw.println("Total PSS by process:"); 10495 dumpMemItems(pw, " ", procMems, true); 10496 pw.println(); 10497 } 10498 pw.println("Total PSS by OOM adjustment:"); 10499 dumpMemItems(pw, " ", oomMems, false); 10500 if (!oomOnly) { 10501 PrintWriter out = categoryPw != null ? categoryPw : pw; 10502 out.println(); 10503 out.println("Total PSS by category:"); 10504 dumpMemItems(out, " ", catMems, true); 10505 } 10506 pw.println(); 10507 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10508 final int[] SINGLE_LONG_FORMAT = new int[] { 10509 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10510 }; 10511 long[] longOut = new long[1]; 10512 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10513 SINGLE_LONG_FORMAT, null, longOut, null); 10514 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10515 longOut[0] = 0; 10516 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10517 SINGLE_LONG_FORMAT, null, longOut, null); 10518 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10519 longOut[0] = 0; 10520 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10521 SINGLE_LONG_FORMAT, null, longOut, null); 10522 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10523 longOut[0] = 0; 10524 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10525 SINGLE_LONG_FORMAT, null, longOut, null); 10526 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10527 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10528 pw.print(shared); pw.println(" kB"); 10529 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10530 pw.print(voltile); pw.println(" kB volatile"); 10531 } 10532 } 10533 10534 /** 10535 * Searches array of arguments for the specified string 10536 * @param args array of argument strings 10537 * @param value value to search for 10538 * @return true if the value is contained in the array 10539 */ 10540 private static boolean scanArgs(String[] args, String value) { 10541 if (args != null) { 10542 for (String arg : args) { 10543 if (value.equals(arg)) { 10544 return true; 10545 } 10546 } 10547 } 10548 return false; 10549 } 10550 10551 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10552 ContentProviderRecord cpr, boolean always) { 10553 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10554 10555 if (!inLaunching || always) { 10556 synchronized (cpr) { 10557 cpr.launchingApp = null; 10558 cpr.notifyAll(); 10559 } 10560 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10561 String names[] = cpr.info.authority.split(";"); 10562 for (int j = 0; j < names.length; j++) { 10563 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10564 } 10565 } 10566 10567 for (int i=0; i<cpr.connections.size(); i++) { 10568 ContentProviderConnection conn = cpr.connections.get(i); 10569 if (conn.waiting) { 10570 // If this connection is waiting for the provider, then we don't 10571 // need to mess with its process unless we are always removing 10572 // or for some reason the provider is not currently launching. 10573 if (inLaunching && !always) { 10574 continue; 10575 } 10576 } 10577 ProcessRecord capp = conn.client; 10578 conn.dead = true; 10579 if (conn.stableCount > 0) { 10580 if (!capp.persistent && capp.thread != null 10581 && capp.pid != 0 10582 && capp.pid != MY_PID) { 10583 Slog.i(TAG, "Kill " + capp.processName 10584 + " (pid " + capp.pid + "): provider " + cpr.info.name 10585 + " in dying process " + (proc != null ? proc.processName : "??")); 10586 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10587 capp.processName, capp.setAdj, "dying provider " 10588 + cpr.name.toShortString()); 10589 Process.killProcessQuiet(capp.pid); 10590 } 10591 } else if (capp.thread != null && conn.provider.provider != null) { 10592 try { 10593 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10594 } catch (RemoteException e) { 10595 } 10596 // In the protocol here, we don't expect the client to correctly 10597 // clean up this connection, we'll just remove it. 10598 cpr.connections.remove(i); 10599 conn.client.conProviders.remove(conn); 10600 } 10601 } 10602 10603 if (inLaunching && always) { 10604 mLaunchingProviders.remove(cpr); 10605 } 10606 return inLaunching; 10607 } 10608 10609 /** 10610 * Main code for cleaning up a process when it has gone away. This is 10611 * called both as a result of the process dying, or directly when stopping 10612 * a process when running in single process mode. 10613 */ 10614 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10615 boolean restarting, boolean allowRestart, int index) { 10616 if (index >= 0) { 10617 mLruProcesses.remove(index); 10618 } 10619 10620 mProcessesToGc.remove(app); 10621 10622 // Dismiss any open dialogs. 10623 if (app.crashDialog != null) { 10624 app.crashDialog.dismiss(); 10625 app.crashDialog = null; 10626 } 10627 if (app.anrDialog != null) { 10628 app.anrDialog.dismiss(); 10629 app.anrDialog = null; 10630 } 10631 if (app.waitDialog != null) { 10632 app.waitDialog.dismiss(); 10633 app.waitDialog = null; 10634 } 10635 10636 app.crashing = false; 10637 app.notResponding = false; 10638 10639 app.resetPackageList(); 10640 app.unlinkDeathRecipient(); 10641 app.thread = null; 10642 app.forcingToForeground = null; 10643 app.foregroundServices = false; 10644 app.foregroundActivities = false; 10645 app.hasShownUi = false; 10646 app.hasAboveClient = false; 10647 10648 mServices.killServicesLocked(app, allowRestart); 10649 10650 boolean restart = false; 10651 10652 // Remove published content providers. 10653 if (!app.pubProviders.isEmpty()) { 10654 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10655 while (it.hasNext()) { 10656 ContentProviderRecord cpr = it.next(); 10657 10658 final boolean always = app.bad || !allowRestart; 10659 if (removeDyingProviderLocked(app, cpr, always) || always) { 10660 // We left the provider in the launching list, need to 10661 // restart it. 10662 restart = true; 10663 } 10664 10665 cpr.provider = null; 10666 cpr.proc = null; 10667 } 10668 app.pubProviders.clear(); 10669 } 10670 10671 // Take care of any launching providers waiting for this process. 10672 if (checkAppInLaunchingProvidersLocked(app, false)) { 10673 restart = true; 10674 } 10675 10676 // Unregister from connected content providers. 10677 if (!app.conProviders.isEmpty()) { 10678 for (int i=0; i<app.conProviders.size(); i++) { 10679 ContentProviderConnection conn = app.conProviders.get(i); 10680 conn.provider.connections.remove(conn); 10681 } 10682 app.conProviders.clear(); 10683 } 10684 10685 // At this point there may be remaining entries in mLaunchingProviders 10686 // where we were the only one waiting, so they are no longer of use. 10687 // Look for these and clean up if found. 10688 // XXX Commented out for now. Trying to figure out a way to reproduce 10689 // the actual situation to identify what is actually going on. 10690 if (false) { 10691 for (int i=0; i<mLaunchingProviders.size(); i++) { 10692 ContentProviderRecord cpr = (ContentProviderRecord) 10693 mLaunchingProviders.get(i); 10694 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10695 synchronized (cpr) { 10696 cpr.launchingApp = null; 10697 cpr.notifyAll(); 10698 } 10699 } 10700 } 10701 } 10702 10703 skipCurrentReceiverLocked(app); 10704 10705 // Unregister any receivers. 10706 if (app.receivers.size() > 0) { 10707 Iterator<ReceiverList> it = app.receivers.iterator(); 10708 while (it.hasNext()) { 10709 removeReceiverLocked(it.next()); 10710 } 10711 app.receivers.clear(); 10712 } 10713 10714 // If the app is undergoing backup, tell the backup manager about it 10715 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10716 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10717 try { 10718 IBackupManager bm = IBackupManager.Stub.asInterface( 10719 ServiceManager.getService(Context.BACKUP_SERVICE)); 10720 bm.agentDisconnected(app.info.packageName); 10721 } catch (RemoteException e) { 10722 // can't happen; backup manager is local 10723 } 10724 } 10725 10726 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10727 ProcessChangeItem item = mPendingProcessChanges.get(i); 10728 if (item.pid == app.pid) { 10729 mPendingProcessChanges.remove(i); 10730 mAvailProcessChanges.add(item); 10731 } 10732 } 10733 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10734 10735 // If the caller is restarting this app, then leave it in its 10736 // current lists and let the caller take care of it. 10737 if (restarting) { 10738 return; 10739 } 10740 10741 if (!app.persistent || app.isolated) { 10742 if (DEBUG_PROCESSES) Slog.v(TAG, 10743 "Removing non-persistent process during cleanup: " + app); 10744 mProcessNames.remove(app.processName, app.uid); 10745 mIsolatedProcesses.remove(app.uid); 10746 if (mHeavyWeightProcess == app) { 10747 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10748 mHeavyWeightProcess.userId, 0)); 10749 mHeavyWeightProcess = null; 10750 } 10751 } else if (!app.removed) { 10752 // This app is persistent, so we need to keep its record around. 10753 // If it is not already on the pending app list, add it there 10754 // and start a new process for it. 10755 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10756 mPersistentStartingProcesses.add(app); 10757 restart = true; 10758 } 10759 } 10760 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10761 "Clean-up removing on hold: " + app); 10762 mProcessesOnHold.remove(app); 10763 10764 if (app == mHomeProcess) { 10765 mHomeProcess = null; 10766 } 10767 if (app == mPreviousProcess) { 10768 mPreviousProcess = null; 10769 } 10770 10771 if (restart && !app.isolated) { 10772 // We have components that still need to be running in the 10773 // process, so re-launch it. 10774 mProcessNames.put(app.processName, app.uid, app); 10775 startProcessLocked(app, "restart", app.processName); 10776 } else if (app.pid > 0 && app.pid != MY_PID) { 10777 // Goodbye! 10778 synchronized (mPidsSelfLocked) { 10779 mPidsSelfLocked.remove(app.pid); 10780 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10781 } 10782 app.setPid(0); 10783 } 10784 } 10785 10786 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10787 // Look through the content providers we are waiting to have launched, 10788 // and if any run in this process then either schedule a restart of 10789 // the process or kill the client waiting for it if this process has 10790 // gone bad. 10791 int NL = mLaunchingProviders.size(); 10792 boolean restart = false; 10793 for (int i=0; i<NL; i++) { 10794 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10795 if (cpr.launchingApp == app) { 10796 if (!alwaysBad && !app.bad) { 10797 restart = true; 10798 } else { 10799 removeDyingProviderLocked(app, cpr, true); 10800 // cpr should have been removed from mLaunchingProviders 10801 NL = mLaunchingProviders.size(); 10802 i--; 10803 } 10804 } 10805 } 10806 return restart; 10807 } 10808 10809 // ========================================================= 10810 // SERVICES 10811 // ========================================================= 10812 10813 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10814 int flags) { 10815 enforceNotIsolatedCaller("getServices"); 10816 synchronized (this) { 10817 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10818 } 10819 } 10820 10821 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10822 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10823 synchronized (this) { 10824 return mServices.getRunningServiceControlPanelLocked(name); 10825 } 10826 } 10827 10828 public ComponentName startService(IApplicationThread caller, Intent service, 10829 String resolvedType, int userId) { 10830 enforceNotIsolatedCaller("startService"); 10831 // Refuse possible leaked file descriptors 10832 if (service != null && service.hasFileDescriptors() == true) { 10833 throw new IllegalArgumentException("File descriptors passed in Intent"); 10834 } 10835 10836 if (DEBUG_SERVICE) 10837 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10838 synchronized(this) { 10839 final int callingPid = Binder.getCallingPid(); 10840 final int callingUid = Binder.getCallingUid(); 10841 checkValidCaller(callingUid, userId); 10842 final long origId = Binder.clearCallingIdentity(); 10843 ComponentName res = mServices.startServiceLocked(caller, service, 10844 resolvedType, callingPid, callingUid, userId); 10845 Binder.restoreCallingIdentity(origId); 10846 return res; 10847 } 10848 } 10849 10850 ComponentName startServiceInPackage(int uid, 10851 Intent service, String resolvedType, int userId) { 10852 synchronized(this) { 10853 if (DEBUG_SERVICE) 10854 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10855 final long origId = Binder.clearCallingIdentity(); 10856 ComponentName res = mServices.startServiceLocked(null, service, 10857 resolvedType, -1, uid, userId); 10858 Binder.restoreCallingIdentity(origId); 10859 return res; 10860 } 10861 } 10862 10863 public int stopService(IApplicationThread caller, Intent service, 10864 String resolvedType, int userId) { 10865 enforceNotIsolatedCaller("stopService"); 10866 // Refuse possible leaked file descriptors 10867 if (service != null && service.hasFileDescriptors() == true) { 10868 throw new IllegalArgumentException("File descriptors passed in Intent"); 10869 } 10870 10871 checkValidCaller(Binder.getCallingUid(), userId); 10872 10873 synchronized(this) { 10874 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10875 } 10876 } 10877 10878 public IBinder peekService(Intent service, String resolvedType) { 10879 enforceNotIsolatedCaller("peekService"); 10880 // Refuse possible leaked file descriptors 10881 if (service != null && service.hasFileDescriptors() == true) { 10882 throw new IllegalArgumentException("File descriptors passed in Intent"); 10883 } 10884 synchronized(this) { 10885 return mServices.peekServiceLocked(service, resolvedType); 10886 } 10887 } 10888 10889 public boolean stopServiceToken(ComponentName className, IBinder token, 10890 int startId) { 10891 synchronized(this) { 10892 return mServices.stopServiceTokenLocked(className, token, startId); 10893 } 10894 } 10895 10896 public void setServiceForeground(ComponentName className, IBinder token, 10897 int id, Notification notification, boolean removeNotification) { 10898 synchronized(this) { 10899 mServices.setServiceForegroundLocked(className, token, id, notification, 10900 removeNotification); 10901 } 10902 } 10903 10904 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10905 boolean requireFull, String name, String callerPackage) { 10906 synchronized(this) { 10907 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10908 requireFull, name, callerPackage); 10909 } 10910 } 10911 10912 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10913 boolean requireFull, String name, String callerPackage) { 10914 final int callingUserId = UserHandle.getUserId(callingUid); 10915 if (callingUserId != userId) { 10916 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10917 if ((requireFull || checkComponentPermission( 10918 android.Manifest.permission.INTERACT_ACROSS_USERS, 10919 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10920 && checkComponentPermission( 10921 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10922 callingPid, callingUid, -1, true) 10923 != PackageManager.PERMISSION_GRANTED) { 10924 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10925 // In this case, they would like to just execute as their 10926 // owner user instead of failing. 10927 userId = callingUserId; 10928 } else { 10929 StringBuilder builder = new StringBuilder(128); 10930 builder.append("Permission Denial: "); 10931 builder.append(name); 10932 if (callerPackage != null) { 10933 builder.append(" from "); 10934 builder.append(callerPackage); 10935 } 10936 builder.append(" asks to run as user "); 10937 builder.append(userId); 10938 builder.append(" but is calling from user "); 10939 builder.append(UserHandle.getUserId(callingUid)); 10940 builder.append("; this requires "); 10941 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10942 if (!requireFull) { 10943 builder.append(" or "); 10944 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10945 } 10946 String msg = builder.toString(); 10947 Slog.w(TAG, msg); 10948 throw new SecurityException(msg); 10949 } 10950 } 10951 } 10952 if (userId == UserHandle.USER_CURRENT 10953 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10954 userId = mCurrentUserId; 10955 } 10956 if (!allowAll && userId < 0) { 10957 throw new IllegalArgumentException( 10958 "Call does not support special user #" + userId); 10959 } 10960 } 10961 return userId; 10962 } 10963 10964 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10965 String className, int flags) { 10966 boolean result = false; 10967 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10968 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10969 if (ActivityManager.checkUidPermission( 10970 android.Manifest.permission.INTERACT_ACROSS_USERS, 10971 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10972 ComponentName comp = new ComponentName(aInfo.packageName, className); 10973 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10974 + " requests FLAG_SINGLE_USER, but app does not hold " 10975 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10976 Slog.w(TAG, msg); 10977 throw new SecurityException(msg); 10978 } 10979 result = true; 10980 } 10981 } else if (componentProcessName == aInfo.packageName) { 10982 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10983 } else if ("system".equals(componentProcessName)) { 10984 result = true; 10985 } 10986 if (DEBUG_MU) { 10987 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10988 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10989 } 10990 return result; 10991 } 10992 10993 public int bindService(IApplicationThread caller, IBinder token, 10994 Intent service, String resolvedType, 10995 IServiceConnection connection, int flags, int userId) { 10996 enforceNotIsolatedCaller("bindService"); 10997 // Refuse possible leaked file descriptors 10998 if (service != null && service.hasFileDescriptors() == true) { 10999 throw new IllegalArgumentException("File descriptors passed in Intent"); 11000 } 11001 11002 synchronized(this) { 11003 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11004 connection, flags, userId); 11005 } 11006 } 11007 11008 public boolean unbindService(IServiceConnection connection) { 11009 synchronized (this) { 11010 return mServices.unbindServiceLocked(connection); 11011 } 11012 } 11013 11014 public void publishService(IBinder token, Intent intent, IBinder service) { 11015 // Refuse possible leaked file descriptors 11016 if (intent != null && intent.hasFileDescriptors() == true) { 11017 throw new IllegalArgumentException("File descriptors passed in Intent"); 11018 } 11019 11020 synchronized(this) { 11021 if (!(token instanceof ServiceRecord)) { 11022 throw new IllegalArgumentException("Invalid service token"); 11023 } 11024 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11025 } 11026 } 11027 11028 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11029 // Refuse possible leaked file descriptors 11030 if (intent != null && intent.hasFileDescriptors() == true) { 11031 throw new IllegalArgumentException("File descriptors passed in Intent"); 11032 } 11033 11034 synchronized(this) { 11035 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11036 } 11037 } 11038 11039 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11040 synchronized(this) { 11041 if (!(token instanceof ServiceRecord)) { 11042 throw new IllegalArgumentException("Invalid service token"); 11043 } 11044 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11045 } 11046 } 11047 11048 // ========================================================= 11049 // BACKUP AND RESTORE 11050 // ========================================================= 11051 11052 // Cause the target app to be launched if necessary and its backup agent 11053 // instantiated. The backup agent will invoke backupAgentCreated() on the 11054 // activity manager to announce its creation. 11055 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11056 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11057 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11058 11059 synchronized(this) { 11060 // !!! TODO: currently no check here that we're already bound 11061 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11062 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11063 synchronized (stats) { 11064 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11065 } 11066 11067 // Backup agent is now in use, its package can't be stopped. 11068 try { 11069 AppGlobals.getPackageManager().setPackageStoppedState( 11070 app.packageName, false, UserHandle.getUserId(app.uid)); 11071 } catch (RemoteException e) { 11072 } catch (IllegalArgumentException e) { 11073 Slog.w(TAG, "Failed trying to unstop package " 11074 + app.packageName + ": " + e); 11075 } 11076 11077 BackupRecord r = new BackupRecord(ss, app, backupMode); 11078 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11079 ? new ComponentName(app.packageName, app.backupAgentName) 11080 : new ComponentName("android", "FullBackupAgent"); 11081 // startProcessLocked() returns existing proc's record if it's already running 11082 ProcessRecord proc = startProcessLocked(app.processName, app, 11083 false, 0, "backup", hostingName, false, false); 11084 if (proc == null) { 11085 Slog.e(TAG, "Unable to start backup agent process " + r); 11086 return false; 11087 } 11088 11089 r.app = proc; 11090 mBackupTarget = r; 11091 mBackupAppName = app.packageName; 11092 11093 // Try not to kill the process during backup 11094 updateOomAdjLocked(proc); 11095 11096 // If the process is already attached, schedule the creation of the backup agent now. 11097 // If it is not yet live, this will be done when it attaches to the framework. 11098 if (proc.thread != null) { 11099 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11100 try { 11101 proc.thread.scheduleCreateBackupAgent(app, 11102 compatibilityInfoForPackageLocked(app), backupMode); 11103 } catch (RemoteException e) { 11104 // Will time out on the backup manager side 11105 } 11106 } else { 11107 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11108 } 11109 // Invariants: at this point, the target app process exists and the application 11110 // is either already running or in the process of coming up. mBackupTarget and 11111 // mBackupAppName describe the app, so that when it binds back to the AM we 11112 // know that it's scheduled for a backup-agent operation. 11113 } 11114 11115 return true; 11116 } 11117 11118 // A backup agent has just come up 11119 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11120 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11121 + " = " + agent); 11122 11123 synchronized(this) { 11124 if (!agentPackageName.equals(mBackupAppName)) { 11125 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11126 return; 11127 } 11128 } 11129 11130 long oldIdent = Binder.clearCallingIdentity(); 11131 try { 11132 IBackupManager bm = IBackupManager.Stub.asInterface( 11133 ServiceManager.getService(Context.BACKUP_SERVICE)); 11134 bm.agentConnected(agentPackageName, agent); 11135 } catch (RemoteException e) { 11136 // can't happen; the backup manager service is local 11137 } catch (Exception e) { 11138 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11139 e.printStackTrace(); 11140 } finally { 11141 Binder.restoreCallingIdentity(oldIdent); 11142 } 11143 } 11144 11145 // done with this agent 11146 public void unbindBackupAgent(ApplicationInfo appInfo) { 11147 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11148 if (appInfo == null) { 11149 Slog.w(TAG, "unbind backup agent for null app"); 11150 return; 11151 } 11152 11153 synchronized(this) { 11154 if (mBackupAppName == null) { 11155 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11156 return; 11157 } 11158 11159 if (!mBackupAppName.equals(appInfo.packageName)) { 11160 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11161 return; 11162 } 11163 11164 ProcessRecord proc = mBackupTarget.app; 11165 mBackupTarget = null; 11166 mBackupAppName = null; 11167 11168 // Not backing this app up any more; reset its OOM adjustment 11169 updateOomAdjLocked(proc); 11170 11171 // If the app crashed during backup, 'thread' will be null here 11172 if (proc.thread != null) { 11173 try { 11174 proc.thread.scheduleDestroyBackupAgent(appInfo, 11175 compatibilityInfoForPackageLocked(appInfo)); 11176 } catch (Exception e) { 11177 Slog.e(TAG, "Exception when unbinding backup agent:"); 11178 e.printStackTrace(); 11179 } 11180 } 11181 } 11182 } 11183 // ========================================================= 11184 // BROADCASTS 11185 // ========================================================= 11186 11187 private final List getStickiesLocked(String action, IntentFilter filter, 11188 List cur, int userId) { 11189 final ContentResolver resolver = mContext.getContentResolver(); 11190 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11191 if (stickies == null) { 11192 return cur; 11193 } 11194 final ArrayList<Intent> list = stickies.get(action); 11195 if (list == null) { 11196 return cur; 11197 } 11198 int N = list.size(); 11199 for (int i=0; i<N; i++) { 11200 Intent intent = list.get(i); 11201 if (filter.match(resolver, intent, true, TAG) >= 0) { 11202 if (cur == null) { 11203 cur = new ArrayList<Intent>(); 11204 } 11205 cur.add(intent); 11206 } 11207 } 11208 return cur; 11209 } 11210 11211 boolean isPendingBroadcastProcessLocked(int pid) { 11212 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11213 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11214 } 11215 11216 void skipPendingBroadcastLocked(int pid) { 11217 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11218 for (BroadcastQueue queue : mBroadcastQueues) { 11219 queue.skipPendingBroadcastLocked(pid); 11220 } 11221 } 11222 11223 // The app just attached; send any pending broadcasts that it should receive 11224 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11225 boolean didSomething = false; 11226 for (BroadcastQueue queue : mBroadcastQueues) { 11227 didSomething |= queue.sendPendingBroadcastsLocked(app); 11228 } 11229 return didSomething; 11230 } 11231 11232 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11233 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11234 enforceNotIsolatedCaller("registerReceiver"); 11235 int callingUid; 11236 int callingPid; 11237 synchronized(this) { 11238 ProcessRecord callerApp = null; 11239 if (caller != null) { 11240 callerApp = getRecordForAppLocked(caller); 11241 if (callerApp == null) { 11242 throw new SecurityException( 11243 "Unable to find app for caller " + caller 11244 + " (pid=" + Binder.getCallingPid() 11245 + ") when registering receiver " + receiver); 11246 } 11247 if (callerApp.info.uid != Process.SYSTEM_UID && 11248 !callerApp.pkgList.contains(callerPackage)) { 11249 throw new SecurityException("Given caller package " + callerPackage 11250 + " is not running in process " + callerApp); 11251 } 11252 callingUid = callerApp.info.uid; 11253 callingPid = callerApp.pid; 11254 } else { 11255 callerPackage = null; 11256 callingUid = Binder.getCallingUid(); 11257 callingPid = Binder.getCallingPid(); 11258 } 11259 11260 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11261 true, true, "registerReceiver", callerPackage); 11262 11263 List allSticky = null; 11264 11265 // Look for any matching sticky broadcasts... 11266 Iterator actions = filter.actionsIterator(); 11267 if (actions != null) { 11268 while (actions.hasNext()) { 11269 String action = (String)actions.next(); 11270 allSticky = getStickiesLocked(action, filter, allSticky, 11271 UserHandle.USER_ALL); 11272 allSticky = getStickiesLocked(action, filter, allSticky, 11273 UserHandle.getUserId(callingUid)); 11274 } 11275 } else { 11276 allSticky = getStickiesLocked(null, filter, allSticky, 11277 UserHandle.USER_ALL); 11278 allSticky = getStickiesLocked(null, filter, allSticky, 11279 UserHandle.getUserId(callingUid)); 11280 } 11281 11282 // The first sticky in the list is returned directly back to 11283 // the client. 11284 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11285 11286 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11287 + ": " + sticky); 11288 11289 if (receiver == null) { 11290 return sticky; 11291 } 11292 11293 ReceiverList rl 11294 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11295 if (rl == null) { 11296 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11297 userId, receiver); 11298 if (rl.app != null) { 11299 rl.app.receivers.add(rl); 11300 } else { 11301 try { 11302 receiver.asBinder().linkToDeath(rl, 0); 11303 } catch (RemoteException e) { 11304 return sticky; 11305 } 11306 rl.linkedToDeath = true; 11307 } 11308 mRegisteredReceivers.put(receiver.asBinder(), rl); 11309 } else if (rl.uid != callingUid) { 11310 throw new IllegalArgumentException( 11311 "Receiver requested to register for uid " + callingUid 11312 + " was previously registered for uid " + rl.uid); 11313 } else if (rl.pid != callingPid) { 11314 throw new IllegalArgumentException( 11315 "Receiver requested to register for pid " + callingPid 11316 + " was previously registered for pid " + rl.pid); 11317 } else if (rl.userId != userId) { 11318 throw new IllegalArgumentException( 11319 "Receiver requested to register for user " + userId 11320 + " was previously registered for user " + rl.userId); 11321 } 11322 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11323 permission, callingUid, userId); 11324 rl.add(bf); 11325 if (!bf.debugCheck()) { 11326 Slog.w(TAG, "==> For Dynamic broadast"); 11327 } 11328 mReceiverResolver.addFilter(bf); 11329 11330 // Enqueue broadcasts for all existing stickies that match 11331 // this filter. 11332 if (allSticky != null) { 11333 ArrayList receivers = new ArrayList(); 11334 receivers.add(bf); 11335 11336 int N = allSticky.size(); 11337 for (int i=0; i<N; i++) { 11338 Intent intent = (Intent)allSticky.get(i); 11339 BroadcastQueue queue = broadcastQueueForIntent(intent); 11340 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11341 null, -1, -1, null, receivers, null, 0, null, null, 11342 false, true, true, -1); 11343 queue.enqueueParallelBroadcastLocked(r); 11344 queue.scheduleBroadcastsLocked(); 11345 } 11346 } 11347 11348 return sticky; 11349 } 11350 } 11351 11352 public void unregisterReceiver(IIntentReceiver receiver) { 11353 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11354 11355 final long origId = Binder.clearCallingIdentity(); 11356 try { 11357 boolean doTrim = false; 11358 11359 synchronized(this) { 11360 ReceiverList rl 11361 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11362 if (rl != null) { 11363 if (rl.curBroadcast != null) { 11364 BroadcastRecord r = rl.curBroadcast; 11365 final boolean doNext = finishReceiverLocked( 11366 receiver.asBinder(), r.resultCode, r.resultData, 11367 r.resultExtras, r.resultAbort, true); 11368 if (doNext) { 11369 doTrim = true; 11370 r.queue.processNextBroadcast(false); 11371 } 11372 } 11373 11374 if (rl.app != null) { 11375 rl.app.receivers.remove(rl); 11376 } 11377 removeReceiverLocked(rl); 11378 if (rl.linkedToDeath) { 11379 rl.linkedToDeath = false; 11380 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11381 } 11382 } 11383 } 11384 11385 // If we actually concluded any broadcasts, we might now be able 11386 // to trim the recipients' apps from our working set 11387 if (doTrim) { 11388 trimApplications(); 11389 return; 11390 } 11391 11392 } finally { 11393 Binder.restoreCallingIdentity(origId); 11394 } 11395 } 11396 11397 void removeReceiverLocked(ReceiverList rl) { 11398 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11399 int N = rl.size(); 11400 for (int i=0; i<N; i++) { 11401 mReceiverResolver.removeFilter(rl.get(i)); 11402 } 11403 } 11404 11405 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11407 ProcessRecord r = mLruProcesses.get(i); 11408 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11409 try { 11410 r.thread.dispatchPackageBroadcast(cmd, packages); 11411 } catch (RemoteException ex) { 11412 } 11413 } 11414 } 11415 } 11416 11417 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11418 int[] users) { 11419 List<ResolveInfo> receivers = null; 11420 try { 11421 HashSet<ComponentName> singleUserReceivers = null; 11422 boolean scannedFirstReceivers = false; 11423 for (int user : users) { 11424 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11425 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11426 if (newReceivers != null && newReceivers.size() == 0) { 11427 newReceivers = null; 11428 } 11429 if (receivers == null) { 11430 receivers = newReceivers; 11431 } else if (newReceivers != null) { 11432 // We need to concatenate the additional receivers 11433 // found with what we have do far. This would be easy, 11434 // but we also need to de-dup any receivers that are 11435 // singleUser. 11436 if (!scannedFirstReceivers) { 11437 // Collect any single user receivers we had already retrieved. 11438 scannedFirstReceivers = true; 11439 for (int i=0; i<receivers.size(); i++) { 11440 ResolveInfo ri = receivers.get(i); 11441 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11442 ComponentName cn = new ComponentName( 11443 ri.activityInfo.packageName, ri.activityInfo.name); 11444 if (singleUserReceivers == null) { 11445 singleUserReceivers = new HashSet<ComponentName>(); 11446 } 11447 singleUserReceivers.add(cn); 11448 } 11449 } 11450 } 11451 // Add the new results to the existing results, tracking 11452 // and de-dupping single user receivers. 11453 for (int i=0; i<newReceivers.size(); i++) { 11454 ResolveInfo ri = newReceivers.get(i); 11455 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11456 ComponentName cn = new ComponentName( 11457 ri.activityInfo.packageName, ri.activityInfo.name); 11458 if (singleUserReceivers == null) { 11459 singleUserReceivers = new HashSet<ComponentName>(); 11460 } 11461 if (!singleUserReceivers.contains(cn)) { 11462 singleUserReceivers.add(cn); 11463 receivers.add(ri); 11464 } 11465 } else { 11466 receivers.add(ri); 11467 } 11468 } 11469 } 11470 } 11471 } catch (RemoteException ex) { 11472 // pm is in same process, this will never happen. 11473 } 11474 return receivers; 11475 } 11476 11477 private final int broadcastIntentLocked(ProcessRecord callerApp, 11478 String callerPackage, Intent intent, String resolvedType, 11479 IIntentReceiver resultTo, int resultCode, String resultData, 11480 Bundle map, String requiredPermission, 11481 boolean ordered, boolean sticky, int callingPid, int callingUid, 11482 int userId) { 11483 intent = new Intent(intent); 11484 11485 // By default broadcasts do not go to stopped apps. 11486 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11487 11488 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11489 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11490 + " ordered=" + ordered + " userid=" + userId); 11491 if ((resultTo != null) && !ordered) { 11492 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11493 } 11494 11495 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11496 true, false, "broadcast", callerPackage); 11497 11498 // Make sure that the user who is receiving this broadcast is started 11499 // If not, we will just skip it. 11500 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11501 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11502 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11503 Slog.w(TAG, "Skipping broadcast of " + intent 11504 + ": user " + userId + " is stopped"); 11505 return ActivityManager.BROADCAST_SUCCESS; 11506 } 11507 } 11508 11509 /* 11510 * Prevent non-system code (defined here to be non-persistent 11511 * processes) from sending protected broadcasts. 11512 */ 11513 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11514 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11515 callingUid == 0) { 11516 // Always okay. 11517 } else if (callerApp == null || !callerApp.persistent) { 11518 try { 11519 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11520 intent.getAction())) { 11521 String msg = "Permission Denial: not allowed to send broadcast " 11522 + intent.getAction() + " from pid=" 11523 + callingPid + ", uid=" + callingUid; 11524 Slog.w(TAG, msg); 11525 throw new SecurityException(msg); 11526 } 11527 } catch (RemoteException e) { 11528 Slog.w(TAG, "Remote exception", e); 11529 return ActivityManager.BROADCAST_SUCCESS; 11530 } 11531 } 11532 11533 // Handle special intents: if this broadcast is from the package 11534 // manager about a package being removed, we need to remove all of 11535 // its activities from the history stack. 11536 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11537 intent.getAction()); 11538 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11539 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11540 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11541 || uidRemoved) { 11542 if (checkComponentPermission( 11543 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11544 callingPid, callingUid, -1, true) 11545 == PackageManager.PERMISSION_GRANTED) { 11546 if (uidRemoved) { 11547 final Bundle intentExtras = intent.getExtras(); 11548 final int uid = intentExtras != null 11549 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11550 if (uid >= 0) { 11551 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11552 synchronized (bs) { 11553 bs.removeUidStatsLocked(uid); 11554 } 11555 } 11556 } else { 11557 // If resources are unavailable just force stop all 11558 // those packages and flush the attribute cache as well. 11559 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11560 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11561 if (list != null && (list.length > 0)) { 11562 for (String pkg : list) { 11563 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11564 } 11565 sendPackageBroadcastLocked( 11566 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11567 } 11568 } else { 11569 Uri data = intent.getData(); 11570 String ssp; 11571 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11572 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11573 forceStopPackageLocked(ssp, 11574 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11575 false, userId); 11576 } 11577 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11578 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11579 new String[] {ssp}, userId); 11580 } 11581 } 11582 } 11583 } 11584 } else { 11585 String msg = "Permission Denial: " + intent.getAction() 11586 + " broadcast from " + callerPackage + " (pid=" + callingPid 11587 + ", uid=" + callingUid + ")" 11588 + " requires " 11589 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11590 Slog.w(TAG, msg); 11591 throw new SecurityException(msg); 11592 } 11593 11594 // Special case for adding a package: by default turn on compatibility 11595 // mode. 11596 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11597 Uri data = intent.getData(); 11598 String ssp; 11599 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11600 mCompatModePackages.handlePackageAddedLocked(ssp, 11601 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11602 } 11603 } 11604 11605 /* 11606 * If this is the time zone changed action, queue up a message that will reset the timezone 11607 * of all currently running processes. This message will get queued up before the broadcast 11608 * happens. 11609 */ 11610 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11611 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11612 } 11613 11614 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11615 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11616 } 11617 11618 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11619 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11620 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11621 } 11622 11623 // Add to the sticky list if requested. 11624 if (sticky) { 11625 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11626 callingPid, callingUid) 11627 != PackageManager.PERMISSION_GRANTED) { 11628 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11629 + callingPid + ", uid=" + callingUid 11630 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11631 Slog.w(TAG, msg); 11632 throw new SecurityException(msg); 11633 } 11634 if (requiredPermission != null) { 11635 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11636 + " and enforce permission " + requiredPermission); 11637 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11638 } 11639 if (intent.getComponent() != null) { 11640 throw new SecurityException( 11641 "Sticky broadcasts can't target a specific component"); 11642 } 11643 // We use userId directly here, since the "all" target is maintained 11644 // as a separate set of sticky broadcasts. 11645 if (userId != UserHandle.USER_ALL) { 11646 // But first, if this is not a broadcast to all users, then 11647 // make sure it doesn't conflict with an existing broadcast to 11648 // all users. 11649 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11650 UserHandle.USER_ALL); 11651 if (stickies != null) { 11652 ArrayList<Intent> list = stickies.get(intent.getAction()); 11653 if (list != null) { 11654 int N = list.size(); 11655 int i; 11656 for (i=0; i<N; i++) { 11657 if (intent.filterEquals(list.get(i))) { 11658 throw new IllegalArgumentException( 11659 "Sticky broadcast " + intent + " for user " 11660 + userId + " conflicts with existing global broadcast"); 11661 } 11662 } 11663 } 11664 } 11665 } 11666 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11667 if (stickies == null) { 11668 stickies = new HashMap<String, ArrayList<Intent>>(); 11669 mStickyBroadcasts.put(userId, stickies); 11670 } 11671 ArrayList<Intent> list = stickies.get(intent.getAction()); 11672 if (list == null) { 11673 list = new ArrayList<Intent>(); 11674 stickies.put(intent.getAction(), list); 11675 } 11676 int N = list.size(); 11677 int i; 11678 for (i=0; i<N; i++) { 11679 if (intent.filterEquals(list.get(i))) { 11680 // This sticky already exists, replace it. 11681 list.set(i, new Intent(intent)); 11682 break; 11683 } 11684 } 11685 if (i >= N) { 11686 list.add(new Intent(intent)); 11687 } 11688 } 11689 11690 int[] users; 11691 if (userId == UserHandle.USER_ALL) { 11692 // Caller wants broadcast to go to all started users. 11693 users = new int[mStartedUsers.size()]; 11694 for (int i=0; i<mStartedUsers.size(); i++) { 11695 users[i] = mStartedUsers.keyAt(i); 11696 } 11697 } else { 11698 // Caller wants broadcast to go to one specific user. 11699 users = new int[] {userId}; 11700 } 11701 11702 // Figure out who all will receive this broadcast. 11703 List receivers = null; 11704 List<BroadcastFilter> registeredReceivers = null; 11705 // Need to resolve the intent to interested receivers... 11706 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11707 == 0) { 11708 receivers = collectReceiverComponents(intent, resolvedType, users); 11709 } 11710 if (intent.getComponent() == null) { 11711 registeredReceivers = mReceiverResolver.queryIntent(intent, 11712 resolvedType, false, userId); 11713 } 11714 11715 final boolean replacePending = 11716 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11717 11718 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11719 + " replacePending=" + replacePending); 11720 11721 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11722 if (!ordered && NR > 0) { 11723 // If we are not serializing this broadcast, then send the 11724 // registered receivers separately so they don't wait for the 11725 // components to be launched. 11726 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11727 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11728 callerPackage, callingPid, callingUid, requiredPermission, 11729 registeredReceivers, resultTo, resultCode, resultData, map, 11730 ordered, sticky, false, userId); 11731 if (DEBUG_BROADCAST) Slog.v( 11732 TAG, "Enqueueing parallel broadcast " + r); 11733 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11734 if (!replaced) { 11735 queue.enqueueParallelBroadcastLocked(r); 11736 queue.scheduleBroadcastsLocked(); 11737 } 11738 registeredReceivers = null; 11739 NR = 0; 11740 } 11741 11742 // Merge into one list. 11743 int ir = 0; 11744 if (receivers != null) { 11745 // A special case for PACKAGE_ADDED: do not allow the package 11746 // being added to see this broadcast. This prevents them from 11747 // using this as a back door to get run as soon as they are 11748 // installed. Maybe in the future we want to have a special install 11749 // broadcast or such for apps, but we'd like to deliberately make 11750 // this decision. 11751 String skipPackages[] = null; 11752 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11753 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11754 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11755 Uri data = intent.getData(); 11756 if (data != null) { 11757 String pkgName = data.getSchemeSpecificPart(); 11758 if (pkgName != null) { 11759 skipPackages = new String[] { pkgName }; 11760 } 11761 } 11762 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11763 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11764 } 11765 if (skipPackages != null && (skipPackages.length > 0)) { 11766 for (String skipPackage : skipPackages) { 11767 if (skipPackage != null) { 11768 int NT = receivers.size(); 11769 for (int it=0; it<NT; it++) { 11770 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11771 if (curt.activityInfo.packageName.equals(skipPackage)) { 11772 receivers.remove(it); 11773 it--; 11774 NT--; 11775 } 11776 } 11777 } 11778 } 11779 } 11780 11781 int NT = receivers != null ? receivers.size() : 0; 11782 int it = 0; 11783 ResolveInfo curt = null; 11784 BroadcastFilter curr = null; 11785 while (it < NT && ir < NR) { 11786 if (curt == null) { 11787 curt = (ResolveInfo)receivers.get(it); 11788 } 11789 if (curr == null) { 11790 curr = registeredReceivers.get(ir); 11791 } 11792 if (curr.getPriority() >= curt.priority) { 11793 // Insert this broadcast record into the final list. 11794 receivers.add(it, curr); 11795 ir++; 11796 curr = null; 11797 it++; 11798 NT++; 11799 } else { 11800 // Skip to the next ResolveInfo in the final list. 11801 it++; 11802 curt = null; 11803 } 11804 } 11805 } 11806 while (ir < NR) { 11807 if (receivers == null) { 11808 receivers = new ArrayList(); 11809 } 11810 receivers.add(registeredReceivers.get(ir)); 11811 ir++; 11812 } 11813 11814 if ((receivers != null && receivers.size() > 0) 11815 || resultTo != null) { 11816 BroadcastQueue queue = broadcastQueueForIntent(intent); 11817 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11818 callerPackage, callingPid, callingUid, requiredPermission, 11819 receivers, resultTo, resultCode, resultData, map, ordered, 11820 sticky, false, userId); 11821 if (DEBUG_BROADCAST) Slog.v( 11822 TAG, "Enqueueing ordered broadcast " + r 11823 + ": prev had " + queue.mOrderedBroadcasts.size()); 11824 if (DEBUG_BROADCAST) { 11825 int seq = r.intent.getIntExtra("seq", -1); 11826 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11827 } 11828 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11829 if (!replaced) { 11830 queue.enqueueOrderedBroadcastLocked(r); 11831 queue.scheduleBroadcastsLocked(); 11832 } 11833 } 11834 11835 return ActivityManager.BROADCAST_SUCCESS; 11836 } 11837 11838 final Intent verifyBroadcastLocked(Intent intent) { 11839 // Refuse possible leaked file descriptors 11840 if (intent != null && intent.hasFileDescriptors() == true) { 11841 throw new IllegalArgumentException("File descriptors passed in Intent"); 11842 } 11843 11844 int flags = intent.getFlags(); 11845 11846 if (!mProcessesReady) { 11847 // if the caller really truly claims to know what they're doing, go 11848 // ahead and allow the broadcast without launching any receivers 11849 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11850 intent = new Intent(intent); 11851 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11852 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11853 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11854 + " before boot completion"); 11855 throw new IllegalStateException("Cannot broadcast before boot completed"); 11856 } 11857 } 11858 11859 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11860 throw new IllegalArgumentException( 11861 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11862 } 11863 11864 return intent; 11865 } 11866 11867 public final int broadcastIntent(IApplicationThread caller, 11868 Intent intent, String resolvedType, IIntentReceiver resultTo, 11869 int resultCode, String resultData, Bundle map, 11870 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11871 enforceNotIsolatedCaller("broadcastIntent"); 11872 synchronized(this) { 11873 intent = verifyBroadcastLocked(intent); 11874 11875 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11876 final int callingPid = Binder.getCallingPid(); 11877 final int callingUid = Binder.getCallingUid(); 11878 final long origId = Binder.clearCallingIdentity(); 11879 int res = broadcastIntentLocked(callerApp, 11880 callerApp != null ? callerApp.info.packageName : null, 11881 intent, resolvedType, resultTo, 11882 resultCode, resultData, map, requiredPermission, serialized, sticky, 11883 callingPid, callingUid, userId); 11884 Binder.restoreCallingIdentity(origId); 11885 return res; 11886 } 11887 } 11888 11889 int broadcastIntentInPackage(String packageName, int uid, 11890 Intent intent, String resolvedType, IIntentReceiver resultTo, 11891 int resultCode, String resultData, Bundle map, 11892 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11893 synchronized(this) { 11894 intent = verifyBroadcastLocked(intent); 11895 11896 final long origId = Binder.clearCallingIdentity(); 11897 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11898 resultTo, resultCode, resultData, map, requiredPermission, 11899 serialized, sticky, -1, uid, userId); 11900 Binder.restoreCallingIdentity(origId); 11901 return res; 11902 } 11903 } 11904 11905 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11906 // Refuse possible leaked file descriptors 11907 if (intent != null && intent.hasFileDescriptors() == true) { 11908 throw new IllegalArgumentException("File descriptors passed in Intent"); 11909 } 11910 11911 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11912 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11913 11914 synchronized(this) { 11915 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11916 != PackageManager.PERMISSION_GRANTED) { 11917 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11918 + Binder.getCallingPid() 11919 + ", uid=" + Binder.getCallingUid() 11920 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11921 Slog.w(TAG, msg); 11922 throw new SecurityException(msg); 11923 } 11924 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11925 if (stickies != null) { 11926 ArrayList<Intent> list = stickies.get(intent.getAction()); 11927 if (list != null) { 11928 int N = list.size(); 11929 int i; 11930 for (i=0; i<N; i++) { 11931 if (intent.filterEquals(list.get(i))) { 11932 list.remove(i); 11933 break; 11934 } 11935 } 11936 if (list.size() <= 0) { 11937 stickies.remove(intent.getAction()); 11938 } 11939 } 11940 if (stickies.size() <= 0) { 11941 mStickyBroadcasts.remove(userId); 11942 } 11943 } 11944 } 11945 } 11946 11947 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11948 String resultData, Bundle resultExtras, boolean resultAbort, 11949 boolean explicit) { 11950 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11951 if (r == null) { 11952 Slog.w(TAG, "finishReceiver called but not found on queue"); 11953 return false; 11954 } 11955 11956 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11957 explicit); 11958 } 11959 11960 public void finishReceiver(IBinder who, int resultCode, String resultData, 11961 Bundle resultExtras, boolean resultAbort) { 11962 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11963 11964 // Refuse possible leaked file descriptors 11965 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11966 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11967 } 11968 11969 final long origId = Binder.clearCallingIdentity(); 11970 try { 11971 boolean doNext = false; 11972 BroadcastRecord r = null; 11973 11974 synchronized(this) { 11975 r = broadcastRecordForReceiverLocked(who); 11976 if (r != null) { 11977 doNext = r.queue.finishReceiverLocked(r, resultCode, 11978 resultData, resultExtras, resultAbort, true); 11979 } 11980 } 11981 11982 if (doNext) { 11983 r.queue.processNextBroadcast(false); 11984 } 11985 trimApplications(); 11986 } finally { 11987 Binder.restoreCallingIdentity(origId); 11988 } 11989 } 11990 11991 // ========================================================= 11992 // INSTRUMENTATION 11993 // ========================================================= 11994 11995 public boolean startInstrumentation(ComponentName className, 11996 String profileFile, int flags, Bundle arguments, 11997 IInstrumentationWatcher watcher, int userId) { 11998 enforceNotIsolatedCaller("startInstrumentation"); 11999 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 12000 userId, false, true, "startInstrumentation", null); 12001 // Refuse possible leaked file descriptors 12002 if (arguments != null && arguments.hasFileDescriptors()) { 12003 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12004 } 12005 12006 synchronized(this) { 12007 InstrumentationInfo ii = null; 12008 ApplicationInfo ai = null; 12009 try { 12010 ii = mContext.getPackageManager().getInstrumentationInfo( 12011 className, STOCK_PM_FLAGS); 12012 ai = AppGlobals.getPackageManager().getApplicationInfo( 12013 ii.targetPackage, STOCK_PM_FLAGS, userId); 12014 } catch (PackageManager.NameNotFoundException e) { 12015 } catch (RemoteException e) { 12016 } 12017 if (ii == null) { 12018 reportStartInstrumentationFailure(watcher, className, 12019 "Unable to find instrumentation info for: " + className); 12020 return false; 12021 } 12022 if (ai == null) { 12023 reportStartInstrumentationFailure(watcher, className, 12024 "Unable to find instrumentation target package: " + ii.targetPackage); 12025 return false; 12026 } 12027 12028 int match = mContext.getPackageManager().checkSignatures( 12029 ii.targetPackage, ii.packageName); 12030 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12031 String msg = "Permission Denial: starting instrumentation " 12032 + className + " from pid=" 12033 + Binder.getCallingPid() 12034 + ", uid=" + Binder.getCallingPid() 12035 + " not allowed because package " + ii.packageName 12036 + " does not have a signature matching the target " 12037 + ii.targetPackage; 12038 reportStartInstrumentationFailure(watcher, className, msg); 12039 throw new SecurityException(msg); 12040 } 12041 12042 final long origId = Binder.clearCallingIdentity(); 12043 // Instrumentation can kill and relaunch even persistent processes 12044 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12045 ProcessRecord app = addAppLocked(ai, false); 12046 app.instrumentationClass = className; 12047 app.instrumentationInfo = ai; 12048 app.instrumentationProfileFile = profileFile; 12049 app.instrumentationArguments = arguments; 12050 app.instrumentationWatcher = watcher; 12051 app.instrumentationResultClass = className; 12052 Binder.restoreCallingIdentity(origId); 12053 } 12054 12055 return true; 12056 } 12057 12058 /** 12059 * Report errors that occur while attempting to start Instrumentation. Always writes the 12060 * error to the logs, but if somebody is watching, send the report there too. This enables 12061 * the "am" command to report errors with more information. 12062 * 12063 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12064 * @param cn The component name of the instrumentation. 12065 * @param report The error report. 12066 */ 12067 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12068 ComponentName cn, String report) { 12069 Slog.w(TAG, report); 12070 try { 12071 if (watcher != null) { 12072 Bundle results = new Bundle(); 12073 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12074 results.putString("Error", report); 12075 watcher.instrumentationStatus(cn, -1, results); 12076 } 12077 } catch (RemoteException e) { 12078 Slog.w(TAG, e); 12079 } 12080 } 12081 12082 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12083 if (app.instrumentationWatcher != null) { 12084 try { 12085 // NOTE: IInstrumentationWatcher *must* be oneway here 12086 app.instrumentationWatcher.instrumentationFinished( 12087 app.instrumentationClass, 12088 resultCode, 12089 results); 12090 } catch (RemoteException e) { 12091 } 12092 } 12093 app.instrumentationWatcher = null; 12094 app.instrumentationClass = null; 12095 app.instrumentationInfo = null; 12096 app.instrumentationProfileFile = null; 12097 app.instrumentationArguments = null; 12098 12099 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12100 } 12101 12102 public void finishInstrumentation(IApplicationThread target, 12103 int resultCode, Bundle results) { 12104 int userId = UserHandle.getCallingUserId(); 12105 // Refuse possible leaked file descriptors 12106 if (results != null && results.hasFileDescriptors()) { 12107 throw new IllegalArgumentException("File descriptors passed in Intent"); 12108 } 12109 12110 synchronized(this) { 12111 ProcessRecord app = getRecordForAppLocked(target); 12112 if (app == null) { 12113 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12114 return; 12115 } 12116 final long origId = Binder.clearCallingIdentity(); 12117 finishInstrumentationLocked(app, resultCode, results); 12118 Binder.restoreCallingIdentity(origId); 12119 } 12120 } 12121 12122 // ========================================================= 12123 // CONFIGURATION 12124 // ========================================================= 12125 12126 public ConfigurationInfo getDeviceConfigurationInfo() { 12127 ConfigurationInfo config = new ConfigurationInfo(); 12128 synchronized (this) { 12129 config.reqTouchScreen = mConfiguration.touchscreen; 12130 config.reqKeyboardType = mConfiguration.keyboard; 12131 config.reqNavigation = mConfiguration.navigation; 12132 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12133 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12134 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12135 } 12136 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12137 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12138 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12139 } 12140 config.reqGlEsVersion = GL_ES_VERSION; 12141 } 12142 return config; 12143 } 12144 12145 public Configuration getConfiguration() { 12146 Configuration ci; 12147 synchronized(this) { 12148 ci = new Configuration(mConfiguration); 12149 } 12150 return ci; 12151 } 12152 12153 public void updatePersistentConfiguration(Configuration values) { 12154 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12155 "updateConfiguration()"); 12156 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12157 "updateConfiguration()"); 12158 if (values == null) { 12159 throw new NullPointerException("Configuration must not be null"); 12160 } 12161 12162 synchronized(this) { 12163 final long origId = Binder.clearCallingIdentity(); 12164 updateConfigurationLocked(values, null, true, false); 12165 Binder.restoreCallingIdentity(origId); 12166 } 12167 } 12168 12169 public void updateConfiguration(Configuration values) { 12170 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12171 "updateConfiguration()"); 12172 12173 synchronized(this) { 12174 if (values == null && mWindowManager != null) { 12175 // sentinel: fetch the current configuration from the window manager 12176 values = mWindowManager.computeNewConfiguration(); 12177 } 12178 12179 if (mWindowManager != null) { 12180 mProcessList.applyDisplaySize(mWindowManager); 12181 } 12182 12183 final long origId = Binder.clearCallingIdentity(); 12184 if (values != null) { 12185 Settings.System.clearConfiguration(values); 12186 } 12187 updateConfigurationLocked(values, null, false, false); 12188 Binder.restoreCallingIdentity(origId); 12189 } 12190 } 12191 12192 /** 12193 * Do either or both things: (1) change the current configuration, and (2) 12194 * make sure the given activity is running with the (now) current 12195 * configuration. Returns true if the activity has been left running, or 12196 * false if <var>starting</var> is being destroyed to match the new 12197 * configuration. 12198 * @param persistent TODO 12199 */ 12200 boolean updateConfigurationLocked(Configuration values, 12201 ActivityRecord starting, boolean persistent, boolean initLocale) { 12202 // do nothing if we are headless 12203 if (mHeadless) return true; 12204 12205 int changes = 0; 12206 12207 boolean kept = true; 12208 12209 if (values != null) { 12210 Configuration newConfig = new Configuration(mConfiguration); 12211 changes = newConfig.updateFrom(values); 12212 if (changes != 0) { 12213 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12214 Slog.i(TAG, "Updating configuration to: " + values); 12215 } 12216 12217 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12218 12219 if (values.locale != null && !initLocale) { 12220 saveLocaleLocked(values.locale, 12221 !values.locale.equals(mConfiguration.locale), 12222 values.userSetLocale); 12223 } 12224 12225 mConfigurationSeq++; 12226 if (mConfigurationSeq <= 0) { 12227 mConfigurationSeq = 1; 12228 } 12229 newConfig.seq = mConfigurationSeq; 12230 mConfiguration = newConfig; 12231 Slog.i(TAG, "Config changed: " + newConfig); 12232 12233 final Configuration configCopy = new Configuration(mConfiguration); 12234 12235 // TODO: If our config changes, should we auto dismiss any currently 12236 // showing dialogs? 12237 mShowDialogs = shouldShowDialogs(newConfig); 12238 12239 AttributeCache ac = AttributeCache.instance(); 12240 if (ac != null) { 12241 ac.updateConfiguration(configCopy); 12242 } 12243 12244 // Make sure all resources in our process are updated 12245 // right now, so that anyone who is going to retrieve 12246 // resource values after we return will be sure to get 12247 // the new ones. This is especially important during 12248 // boot, where the first config change needs to guarantee 12249 // all resources have that config before following boot 12250 // code is executed. 12251 mSystemThread.applyConfigurationToResources(configCopy); 12252 12253 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12254 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12255 msg.obj = new Configuration(configCopy); 12256 mHandler.sendMessage(msg); 12257 } 12258 12259 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12260 ProcessRecord app = mLruProcesses.get(i); 12261 try { 12262 if (app.thread != null) { 12263 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12264 + app.processName + " new config " + mConfiguration); 12265 app.thread.scheduleConfigurationChanged(configCopy); 12266 } 12267 } catch (Exception e) { 12268 } 12269 } 12270 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12271 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12272 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12273 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12274 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12275 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12276 broadcastIntentLocked(null, null, 12277 new Intent(Intent.ACTION_LOCALE_CHANGED), 12278 null, null, 0, null, null, 12279 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12280 } 12281 } 12282 } 12283 12284 if (changes != 0 && starting == null) { 12285 // If the configuration changed, and the caller is not already 12286 // in the process of starting an activity, then find the top 12287 // activity to check if its configuration needs to change. 12288 starting = mMainStack.topRunningActivityLocked(null); 12289 } 12290 12291 if (starting != null) { 12292 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12293 // And we need to make sure at this point that all other activities 12294 // are made visible with the correct configuration. 12295 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12296 } 12297 12298 if (values != null && mWindowManager != null) { 12299 mWindowManager.setNewConfiguration(mConfiguration); 12300 } 12301 12302 return kept; 12303 } 12304 12305 /** 12306 * Decide based on the configuration whether we should shouw the ANR, 12307 * crash, etc dialogs. The idea is that if there is no affordnace to 12308 * press the on-screen buttons, we shouldn't show the dialog. 12309 * 12310 * A thought: SystemUI might also want to get told about this, the Power 12311 * dialog / global actions also might want different behaviors. 12312 */ 12313 private static final boolean shouldShowDialogs(Configuration config) { 12314 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12315 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12316 } 12317 12318 /** 12319 * Save the locale. You must be inside a synchronized (this) block. 12320 */ 12321 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12322 if(isDiff) { 12323 SystemProperties.set("user.language", l.getLanguage()); 12324 SystemProperties.set("user.region", l.getCountry()); 12325 } 12326 12327 if(isPersist) { 12328 SystemProperties.set("persist.sys.language", l.getLanguage()); 12329 SystemProperties.set("persist.sys.country", l.getCountry()); 12330 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12331 } 12332 } 12333 12334 @Override 12335 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12336 ActivityRecord srec = ActivityRecord.forToken(token); 12337 return srec != null && srec.task.affinity != null && 12338 srec.task.affinity.equals(destAffinity); 12339 } 12340 12341 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12342 Intent resultData) { 12343 ComponentName dest = destIntent.getComponent(); 12344 12345 synchronized (this) { 12346 ActivityRecord srec = ActivityRecord.forToken(token); 12347 if (srec == null) { 12348 return false; 12349 } 12350 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12351 final int start = history.indexOf(srec); 12352 if (start < 0) { 12353 // Current activity is not in history stack; do nothing. 12354 return false; 12355 } 12356 int finishTo = start - 1; 12357 ActivityRecord parent = null; 12358 boolean foundParentInTask = false; 12359 if (dest != null) { 12360 TaskRecord tr = srec.task; 12361 for (int i = start - 1; i >= 0; i--) { 12362 ActivityRecord r = history.get(i); 12363 if (tr != r.task) { 12364 // Couldn't find parent in the same task; stop at the one above this. 12365 // (Root of current task; in-app "home" behavior) 12366 // Always at least finish the current activity. 12367 finishTo = Math.min(start - 1, i + 1); 12368 parent = history.get(finishTo); 12369 break; 12370 } else if (r.info.packageName.equals(dest.getPackageName()) && 12371 r.info.name.equals(dest.getClassName())) { 12372 finishTo = i; 12373 parent = r; 12374 foundParentInTask = true; 12375 break; 12376 } 12377 } 12378 } 12379 12380 if (mController != null) { 12381 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12382 if (next != null) { 12383 // ask watcher if this is allowed 12384 boolean resumeOK = true; 12385 try { 12386 resumeOK = mController.activityResuming(next.packageName); 12387 } catch (RemoteException e) { 12388 mController = null; 12389 } 12390 12391 if (!resumeOK) { 12392 return false; 12393 } 12394 } 12395 } 12396 final long origId = Binder.clearCallingIdentity(); 12397 for (int i = start; i > finishTo; i--) { 12398 ActivityRecord r = history.get(i); 12399 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12400 "navigate-up", true); 12401 // Only return the supplied result for the first activity finished 12402 resultCode = Activity.RESULT_CANCELED; 12403 resultData = null; 12404 } 12405 12406 if (parent != null && foundParentInTask) { 12407 final int parentLaunchMode = parent.info.launchMode; 12408 final int destIntentFlags = destIntent.getFlags(); 12409 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12410 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12411 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12412 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12413 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12414 } else { 12415 try { 12416 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12417 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12418 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12419 null, aInfo, parent.appToken, null, 12420 0, -1, parent.launchedFromUid, 0, null, true, null); 12421 foundParentInTask = res == ActivityManager.START_SUCCESS; 12422 } catch (RemoteException e) { 12423 foundParentInTask = false; 12424 } 12425 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12426 resultData, "navigate-up", true); 12427 } 12428 } 12429 Binder.restoreCallingIdentity(origId); 12430 return foundParentInTask; 12431 } 12432 } 12433 12434 public int getLaunchedFromUid(IBinder activityToken) { 12435 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12436 if (srec == null) { 12437 return -1; 12438 } 12439 return srec.launchedFromUid; 12440 } 12441 12442 // ========================================================= 12443 // LIFETIME MANAGEMENT 12444 // ========================================================= 12445 12446 // Returns which broadcast queue the app is the current [or imminent] receiver 12447 // on, or 'null' if the app is not an active broadcast recipient. 12448 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12449 BroadcastRecord r = app.curReceiver; 12450 if (r != null) { 12451 return r.queue; 12452 } 12453 12454 // It's not the current receiver, but it might be starting up to become one 12455 synchronized (this) { 12456 for (BroadcastQueue queue : mBroadcastQueues) { 12457 r = queue.mPendingBroadcast; 12458 if (r != null && r.curApp == app) { 12459 // found it; report which queue it's in 12460 return queue; 12461 } 12462 } 12463 } 12464 12465 return null; 12466 } 12467 12468 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12469 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12470 if (mAdjSeq == app.adjSeq) { 12471 // This adjustment has already been computed. If we are calling 12472 // from the top, we may have already computed our adjustment with 12473 // an earlier hidden adjustment that isn't really for us... if 12474 // so, use the new hidden adjustment. 12475 if (!recursed && app.hidden) { 12476 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12477 app.hasActivities ? hiddenAdj : emptyAdj; 12478 } 12479 return app.curRawAdj; 12480 } 12481 12482 if (app.thread == null) { 12483 app.adjSeq = mAdjSeq; 12484 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12485 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12486 } 12487 12488 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12489 app.adjSource = null; 12490 app.adjTarget = null; 12491 app.empty = false; 12492 app.hidden = false; 12493 12494 final int activitiesSize = app.activities.size(); 12495 12496 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12497 // The max adjustment doesn't allow this app to be anything 12498 // below foreground, so it is not worth doing work for it. 12499 app.adjType = "fixed"; 12500 app.adjSeq = mAdjSeq; 12501 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12502 app.hasActivities = false; 12503 app.foregroundActivities = false; 12504 app.keeping = true; 12505 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12506 // System process can do UI, and when they do we want to have 12507 // them trim their memory after the user leaves the UI. To 12508 // facilitate this, here we need to determine whether or not it 12509 // is currently showing UI. 12510 app.systemNoUi = true; 12511 if (app == TOP_APP) { 12512 app.systemNoUi = false; 12513 app.hasActivities = true; 12514 } else if (activitiesSize > 0) { 12515 for (int j = 0; j < activitiesSize; j++) { 12516 final ActivityRecord r = app.activities.get(j); 12517 if (r.visible) { 12518 app.systemNoUi = false; 12519 } 12520 if (r.app == app) { 12521 app.hasActivities = true; 12522 } 12523 } 12524 } 12525 return (app.curAdj=app.maxAdj); 12526 } 12527 12528 app.keeping = false; 12529 app.systemNoUi = false; 12530 app.hasActivities = false; 12531 12532 // Determine the importance of the process, starting with most 12533 // important to least, and assign an appropriate OOM adjustment. 12534 int adj; 12535 int schedGroup; 12536 boolean foregroundActivities = false; 12537 boolean interesting = false; 12538 BroadcastQueue queue; 12539 if (app == TOP_APP) { 12540 // The last app on the list is the foreground app. 12541 adj = ProcessList.FOREGROUND_APP_ADJ; 12542 schedGroup = Process.THREAD_GROUP_DEFAULT; 12543 app.adjType = "top-activity"; 12544 foregroundActivities = true; 12545 interesting = true; 12546 app.hasActivities = true; 12547 } else if (app.instrumentationClass != null) { 12548 // Don't want to kill running instrumentation. 12549 adj = ProcessList.FOREGROUND_APP_ADJ; 12550 schedGroup = Process.THREAD_GROUP_DEFAULT; 12551 app.adjType = "instrumentation"; 12552 interesting = true; 12553 } else if ((queue = isReceivingBroadcast(app)) != null) { 12554 // An app that is currently receiving a broadcast also 12555 // counts as being in the foreground for OOM killer purposes. 12556 // It's placed in a sched group based on the nature of the 12557 // broadcast as reflected by which queue it's active in. 12558 adj = ProcessList.FOREGROUND_APP_ADJ; 12559 schedGroup = (queue == mFgBroadcastQueue) 12560 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12561 app.adjType = "broadcast"; 12562 } else if (app.executingServices.size() > 0) { 12563 // An app that is currently executing a service callback also 12564 // counts as being in the foreground. 12565 adj = ProcessList.FOREGROUND_APP_ADJ; 12566 schedGroup = Process.THREAD_GROUP_DEFAULT; 12567 app.adjType = "exec-service"; 12568 } else { 12569 // Assume process is hidden (has activities); we will correct 12570 // later if this is not the case. 12571 adj = hiddenAdj; 12572 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12573 app.hidden = true; 12574 app.adjType = "bg-activities"; 12575 } 12576 12577 boolean hasStoppingActivities = false; 12578 12579 // Examine all activities if not already foreground. 12580 if (!foregroundActivities && activitiesSize > 0) { 12581 for (int j = 0; j < activitiesSize; j++) { 12582 final ActivityRecord r = app.activities.get(j); 12583 if (r.visible) { 12584 // App has a visible activity; only upgrade adjustment. 12585 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12586 adj = ProcessList.VISIBLE_APP_ADJ; 12587 app.adjType = "visible"; 12588 } 12589 schedGroup = Process.THREAD_GROUP_DEFAULT; 12590 app.hidden = false; 12591 app.hasActivities = true; 12592 foregroundActivities = true; 12593 break; 12594 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12595 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12596 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12597 app.adjType = "pausing"; 12598 } 12599 app.hidden = false; 12600 foregroundActivities = true; 12601 } else if (r.state == ActivityState.STOPPING) { 12602 // We will apply the actual adjustment later, because 12603 // we want to allow this process to immediately go through 12604 // any memory trimming that is in effect. 12605 app.hidden = false; 12606 foregroundActivities = true; 12607 hasStoppingActivities = true; 12608 } 12609 if (r.app == app) { 12610 app.hasActivities = true; 12611 } 12612 } 12613 } 12614 12615 if (adj == hiddenAdj && !app.hasActivities) { 12616 // Whoops, this process is completely empty as far as we know 12617 // at this point. 12618 adj = emptyAdj; 12619 app.empty = true; 12620 app.adjType = "bg-empty"; 12621 } 12622 12623 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12624 if (app.foregroundServices) { 12625 // The user is aware of this app, so make it visible. 12626 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12627 app.hidden = false; 12628 app.adjType = "foreground-service"; 12629 schedGroup = Process.THREAD_GROUP_DEFAULT; 12630 } else if (app.forcingToForeground != null) { 12631 // The user is aware of this app, so make it visible. 12632 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12633 app.hidden = false; 12634 app.adjType = "force-foreground"; 12635 app.adjSource = app.forcingToForeground; 12636 schedGroup = Process.THREAD_GROUP_DEFAULT; 12637 } 12638 } 12639 12640 if (app.foregroundServices) { 12641 interesting = true; 12642 } 12643 12644 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12645 // We don't want to kill the current heavy-weight process. 12646 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12647 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12648 app.hidden = false; 12649 app.adjType = "heavy"; 12650 } 12651 12652 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12653 // This process is hosting what we currently consider to be the 12654 // home app, so we don't want to let it go into the background. 12655 adj = ProcessList.HOME_APP_ADJ; 12656 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12657 app.hidden = false; 12658 app.adjType = "home"; 12659 } 12660 12661 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12662 && app.activities.size() > 0) { 12663 // This was the previous process that showed UI to the user. 12664 // We want to try to keep it around more aggressively, to give 12665 // a good experience around switching between two apps. 12666 adj = ProcessList.PREVIOUS_APP_ADJ; 12667 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12668 app.hidden = false; 12669 app.adjType = "previous"; 12670 } 12671 12672 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12673 + " reason=" + app.adjType); 12674 12675 // By default, we use the computed adjustment. It may be changed if 12676 // there are applications dependent on our services or providers, but 12677 // this gives us a baseline and makes sure we don't get into an 12678 // infinite recursion. 12679 app.adjSeq = mAdjSeq; 12680 app.curRawAdj = app.nonStoppingAdj = adj; 12681 12682 if (mBackupTarget != null && app == mBackupTarget.app) { 12683 // If possible we want to avoid killing apps while they're being backed up 12684 if (adj > ProcessList.BACKUP_APP_ADJ) { 12685 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12686 adj = ProcessList.BACKUP_APP_ADJ; 12687 app.adjType = "backup"; 12688 app.hidden = false; 12689 } 12690 } 12691 12692 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12693 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12694 final long now = SystemClock.uptimeMillis(); 12695 // This process is more important if the top activity is 12696 // bound to the service. 12697 Iterator<ServiceRecord> jt = app.services.iterator(); 12698 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12699 ServiceRecord s = jt.next(); 12700 if (s.startRequested) { 12701 if (app.hasShownUi && app != mHomeProcess) { 12702 // If this process has shown some UI, let it immediately 12703 // go to the LRU list because it may be pretty heavy with 12704 // UI stuff. We'll tag it with a label just to help 12705 // debug and understand what is going on. 12706 if (adj > ProcessList.SERVICE_ADJ) { 12707 app.adjType = "started-bg-ui-services"; 12708 } 12709 } else { 12710 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12711 // This service has seen some activity within 12712 // recent memory, so we will keep its process ahead 12713 // of the background processes. 12714 if (adj > ProcessList.SERVICE_ADJ) { 12715 adj = ProcessList.SERVICE_ADJ; 12716 app.adjType = "started-services"; 12717 app.hidden = false; 12718 } 12719 } 12720 // If we have let the service slide into the background 12721 // state, still have some text describing what it is doing 12722 // even though the service no longer has an impact. 12723 if (adj > ProcessList.SERVICE_ADJ) { 12724 app.adjType = "started-bg-services"; 12725 } 12726 } 12727 // Don't kill this process because it is doing work; it 12728 // has said it is doing work. 12729 app.keeping = true; 12730 } 12731 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12732 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12733 Iterator<ArrayList<ConnectionRecord>> kt 12734 = s.connections.values().iterator(); 12735 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12736 ArrayList<ConnectionRecord> clist = kt.next(); 12737 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12738 // XXX should compute this based on the max of 12739 // all connected clients. 12740 ConnectionRecord cr = clist.get(i); 12741 if (cr.binding.client == app) { 12742 // Binding to ourself is not interesting. 12743 continue; 12744 } 12745 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12746 ProcessRecord client = cr.binding.client; 12747 int clientAdj = adj; 12748 int myHiddenAdj = hiddenAdj; 12749 if (myHiddenAdj > client.hiddenAdj) { 12750 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12751 myHiddenAdj = client.hiddenAdj; 12752 } else { 12753 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12754 } 12755 } 12756 int myEmptyAdj = emptyAdj; 12757 if (myEmptyAdj > client.emptyAdj) { 12758 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12759 myEmptyAdj = client.emptyAdj; 12760 } else { 12761 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12762 } 12763 } 12764 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12765 myEmptyAdj, TOP_APP, true, doingAll); 12766 String adjType = null; 12767 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12768 // Not doing bind OOM management, so treat 12769 // this guy more like a started service. 12770 if (app.hasShownUi && app != mHomeProcess) { 12771 // If this process has shown some UI, let it immediately 12772 // go to the LRU list because it may be pretty heavy with 12773 // UI stuff. We'll tag it with a label just to help 12774 // debug and understand what is going on. 12775 if (adj > clientAdj) { 12776 adjType = "bound-bg-ui-services"; 12777 } 12778 app.hidden = false; 12779 clientAdj = adj; 12780 } else { 12781 if (now >= (s.lastActivity 12782 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12783 // This service has not seen activity within 12784 // recent memory, so allow it to drop to the 12785 // LRU list if there is no other reason to keep 12786 // it around. We'll also tag it with a label just 12787 // to help debug and undertand what is going on. 12788 if (adj > clientAdj) { 12789 adjType = "bound-bg-services"; 12790 } 12791 clientAdj = adj; 12792 } 12793 } 12794 } 12795 if (adj > clientAdj) { 12796 // If this process has recently shown UI, and 12797 // the process that is binding to it is less 12798 // important than being visible, then we don't 12799 // care about the binding as much as we care 12800 // about letting this process get into the LRU 12801 // list to be killed and restarted if needed for 12802 // memory. 12803 if (app.hasShownUi && app != mHomeProcess 12804 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12805 adjType = "bound-bg-ui-services"; 12806 } else { 12807 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12808 |Context.BIND_IMPORTANT)) != 0) { 12809 adj = clientAdj; 12810 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12811 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12812 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12813 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12814 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12815 adj = clientAdj; 12816 } else { 12817 app.pendingUiClean = true; 12818 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12819 adj = ProcessList.VISIBLE_APP_ADJ; 12820 } 12821 } 12822 if (!client.hidden) { 12823 app.hidden = false; 12824 } 12825 if (client.keeping) { 12826 app.keeping = true; 12827 } 12828 adjType = "service"; 12829 } 12830 } 12831 if (adjType != null) { 12832 app.adjType = adjType; 12833 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12834 .REASON_SERVICE_IN_USE; 12835 app.adjSource = cr.binding.client; 12836 app.adjSourceOom = clientAdj; 12837 app.adjTarget = s.name; 12838 } 12839 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12840 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12841 schedGroup = Process.THREAD_GROUP_DEFAULT; 12842 } 12843 } 12844 } 12845 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12846 ActivityRecord a = cr.activity; 12847 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12848 (a.visible || a.state == ActivityState.RESUMED 12849 || a.state == ActivityState.PAUSING)) { 12850 adj = ProcessList.FOREGROUND_APP_ADJ; 12851 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12852 schedGroup = Process.THREAD_GROUP_DEFAULT; 12853 } 12854 app.hidden = false; 12855 app.adjType = "service"; 12856 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12857 .REASON_SERVICE_IN_USE; 12858 app.adjSource = a; 12859 app.adjSourceOom = adj; 12860 app.adjTarget = s.name; 12861 } 12862 } 12863 } 12864 } 12865 } 12866 } 12867 12868 // Finally, if this process has active services running in it, we 12869 // would like to avoid killing it unless it would prevent the current 12870 // application from running. By default we put the process in 12871 // with the rest of the background processes; as we scan through 12872 // its services we may bump it up from there. 12873 if (adj > hiddenAdj) { 12874 adj = hiddenAdj; 12875 app.hidden = false; 12876 app.adjType = "bg-services"; 12877 } 12878 } 12879 12880 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12881 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12882 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12883 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12884 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12885 ContentProviderRecord cpr = jt.next(); 12886 for (int i = cpr.connections.size()-1; 12887 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12888 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12889 i--) { 12890 ContentProviderConnection conn = cpr.connections.get(i); 12891 ProcessRecord client = conn.client; 12892 if (client == app) { 12893 // Being our own client is not interesting. 12894 continue; 12895 } 12896 int myHiddenAdj = hiddenAdj; 12897 if (myHiddenAdj > client.hiddenAdj) { 12898 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12899 myHiddenAdj = client.hiddenAdj; 12900 } else { 12901 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12902 } 12903 } 12904 int myEmptyAdj = emptyAdj; 12905 if (myEmptyAdj > client.emptyAdj) { 12906 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12907 myEmptyAdj = client.emptyAdj; 12908 } else { 12909 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12910 } 12911 } 12912 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12913 myEmptyAdj, TOP_APP, true, doingAll); 12914 if (adj > clientAdj) { 12915 if (app.hasShownUi && app != mHomeProcess 12916 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12917 app.adjType = "bg-ui-provider"; 12918 } else { 12919 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12920 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12921 app.adjType = "provider"; 12922 } 12923 if (!client.hidden) { 12924 app.hidden = false; 12925 } 12926 if (client.keeping) { 12927 app.keeping = true; 12928 } 12929 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12930 .REASON_PROVIDER_IN_USE; 12931 app.adjSource = client; 12932 app.adjSourceOom = clientAdj; 12933 app.adjTarget = cpr.name; 12934 } 12935 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12936 schedGroup = Process.THREAD_GROUP_DEFAULT; 12937 } 12938 } 12939 // If the provider has external (non-framework) process 12940 // dependencies, ensure that its adjustment is at least 12941 // FOREGROUND_APP_ADJ. 12942 if (cpr.hasExternalProcessHandles()) { 12943 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12944 adj = ProcessList.FOREGROUND_APP_ADJ; 12945 schedGroup = Process.THREAD_GROUP_DEFAULT; 12946 app.hidden = false; 12947 app.keeping = true; 12948 app.adjType = "provider"; 12949 app.adjTarget = cpr.name; 12950 } 12951 } 12952 } 12953 } 12954 12955 if (adj == ProcessList.SERVICE_ADJ) { 12956 if (doingAll) { 12957 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12958 mNewNumServiceProcs++; 12959 } 12960 if (app.serviceb) { 12961 adj = ProcessList.SERVICE_B_ADJ; 12962 } 12963 } else { 12964 app.serviceb = false; 12965 } 12966 12967 app.nonStoppingAdj = adj; 12968 12969 if (hasStoppingActivities) { 12970 // Only upgrade adjustment. 12971 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12972 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12973 app.adjType = "stopping"; 12974 } 12975 } 12976 12977 app.curRawAdj = adj; 12978 12979 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12980 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12981 if (adj > app.maxAdj) { 12982 adj = app.maxAdj; 12983 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12984 schedGroup = Process.THREAD_GROUP_DEFAULT; 12985 } 12986 } 12987 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12988 app.keeping = true; 12989 } 12990 12991 if (app.hasAboveClient) { 12992 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12993 // then we need to drop its adjustment to be lower than the service's 12994 // in order to honor the request. We want to drop it by one adjustment 12995 // level... but there is special meaning applied to various levels so 12996 // we will skip some of them. 12997 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12998 // System process will not get dropped, ever 12999 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13000 adj = ProcessList.VISIBLE_APP_ADJ; 13001 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13002 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13003 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13004 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13005 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13006 adj++; 13007 } 13008 } 13009 13010 int importance = app.memImportance; 13011 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13012 app.curAdj = adj; 13013 app.curSchedGroup = schedGroup; 13014 if (!interesting) { 13015 // For this reporting, if there is not something explicitly 13016 // interesting in this process then we will push it to the 13017 // background importance. 13018 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13019 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13020 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13021 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13022 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13023 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13024 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13025 } else if (adj >= ProcessList.SERVICE_ADJ) { 13026 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13027 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13028 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13029 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13030 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13031 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13032 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13033 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13034 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13035 } else { 13036 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13037 } 13038 } 13039 13040 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13041 if (foregroundActivities != app.foregroundActivities) { 13042 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13043 } 13044 if (changes != 0) { 13045 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13046 app.memImportance = importance; 13047 app.foregroundActivities = foregroundActivities; 13048 int i = mPendingProcessChanges.size()-1; 13049 ProcessChangeItem item = null; 13050 while (i >= 0) { 13051 item = mPendingProcessChanges.get(i); 13052 if (item.pid == app.pid) { 13053 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13054 break; 13055 } 13056 i--; 13057 } 13058 if (i < 0) { 13059 // No existing item in pending changes; need a new one. 13060 final int NA = mAvailProcessChanges.size(); 13061 if (NA > 0) { 13062 item = mAvailProcessChanges.remove(NA-1); 13063 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13064 } else { 13065 item = new ProcessChangeItem(); 13066 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13067 } 13068 item.changes = 0; 13069 item.pid = app.pid; 13070 item.uid = app.info.uid; 13071 if (mPendingProcessChanges.size() == 0) { 13072 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13073 "*** Enqueueing dispatch processes changed!"); 13074 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13075 } 13076 mPendingProcessChanges.add(item); 13077 } 13078 item.changes |= changes; 13079 item.importance = importance; 13080 item.foregroundActivities = foregroundActivities; 13081 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13082 + Integer.toHexString(System.identityHashCode(item)) 13083 + " " + app.toShortString() + ": changes=" + item.changes 13084 + " importance=" + item.importance 13085 + " foreground=" + item.foregroundActivities 13086 + " type=" + app.adjType + " source=" + app.adjSource 13087 + " target=" + app.adjTarget); 13088 } 13089 13090 return app.curRawAdj; 13091 } 13092 13093 /** 13094 * Ask a given process to GC right now. 13095 */ 13096 final void performAppGcLocked(ProcessRecord app) { 13097 try { 13098 app.lastRequestedGc = SystemClock.uptimeMillis(); 13099 if (app.thread != null) { 13100 if (app.reportLowMemory) { 13101 app.reportLowMemory = false; 13102 app.thread.scheduleLowMemory(); 13103 } else { 13104 app.thread.processInBackground(); 13105 } 13106 } 13107 } catch (Exception e) { 13108 // whatever. 13109 } 13110 } 13111 13112 /** 13113 * Returns true if things are idle enough to perform GCs. 13114 */ 13115 private final boolean canGcNowLocked() { 13116 boolean processingBroadcasts = false; 13117 for (BroadcastQueue q : mBroadcastQueues) { 13118 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13119 processingBroadcasts = true; 13120 } 13121 } 13122 return !processingBroadcasts 13123 && (mSleeping || (mMainStack.mResumedActivity != null && 13124 mMainStack.mResumedActivity.idle)); 13125 } 13126 13127 /** 13128 * Perform GCs on all processes that are waiting for it, but only 13129 * if things are idle. 13130 */ 13131 final void performAppGcsLocked() { 13132 final int N = mProcessesToGc.size(); 13133 if (N <= 0) { 13134 return; 13135 } 13136 if (canGcNowLocked()) { 13137 while (mProcessesToGc.size() > 0) { 13138 ProcessRecord proc = mProcessesToGc.remove(0); 13139 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13140 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13141 <= SystemClock.uptimeMillis()) { 13142 // To avoid spamming the system, we will GC processes one 13143 // at a time, waiting a few seconds between each. 13144 performAppGcLocked(proc); 13145 scheduleAppGcsLocked(); 13146 return; 13147 } else { 13148 // It hasn't been long enough since we last GCed this 13149 // process... put it in the list to wait for its time. 13150 addProcessToGcListLocked(proc); 13151 break; 13152 } 13153 } 13154 } 13155 13156 scheduleAppGcsLocked(); 13157 } 13158 } 13159 13160 /** 13161 * If all looks good, perform GCs on all processes waiting for them. 13162 */ 13163 final void performAppGcsIfAppropriateLocked() { 13164 if (canGcNowLocked()) { 13165 performAppGcsLocked(); 13166 return; 13167 } 13168 // Still not idle, wait some more. 13169 scheduleAppGcsLocked(); 13170 } 13171 13172 /** 13173 * Schedule the execution of all pending app GCs. 13174 */ 13175 final void scheduleAppGcsLocked() { 13176 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13177 13178 if (mProcessesToGc.size() > 0) { 13179 // Schedule a GC for the time to the next process. 13180 ProcessRecord proc = mProcessesToGc.get(0); 13181 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13182 13183 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13184 long now = SystemClock.uptimeMillis(); 13185 if (when < (now+GC_TIMEOUT)) { 13186 when = now + GC_TIMEOUT; 13187 } 13188 mHandler.sendMessageAtTime(msg, when); 13189 } 13190 } 13191 13192 /** 13193 * Add a process to the array of processes waiting to be GCed. Keeps the 13194 * list in sorted order by the last GC time. The process can't already be 13195 * on the list. 13196 */ 13197 final void addProcessToGcListLocked(ProcessRecord proc) { 13198 boolean added = false; 13199 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13200 if (mProcessesToGc.get(i).lastRequestedGc < 13201 proc.lastRequestedGc) { 13202 added = true; 13203 mProcessesToGc.add(i+1, proc); 13204 break; 13205 } 13206 } 13207 if (!added) { 13208 mProcessesToGc.add(0, proc); 13209 } 13210 } 13211 13212 /** 13213 * Set up to ask a process to GC itself. This will either do it 13214 * immediately, or put it on the list of processes to gc the next 13215 * time things are idle. 13216 */ 13217 final void scheduleAppGcLocked(ProcessRecord app) { 13218 long now = SystemClock.uptimeMillis(); 13219 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13220 return; 13221 } 13222 if (!mProcessesToGc.contains(app)) { 13223 addProcessToGcListLocked(app); 13224 scheduleAppGcsLocked(); 13225 } 13226 } 13227 13228 final void checkExcessivePowerUsageLocked(boolean doKills) { 13229 updateCpuStatsNow(); 13230 13231 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13232 boolean doWakeKills = doKills; 13233 boolean doCpuKills = doKills; 13234 if (mLastPowerCheckRealtime == 0) { 13235 doWakeKills = false; 13236 } 13237 if (mLastPowerCheckUptime == 0) { 13238 doCpuKills = false; 13239 } 13240 if (stats.isScreenOn()) { 13241 doWakeKills = false; 13242 } 13243 final long curRealtime = SystemClock.elapsedRealtime(); 13244 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13245 final long curUptime = SystemClock.uptimeMillis(); 13246 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13247 mLastPowerCheckRealtime = curRealtime; 13248 mLastPowerCheckUptime = curUptime; 13249 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13250 doWakeKills = false; 13251 } 13252 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13253 doCpuKills = false; 13254 } 13255 int i = mLruProcesses.size(); 13256 while (i > 0) { 13257 i--; 13258 ProcessRecord app = mLruProcesses.get(i); 13259 if (!app.keeping) { 13260 long wtime; 13261 synchronized (stats) { 13262 wtime = stats.getProcessWakeTime(app.info.uid, 13263 app.pid, curRealtime); 13264 } 13265 long wtimeUsed = wtime - app.lastWakeTime; 13266 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13267 if (DEBUG_POWER) { 13268 StringBuilder sb = new StringBuilder(128); 13269 sb.append("Wake for "); 13270 app.toShortString(sb); 13271 sb.append(": over "); 13272 TimeUtils.formatDuration(realtimeSince, sb); 13273 sb.append(" used "); 13274 TimeUtils.formatDuration(wtimeUsed, sb); 13275 sb.append(" ("); 13276 sb.append((wtimeUsed*100)/realtimeSince); 13277 sb.append("%)"); 13278 Slog.i(TAG, sb.toString()); 13279 sb.setLength(0); 13280 sb.append("CPU for "); 13281 app.toShortString(sb); 13282 sb.append(": over "); 13283 TimeUtils.formatDuration(uptimeSince, sb); 13284 sb.append(" used "); 13285 TimeUtils.formatDuration(cputimeUsed, sb); 13286 sb.append(" ("); 13287 sb.append((cputimeUsed*100)/uptimeSince); 13288 sb.append("%)"); 13289 Slog.i(TAG, sb.toString()); 13290 } 13291 // If a process has held a wake lock for more 13292 // than 50% of the time during this period, 13293 // that sounds bad. Kill! 13294 if (doWakeKills && realtimeSince > 0 13295 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13296 synchronized (stats) { 13297 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13298 realtimeSince, wtimeUsed); 13299 } 13300 Slog.w(TAG, "Excessive wake lock in " + app.processName 13301 + " (pid " + app.pid + "): held " + wtimeUsed 13302 + " during " + realtimeSince); 13303 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13304 app.processName, app.setAdj, "excessive wake lock"); 13305 Process.killProcessQuiet(app.pid); 13306 } else if (doCpuKills && uptimeSince > 0 13307 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13308 synchronized (stats) { 13309 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13310 uptimeSince, cputimeUsed); 13311 } 13312 Slog.w(TAG, "Excessive CPU in " + app.processName 13313 + " (pid " + app.pid + "): used " + cputimeUsed 13314 + " during " + uptimeSince); 13315 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13316 app.processName, app.setAdj, "excessive cpu"); 13317 Process.killProcessQuiet(app.pid); 13318 } else { 13319 app.lastWakeTime = wtime; 13320 app.lastCpuTime = app.curCpuTime; 13321 } 13322 } 13323 } 13324 } 13325 13326 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13327 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13328 app.hiddenAdj = hiddenAdj; 13329 app.emptyAdj = emptyAdj; 13330 13331 if (app.thread == null) { 13332 return false; 13333 } 13334 13335 final boolean wasKeeping = app.keeping; 13336 13337 boolean success = true; 13338 13339 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13340 13341 if (app.curRawAdj != app.setRawAdj) { 13342 if (wasKeeping && !app.keeping) { 13343 // This app is no longer something we want to keep. Note 13344 // its current wake lock time to later know to kill it if 13345 // it is not behaving well. 13346 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13347 synchronized (stats) { 13348 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13349 app.pid, SystemClock.elapsedRealtime()); 13350 } 13351 app.lastCpuTime = app.curCpuTime; 13352 } 13353 13354 app.setRawAdj = app.curRawAdj; 13355 } 13356 13357 if (app.curAdj != app.setAdj) { 13358 if (Process.setOomAdj(app.pid, app.curAdj)) { 13359 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13360 TAG, "Set " + app.pid + " " + app.processName + 13361 " adj " + app.curAdj + ": " + app.adjType); 13362 app.setAdj = app.curAdj; 13363 } else { 13364 success = false; 13365 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13366 } 13367 } 13368 if (app.setSchedGroup != app.curSchedGroup) { 13369 app.setSchedGroup = app.curSchedGroup; 13370 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13371 "Setting process group of " + app.processName 13372 + " to " + app.curSchedGroup); 13373 if (app.waitingToKill != null && 13374 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13375 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13376 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13377 app.processName, app.setAdj, app.waitingToKill); 13378 app.killedBackground = true; 13379 Process.killProcessQuiet(app.pid); 13380 success = false; 13381 } else { 13382 if (true) { 13383 long oldId = Binder.clearCallingIdentity(); 13384 try { 13385 Process.setProcessGroup(app.pid, app.curSchedGroup); 13386 } catch (Exception e) { 13387 Slog.w(TAG, "Failed setting process group of " + app.pid 13388 + " to " + app.curSchedGroup); 13389 e.printStackTrace(); 13390 } finally { 13391 Binder.restoreCallingIdentity(oldId); 13392 } 13393 } else { 13394 if (app.thread != null) { 13395 try { 13396 app.thread.setSchedulingGroup(app.curSchedGroup); 13397 } catch (RemoteException e) { 13398 } 13399 } 13400 } 13401 } 13402 } 13403 return success; 13404 } 13405 13406 private final ActivityRecord resumedAppLocked() { 13407 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13408 if (resumedActivity == null || resumedActivity.app == null) { 13409 resumedActivity = mMainStack.mPausingActivity; 13410 if (resumedActivity == null || resumedActivity.app == null) { 13411 resumedActivity = mMainStack.topRunningActivityLocked(null); 13412 } 13413 } 13414 return resumedActivity; 13415 } 13416 13417 final boolean updateOomAdjLocked(ProcessRecord app) { 13418 final ActivityRecord TOP_ACT = resumedAppLocked(); 13419 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13420 int curAdj = app.curAdj; 13421 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13422 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13423 13424 mAdjSeq++; 13425 13426 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13427 TOP_APP, false); 13428 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13429 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13430 if (nowHidden != wasHidden) { 13431 // Changed to/from hidden state, so apps after it in the LRU 13432 // list may also be changed. 13433 updateOomAdjLocked(); 13434 } 13435 return success; 13436 } 13437 13438 final void updateOomAdjLocked() { 13439 final ActivityRecord TOP_ACT = resumedAppLocked(); 13440 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13441 13442 if (false) { 13443 RuntimeException e = new RuntimeException(); 13444 e.fillInStackTrace(); 13445 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13446 } 13447 13448 mAdjSeq++; 13449 mNewNumServiceProcs = 0; 13450 13451 // Let's determine how many processes we have running vs. 13452 // how many slots we have for background processes; we may want 13453 // to put multiple processes in a slot of there are enough of 13454 // them. 13455 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13456 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13457 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13458 if (emptyFactor < 1) emptyFactor = 1; 13459 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13460 if (hiddenFactor < 1) hiddenFactor = 1; 13461 int stepHidden = 0; 13462 int stepEmpty = 0; 13463 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13464 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13465 int numHidden = 0; 13466 int numEmpty = 0; 13467 int numTrimming = 0; 13468 13469 mNumNonHiddenProcs = 0; 13470 mNumHiddenProcs = 0; 13471 13472 // First update the OOM adjustment for each of the 13473 // application processes based on their current state. 13474 int i = mLruProcesses.size(); 13475 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13476 int nextHiddenAdj = curHiddenAdj+1; 13477 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13478 int nextEmptyAdj = curEmptyAdj+2; 13479 while (i > 0) { 13480 i--; 13481 ProcessRecord app = mLruProcesses.get(i); 13482 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13483 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13484 if (!app.killedBackground) { 13485 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13486 // This process was assigned as a hidden process... step the 13487 // hidden level. 13488 mNumHiddenProcs++; 13489 if (curHiddenAdj != nextHiddenAdj) { 13490 stepHidden++; 13491 if (stepHidden >= hiddenFactor) { 13492 stepHidden = 0; 13493 curHiddenAdj = nextHiddenAdj; 13494 nextHiddenAdj += 2; 13495 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13496 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13497 } 13498 } 13499 } 13500 numHidden++; 13501 if (numHidden > hiddenProcessLimit) { 13502 Slog.i(TAG, "No longer want " + app.processName 13503 + " (pid " + app.pid + "): hidden #" + numHidden); 13504 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13505 app.processName, app.setAdj, "too many background"); 13506 app.killedBackground = true; 13507 Process.killProcessQuiet(app.pid); 13508 } 13509 } else { 13510 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13511 // This process was assigned as an empty process... step the 13512 // empty level. 13513 if (curEmptyAdj != nextEmptyAdj) { 13514 stepEmpty++; 13515 if (stepEmpty >= emptyFactor) { 13516 stepEmpty = 0; 13517 curEmptyAdj = nextEmptyAdj; 13518 nextEmptyAdj += 2; 13519 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13520 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13521 } 13522 } 13523 } 13524 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13525 mNumNonHiddenProcs++; 13526 } 13527 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13528 numEmpty++; 13529 if (numEmpty > emptyProcessLimit) { 13530 Slog.i(TAG, "No longer want " + app.processName 13531 + " (pid " + app.pid + "): empty #" + numEmpty); 13532 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13533 app.processName, app.setAdj, "too many background"); 13534 app.killedBackground = true; 13535 Process.killProcessQuiet(app.pid); 13536 } 13537 } 13538 } 13539 if (app.isolated && app.services.size() <= 0) { 13540 // If this is an isolated process, and there are no 13541 // services running in it, then the process is no longer 13542 // needed. We agressively kill these because we can by 13543 // definition not re-use the same process again, and it is 13544 // good to avoid having whatever code was running in them 13545 // left sitting around after no longer needed. 13546 Slog.i(TAG, "Isolated process " + app.processName 13547 + " (pid " + app.pid + ") no longer needed"); 13548 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13549 app.processName, app.setAdj, "isolated not needed"); 13550 app.killedBackground = true; 13551 Process.killProcessQuiet(app.pid); 13552 } 13553 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13554 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13555 && !app.killedBackground) { 13556 numTrimming++; 13557 } 13558 } 13559 } 13560 13561 mNumServiceProcs = mNewNumServiceProcs; 13562 13563 // Now determine the memory trimming level of background processes. 13564 // Unfortunately we need to start at the back of the list to do this 13565 // properly. We only do this if the number of background apps we 13566 // are managing to keep around is less than half the maximum we desire; 13567 // if we are keeping a good number around, we'll let them use whatever 13568 // memory they want. 13569 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13570 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13571 final int numHiddenAndEmpty = numHidden + numEmpty; 13572 final int N = mLruProcesses.size(); 13573 int factor = numTrimming/3; 13574 int minFactor = 2; 13575 if (mHomeProcess != null) minFactor++; 13576 if (mPreviousProcess != null) minFactor++; 13577 if (factor < minFactor) factor = minFactor; 13578 int step = 0; 13579 int fgTrimLevel; 13580 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13581 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13582 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13583 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13584 } else { 13585 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13586 } 13587 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13588 for (i=0; i<N; i++) { 13589 ProcessRecord app = mLruProcesses.get(i); 13590 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13591 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13592 && !app.killedBackground) { 13593 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13594 try { 13595 app.thread.scheduleTrimMemory(curLevel); 13596 } catch (RemoteException e) { 13597 } 13598 if (false) { 13599 // For now we won't do this; our memory trimming seems 13600 // to be good enough at this point that destroying 13601 // activities causes more harm than good. 13602 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13603 && app != mHomeProcess && app != mPreviousProcess) { 13604 // Need to do this on its own message because the stack may not 13605 // be in a consistent state at this point. 13606 // For these apps we will also finish their activities 13607 // to help them free memory. 13608 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13609 } 13610 } 13611 } 13612 app.trimMemoryLevel = curLevel; 13613 step++; 13614 if (step >= factor) { 13615 step = 0; 13616 switch (curLevel) { 13617 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13618 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13619 break; 13620 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13621 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13622 break; 13623 } 13624 } 13625 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13626 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13627 && app.thread != null) { 13628 try { 13629 app.thread.scheduleTrimMemory( 13630 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13631 } catch (RemoteException e) { 13632 } 13633 } 13634 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13635 } else { 13636 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13637 && app.pendingUiClean) { 13638 // If this application is now in the background and it 13639 // had done UI, then give it the special trim level to 13640 // have it free UI resources. 13641 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13642 if (app.trimMemoryLevel < level && app.thread != null) { 13643 try { 13644 app.thread.scheduleTrimMemory(level); 13645 } catch (RemoteException e) { 13646 } 13647 } 13648 app.pendingUiClean = false; 13649 } 13650 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13651 try { 13652 app.thread.scheduleTrimMemory(fgTrimLevel); 13653 } catch (RemoteException e) { 13654 } 13655 } 13656 app.trimMemoryLevel = fgTrimLevel; 13657 } 13658 } 13659 } else { 13660 final int N = mLruProcesses.size(); 13661 for (i=0; i<N; i++) { 13662 ProcessRecord app = mLruProcesses.get(i); 13663 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13664 && app.pendingUiClean) { 13665 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13666 && app.thread != null) { 13667 try { 13668 app.thread.scheduleTrimMemory( 13669 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13670 } catch (RemoteException e) { 13671 } 13672 } 13673 app.pendingUiClean = false; 13674 } 13675 app.trimMemoryLevel = 0; 13676 } 13677 } 13678 13679 if (mAlwaysFinishActivities) { 13680 // Need to do this on its own message because the stack may not 13681 // be in a consistent state at this point. 13682 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13683 } 13684 } 13685 13686 final void trimApplications() { 13687 synchronized (this) { 13688 int i; 13689 13690 // First remove any unused application processes whose package 13691 // has been removed. 13692 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13693 final ProcessRecord app = mRemovedProcesses.get(i); 13694 if (app.activities.size() == 0 13695 && app.curReceiver == null && app.services.size() == 0) { 13696 Slog.i( 13697 TAG, "Exiting empty application process " 13698 + app.processName + " (" 13699 + (app.thread != null ? app.thread.asBinder() : null) 13700 + ")\n"); 13701 if (app.pid > 0 && app.pid != MY_PID) { 13702 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13703 app.processName, app.setAdj, "empty"); 13704 Process.killProcessQuiet(app.pid); 13705 } else { 13706 try { 13707 app.thread.scheduleExit(); 13708 } catch (Exception e) { 13709 // Ignore exceptions. 13710 } 13711 } 13712 cleanUpApplicationRecordLocked(app, false, true, -1); 13713 mRemovedProcesses.remove(i); 13714 13715 if (app.persistent) { 13716 if (app.persistent) { 13717 addAppLocked(app.info, false); 13718 } 13719 } 13720 } 13721 } 13722 13723 // Now update the oom adj for all processes. 13724 updateOomAdjLocked(); 13725 } 13726 } 13727 13728 /** This method sends the specified signal to each of the persistent apps */ 13729 public void signalPersistentProcesses(int sig) throws RemoteException { 13730 if (sig != Process.SIGNAL_USR1) { 13731 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13732 } 13733 13734 synchronized (this) { 13735 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13736 != PackageManager.PERMISSION_GRANTED) { 13737 throw new SecurityException("Requires permission " 13738 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13739 } 13740 13741 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13742 ProcessRecord r = mLruProcesses.get(i); 13743 if (r.thread != null && r.persistent) { 13744 Process.sendSignal(r.pid, sig); 13745 } 13746 } 13747 } 13748 } 13749 13750 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13751 if (proc == null || proc == mProfileProc) { 13752 proc = mProfileProc; 13753 path = mProfileFile; 13754 profileType = mProfileType; 13755 clearProfilerLocked(); 13756 } 13757 if (proc == null) { 13758 return; 13759 } 13760 try { 13761 proc.thread.profilerControl(false, path, null, profileType); 13762 } catch (RemoteException e) { 13763 throw new IllegalStateException("Process disappeared"); 13764 } 13765 } 13766 13767 private void clearProfilerLocked() { 13768 if (mProfileFd != null) { 13769 try { 13770 mProfileFd.close(); 13771 } catch (IOException e) { 13772 } 13773 } 13774 mProfileApp = null; 13775 mProfileProc = null; 13776 mProfileFile = null; 13777 mProfileType = 0; 13778 mAutoStopProfiler = false; 13779 } 13780 13781 public boolean profileControl(String process, int userId, boolean start, 13782 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13783 13784 try { 13785 synchronized (this) { 13786 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13787 // its own permission. 13788 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13789 != PackageManager.PERMISSION_GRANTED) { 13790 throw new SecurityException("Requires permission " 13791 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13792 } 13793 13794 if (start && fd == null) { 13795 throw new IllegalArgumentException("null fd"); 13796 } 13797 13798 ProcessRecord proc = null; 13799 if (process != null) { 13800 proc = findProcessLocked(process, userId, "profileControl"); 13801 } 13802 13803 if (start && (proc == null || proc.thread == null)) { 13804 throw new IllegalArgumentException("Unknown process: " + process); 13805 } 13806 13807 if (start) { 13808 stopProfilerLocked(null, null, 0); 13809 setProfileApp(proc.info, proc.processName, path, fd, false); 13810 mProfileProc = proc; 13811 mProfileType = profileType; 13812 try { 13813 fd = fd.dup(); 13814 } catch (IOException e) { 13815 fd = null; 13816 } 13817 proc.thread.profilerControl(start, path, fd, profileType); 13818 fd = null; 13819 mProfileFd = null; 13820 } else { 13821 stopProfilerLocked(proc, path, profileType); 13822 if (fd != null) { 13823 try { 13824 fd.close(); 13825 } catch (IOException e) { 13826 } 13827 } 13828 } 13829 13830 return true; 13831 } 13832 } catch (RemoteException e) { 13833 throw new IllegalStateException("Process disappeared"); 13834 } finally { 13835 if (fd != null) { 13836 try { 13837 fd.close(); 13838 } catch (IOException e) { 13839 } 13840 } 13841 } 13842 } 13843 13844 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13845 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13846 userId, true, true, callName, null); 13847 ProcessRecord proc = null; 13848 try { 13849 int pid = Integer.parseInt(process); 13850 synchronized (mPidsSelfLocked) { 13851 proc = mPidsSelfLocked.get(pid); 13852 } 13853 } catch (NumberFormatException e) { 13854 } 13855 13856 if (proc == null) { 13857 HashMap<String, SparseArray<ProcessRecord>> all 13858 = mProcessNames.getMap(); 13859 SparseArray<ProcessRecord> procs = all.get(process); 13860 if (procs != null && procs.size() > 0) { 13861 proc = procs.valueAt(0); 13862 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13863 for (int i=1; i<procs.size(); i++) { 13864 ProcessRecord thisProc = procs.valueAt(i); 13865 if (thisProc.userId == userId) { 13866 proc = thisProc; 13867 break; 13868 } 13869 } 13870 } 13871 } 13872 } 13873 13874 return proc; 13875 } 13876 13877 public boolean dumpHeap(String process, int userId, boolean managed, 13878 String path, ParcelFileDescriptor fd) throws RemoteException { 13879 13880 try { 13881 synchronized (this) { 13882 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13883 // its own permission (same as profileControl). 13884 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13885 != PackageManager.PERMISSION_GRANTED) { 13886 throw new SecurityException("Requires permission " 13887 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13888 } 13889 13890 if (fd == null) { 13891 throw new IllegalArgumentException("null fd"); 13892 } 13893 13894 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13895 if (proc == null || proc.thread == null) { 13896 throw new IllegalArgumentException("Unknown process: " + process); 13897 } 13898 13899 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13900 if (!isDebuggable) { 13901 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13902 throw new SecurityException("Process not debuggable: " + proc); 13903 } 13904 } 13905 13906 proc.thread.dumpHeap(managed, path, fd); 13907 fd = null; 13908 return true; 13909 } 13910 } catch (RemoteException e) { 13911 throw new IllegalStateException("Process disappeared"); 13912 } finally { 13913 if (fd != null) { 13914 try { 13915 fd.close(); 13916 } catch (IOException e) { 13917 } 13918 } 13919 } 13920 } 13921 13922 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13923 public void monitor() { 13924 synchronized (this) { } 13925 } 13926 13927 void onCoreSettingsChange(Bundle settings) { 13928 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13929 ProcessRecord processRecord = mLruProcesses.get(i); 13930 try { 13931 if (processRecord.thread != null) { 13932 processRecord.thread.setCoreSettings(settings); 13933 } 13934 } catch (RemoteException re) { 13935 /* ignore */ 13936 } 13937 } 13938 } 13939 13940 // Multi-user methods 13941 13942 @Override 13943 public boolean switchUser(int userId) { 13944 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13945 != PackageManager.PERMISSION_GRANTED) { 13946 String msg = "Permission Denial: switchUser() from pid=" 13947 + Binder.getCallingPid() 13948 + ", uid=" + Binder.getCallingUid() 13949 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13950 Slog.w(TAG, msg); 13951 throw new SecurityException(msg); 13952 } 13953 13954 final long ident = Binder.clearCallingIdentity(); 13955 try { 13956 synchronized (this) { 13957 final int oldUserId = mCurrentUserId; 13958 if (oldUserId == userId) { 13959 return true; 13960 } 13961 13962 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 13963 if (userInfo == null) { 13964 Slog.w(TAG, "No user info for user #" + userId); 13965 return false; 13966 } 13967 13968 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13969 R.anim.screen_user_enter); 13970 13971 // If the user we are switching to is not currently started, then 13972 // we need to start it now. 13973 if (mStartedUsers.get(userId) == null) { 13974 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13975 } 13976 13977 mCurrentUserId = userId; 13978 final Integer userIdInt = Integer.valueOf(userId); 13979 mUserLru.remove(userIdInt); 13980 mUserLru.add(userIdInt); 13981 13982 final UserStartedState uss = mStartedUsers.get(userId); 13983 13984 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 13985 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 13986 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 13987 oldUserId, userId, uss)); 13988 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 13989 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 13990 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 13991 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13992 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13993 broadcastIntentLocked(null, null, intent, 13994 null, null, 0, null, null, null, 13995 false, false, MY_PID, Process.SYSTEM_UID, userId); 13996 13997 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 13998 if (userId != 0) { 13999 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14000 broadcastIntentLocked(null, null, intent, null, 14001 new IIntentReceiver.Stub() { 14002 public void performReceive(Intent intent, int resultCode, 14003 String data, Bundle extras, boolean ordered, 14004 boolean sticky, int sendingUser) { 14005 synchronized (ActivityManagerService.this) { 14006 getUserManagerLocked().makeInitialized(userInfo.id); 14007 } 14008 } 14009 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14010 userId); 14011 } else { 14012 getUserManagerLocked().makeInitialized(userInfo.id); 14013 } 14014 } 14015 14016 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14017 if (!haveActivities) { 14018 startHomeActivityLocked(userId); 14019 } 14020 14021 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14022 } 14023 } finally { 14024 Binder.restoreCallingIdentity(ident); 14025 } 14026 14027 return true; 14028 } 14029 14030 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14031 long ident = Binder.clearCallingIdentity(); 14032 try { 14033 Intent intent; 14034 if (oldUserId >= 0) { 14035 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14036 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14037 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14038 broadcastIntentLocked(null, null, intent, 14039 null, null, 0, null, null, null, 14040 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14041 } 14042 if (newUserId >= 0) { 14043 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14044 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14045 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14046 broadcastIntentLocked(null, null, intent, 14047 null, null, 0, null, null, null, 14048 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14049 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14051 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14052 broadcastIntentLocked(null, null, intent, 14053 null, null, 0, null, null, 14054 android.Manifest.permission.MANAGE_USERS, 14055 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14056 } 14057 } finally { 14058 Binder.restoreCallingIdentity(ident); 14059 } 14060 } 14061 14062 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14063 final int newUserId) { 14064 final int N = mUserSwitchObservers.beginBroadcast(); 14065 if (N > 0) { 14066 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14067 int mCount = 0; 14068 @Override 14069 public void sendResult(Bundle data) throws RemoteException { 14070 synchronized (ActivityManagerService.this) { 14071 if (mCurUserSwitchCallback == this) { 14072 mCount++; 14073 if (mCount == N) { 14074 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14075 } 14076 } 14077 } 14078 } 14079 }; 14080 synchronized (this) { 14081 mCurUserSwitchCallback = callback; 14082 } 14083 for (int i=0; i<N; i++) { 14084 try { 14085 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14086 newUserId, callback); 14087 } catch (RemoteException e) { 14088 } 14089 } 14090 } else { 14091 synchronized (this) { 14092 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14093 } 14094 } 14095 mUserSwitchObservers.finishBroadcast(); 14096 } 14097 14098 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14099 synchronized (this) { 14100 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14101 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14102 } 14103 } 14104 14105 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14106 mCurUserSwitchCallback = null; 14107 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14108 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14109 oldUserId, newUserId, uss)); 14110 } 14111 14112 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14113 final int N = mUserSwitchObservers.beginBroadcast(); 14114 for (int i=0; i<N; i++) { 14115 try { 14116 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14117 } catch (RemoteException e) { 14118 } 14119 } 14120 mUserSwitchObservers.finishBroadcast(); 14121 synchronized (this) { 14122 mWindowManager.stopFreezingScreen(); 14123 } 14124 } 14125 14126 void finishUserSwitch(UserStartedState uss) { 14127 synchronized (this) { 14128 if (uss.mState == UserStartedState.STATE_BOOTING 14129 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14130 uss.mState = UserStartedState.STATE_RUNNING; 14131 final int userId = uss.mHandle.getIdentifier(); 14132 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14133 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14134 broadcastIntentLocked(null, null, intent, 14135 null, null, 0, null, null, 14136 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14137 false, false, MY_PID, Process.SYSTEM_UID, userId); 14138 } 14139 } 14140 } 14141 14142 @Override 14143 public int stopUser(final int userId, final IStopUserCallback callback) { 14144 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14145 != PackageManager.PERMISSION_GRANTED) { 14146 String msg = "Permission Denial: switchUser() from pid=" 14147 + Binder.getCallingPid() 14148 + ", uid=" + Binder.getCallingUid() 14149 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14150 Slog.w(TAG, msg); 14151 throw new SecurityException(msg); 14152 } 14153 if (userId <= 0) { 14154 throw new IllegalArgumentException("Can't stop primary user " + userId); 14155 } 14156 synchronized (this) { 14157 if (mCurrentUserId == userId) { 14158 return ActivityManager.USER_OP_IS_CURRENT; 14159 } 14160 14161 final UserStartedState uss = mStartedUsers.get(userId); 14162 if (uss == null) { 14163 // User is not started, nothing to do... but we do need to 14164 // callback if requested. 14165 if (callback != null) { 14166 mHandler.post(new Runnable() { 14167 @Override 14168 public void run() { 14169 try { 14170 callback.userStopped(userId); 14171 } catch (RemoteException e) { 14172 } 14173 } 14174 }); 14175 } 14176 return ActivityManager.USER_OP_SUCCESS; 14177 } 14178 14179 if (callback != null) { 14180 uss.mStopCallbacks.add(callback); 14181 } 14182 14183 if (uss.mState != UserStartedState.STATE_STOPPING) { 14184 uss.mState = UserStartedState.STATE_STOPPING; 14185 14186 long ident = Binder.clearCallingIdentity(); 14187 try { 14188 // Inform of user switch 14189 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14190 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14191 @Override 14192 public void performReceive(Intent intent, int resultCode, String data, 14193 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14194 finishUserStop(uss); 14195 } 14196 }; 14197 broadcastIntentLocked(null, null, intent, 14198 null, resultReceiver, 0, null, null, null, 14199 true, false, MY_PID, Process.SYSTEM_UID, userId); 14200 } finally { 14201 Binder.restoreCallingIdentity(ident); 14202 } 14203 } 14204 } 14205 14206 return ActivityManager.USER_OP_SUCCESS; 14207 } 14208 14209 void finishUserStop(UserStartedState uss) { 14210 final int userId = uss.mHandle.getIdentifier(); 14211 boolean stopped; 14212 ArrayList<IStopUserCallback> callbacks; 14213 synchronized (this) { 14214 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14215 if (uss.mState != UserStartedState.STATE_STOPPING 14216 || mStartedUsers.get(userId) != uss) { 14217 stopped = false; 14218 } else { 14219 stopped = true; 14220 // User can no longer run. 14221 mStartedUsers.remove(userId); 14222 14223 // Clean up all state and processes associated with the user. 14224 // Kill all the processes for the user. 14225 forceStopUserLocked(userId); 14226 } 14227 } 14228 14229 for (int i=0; i<callbacks.size(); i++) { 14230 try { 14231 if (stopped) callbacks.get(i).userStopped(userId); 14232 else callbacks.get(i).userStopAborted(userId); 14233 } catch (RemoteException e) { 14234 } 14235 } 14236 } 14237 14238 @Override 14239 public UserInfo getCurrentUser() { 14240 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14241 != PackageManager.PERMISSION_GRANTED) { 14242 String msg = "Permission Denial: getCurrentUser() from pid=" 14243 + Binder.getCallingPid() 14244 + ", uid=" + Binder.getCallingUid() 14245 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14246 Slog.w(TAG, msg); 14247 throw new SecurityException(msg); 14248 } 14249 synchronized (this) { 14250 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14251 } 14252 } 14253 14254 @Override 14255 public boolean isUserRunning(int userId) { 14256 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14257 != PackageManager.PERMISSION_GRANTED) { 14258 String msg = "Permission Denial: isUserRunning() from pid=" 14259 + Binder.getCallingPid() 14260 + ", uid=" + Binder.getCallingUid() 14261 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14262 Slog.w(TAG, msg); 14263 throw new SecurityException(msg); 14264 } 14265 synchronized (this) { 14266 return isUserRunningLocked(userId); 14267 } 14268 } 14269 14270 boolean isUserRunningLocked(int userId) { 14271 UserStartedState state = mStartedUsers.get(userId); 14272 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14273 } 14274 14275 @Override 14276 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14277 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14278 != PackageManager.PERMISSION_GRANTED) { 14279 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14280 + Binder.getCallingPid() 14281 + ", uid=" + Binder.getCallingUid() 14282 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14283 Slog.w(TAG, msg); 14284 throw new SecurityException(msg); 14285 } 14286 14287 mUserSwitchObservers.register(observer); 14288 } 14289 14290 @Override 14291 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14292 mUserSwitchObservers.unregister(observer); 14293 } 14294 14295 private boolean userExists(int userId) { 14296 if (userId == 0) { 14297 return true; 14298 } 14299 UserManagerService ums = getUserManagerLocked(); 14300 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14301 } 14302 14303 int[] getUsersLocked() { 14304 UserManagerService ums = getUserManagerLocked(); 14305 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14306 } 14307 14308 UserManagerService getUserManagerLocked() { 14309 if (mUserManager == null) { 14310 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14311 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14312 } 14313 return mUserManager; 14314 } 14315 14316 private void checkValidCaller(int uid, int userId) { 14317 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14318 14319 throw new SecurityException("Caller uid=" + uid 14320 + " is not privileged to communicate with user=" + userId); 14321 } 14322 14323 private int applyUserId(int uid, int userId) { 14324 return UserHandle.getUid(userId, uid); 14325 } 14326 14327 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14328 if (info == null) return null; 14329 ApplicationInfo newInfo = new ApplicationInfo(info); 14330 newInfo.uid = applyUserId(info.uid, userId); 14331 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14332 + info.packageName; 14333 return newInfo; 14334 } 14335 14336 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14337 if (aInfo == null 14338 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14339 return aInfo; 14340 } 14341 14342 ActivityInfo info = new ActivityInfo(aInfo); 14343 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14344 return info; 14345 } 14346} 14347