ActivityManagerService.java revision cc5a055613efb463275633d83a04674b0be6d770
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Arrays; 151import java.util.Collections; 152import java.util.Comparator; 153import java.util.HashMap; 154import java.util.HashSet; 155import java.util.Iterator; 156import java.util.List; 157import java.util.Locale; 158import java.util.Map; 159import java.util.Set; 160import java.util.concurrent.atomic.AtomicBoolean; 161import java.util.concurrent.atomic.AtomicLong; 162 163public final class ActivityManagerService extends ActivityManagerNative 164 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 165 private static final String USER_DATA_DIR = "/data/user/"; 166 static final String TAG = "ActivityManager"; 167 static final String TAG_MU = "ActivityManagerServiceMU"; 168 static final boolean DEBUG = false; 169 static final boolean localLOGV = DEBUG; 170 static final boolean DEBUG_SWITCH = localLOGV || false; 171 static final boolean DEBUG_TASKS = localLOGV || false; 172 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 173 static final boolean DEBUG_PAUSE = localLOGV || false; 174 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 175 static final boolean DEBUG_TRANSITION = localLOGV || false; 176 static final boolean DEBUG_BROADCAST = localLOGV || false; 177 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_SERVICE = localLOGV || false; 180 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 181 static final boolean DEBUG_VISBILITY = localLOGV || false; 182 static final boolean DEBUG_PROCESSES = localLOGV || false; 183 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 184 static final boolean DEBUG_CLEANUP = localLOGV || false; 185 static final boolean DEBUG_PROVIDER = localLOGV || false; 186 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 187 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 188 static final boolean DEBUG_RESULTS = localLOGV || false; 189 static final boolean DEBUG_BACKUP = localLOGV || false; 190 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 191 static final boolean DEBUG_POWER = localLOGV || false; 192 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 193 static final boolean DEBUG_MU = localLOGV || false; 194 static final boolean VALIDATE_TOKENS = false; 195 static final boolean SHOW_ACTIVITY_START_TIME = true; 196 197 // Control over CPU and battery monitoring. 198 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 199 static final boolean MONITOR_CPU_USAGE = true; 200 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 201 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 202 static final boolean MONITOR_THREAD_CPU_USAGE = false; 203 204 // The flags that are set for all calls we make to the package manager. 205 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 206 207 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 208 209 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 210 211 // Maximum number of recent tasks that we can remember. 212 static final int MAX_RECENT_TASKS = 20; 213 214 // Amount of time after a call to stopAppSwitches() during which we will 215 // prevent further untrusted switches from happening. 216 static final long APP_SWITCH_DELAY_TIME = 5*1000; 217 218 // How long we wait for a launched process to attach to the activity manager 219 // before we decide it's never going to come up for real. 220 static final int PROC_START_TIMEOUT = 10*1000; 221 222 // How long we wait for a launched process to attach to the activity manager 223 // before we decide it's never going to come up for real, when the process was 224 // started with a wrapper for instrumentation (such as Valgrind) because it 225 // could take much longer than usual. 226 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 227 228 // How long to wait after going idle before forcing apps to GC. 229 static final int GC_TIMEOUT = 5*1000; 230 231 // The minimum amount of time between successive GC requests for a process. 232 static final int GC_MIN_INTERVAL = 60*1000; 233 234 // The rate at which we check for apps using excessive power -- 15 mins. 235 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 236 237 // The minimum sample duration we will allow before deciding we have 238 // enough data on wake locks to start killing things. 239 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 240 241 // The minimum sample duration we will allow before deciding we have 242 // enough data on CPU usage to start killing things. 243 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 244 245 // How long we allow a receiver to run before giving up on it. 246 static final int BROADCAST_FG_TIMEOUT = 10*1000; 247 static final int BROADCAST_BG_TIMEOUT = 60*1000; 248 249 // How long we wait until we timeout on key dispatching. 250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 251 252 // How long we wait until we timeout on key dispatching during instrumentation. 253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 254 255 // Amount of time we wait for observers to handle a user switch before 256 // giving up on them and unfreezing the screen. 257 static final int USER_SWITCH_TIMEOUT = 2*1000; 258 259 // Maximum number of users we allow to be running at a time. 260 static final int MAX_RUNNING_USERS = 3; 261 262 static final int MY_PID = Process.myPid(); 263 264 static final String[] EMPTY_STRING_ARRAY = new String[0]; 265 266 public ActivityStack mMainStack; 267 268 private final boolean mHeadless; 269 270 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 271 // default actuion automatically. Important for devices without direct input 272 // devices. 273 private boolean mShowDialogs = true; 274 275 /** 276 * Description of a request to start a new activity, which has been held 277 * due to app switches being disabled. 278 */ 279 static class PendingActivityLaunch { 280 ActivityRecord r; 281 ActivityRecord sourceRecord; 282 int startFlags; 283 } 284 285 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 286 = new ArrayList<PendingActivityLaunch>(); 287 288 289 BroadcastQueue mFgBroadcastQueue; 290 BroadcastQueue mBgBroadcastQueue; 291 // Convenient for easy iteration over the queues. Foreground is first 292 // so that dispatch of foreground broadcasts gets precedence. 293 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 294 295 BroadcastQueue broadcastQueueForIntent(Intent intent) { 296 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 297 if (DEBUG_BACKGROUND_BROADCAST) { 298 Slog.i(TAG, "Broadcast intent " + intent + " on " 299 + (isFg ? "foreground" : "background") 300 + " queue"); 301 } 302 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 303 } 304 305 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 306 for (BroadcastQueue queue : mBroadcastQueues) { 307 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 308 if (r != null) { 309 return r; 310 } 311 } 312 return null; 313 } 314 315 /** 316 * Activity we have told the window manager to have key focus. 317 */ 318 ActivityRecord mFocusedActivity = null; 319 /** 320 * List of intents that were used to start the most recent tasks. 321 */ 322 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 323 324 /** 325 * Process management. 326 */ 327 final ProcessList mProcessList = new ProcessList(); 328 329 /** 330 * All of the applications we currently have running organized by name. 331 * The keys are strings of the application package name (as 332 * returned by the package manager), and the keys are ApplicationRecord 333 * objects. 334 */ 335 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 336 337 /** 338 * The currently running isolated processes. 339 */ 340 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 341 342 /** 343 * Counter for assigning isolated process uids, to avoid frequently reusing the 344 * same ones. 345 */ 346 int mNextIsolatedProcessUid = 0; 347 348 /** 349 * The currently running heavy-weight process, if any. 350 */ 351 ProcessRecord mHeavyWeightProcess = null; 352 353 /** 354 * The last time that various processes have crashed. 355 */ 356 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 357 358 /** 359 * Set of applications that we consider to be bad, and will reject 360 * incoming broadcasts from (which the user has no control over). 361 * Processes are added to this set when they have crashed twice within 362 * a minimum amount of time; they are removed from it when they are 363 * later restarted (hopefully due to some user action). The value is the 364 * time it was added to the list. 365 */ 366 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 367 368 /** 369 * All of the processes we currently have running organized by pid. 370 * The keys are the pid running the application. 371 * 372 * <p>NOTE: This object is protected by its own lock, NOT the global 373 * activity manager lock! 374 */ 375 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 376 377 /** 378 * All of the processes that have been forced to be foreground. The key 379 * is the pid of the caller who requested it (we hold a death 380 * link on it). 381 */ 382 abstract class ForegroundToken implements IBinder.DeathRecipient { 383 int pid; 384 IBinder token; 385 } 386 final SparseArray<ForegroundToken> mForegroundProcesses 387 = new SparseArray<ForegroundToken>(); 388 389 /** 390 * List of records for processes that someone had tried to start before the 391 * system was ready. We don't start them at that point, but ensure they 392 * are started by the time booting is complete. 393 */ 394 final ArrayList<ProcessRecord> mProcessesOnHold 395 = new ArrayList<ProcessRecord>(); 396 397 /** 398 * List of persistent applications that are in the process 399 * of being started. 400 */ 401 final ArrayList<ProcessRecord> mPersistentStartingProcesses 402 = new ArrayList<ProcessRecord>(); 403 404 /** 405 * Processes that are being forcibly torn down. 406 */ 407 final ArrayList<ProcessRecord> mRemovedProcesses 408 = new ArrayList<ProcessRecord>(); 409 410 /** 411 * List of running applications, sorted by recent usage. 412 * The first entry in the list is the least recently used. 413 * It contains ApplicationRecord objects. This list does NOT include 414 * any persistent application records (since we never want to exit them). 415 */ 416 final ArrayList<ProcessRecord> mLruProcesses 417 = new ArrayList<ProcessRecord>(); 418 419 /** 420 * List of processes that should gc as soon as things are idle. 421 */ 422 final ArrayList<ProcessRecord> mProcessesToGc 423 = new ArrayList<ProcessRecord>(); 424 425 /** 426 * This is the process holding what we currently consider to be 427 * the "home" activity. 428 */ 429 ProcessRecord mHomeProcess; 430 431 /** 432 * This is the process holding the activity the user last visited that 433 * is in a different process from the one they are currently in. 434 */ 435 ProcessRecord mPreviousProcess; 436 437 /** 438 * The time at which the previous process was last visible. 439 */ 440 long mPreviousProcessVisibleTime; 441 442 /** 443 * Which uses have been started, so are allowed to run code. 444 */ 445 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 446 447 /** 448 * LRU list of history of current users. Most recently current is at the end. 449 */ 450 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 451 452 /** 453 * Constant array of the users that are currently started. 454 */ 455 int[] mStartedUserArray = new int[] { 0 }; 456 457 /** 458 * Registered observers of the user switching mechanics. 459 */ 460 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 461 = new RemoteCallbackList<IUserSwitchObserver>(); 462 463 /** 464 * Currently active user switch. 465 */ 466 Object mCurUserSwitchCallback; 467 468 /** 469 * Packages that the user has asked to have run in screen size 470 * compatibility mode instead of filling the screen. 471 */ 472 final CompatModePackages mCompatModePackages; 473 474 /** 475 * Set of PendingResultRecord objects that are currently active. 476 */ 477 final HashSet mPendingResultRecords = new HashSet(); 478 479 /** 480 * Set of IntentSenderRecord objects that are currently active. 481 */ 482 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 483 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 484 485 /** 486 * Fingerprints (hashCode()) of stack traces that we've 487 * already logged DropBox entries for. Guarded by itself. If 488 * something (rogue user app) forces this over 489 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 490 */ 491 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 492 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 493 494 /** 495 * Strict Mode background batched logging state. 496 * 497 * The string buffer is guarded by itself, and its lock is also 498 * used to determine if another batched write is already 499 * in-flight. 500 */ 501 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 502 503 /** 504 * Keeps track of all IIntentReceivers that have been registered for 505 * broadcasts. Hash keys are the receiver IBinder, hash value is 506 * a ReceiverList. 507 */ 508 final HashMap mRegisteredReceivers = new HashMap(); 509 510 /** 511 * Resolver for broadcast intents to registered receivers. 512 * Holds BroadcastFilter (subclass of IntentFilter). 513 */ 514 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 515 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 516 @Override 517 protected boolean allowFilterResult( 518 BroadcastFilter filter, List<BroadcastFilter> dest) { 519 IBinder target = filter.receiverList.receiver.asBinder(); 520 for (int i=dest.size()-1; i>=0; i--) { 521 if (dest.get(i).receiverList.receiver.asBinder() == target) { 522 return false; 523 } 524 } 525 return true; 526 } 527 528 @Override 529 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 530 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 531 || userId == filter.owningUserId) { 532 return super.newResult(filter, match, userId); 533 } 534 return null; 535 } 536 537 @Override 538 protected BroadcastFilter[] newArray(int size) { 539 return new BroadcastFilter[size]; 540 } 541 542 @Override 543 protected String packageForFilter(BroadcastFilter filter) { 544 return filter.packageName; 545 } 546 }; 547 548 /** 549 * State of all active sticky broadcasts per user. Keys are the action of the 550 * sticky Intent, values are an ArrayList of all broadcasted intents with 551 * that action (which should usually be one). The SparseArray is keyed 552 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 553 * for stickies that are sent to all users. 554 */ 555 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 556 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 557 558 final ActiveServices mServices; 559 560 /** 561 * Backup/restore process management 562 */ 563 String mBackupAppName = null; 564 BackupRecord mBackupTarget = null; 565 566 /** 567 * List of PendingThumbnailsRecord objects of clients who are still 568 * waiting to receive all of the thumbnails for a task. 569 */ 570 final ArrayList mPendingThumbnails = new ArrayList(); 571 572 /** 573 * List of HistoryRecord objects that have been finished and must 574 * still report back to a pending thumbnail receiver. 575 */ 576 final ArrayList mCancelledThumbnails = new ArrayList(); 577 578 final ProviderMap mProviderMap; 579 580 /** 581 * List of content providers who have clients waiting for them. The 582 * application is currently being launched and the provider will be 583 * removed from this list once it is published. 584 */ 585 final ArrayList<ContentProviderRecord> mLaunchingProviders 586 = new ArrayList<ContentProviderRecord>(); 587 588 /** 589 * Global set of specific Uri permissions that have been granted. 590 */ 591 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 592 = new SparseArray<HashMap<Uri, UriPermission>>(); 593 594 CoreSettingsObserver mCoreSettingsObserver; 595 596 /** 597 * Thread-local storage used to carry caller permissions over through 598 * indirect content-provider access. 599 * @see #ActivityManagerService.openContentUri() 600 */ 601 private class Identity { 602 public int pid; 603 public int uid; 604 605 Identity(int _pid, int _uid) { 606 pid = _pid; 607 uid = _uid; 608 } 609 } 610 611 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 612 613 /** 614 * All information we have collected about the runtime performance of 615 * any user id that can impact battery performance. 616 */ 617 final BatteryStatsService mBatteryStatsService; 618 619 /** 620 * information about component usage 621 */ 622 final UsageStatsService mUsageStatsService; 623 624 /** 625 * Current configuration information. HistoryRecord objects are given 626 * a reference to this object to indicate which configuration they are 627 * currently running in, so this object must be kept immutable. 628 */ 629 Configuration mConfiguration = new Configuration(); 630 631 /** 632 * Current sequencing integer of the configuration, for skipping old 633 * configurations. 634 */ 635 int mConfigurationSeq = 0; 636 637 /** 638 * Hardware-reported OpenGLES version. 639 */ 640 final int GL_ES_VERSION; 641 642 /** 643 * List of initialization arguments to pass to all processes when binding applications to them. 644 * For example, references to the commonly used services. 645 */ 646 HashMap<String, IBinder> mAppBindArgs; 647 648 /** 649 * Temporary to avoid allocations. Protected by main lock. 650 */ 651 final StringBuilder mStringBuilder = new StringBuilder(256); 652 653 /** 654 * Used to control how we initialize the service. 655 */ 656 boolean mStartRunning = false; 657 ComponentName mTopComponent; 658 String mTopAction; 659 String mTopData; 660 boolean mProcessesReady = false; 661 boolean mSystemReady = false; 662 boolean mBooting = false; 663 boolean mWaitingUpdate = false; 664 boolean mDidUpdate = false; 665 boolean mOnBattery = false; 666 boolean mLaunchWarningShown = false; 667 668 Context mContext; 669 670 int mFactoryTest; 671 672 boolean mCheckedForSetup; 673 674 /** 675 * The time at which we will allow normal application switches again, 676 * after a call to {@link #stopAppSwitches()}. 677 */ 678 long mAppSwitchesAllowedTime; 679 680 /** 681 * This is set to true after the first switch after mAppSwitchesAllowedTime 682 * is set; any switches after that will clear the time. 683 */ 684 boolean mDidAppSwitch; 685 686 /** 687 * Last time (in realtime) at which we checked for power usage. 688 */ 689 long mLastPowerCheckRealtime; 690 691 /** 692 * Last time (in uptime) at which we checked for power usage. 693 */ 694 long mLastPowerCheckUptime; 695 696 /** 697 * Set while we are wanting to sleep, to prevent any 698 * activities from being started/resumed. 699 */ 700 boolean mSleeping = false; 701 702 /** 703 * State of external calls telling us if the device is asleep. 704 */ 705 boolean mWentToSleep = false; 706 707 /** 708 * State of external call telling us if the lock screen is shown. 709 */ 710 boolean mLockScreenShown = false; 711 712 /** 713 * Set if we are shutting down the system, similar to sleeping. 714 */ 715 boolean mShuttingDown = false; 716 717 /** 718 * Task identifier that activities are currently being started 719 * in. Incremented each time a new task is created. 720 * todo: Replace this with a TokenSpace class that generates non-repeating 721 * integers that won't wrap. 722 */ 723 int mCurTask = 1; 724 725 /** 726 * Current sequence id for oom_adj computation traversal. 727 */ 728 int mAdjSeq = 0; 729 730 /** 731 * Current sequence id for process LRU updating. 732 */ 733 int mLruSeq = 0; 734 735 /** 736 * Keep track of the non-hidden/empty process we last found, to help 737 * determine how to distribute hidden/empty processes next time. 738 */ 739 int mNumNonHiddenProcs = 0; 740 741 /** 742 * Keep track of the number of hidden procs, to balance oom adj 743 * distribution between those and empty procs. 744 */ 745 int mNumHiddenProcs = 0; 746 747 /** 748 * Keep track of the number of service processes we last found, to 749 * determine on the next iteration which should be B services. 750 */ 751 int mNumServiceProcs = 0; 752 int mNewNumServiceProcs = 0; 753 754 /** 755 * System monitoring: number of processes that died since the last 756 * N procs were started. 757 */ 758 int[] mProcDeaths = new int[20]; 759 760 /** 761 * This is set if we had to do a delayed dexopt of an app before launching 762 * it, to increasing the ANR timeouts in that case. 763 */ 764 boolean mDidDexOpt; 765 766 String mDebugApp = null; 767 boolean mWaitForDebugger = false; 768 boolean mDebugTransient = false; 769 String mOrigDebugApp = null; 770 boolean mOrigWaitForDebugger = false; 771 boolean mAlwaysFinishActivities = false; 772 IActivityController mController = null; 773 String mProfileApp = null; 774 ProcessRecord mProfileProc = null; 775 String mProfileFile; 776 ParcelFileDescriptor mProfileFd; 777 int mProfileType = 0; 778 boolean mAutoStopProfiler = false; 779 String mOpenGlTraceApp = null; 780 781 static class ProcessChangeItem { 782 static final int CHANGE_ACTIVITIES = 1<<0; 783 static final int CHANGE_IMPORTANCE= 1<<1; 784 int changes; 785 int uid; 786 int pid; 787 int importance; 788 boolean foregroundActivities; 789 } 790 791 final RemoteCallbackList<IProcessObserver> mProcessObservers 792 = new RemoteCallbackList<IProcessObserver>(); 793 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 794 795 final ArrayList<ProcessChangeItem> mPendingProcessChanges 796 = new ArrayList<ProcessChangeItem>(); 797 final ArrayList<ProcessChangeItem> mAvailProcessChanges 798 = new ArrayList<ProcessChangeItem>(); 799 800 /** 801 * Callback of last caller to {@link #requestPss}. 802 */ 803 Runnable mRequestPssCallback; 804 805 /** 806 * Remaining processes for which we are waiting results from the last 807 * call to {@link #requestPss}. 808 */ 809 final ArrayList<ProcessRecord> mRequestPssList 810 = new ArrayList<ProcessRecord>(); 811 812 /** 813 * Runtime statistics collection thread. This object's lock is used to 814 * protect all related state. 815 */ 816 final Thread mProcessStatsThread; 817 818 /** 819 * Used to collect process stats when showing not responding dialog. 820 * Protected by mProcessStatsThread. 821 */ 822 final ProcessStats mProcessStats = new ProcessStats( 823 MONITOR_THREAD_CPU_USAGE); 824 final AtomicLong mLastCpuTime = new AtomicLong(0); 825 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 826 827 long mLastWriteTime = 0; 828 829 /** 830 * Set to true after the system has finished booting. 831 */ 832 boolean mBooted = false; 833 834 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 835 int mProcessLimitOverride = -1; 836 837 WindowManagerService mWindowManager; 838 839 static ActivityManagerService mSelf; 840 static ActivityThread mSystemThread; 841 842 private int mCurrentUserId = 0; 843 private int[] mCurrentUserArray = new int[] { 0 }; 844 private UserManagerService mUserManager; 845 846 private final class AppDeathRecipient implements IBinder.DeathRecipient { 847 final ProcessRecord mApp; 848 final int mPid; 849 final IApplicationThread mAppThread; 850 851 AppDeathRecipient(ProcessRecord app, int pid, 852 IApplicationThread thread) { 853 if (localLOGV) Slog.v( 854 TAG, "New death recipient " + this 855 + " for thread " + thread.asBinder()); 856 mApp = app; 857 mPid = pid; 858 mAppThread = thread; 859 } 860 861 public void binderDied() { 862 if (localLOGV) Slog.v( 863 TAG, "Death received in " + this 864 + " for thread " + mAppThread.asBinder()); 865 synchronized(ActivityManagerService.this) { 866 appDiedLocked(mApp, mPid, mAppThread); 867 } 868 } 869 } 870 871 static final int SHOW_ERROR_MSG = 1; 872 static final int SHOW_NOT_RESPONDING_MSG = 2; 873 static final int SHOW_FACTORY_ERROR_MSG = 3; 874 static final int UPDATE_CONFIGURATION_MSG = 4; 875 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 876 static final int WAIT_FOR_DEBUGGER_MSG = 6; 877 static final int SERVICE_TIMEOUT_MSG = 12; 878 static final int UPDATE_TIME_ZONE = 13; 879 static final int SHOW_UID_ERROR_MSG = 14; 880 static final int IM_FEELING_LUCKY_MSG = 15; 881 static final int PROC_START_TIMEOUT_MSG = 20; 882 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 883 static final int KILL_APPLICATION_MSG = 22; 884 static final int FINALIZE_PENDING_INTENT_MSG = 23; 885 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 886 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 887 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 888 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 889 static final int CLEAR_DNS_CACHE = 28; 890 static final int UPDATE_HTTP_PROXY = 29; 891 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 892 static final int DISPATCH_PROCESSES_CHANGED = 31; 893 static final int DISPATCH_PROCESS_DIED = 32; 894 static final int REPORT_MEM_USAGE = 33; 895 static final int REPORT_USER_SWITCH_MSG = 34; 896 static final int CONTINUE_USER_SWITCH_MSG = 35; 897 static final int USER_SWITCH_TIMEOUT_MSG = 36; 898 899 static final int FIRST_ACTIVITY_STACK_MSG = 100; 900 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 901 static final int FIRST_COMPAT_MODE_MSG = 300; 902 903 AlertDialog mUidAlert; 904 CompatModeDialog mCompatModeDialog; 905 long mLastMemUsageReportTime = 0; 906 907 final Handler mHandler = new Handler() { 908 //public Handler() { 909 // if (localLOGV) Slog.v(TAG, "Handler started!"); 910 //} 911 912 public void handleMessage(Message msg) { 913 switch (msg.what) { 914 case SHOW_ERROR_MSG: { 915 HashMap data = (HashMap) msg.obj; 916 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 917 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 918 synchronized (ActivityManagerService.this) { 919 ProcessRecord proc = (ProcessRecord)data.get("app"); 920 AppErrorResult res = (AppErrorResult) data.get("result"); 921 if (proc != null && proc.crashDialog != null) { 922 Slog.e(TAG, "App already has crash dialog: " + proc); 923 if (res != null) { 924 res.set(0); 925 } 926 return; 927 } 928 if (!showBackground && UserHandle.getAppId(proc.uid) 929 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 930 && proc.pid != MY_PID) { 931 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 932 if (res != null) { 933 res.set(0); 934 } 935 return; 936 } 937 if (mShowDialogs && !mSleeping && !mShuttingDown) { 938 Dialog d = new AppErrorDialog(mContext, 939 ActivityManagerService.this, res, proc); 940 d.show(); 941 proc.crashDialog = d; 942 } else { 943 // The device is asleep, so just pretend that the user 944 // saw a crash dialog and hit "force quit". 945 if (res != null) { 946 res.set(0); 947 } 948 } 949 } 950 951 ensureBootCompleted(); 952 } break; 953 case SHOW_NOT_RESPONDING_MSG: { 954 synchronized (ActivityManagerService.this) { 955 HashMap data = (HashMap) msg.obj; 956 ProcessRecord proc = (ProcessRecord)data.get("app"); 957 if (proc != null && proc.anrDialog != null) { 958 Slog.e(TAG, "App already has anr dialog: " + proc); 959 return; 960 } 961 962 Intent intent = new Intent("android.intent.action.ANR"); 963 if (!mProcessesReady) { 964 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 965 | Intent.FLAG_RECEIVER_FOREGROUND); 966 } 967 broadcastIntentLocked(null, null, intent, 968 null, null, 0, null, null, null, 969 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 970 971 if (mShowDialogs) { 972 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 973 mContext, proc, (ActivityRecord)data.get("activity")); 974 d.show(); 975 proc.anrDialog = d; 976 } else { 977 // Just kill the app if there is no dialog to be shown. 978 killAppAtUsersRequest(proc, null); 979 } 980 } 981 982 ensureBootCompleted(); 983 } break; 984 case SHOW_STRICT_MODE_VIOLATION_MSG: { 985 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 986 synchronized (ActivityManagerService.this) { 987 ProcessRecord proc = (ProcessRecord) data.get("app"); 988 if (proc == null) { 989 Slog.e(TAG, "App not found when showing strict mode dialog."); 990 break; 991 } 992 if (proc.crashDialog != null) { 993 Slog.e(TAG, "App already has strict mode dialog: " + proc); 994 return; 995 } 996 AppErrorResult res = (AppErrorResult) data.get("result"); 997 if (mShowDialogs && !mSleeping && !mShuttingDown) { 998 Dialog d = new StrictModeViolationDialog(mContext, 999 ActivityManagerService.this, res, proc); 1000 d.show(); 1001 proc.crashDialog = d; 1002 } else { 1003 // The device is asleep, so just pretend that the user 1004 // saw a crash dialog and hit "force quit". 1005 res.set(0); 1006 } 1007 } 1008 ensureBootCompleted(); 1009 } break; 1010 case SHOW_FACTORY_ERROR_MSG: { 1011 Dialog d = new FactoryErrorDialog( 1012 mContext, msg.getData().getCharSequence("msg")); 1013 d.show(); 1014 ensureBootCompleted(); 1015 } break; 1016 case UPDATE_CONFIGURATION_MSG: { 1017 final ContentResolver resolver = mContext.getContentResolver(); 1018 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1019 } break; 1020 case GC_BACKGROUND_PROCESSES_MSG: { 1021 synchronized (ActivityManagerService.this) { 1022 performAppGcsIfAppropriateLocked(); 1023 } 1024 } break; 1025 case WAIT_FOR_DEBUGGER_MSG: { 1026 synchronized (ActivityManagerService.this) { 1027 ProcessRecord app = (ProcessRecord)msg.obj; 1028 if (msg.arg1 != 0) { 1029 if (!app.waitedForDebugger) { 1030 Dialog d = new AppWaitingForDebuggerDialog( 1031 ActivityManagerService.this, 1032 mContext, app); 1033 app.waitDialog = d; 1034 app.waitedForDebugger = true; 1035 d.show(); 1036 } 1037 } else { 1038 if (app.waitDialog != null) { 1039 app.waitDialog.dismiss(); 1040 app.waitDialog = null; 1041 } 1042 } 1043 } 1044 } break; 1045 case SERVICE_TIMEOUT_MSG: { 1046 if (mDidDexOpt) { 1047 mDidDexOpt = false; 1048 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1049 nmsg.obj = msg.obj; 1050 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1051 return; 1052 } 1053 mServices.serviceTimeout((ProcessRecord)msg.obj); 1054 } break; 1055 case UPDATE_TIME_ZONE: { 1056 synchronized (ActivityManagerService.this) { 1057 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1058 ProcessRecord r = mLruProcesses.get(i); 1059 if (r.thread != null) { 1060 try { 1061 r.thread.updateTimeZone(); 1062 } catch (RemoteException ex) { 1063 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1064 } 1065 } 1066 } 1067 } 1068 } break; 1069 case CLEAR_DNS_CACHE: { 1070 synchronized (ActivityManagerService.this) { 1071 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1072 ProcessRecord r = mLruProcesses.get(i); 1073 if (r.thread != null) { 1074 try { 1075 r.thread.clearDnsCache(); 1076 } catch (RemoteException ex) { 1077 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1078 } 1079 } 1080 } 1081 } 1082 } break; 1083 case UPDATE_HTTP_PROXY: { 1084 ProxyProperties proxy = (ProxyProperties)msg.obj; 1085 String host = ""; 1086 String port = ""; 1087 String exclList = ""; 1088 if (proxy != null) { 1089 host = proxy.getHost(); 1090 port = Integer.toString(proxy.getPort()); 1091 exclList = proxy.getExclusionList(); 1092 } 1093 synchronized (ActivityManagerService.this) { 1094 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1095 ProcessRecord r = mLruProcesses.get(i); 1096 if (r.thread != null) { 1097 try { 1098 r.thread.setHttpProxy(host, port, exclList); 1099 } catch (RemoteException ex) { 1100 Slog.w(TAG, "Failed to update http proxy for: " + 1101 r.info.processName); 1102 } 1103 } 1104 } 1105 } 1106 } break; 1107 case SHOW_UID_ERROR_MSG: { 1108 String title = "System UIDs Inconsistent"; 1109 String text = "UIDs on the system are inconsistent, you need to wipe your" 1110 + " data partition or your device will be unstable."; 1111 Log.e(TAG, title + ": " + text); 1112 if (mShowDialogs) { 1113 // XXX This is a temporary dialog, no need to localize. 1114 AlertDialog d = new BaseErrorDialog(mContext); 1115 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1116 d.setCancelable(false); 1117 d.setTitle(title); 1118 d.setMessage(text); 1119 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1120 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1121 mUidAlert = d; 1122 d.show(); 1123 } 1124 } break; 1125 case IM_FEELING_LUCKY_MSG: { 1126 if (mUidAlert != null) { 1127 mUidAlert.dismiss(); 1128 mUidAlert = null; 1129 } 1130 } break; 1131 case PROC_START_TIMEOUT_MSG: { 1132 if (mDidDexOpt) { 1133 mDidDexOpt = false; 1134 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1135 nmsg.obj = msg.obj; 1136 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1137 return; 1138 } 1139 ProcessRecord app = (ProcessRecord)msg.obj; 1140 synchronized (ActivityManagerService.this) { 1141 processStartTimedOutLocked(app); 1142 } 1143 } break; 1144 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1145 synchronized (ActivityManagerService.this) { 1146 doPendingActivityLaunchesLocked(true); 1147 } 1148 } break; 1149 case KILL_APPLICATION_MSG: { 1150 synchronized (ActivityManagerService.this) { 1151 int appid = msg.arg1; 1152 boolean restart = (msg.arg2 == 1); 1153 String pkg = (String) msg.obj; 1154 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1155 UserHandle.USER_ALL); 1156 } 1157 } break; 1158 case FINALIZE_PENDING_INTENT_MSG: { 1159 ((PendingIntentRecord)msg.obj).completeFinalize(); 1160 } break; 1161 case POST_HEAVY_NOTIFICATION_MSG: { 1162 INotificationManager inm = NotificationManager.getService(); 1163 if (inm == null) { 1164 return; 1165 } 1166 1167 ActivityRecord root = (ActivityRecord)msg.obj; 1168 ProcessRecord process = root.app; 1169 if (process == null) { 1170 return; 1171 } 1172 1173 try { 1174 Context context = mContext.createPackageContext(process.info.packageName, 0); 1175 String text = mContext.getString(R.string.heavy_weight_notification, 1176 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1177 Notification notification = new Notification(); 1178 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1179 notification.when = 0; 1180 notification.flags = Notification.FLAG_ONGOING_EVENT; 1181 notification.tickerText = text; 1182 notification.defaults = 0; // please be quiet 1183 notification.sound = null; 1184 notification.vibrate = null; 1185 notification.setLatestEventInfo(context, text, 1186 mContext.getText(R.string.heavy_weight_notification_detail), 1187 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1188 PendingIntent.FLAG_CANCEL_CURRENT, null, 1189 new UserHandle(root.userId))); 1190 1191 try { 1192 int[] outId = new int[1]; 1193 inm.enqueueNotificationWithTag("android", null, 1194 R.string.heavy_weight_notification, 1195 notification, outId, root.userId); 1196 } catch (RuntimeException e) { 1197 Slog.w(ActivityManagerService.TAG, 1198 "Error showing notification for heavy-weight app", e); 1199 } catch (RemoteException e) { 1200 } 1201 } catch (NameNotFoundException e) { 1202 Slog.w(TAG, "Unable to create context for heavy notification", e); 1203 } 1204 } break; 1205 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1206 INotificationManager inm = NotificationManager.getService(); 1207 if (inm == null) { 1208 return; 1209 } 1210 try { 1211 inm.cancelNotificationWithTag("android", null, 1212 R.string.heavy_weight_notification, msg.arg1); 1213 } catch (RuntimeException e) { 1214 Slog.w(ActivityManagerService.TAG, 1215 "Error canceling notification for service", e); 1216 } catch (RemoteException e) { 1217 } 1218 } break; 1219 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1220 synchronized (ActivityManagerService.this) { 1221 checkExcessivePowerUsageLocked(true); 1222 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1223 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1224 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1225 } 1226 } break; 1227 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1228 synchronized (ActivityManagerService.this) { 1229 ActivityRecord ar = (ActivityRecord)msg.obj; 1230 if (mCompatModeDialog != null) { 1231 if (mCompatModeDialog.mAppInfo.packageName.equals( 1232 ar.info.applicationInfo.packageName)) { 1233 return; 1234 } 1235 mCompatModeDialog.dismiss(); 1236 mCompatModeDialog = null; 1237 } 1238 if (ar != null && false) { 1239 if (mCompatModePackages.getPackageAskCompatModeLocked( 1240 ar.packageName)) { 1241 int mode = mCompatModePackages.computeCompatModeLocked( 1242 ar.info.applicationInfo); 1243 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1244 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1245 mCompatModeDialog = new CompatModeDialog( 1246 ActivityManagerService.this, mContext, 1247 ar.info.applicationInfo); 1248 mCompatModeDialog.show(); 1249 } 1250 } 1251 } 1252 } 1253 break; 1254 } 1255 case DISPATCH_PROCESSES_CHANGED: { 1256 dispatchProcessesChanged(); 1257 break; 1258 } 1259 case DISPATCH_PROCESS_DIED: { 1260 final int pid = msg.arg1; 1261 final int uid = msg.arg2; 1262 dispatchProcessDied(pid, uid); 1263 break; 1264 } 1265 case REPORT_MEM_USAGE: { 1266 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1267 if (!isDebuggable) { 1268 return; 1269 } 1270 synchronized (ActivityManagerService.this) { 1271 long now = SystemClock.uptimeMillis(); 1272 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1273 // Don't report more than every 5 minutes to somewhat 1274 // avoid spamming. 1275 return; 1276 } 1277 mLastMemUsageReportTime = now; 1278 } 1279 Thread thread = new Thread() { 1280 @Override public void run() { 1281 StringBuilder dropBuilder = new StringBuilder(1024); 1282 StringBuilder logBuilder = new StringBuilder(1024); 1283 StringWriter oomSw = new StringWriter(); 1284 PrintWriter oomPw = new PrintWriter(oomSw); 1285 StringWriter catSw = new StringWriter(); 1286 PrintWriter catPw = new PrintWriter(catSw); 1287 String[] emptyArgs = new String[] { }; 1288 StringBuilder tag = new StringBuilder(128); 1289 StringBuilder stack = new StringBuilder(128); 1290 tag.append("Low on memory -- "); 1291 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1292 tag, stack); 1293 dropBuilder.append(stack); 1294 dropBuilder.append('\n'); 1295 dropBuilder.append('\n'); 1296 String oomString = oomSw.toString(); 1297 dropBuilder.append(oomString); 1298 dropBuilder.append('\n'); 1299 logBuilder.append(oomString); 1300 try { 1301 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1302 "procrank", }); 1303 final InputStreamReader converter = new InputStreamReader( 1304 proc.getInputStream()); 1305 BufferedReader in = new BufferedReader(converter); 1306 String line; 1307 while (true) { 1308 line = in.readLine(); 1309 if (line == null) { 1310 break; 1311 } 1312 if (line.length() > 0) { 1313 logBuilder.append(line); 1314 logBuilder.append('\n'); 1315 } 1316 dropBuilder.append(line); 1317 dropBuilder.append('\n'); 1318 } 1319 converter.close(); 1320 } catch (IOException e) { 1321 } 1322 synchronized (ActivityManagerService.this) { 1323 catPw.println(); 1324 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1325 catPw.println(); 1326 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1327 false, false, null); 1328 catPw.println(); 1329 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1330 } 1331 dropBuilder.append(catSw.toString()); 1332 addErrorToDropBox("lowmem", null, "system_server", null, 1333 null, tag.toString(), dropBuilder.toString(), null, null); 1334 Slog.i(TAG, logBuilder.toString()); 1335 synchronized (ActivityManagerService.this) { 1336 long now = SystemClock.uptimeMillis(); 1337 if (mLastMemUsageReportTime < now) { 1338 mLastMemUsageReportTime = now; 1339 } 1340 } 1341 } 1342 }; 1343 thread.start(); 1344 break; 1345 } 1346 case REPORT_USER_SWITCH_MSG: { 1347 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1348 break; 1349 } 1350 case CONTINUE_USER_SWITCH_MSG: { 1351 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1352 break; 1353 } 1354 case USER_SWITCH_TIMEOUT_MSG: { 1355 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1356 break; 1357 } 1358 } 1359 } 1360 }; 1361 1362 public static void setSystemProcess() { 1363 try { 1364 ActivityManagerService m = mSelf; 1365 1366 ServiceManager.addService("activity", m, true); 1367 ServiceManager.addService("meminfo", new MemBinder(m)); 1368 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1369 ServiceManager.addService("dbinfo", new DbBinder(m)); 1370 if (MONITOR_CPU_USAGE) { 1371 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1372 } 1373 ServiceManager.addService("permission", new PermissionController(m)); 1374 1375 ApplicationInfo info = 1376 mSelf.mContext.getPackageManager().getApplicationInfo( 1377 "android", STOCK_PM_FLAGS); 1378 mSystemThread.installSystemApplicationInfo(info); 1379 1380 synchronized (mSelf) { 1381 ProcessRecord app = mSelf.newProcessRecordLocked( 1382 mSystemThread.getApplicationThread(), info, 1383 info.processName, false); 1384 app.persistent = true; 1385 app.pid = MY_PID; 1386 app.maxAdj = ProcessList.SYSTEM_ADJ; 1387 mSelf.mProcessNames.put(app.processName, app.uid, app); 1388 synchronized (mSelf.mPidsSelfLocked) { 1389 mSelf.mPidsSelfLocked.put(app.pid, app); 1390 } 1391 mSelf.updateLruProcessLocked(app, true); 1392 } 1393 } catch (PackageManager.NameNotFoundException e) { 1394 throw new RuntimeException( 1395 "Unable to find android system package", e); 1396 } 1397 } 1398 1399 public void setWindowManager(WindowManagerService wm) { 1400 mWindowManager = wm; 1401 } 1402 1403 public static final Context main(int factoryTest) { 1404 AThread thr = new AThread(); 1405 thr.start(); 1406 1407 synchronized (thr) { 1408 while (thr.mService == null) { 1409 try { 1410 thr.wait(); 1411 } catch (InterruptedException e) { 1412 } 1413 } 1414 } 1415 1416 ActivityManagerService m = thr.mService; 1417 mSelf = m; 1418 ActivityThread at = ActivityThread.systemMain(); 1419 mSystemThread = at; 1420 Context context = at.getSystemContext(); 1421 context.setTheme(android.R.style.Theme_Holo); 1422 m.mContext = context; 1423 m.mFactoryTest = factoryTest; 1424 m.mMainStack = new ActivityStack(m, context, true); 1425 1426 m.mBatteryStatsService.publish(context); 1427 m.mUsageStatsService.publish(context); 1428 1429 synchronized (thr) { 1430 thr.mReady = true; 1431 thr.notifyAll(); 1432 } 1433 1434 m.startRunning(null, null, null, null); 1435 1436 return context; 1437 } 1438 1439 public static ActivityManagerService self() { 1440 return mSelf; 1441 } 1442 1443 static class AThread extends Thread { 1444 ActivityManagerService mService; 1445 boolean mReady = false; 1446 1447 public AThread() { 1448 super("ActivityManager"); 1449 } 1450 1451 public void run() { 1452 Looper.prepare(); 1453 1454 android.os.Process.setThreadPriority( 1455 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1456 android.os.Process.setCanSelfBackground(false); 1457 1458 ActivityManagerService m = new ActivityManagerService(); 1459 1460 synchronized (this) { 1461 mService = m; 1462 notifyAll(); 1463 } 1464 1465 synchronized (this) { 1466 while (!mReady) { 1467 try { 1468 wait(); 1469 } catch (InterruptedException e) { 1470 } 1471 } 1472 } 1473 1474 // For debug builds, log event loop stalls to dropbox for analysis. 1475 if (StrictMode.conditionallyEnableDebugLogging()) { 1476 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1477 } 1478 1479 Looper.loop(); 1480 } 1481 } 1482 1483 static class MemBinder extends Binder { 1484 ActivityManagerService mActivityManagerService; 1485 MemBinder(ActivityManagerService activityManagerService) { 1486 mActivityManagerService = activityManagerService; 1487 } 1488 1489 @Override 1490 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1491 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1492 != PackageManager.PERMISSION_GRANTED) { 1493 pw.println("Permission Denial: can't dump meminfo from from pid=" 1494 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1495 + " without permission " + android.Manifest.permission.DUMP); 1496 return; 1497 } 1498 1499 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1500 false, null, null, null); 1501 } 1502 } 1503 1504 static class GraphicsBinder extends Binder { 1505 ActivityManagerService mActivityManagerService; 1506 GraphicsBinder(ActivityManagerService activityManagerService) { 1507 mActivityManagerService = activityManagerService; 1508 } 1509 1510 @Override 1511 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1512 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1513 != PackageManager.PERMISSION_GRANTED) { 1514 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1515 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1516 + " without permission " + android.Manifest.permission.DUMP); 1517 return; 1518 } 1519 1520 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1521 } 1522 } 1523 1524 static class DbBinder extends Binder { 1525 ActivityManagerService mActivityManagerService; 1526 DbBinder(ActivityManagerService activityManagerService) { 1527 mActivityManagerService = activityManagerService; 1528 } 1529 1530 @Override 1531 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1532 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1533 != PackageManager.PERMISSION_GRANTED) { 1534 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1535 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1536 + " without permission " + android.Manifest.permission.DUMP); 1537 return; 1538 } 1539 1540 mActivityManagerService.dumpDbInfo(fd, pw, args); 1541 } 1542 } 1543 1544 static class CpuBinder extends Binder { 1545 ActivityManagerService mActivityManagerService; 1546 CpuBinder(ActivityManagerService activityManagerService) { 1547 mActivityManagerService = activityManagerService; 1548 } 1549 1550 @Override 1551 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1552 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1553 != PackageManager.PERMISSION_GRANTED) { 1554 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1555 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1556 + " without permission " + android.Manifest.permission.DUMP); 1557 return; 1558 } 1559 1560 synchronized (mActivityManagerService.mProcessStatsThread) { 1561 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1562 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1563 SystemClock.uptimeMillis())); 1564 } 1565 } 1566 } 1567 1568 private ActivityManagerService() { 1569 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1570 1571 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1572 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1573 mBroadcastQueues[0] = mFgBroadcastQueue; 1574 mBroadcastQueues[1] = mBgBroadcastQueue; 1575 1576 mServices = new ActiveServices(this); 1577 mProviderMap = new ProviderMap(this); 1578 1579 File dataDir = Environment.getDataDirectory(); 1580 File systemDir = new File(dataDir, "system"); 1581 systemDir.mkdirs(); 1582 mBatteryStatsService = new BatteryStatsService(new File( 1583 systemDir, "batterystats.bin").toString()); 1584 mBatteryStatsService.getActiveStatistics().readLocked(); 1585 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1586 mOnBattery = DEBUG_POWER ? true 1587 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1588 mBatteryStatsService.getActiveStatistics().setCallback(this); 1589 1590 mUsageStatsService = new UsageStatsService(new File( 1591 systemDir, "usagestats").toString()); 1592 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1593 1594 // User 0 is the first and only user that runs at boot. 1595 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1596 mUserLru.add(Integer.valueOf(0)); 1597 updateStartedUserArrayLocked(); 1598 1599 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1600 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1601 1602 mConfiguration.setToDefaults(); 1603 mConfiguration.setLocale(Locale.getDefault()); 1604 1605 mConfigurationSeq = mConfiguration.seq = 1; 1606 mProcessStats.init(); 1607 1608 mCompatModePackages = new CompatModePackages(this, systemDir); 1609 1610 // Add ourself to the Watchdog monitors. 1611 Watchdog.getInstance().addMonitor(this); 1612 1613 mProcessStatsThread = new Thread("ProcessStats") { 1614 public void run() { 1615 while (true) { 1616 try { 1617 try { 1618 synchronized(this) { 1619 final long now = SystemClock.uptimeMillis(); 1620 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1621 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1622 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1623 // + ", write delay=" + nextWriteDelay); 1624 if (nextWriteDelay < nextCpuDelay) { 1625 nextCpuDelay = nextWriteDelay; 1626 } 1627 if (nextCpuDelay > 0) { 1628 mProcessStatsMutexFree.set(true); 1629 this.wait(nextCpuDelay); 1630 } 1631 } 1632 } catch (InterruptedException e) { 1633 } 1634 updateCpuStatsNow(); 1635 } catch (Exception e) { 1636 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1637 } 1638 } 1639 } 1640 }; 1641 mProcessStatsThread.start(); 1642 } 1643 1644 @Override 1645 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1646 throws RemoteException { 1647 if (code == SYSPROPS_TRANSACTION) { 1648 // We need to tell all apps about the system property change. 1649 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1650 synchronized(this) { 1651 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1652 final int NA = apps.size(); 1653 for (int ia=0; ia<NA; ia++) { 1654 ProcessRecord app = apps.valueAt(ia); 1655 if (app.thread != null) { 1656 procs.add(app.thread.asBinder()); 1657 } 1658 } 1659 } 1660 } 1661 1662 int N = procs.size(); 1663 for (int i=0; i<N; i++) { 1664 Parcel data2 = Parcel.obtain(); 1665 try { 1666 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1667 } catch (RemoteException e) { 1668 } 1669 data2.recycle(); 1670 } 1671 } 1672 try { 1673 return super.onTransact(code, data, reply, flags); 1674 } catch (RuntimeException e) { 1675 // The activity manager only throws security exceptions, so let's 1676 // log all others. 1677 if (!(e instanceof SecurityException)) { 1678 Slog.e(TAG, "Activity Manager Crash", e); 1679 } 1680 throw e; 1681 } 1682 } 1683 1684 void updateCpuStats() { 1685 final long now = SystemClock.uptimeMillis(); 1686 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1687 return; 1688 } 1689 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1690 synchronized (mProcessStatsThread) { 1691 mProcessStatsThread.notify(); 1692 } 1693 } 1694 } 1695 1696 void updateCpuStatsNow() { 1697 synchronized (mProcessStatsThread) { 1698 mProcessStatsMutexFree.set(false); 1699 final long now = SystemClock.uptimeMillis(); 1700 boolean haveNewCpuStats = false; 1701 1702 if (MONITOR_CPU_USAGE && 1703 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1704 mLastCpuTime.set(now); 1705 haveNewCpuStats = true; 1706 mProcessStats.update(); 1707 //Slog.i(TAG, mProcessStats.printCurrentState()); 1708 //Slog.i(TAG, "Total CPU usage: " 1709 // + mProcessStats.getTotalCpuPercent() + "%"); 1710 1711 // Slog the cpu usage if the property is set. 1712 if ("true".equals(SystemProperties.get("events.cpu"))) { 1713 int user = mProcessStats.getLastUserTime(); 1714 int system = mProcessStats.getLastSystemTime(); 1715 int iowait = mProcessStats.getLastIoWaitTime(); 1716 int irq = mProcessStats.getLastIrqTime(); 1717 int softIrq = mProcessStats.getLastSoftIrqTime(); 1718 int idle = mProcessStats.getLastIdleTime(); 1719 1720 int total = user + system + iowait + irq + softIrq + idle; 1721 if (total == 0) total = 1; 1722 1723 EventLog.writeEvent(EventLogTags.CPU, 1724 ((user+system+iowait+irq+softIrq) * 100) / total, 1725 (user * 100) / total, 1726 (system * 100) / total, 1727 (iowait * 100) / total, 1728 (irq * 100) / total, 1729 (softIrq * 100) / total); 1730 } 1731 } 1732 1733 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1734 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1735 synchronized(bstats) { 1736 synchronized(mPidsSelfLocked) { 1737 if (haveNewCpuStats) { 1738 if (mOnBattery) { 1739 int perc = bstats.startAddingCpuLocked(); 1740 int totalUTime = 0; 1741 int totalSTime = 0; 1742 final int N = mProcessStats.countStats(); 1743 for (int i=0; i<N; i++) { 1744 ProcessStats.Stats st = mProcessStats.getStats(i); 1745 if (!st.working) { 1746 continue; 1747 } 1748 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1749 int otherUTime = (st.rel_utime*perc)/100; 1750 int otherSTime = (st.rel_stime*perc)/100; 1751 totalUTime += otherUTime; 1752 totalSTime += otherSTime; 1753 if (pr != null) { 1754 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1755 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1756 st.rel_stime-otherSTime); 1757 ps.addSpeedStepTimes(cpuSpeedTimes); 1758 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1759 } else { 1760 BatteryStatsImpl.Uid.Proc ps = 1761 bstats.getProcessStatsLocked(st.name, st.pid); 1762 if (ps != null) { 1763 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1764 st.rel_stime-otherSTime); 1765 ps.addSpeedStepTimes(cpuSpeedTimes); 1766 } 1767 } 1768 } 1769 bstats.finishAddingCpuLocked(perc, totalUTime, 1770 totalSTime, cpuSpeedTimes); 1771 } 1772 } 1773 } 1774 1775 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1776 mLastWriteTime = now; 1777 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1778 } 1779 } 1780 } 1781 } 1782 1783 @Override 1784 public void batteryNeedsCpuUpdate() { 1785 updateCpuStatsNow(); 1786 } 1787 1788 @Override 1789 public void batteryPowerChanged(boolean onBattery) { 1790 // When plugging in, update the CPU stats first before changing 1791 // the plug state. 1792 updateCpuStatsNow(); 1793 synchronized (this) { 1794 synchronized(mPidsSelfLocked) { 1795 mOnBattery = DEBUG_POWER ? true : onBattery; 1796 } 1797 } 1798 } 1799 1800 /** 1801 * Initialize the application bind args. These are passed to each 1802 * process when the bindApplication() IPC is sent to the process. They're 1803 * lazily setup to make sure the services are running when they're asked for. 1804 */ 1805 private HashMap<String, IBinder> getCommonServicesLocked() { 1806 if (mAppBindArgs == null) { 1807 mAppBindArgs = new HashMap<String, IBinder>(); 1808 1809 // Setup the application init args 1810 mAppBindArgs.put("package", ServiceManager.getService("package")); 1811 mAppBindArgs.put("window", ServiceManager.getService("window")); 1812 mAppBindArgs.put(Context.ALARM_SERVICE, 1813 ServiceManager.getService(Context.ALARM_SERVICE)); 1814 } 1815 return mAppBindArgs; 1816 } 1817 1818 final void setFocusedActivityLocked(ActivityRecord r) { 1819 if (mFocusedActivity != r) { 1820 mFocusedActivity = r; 1821 if (r != null) { 1822 mWindowManager.setFocusedApp(r.appToken, true); 1823 } 1824 } 1825 } 1826 1827 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { 1828 // put it on the LRU to keep track of when it should be exited. 1829 int lrui = mLruProcesses.indexOf(app); 1830 if (lrui >= 0) mLruProcesses.remove(lrui); 1831 1832 int i = mLruProcesses.size()-1; 1833 int skipTop = 0; 1834 1835 app.lruSeq = mLruSeq; 1836 1837 // compute the new weight for this process. 1838 app.lastActivityTime = SystemClock.uptimeMillis(); 1839 if (app.activities.size() > 0) { 1840 // If this process has activities, we more strongly want to keep 1841 // it around. 1842 app.lruWeight = app.lastActivityTime; 1843 } else if (app.pubProviders.size() > 0) { 1844 // If this process contains content providers, we want to keep 1845 // it a little more strongly. 1846 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1847 // Also don't let it kick out the first few "real" hidden processes. 1848 skipTop = ProcessList.MIN_HIDDEN_APPS; 1849 } else { 1850 // If this process doesn't have activities, we less strongly 1851 // want to keep it around, and generally want to avoid getting 1852 // in front of any very recently used activities. 1853 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1854 // Also don't let it kick out the first few "real" hidden processes. 1855 skipTop = ProcessList.MIN_HIDDEN_APPS; 1856 } 1857 1858 while (i >= 0) { 1859 ProcessRecord p = mLruProcesses.get(i); 1860 // If this app shouldn't be in front of the first N background 1861 // apps, then skip over that many that are currently hidden. 1862 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1863 skipTop--; 1864 } 1865 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1866 mLruProcesses.add(i+1, app); 1867 break; 1868 } 1869 i--; 1870 } 1871 if (i < 0) { 1872 mLruProcesses.add(0, app); 1873 } 1874 1875 // If the app is currently using a content provider or service, 1876 // bump those processes as well. 1877 if (app.connections.size() > 0) { 1878 for (ConnectionRecord cr : app.connections) { 1879 if (cr.binding != null && cr.binding.service != null 1880 && cr.binding.service.app != null 1881 && cr.binding.service.app.lruSeq != mLruSeq) { 1882 updateLruProcessInternalLocked(cr.binding.service.app, i+1); 1883 } 1884 } 1885 } 1886 for (int j=app.conProviders.size()-1; j>=0; j--) { 1887 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1888 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1889 updateLruProcessInternalLocked(cpr.proc, i+1); 1890 } 1891 } 1892 } 1893 1894 final void updateLruProcessLocked(ProcessRecord app, 1895 boolean oomAdj) { 1896 mLruSeq++; 1897 updateLruProcessInternalLocked(app, 0); 1898 1899 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1900 if (oomAdj) { 1901 updateOomAdjLocked(); 1902 } 1903 } 1904 1905 final ProcessRecord getProcessRecordLocked( 1906 String processName, int uid) { 1907 if (uid == Process.SYSTEM_UID) { 1908 // The system gets to run in any process. If there are multiple 1909 // processes with the same uid, just pick the first (this 1910 // should never happen). 1911 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1912 processName); 1913 if (procs == null) return null; 1914 final int N = procs.size(); 1915 for (int i = 0; i < N; i++) { 1916 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1917 } 1918 } 1919 ProcessRecord proc = mProcessNames.get(processName, uid); 1920 return proc; 1921 } 1922 1923 void ensurePackageDexOpt(String packageName) { 1924 IPackageManager pm = AppGlobals.getPackageManager(); 1925 try { 1926 if (pm.performDexOpt(packageName)) { 1927 mDidDexOpt = true; 1928 } 1929 } catch (RemoteException e) { 1930 } 1931 } 1932 1933 boolean isNextTransitionForward() { 1934 int transit = mWindowManager.getPendingAppTransition(); 1935 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1936 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1937 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1938 } 1939 1940 final ProcessRecord startProcessLocked(String processName, 1941 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1942 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1943 boolean isolated) { 1944 ProcessRecord app; 1945 if (!isolated) { 1946 app = getProcessRecordLocked(processName, info.uid); 1947 } else { 1948 // If this is an isolated process, it can't re-use an existing process. 1949 app = null; 1950 } 1951 // We don't have to do anything more if: 1952 // (1) There is an existing application record; and 1953 // (2) The caller doesn't think it is dead, OR there is no thread 1954 // object attached to it so we know it couldn't have crashed; and 1955 // (3) There is a pid assigned to it, so it is either starting or 1956 // already running. 1957 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1958 + " app=" + app + " knownToBeDead=" + knownToBeDead 1959 + " thread=" + (app != null ? app.thread : null) 1960 + " pid=" + (app != null ? app.pid : -1)); 1961 if (app != null && app.pid > 0) { 1962 if (!knownToBeDead || app.thread == null) { 1963 // We already have the app running, or are waiting for it to 1964 // come up (we have a pid but not yet its thread), so keep it. 1965 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1966 // If this is a new package in the process, add the package to the list 1967 app.addPackage(info.packageName); 1968 return app; 1969 } else { 1970 // An application record is attached to a previous process, 1971 // clean it up now. 1972 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 1973 handleAppDiedLocked(app, true, true); 1974 } 1975 } 1976 1977 String hostingNameStr = hostingName != null 1978 ? hostingName.flattenToShortString() : null; 1979 1980 if (!isolated) { 1981 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1982 // If we are in the background, then check to see if this process 1983 // is bad. If so, we will just silently fail. 1984 if (mBadProcesses.get(info.processName, info.uid) != null) { 1985 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1986 + "/" + info.processName); 1987 return null; 1988 } 1989 } else { 1990 // When the user is explicitly starting a process, then clear its 1991 // crash count so that we won't make it bad until they see at 1992 // least one crash dialog again, and make the process good again 1993 // if it had been bad. 1994 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1995 + "/" + info.processName); 1996 mProcessCrashTimes.remove(info.processName, info.uid); 1997 if (mBadProcesses.get(info.processName, info.uid) != null) { 1998 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 1999 UserHandle.getUserId(info.uid), info.uid, 2000 info.processName); 2001 mBadProcesses.remove(info.processName, info.uid); 2002 if (app != null) { 2003 app.bad = false; 2004 } 2005 } 2006 } 2007 } 2008 2009 if (app == null) { 2010 app = newProcessRecordLocked(null, info, processName, isolated); 2011 if (app == null) { 2012 Slog.w(TAG, "Failed making new process record for " 2013 + processName + "/" + info.uid + " isolated=" + isolated); 2014 return null; 2015 } 2016 mProcessNames.put(processName, app.uid, app); 2017 if (isolated) { 2018 mIsolatedProcesses.put(app.uid, app); 2019 } 2020 } else { 2021 // If this is a new package in the process, add the package to the list 2022 app.addPackage(info.packageName); 2023 } 2024 2025 // If the system is not ready yet, then hold off on starting this 2026 // process until it is. 2027 if (!mProcessesReady 2028 && !isAllowedWhileBooting(info) 2029 && !allowWhileBooting) { 2030 if (!mProcessesOnHold.contains(app)) { 2031 mProcessesOnHold.add(app); 2032 } 2033 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2034 return app; 2035 } 2036 2037 startProcessLocked(app, hostingType, hostingNameStr); 2038 return (app.pid != 0) ? app : null; 2039 } 2040 2041 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2042 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2043 } 2044 2045 private final void startProcessLocked(ProcessRecord app, 2046 String hostingType, String hostingNameStr) { 2047 if (app.pid > 0 && app.pid != MY_PID) { 2048 synchronized (mPidsSelfLocked) { 2049 mPidsSelfLocked.remove(app.pid); 2050 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2051 } 2052 app.setPid(0); 2053 } 2054 2055 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2056 "startProcessLocked removing on hold: " + app); 2057 mProcessesOnHold.remove(app); 2058 2059 updateCpuStats(); 2060 2061 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2062 mProcDeaths[0] = 0; 2063 2064 try { 2065 int uid = app.uid; 2066 2067 int[] gids = null; 2068 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2069 if (!app.isolated) { 2070 int[] permGids = null; 2071 try { 2072 final PackageManager pm = mContext.getPackageManager(); 2073 permGids = pm.getPackageGids(app.info.packageName); 2074 2075 if (Environment.isExternalStorageEmulated()) { 2076 if (pm.checkPermission( 2077 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2078 app.info.packageName) == PERMISSION_GRANTED) { 2079 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2080 } else { 2081 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2082 } 2083 } 2084 } catch (PackageManager.NameNotFoundException e) { 2085 Slog.w(TAG, "Unable to retrieve gids", e); 2086 } 2087 2088 /* 2089 * Add shared application GID so applications can share some 2090 * resources like shared libraries 2091 */ 2092 if (permGids == null) { 2093 gids = new int[1]; 2094 } else { 2095 gids = new int[permGids.length + 1]; 2096 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2097 } 2098 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2099 } 2100 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2101 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2102 && mTopComponent != null 2103 && app.processName.equals(mTopComponent.getPackageName())) { 2104 uid = 0; 2105 } 2106 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2107 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2108 uid = 0; 2109 } 2110 } 2111 int debugFlags = 0; 2112 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2113 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2114 // Also turn on CheckJNI for debuggable apps. It's quite 2115 // awkward to turn on otherwise. 2116 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2117 } 2118 // Run the app in safe mode if its manifest requests so or the 2119 // system is booted in safe mode. 2120 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2121 Zygote.systemInSafeMode == true) { 2122 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2123 } 2124 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2125 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2126 } 2127 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2128 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2129 } 2130 if ("1".equals(SystemProperties.get("debug.assert"))) { 2131 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2132 } 2133 2134 // Start the process. It will either succeed and return a result containing 2135 // the PID of the new process, or else throw a RuntimeException. 2136 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2137 app.processName, uid, uid, gids, debugFlags, mountExternal, 2138 app.info.targetSdkVersion, null, null); 2139 2140 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2141 synchronized (bs) { 2142 if (bs.isOnBattery()) { 2143 app.batteryStats.incStartsLocked(); 2144 } 2145 } 2146 2147 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2148 UserHandle.getUserId(uid), startResult.pid, uid, 2149 app.processName, hostingType, 2150 hostingNameStr != null ? hostingNameStr : ""); 2151 2152 if (app.persistent) { 2153 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2154 } 2155 2156 StringBuilder buf = mStringBuilder; 2157 buf.setLength(0); 2158 buf.append("Start proc "); 2159 buf.append(app.processName); 2160 buf.append(" for "); 2161 buf.append(hostingType); 2162 if (hostingNameStr != null) { 2163 buf.append(" "); 2164 buf.append(hostingNameStr); 2165 } 2166 buf.append(": pid="); 2167 buf.append(startResult.pid); 2168 buf.append(" uid="); 2169 buf.append(uid); 2170 buf.append(" gids={"); 2171 if (gids != null) { 2172 for (int gi=0; gi<gids.length; gi++) { 2173 if (gi != 0) buf.append(", "); 2174 buf.append(gids[gi]); 2175 2176 } 2177 } 2178 buf.append("}"); 2179 Slog.i(TAG, buf.toString()); 2180 app.setPid(startResult.pid); 2181 app.usingWrapper = startResult.usingWrapper; 2182 app.removed = false; 2183 synchronized (mPidsSelfLocked) { 2184 this.mPidsSelfLocked.put(startResult.pid, app); 2185 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2186 msg.obj = app; 2187 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2188 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2189 } 2190 } catch (RuntimeException e) { 2191 // XXX do better error recovery. 2192 app.setPid(0); 2193 Slog.e(TAG, "Failure starting process " + app.processName, e); 2194 } 2195 } 2196 2197 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2198 if (resumed) { 2199 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2200 } else { 2201 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2202 } 2203 } 2204 2205 boolean startHomeActivityLocked(int userId) { 2206 if (mHeadless) { 2207 // Added because none of the other calls to ensureBootCompleted seem to fire 2208 // when running headless. 2209 ensureBootCompleted(); 2210 return false; 2211 } 2212 2213 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2214 && mTopAction == null) { 2215 // We are running in factory test mode, but unable to find 2216 // the factory test app, so just sit around displaying the 2217 // error message and don't try to start anything. 2218 return false; 2219 } 2220 Intent intent = new Intent( 2221 mTopAction, 2222 mTopData != null ? Uri.parse(mTopData) : null); 2223 intent.setComponent(mTopComponent); 2224 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2225 intent.addCategory(Intent.CATEGORY_HOME); 2226 } 2227 ActivityInfo aInfo = 2228 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2229 if (aInfo != null) { 2230 intent.setComponent(new ComponentName( 2231 aInfo.applicationInfo.packageName, aInfo.name)); 2232 // Don't do this if the home app is currently being 2233 // instrumented. 2234 aInfo = new ActivityInfo(aInfo); 2235 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2236 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2237 aInfo.applicationInfo.uid); 2238 if (app == null || app.instrumentationClass == null) { 2239 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2240 mMainStack.startActivityLocked(null, intent, null, aInfo, 2241 null, null, 0, 0, 0, 0, null, false, null); 2242 } 2243 } 2244 2245 return true; 2246 } 2247 2248 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2249 ActivityInfo ai = null; 2250 ComponentName comp = intent.getComponent(); 2251 try { 2252 if (comp != null) { 2253 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2254 } else { 2255 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2256 intent, 2257 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2258 flags, userId); 2259 2260 if (info != null) { 2261 ai = info.activityInfo; 2262 } 2263 } 2264 } catch (RemoteException e) { 2265 // ignore 2266 } 2267 2268 return ai; 2269 } 2270 2271 /** 2272 * Starts the "new version setup screen" if appropriate. 2273 */ 2274 void startSetupActivityLocked() { 2275 // Only do this once per boot. 2276 if (mCheckedForSetup) { 2277 return; 2278 } 2279 2280 // We will show this screen if the current one is a different 2281 // version than the last one shown, and we are not running in 2282 // low-level factory test mode. 2283 final ContentResolver resolver = mContext.getContentResolver(); 2284 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2285 Settings.Global.getInt(resolver, 2286 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2287 mCheckedForSetup = true; 2288 2289 // See if we should be showing the platform update setup UI. 2290 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2291 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2292 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2293 2294 // We don't allow third party apps to replace this. 2295 ResolveInfo ri = null; 2296 for (int i=0; ris != null && i<ris.size(); i++) { 2297 if ((ris.get(i).activityInfo.applicationInfo.flags 2298 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2299 ri = ris.get(i); 2300 break; 2301 } 2302 } 2303 2304 if (ri != null) { 2305 String vers = ri.activityInfo.metaData != null 2306 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2307 : null; 2308 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2309 vers = ri.activityInfo.applicationInfo.metaData.getString( 2310 Intent.METADATA_SETUP_VERSION); 2311 } 2312 String lastVers = Settings.Secure.getString( 2313 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2314 if (vers != null && !vers.equals(lastVers)) { 2315 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2316 intent.setComponent(new ComponentName( 2317 ri.activityInfo.packageName, ri.activityInfo.name)); 2318 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2319 null, null, 0, 0, 0, 0, null, false, null); 2320 } 2321 } 2322 } 2323 } 2324 2325 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2326 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2327 } 2328 2329 void enforceNotIsolatedCaller(String caller) { 2330 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2331 throw new SecurityException("Isolated process not allowed to call " + caller); 2332 } 2333 } 2334 2335 public int getFrontActivityScreenCompatMode() { 2336 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2337 synchronized (this) { 2338 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2339 } 2340 } 2341 2342 public void setFrontActivityScreenCompatMode(int mode) { 2343 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2344 "setFrontActivityScreenCompatMode"); 2345 synchronized (this) { 2346 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2347 } 2348 } 2349 2350 public int getPackageScreenCompatMode(String packageName) { 2351 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2352 synchronized (this) { 2353 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2354 } 2355 } 2356 2357 public void setPackageScreenCompatMode(String packageName, int mode) { 2358 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2359 "setPackageScreenCompatMode"); 2360 synchronized (this) { 2361 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2362 } 2363 } 2364 2365 public boolean getPackageAskScreenCompat(String packageName) { 2366 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2367 synchronized (this) { 2368 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2369 } 2370 } 2371 2372 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2373 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2374 "setPackageAskScreenCompat"); 2375 synchronized (this) { 2376 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2377 } 2378 } 2379 2380 void reportResumedActivityLocked(ActivityRecord r) { 2381 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2382 updateUsageStats(r, true); 2383 } 2384 2385 private void dispatchProcessesChanged() { 2386 int N; 2387 synchronized (this) { 2388 N = mPendingProcessChanges.size(); 2389 if (mActiveProcessChanges.length < N) { 2390 mActiveProcessChanges = new ProcessChangeItem[N]; 2391 } 2392 mPendingProcessChanges.toArray(mActiveProcessChanges); 2393 mAvailProcessChanges.addAll(mPendingProcessChanges); 2394 mPendingProcessChanges.clear(); 2395 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2396 } 2397 int i = mProcessObservers.beginBroadcast(); 2398 while (i > 0) { 2399 i--; 2400 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2401 if (observer != null) { 2402 try { 2403 for (int j=0; j<N; j++) { 2404 ProcessChangeItem item = mActiveProcessChanges[j]; 2405 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2406 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2407 + item.pid + " uid=" + item.uid + ": " 2408 + item.foregroundActivities); 2409 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2410 item.foregroundActivities); 2411 } 2412 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2413 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2414 + item.pid + " uid=" + item.uid + ": " + item.importance); 2415 observer.onImportanceChanged(item.pid, item.uid, 2416 item.importance); 2417 } 2418 } 2419 } catch (RemoteException e) { 2420 } 2421 } 2422 } 2423 mProcessObservers.finishBroadcast(); 2424 } 2425 2426 private void dispatchProcessDied(int pid, int uid) { 2427 int i = mProcessObservers.beginBroadcast(); 2428 while (i > 0) { 2429 i--; 2430 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2431 if (observer != null) { 2432 try { 2433 observer.onProcessDied(pid, uid); 2434 } catch (RemoteException e) { 2435 } 2436 } 2437 } 2438 mProcessObservers.finishBroadcast(); 2439 } 2440 2441 final void doPendingActivityLaunchesLocked(boolean doResume) { 2442 final int N = mPendingActivityLaunches.size(); 2443 if (N <= 0) { 2444 return; 2445 } 2446 for (int i=0; i<N; i++) { 2447 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2448 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2449 pal.startFlags, doResume && i == (N-1), null); 2450 } 2451 mPendingActivityLaunches.clear(); 2452 } 2453 2454 public final int startActivity(IApplicationThread caller, 2455 Intent intent, String resolvedType, IBinder resultTo, 2456 String resultWho, int requestCode, int startFlags, 2457 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2458 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2459 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2460 } 2461 2462 public final int startActivityAsUser(IApplicationThread caller, 2463 Intent intent, String resolvedType, IBinder resultTo, 2464 String resultWho, int requestCode, int startFlags, 2465 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2466 enforceNotIsolatedCaller("startActivity"); 2467 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2468 false, true, "startActivity", null); 2469 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2470 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2471 null, null, options, userId); 2472 } 2473 2474 public final WaitResult startActivityAndWait(IApplicationThread caller, 2475 Intent intent, String resolvedType, IBinder resultTo, 2476 String resultWho, int requestCode, int startFlags, String profileFile, 2477 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2478 enforceNotIsolatedCaller("startActivityAndWait"); 2479 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2480 false, true, "startActivityAndWait", null); 2481 WaitResult res = new WaitResult(); 2482 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2483 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2484 res, null, options, UserHandle.getCallingUserId()); 2485 return res; 2486 } 2487 2488 public final int startActivityWithConfig(IApplicationThread caller, 2489 Intent intent, String resolvedType, IBinder resultTo, 2490 String resultWho, int requestCode, int startFlags, Configuration config, 2491 Bundle options, int userId) { 2492 enforceNotIsolatedCaller("startActivityWithConfig"); 2493 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2494 false, true, "startActivityWithConfig", null); 2495 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2496 resultTo, resultWho, requestCode, startFlags, 2497 null, null, null, config, options, userId); 2498 return ret; 2499 } 2500 2501 public int startActivityIntentSender(IApplicationThread caller, 2502 IntentSender intent, Intent fillInIntent, String resolvedType, 2503 IBinder resultTo, String resultWho, int requestCode, 2504 int flagsMask, int flagsValues, Bundle options) { 2505 enforceNotIsolatedCaller("startActivityIntentSender"); 2506 // Refuse possible leaked file descriptors 2507 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2508 throw new IllegalArgumentException("File descriptors passed in Intent"); 2509 } 2510 2511 IIntentSender sender = intent.getTarget(); 2512 if (!(sender instanceof PendingIntentRecord)) { 2513 throw new IllegalArgumentException("Bad PendingIntent object"); 2514 } 2515 2516 PendingIntentRecord pir = (PendingIntentRecord)sender; 2517 2518 synchronized (this) { 2519 // If this is coming from the currently resumed activity, it is 2520 // effectively saying that app switches are allowed at this point. 2521 if (mMainStack.mResumedActivity != null 2522 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2523 Binder.getCallingUid()) { 2524 mAppSwitchesAllowedTime = 0; 2525 } 2526 } 2527 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2528 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2529 return ret; 2530 } 2531 2532 public boolean startNextMatchingActivity(IBinder callingActivity, 2533 Intent intent, Bundle options) { 2534 // Refuse possible leaked file descriptors 2535 if (intent != null && intent.hasFileDescriptors() == true) { 2536 throw new IllegalArgumentException("File descriptors passed in Intent"); 2537 } 2538 2539 synchronized (this) { 2540 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2541 if (r == null) { 2542 ActivityOptions.abort(options); 2543 return false; 2544 } 2545 if (r.app == null || r.app.thread == null) { 2546 // The caller is not running... d'oh! 2547 ActivityOptions.abort(options); 2548 return false; 2549 } 2550 intent = new Intent(intent); 2551 // The caller is not allowed to change the data. 2552 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2553 // And we are resetting to find the next component... 2554 intent.setComponent(null); 2555 2556 ActivityInfo aInfo = null; 2557 try { 2558 List<ResolveInfo> resolves = 2559 AppGlobals.getPackageManager().queryIntentActivities( 2560 intent, r.resolvedType, 2561 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2562 UserHandle.getCallingUserId()); 2563 2564 // Look for the original activity in the list... 2565 final int N = resolves != null ? resolves.size() : 0; 2566 for (int i=0; i<N; i++) { 2567 ResolveInfo rInfo = resolves.get(i); 2568 if (rInfo.activityInfo.packageName.equals(r.packageName) 2569 && rInfo.activityInfo.name.equals(r.info.name)) { 2570 // We found the current one... the next matching is 2571 // after it. 2572 i++; 2573 if (i<N) { 2574 aInfo = resolves.get(i).activityInfo; 2575 } 2576 break; 2577 } 2578 } 2579 } catch (RemoteException e) { 2580 } 2581 2582 if (aInfo == null) { 2583 // Nobody who is next! 2584 ActivityOptions.abort(options); 2585 return false; 2586 } 2587 2588 intent.setComponent(new ComponentName( 2589 aInfo.applicationInfo.packageName, aInfo.name)); 2590 intent.setFlags(intent.getFlags()&~( 2591 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2592 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2593 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2594 Intent.FLAG_ACTIVITY_NEW_TASK)); 2595 2596 // Okay now we need to start the new activity, replacing the 2597 // currently running activity. This is a little tricky because 2598 // we want to start the new one as if the current one is finished, 2599 // but not finish the current one first so that there is no flicker. 2600 // And thus... 2601 final boolean wasFinishing = r.finishing; 2602 r.finishing = true; 2603 2604 // Propagate reply information over to the new activity. 2605 final ActivityRecord resultTo = r.resultTo; 2606 final String resultWho = r.resultWho; 2607 final int requestCode = r.requestCode; 2608 r.resultTo = null; 2609 if (resultTo != null) { 2610 resultTo.removeResultsLocked(r, resultWho, requestCode); 2611 } 2612 2613 final long origId = Binder.clearCallingIdentity(); 2614 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2615 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2616 resultWho, requestCode, -1, r.launchedFromUid, 0, 2617 options, false, null); 2618 Binder.restoreCallingIdentity(origId); 2619 2620 r.finishing = wasFinishing; 2621 if (res != ActivityManager.START_SUCCESS) { 2622 return false; 2623 } 2624 return true; 2625 } 2626 } 2627 2628 final int startActivityInPackage(int uid, 2629 Intent intent, String resolvedType, IBinder resultTo, 2630 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2631 2632 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2633 false, true, "startActivityInPackage", null); 2634 2635 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2636 resultTo, resultWho, requestCode, startFlags, 2637 null, null, null, null, options, userId); 2638 return ret; 2639 } 2640 2641 public final int startActivities(IApplicationThread caller, 2642 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 2643 int userId) { 2644 enforceNotIsolatedCaller("startActivities"); 2645 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2646 false, true, "startActivity", null); 2647 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2648 options, userId); 2649 return ret; 2650 } 2651 2652 final int startActivitiesInPackage(int uid, 2653 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2654 Bundle options, int userId) { 2655 2656 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2657 false, true, "startActivityInPackage", null); 2658 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2659 options, userId); 2660 return ret; 2661 } 2662 2663 final void addRecentTaskLocked(TaskRecord task) { 2664 int N = mRecentTasks.size(); 2665 // Quick case: check if the top-most recent task is the same. 2666 if (N > 0 && mRecentTasks.get(0) == task) { 2667 return; 2668 } 2669 // Remove any existing entries that are the same kind of task. 2670 for (int i=0; i<N; i++) { 2671 TaskRecord tr = mRecentTasks.get(i); 2672 if (task.userId == tr.userId 2673 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2674 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2675 mRecentTasks.remove(i); 2676 i--; 2677 N--; 2678 if (task.intent == null) { 2679 // If the new recent task we are adding is not fully 2680 // specified, then replace it with the existing recent task. 2681 task = tr; 2682 } 2683 } 2684 } 2685 if (N >= MAX_RECENT_TASKS) { 2686 mRecentTasks.remove(N-1); 2687 } 2688 mRecentTasks.add(0, task); 2689 } 2690 2691 public void setRequestedOrientation(IBinder token, 2692 int requestedOrientation) { 2693 synchronized (this) { 2694 ActivityRecord r = mMainStack.isInStackLocked(token); 2695 if (r == null) { 2696 return; 2697 } 2698 final long origId = Binder.clearCallingIdentity(); 2699 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2700 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2701 mConfiguration, 2702 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2703 if (config != null) { 2704 r.frozenBeforeDestroy = true; 2705 if (!updateConfigurationLocked(config, r, false, false)) { 2706 mMainStack.resumeTopActivityLocked(null); 2707 } 2708 } 2709 Binder.restoreCallingIdentity(origId); 2710 } 2711 } 2712 2713 public int getRequestedOrientation(IBinder token) { 2714 synchronized (this) { 2715 ActivityRecord r = mMainStack.isInStackLocked(token); 2716 if (r == null) { 2717 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2718 } 2719 return mWindowManager.getAppOrientation(r.appToken); 2720 } 2721 } 2722 2723 /** 2724 * This is the internal entry point for handling Activity.finish(). 2725 * 2726 * @param token The Binder token referencing the Activity we want to finish. 2727 * @param resultCode Result code, if any, from this Activity. 2728 * @param resultData Result data (Intent), if any, from this Activity. 2729 * 2730 * @return Returns true if the activity successfully finished, or false if it is still running. 2731 */ 2732 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2733 // Refuse possible leaked file descriptors 2734 if (resultData != null && resultData.hasFileDescriptors() == true) { 2735 throw new IllegalArgumentException("File descriptors passed in Intent"); 2736 } 2737 2738 synchronized(this) { 2739 if (mController != null) { 2740 // Find the first activity that is not finishing. 2741 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2742 if (next != null) { 2743 // ask watcher if this is allowed 2744 boolean resumeOK = true; 2745 try { 2746 resumeOK = mController.activityResuming(next.packageName); 2747 } catch (RemoteException e) { 2748 mController = null; 2749 } 2750 2751 if (!resumeOK) { 2752 return false; 2753 } 2754 } 2755 } 2756 final long origId = Binder.clearCallingIdentity(); 2757 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2758 resultData, "app-request", true); 2759 Binder.restoreCallingIdentity(origId); 2760 return res; 2761 } 2762 } 2763 2764 public final void finishHeavyWeightApp() { 2765 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2766 != PackageManager.PERMISSION_GRANTED) { 2767 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2768 + Binder.getCallingPid() 2769 + ", uid=" + Binder.getCallingUid() 2770 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2771 Slog.w(TAG, msg); 2772 throw new SecurityException(msg); 2773 } 2774 2775 synchronized(this) { 2776 if (mHeavyWeightProcess == null) { 2777 return; 2778 } 2779 2780 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2781 mHeavyWeightProcess.activities); 2782 for (int i=0; i<activities.size(); i++) { 2783 ActivityRecord r = activities.get(i); 2784 if (!r.finishing) { 2785 int index = mMainStack.indexOfTokenLocked(r.appToken); 2786 if (index >= 0) { 2787 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2788 null, "finish-heavy", true); 2789 } 2790 } 2791 } 2792 2793 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2794 mHeavyWeightProcess.userId, 0)); 2795 mHeavyWeightProcess = null; 2796 } 2797 } 2798 2799 public void crashApplication(int uid, int initialPid, String packageName, 2800 String message) { 2801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2802 != PackageManager.PERMISSION_GRANTED) { 2803 String msg = "Permission Denial: crashApplication() from pid=" 2804 + Binder.getCallingPid() 2805 + ", uid=" + Binder.getCallingUid() 2806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2807 Slog.w(TAG, msg); 2808 throw new SecurityException(msg); 2809 } 2810 2811 synchronized(this) { 2812 ProcessRecord proc = null; 2813 2814 // Figure out which process to kill. We don't trust that initialPid 2815 // still has any relation to current pids, so must scan through the 2816 // list. 2817 synchronized (mPidsSelfLocked) { 2818 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2819 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2820 if (p.uid != uid) { 2821 continue; 2822 } 2823 if (p.pid == initialPid) { 2824 proc = p; 2825 break; 2826 } 2827 for (String str : p.pkgList) { 2828 if (str.equals(packageName)) { 2829 proc = p; 2830 } 2831 } 2832 } 2833 } 2834 2835 if (proc == null) { 2836 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2837 + " initialPid=" + initialPid 2838 + " packageName=" + packageName); 2839 return; 2840 } 2841 2842 if (proc.thread != null) { 2843 if (proc.pid == Process.myPid()) { 2844 Log.w(TAG, "crashApplication: trying to crash self!"); 2845 return; 2846 } 2847 long ident = Binder.clearCallingIdentity(); 2848 try { 2849 proc.thread.scheduleCrash(message); 2850 } catch (RemoteException e) { 2851 } 2852 Binder.restoreCallingIdentity(ident); 2853 } 2854 } 2855 } 2856 2857 public final void finishSubActivity(IBinder token, String resultWho, 2858 int requestCode) { 2859 synchronized(this) { 2860 final long origId = Binder.clearCallingIdentity(); 2861 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2862 Binder.restoreCallingIdentity(origId); 2863 } 2864 } 2865 2866 public boolean finishActivityAffinity(IBinder token) { 2867 synchronized(this) { 2868 final long origId = Binder.clearCallingIdentity(); 2869 boolean res = mMainStack.finishActivityAffinityLocked(token); 2870 Binder.restoreCallingIdentity(origId); 2871 return res; 2872 } 2873 } 2874 2875 public boolean willActivityBeVisible(IBinder token) { 2876 synchronized(this) { 2877 int i; 2878 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2879 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2880 if (r.appToken == token) { 2881 return true; 2882 } 2883 if (r.fullscreen && !r.finishing) { 2884 return false; 2885 } 2886 } 2887 return true; 2888 } 2889 } 2890 2891 public void overridePendingTransition(IBinder token, String packageName, 2892 int enterAnim, int exitAnim) { 2893 synchronized(this) { 2894 ActivityRecord self = mMainStack.isInStackLocked(token); 2895 if (self == null) { 2896 return; 2897 } 2898 2899 final long origId = Binder.clearCallingIdentity(); 2900 2901 if (self.state == ActivityState.RESUMED 2902 || self.state == ActivityState.PAUSING) { 2903 mWindowManager.overridePendingAppTransition(packageName, 2904 enterAnim, exitAnim, null); 2905 } 2906 2907 Binder.restoreCallingIdentity(origId); 2908 } 2909 } 2910 2911 /** 2912 * Main function for removing an existing process from the activity manager 2913 * as a result of that process going away. Clears out all connections 2914 * to the process. 2915 */ 2916 private final void handleAppDiedLocked(ProcessRecord app, 2917 boolean restarting, boolean allowRestart) { 2918 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2919 if (!restarting) { 2920 mLruProcesses.remove(app); 2921 } 2922 2923 if (mProfileProc == app) { 2924 clearProfilerLocked(); 2925 } 2926 2927 // Just in case... 2928 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2929 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG, 2930 "App died while pausing: " + mMainStack.mPausingActivity); 2931 mMainStack.mPausingActivity = null; 2932 } 2933 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2934 mMainStack.mLastPausedActivity = null; 2935 } 2936 2937 // Remove this application's activities from active lists. 2938 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app); 2939 2940 app.activities.clear(); 2941 2942 if (app.instrumentationClass != null) { 2943 Slog.w(TAG, "Crash of app " + app.processName 2944 + " running instrumentation " + app.instrumentationClass); 2945 Bundle info = new Bundle(); 2946 info.putString("shortMsg", "Process crashed."); 2947 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2948 } 2949 2950 if (!restarting) { 2951 if (!mMainStack.resumeTopActivityLocked(null)) { 2952 // If there was nothing to resume, and we are not already 2953 // restarting this process, but there is a visible activity that 2954 // is hosted by the process... then make sure all visible 2955 // activities are running, taking care of restarting this 2956 // process. 2957 if (hasVisibleActivities) { 2958 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2959 } 2960 } 2961 } 2962 } 2963 2964 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2965 IBinder threadBinder = thread.asBinder(); 2966 // Find the application record. 2967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2968 ProcessRecord rec = mLruProcesses.get(i); 2969 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2970 return i; 2971 } 2972 } 2973 return -1; 2974 } 2975 2976 final ProcessRecord getRecordForAppLocked( 2977 IApplicationThread thread) { 2978 if (thread == null) { 2979 return null; 2980 } 2981 2982 int appIndex = getLRURecordIndexForAppLocked(thread); 2983 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2984 } 2985 2986 final void appDiedLocked(ProcessRecord app, int pid, 2987 IApplicationThread thread) { 2988 2989 mProcDeaths[0]++; 2990 2991 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2992 synchronized (stats) { 2993 stats.noteProcessDiedLocked(app.info.uid, pid); 2994 } 2995 2996 // Clean up already done if the process has been re-started. 2997 if (app.pid == pid && app.thread != null && 2998 app.thread.asBinder() == thread.asBinder()) { 2999 if (!app.killedBackground) { 3000 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3001 + ") has died."); 3002 } 3003 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3004 if (DEBUG_CLEANUP) Slog.v( 3005 TAG, "Dying app: " + app + ", pid: " + pid 3006 + ", thread: " + thread.asBinder()); 3007 boolean doLowMem = app.instrumentationClass == null; 3008 handleAppDiedLocked(app, false, true); 3009 3010 if (doLowMem) { 3011 // If there are no longer any background processes running, 3012 // and the app that died was not running instrumentation, 3013 // then tell everyone we are now low on memory. 3014 boolean haveBg = false; 3015 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3016 ProcessRecord rec = mLruProcesses.get(i); 3017 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3018 haveBg = true; 3019 break; 3020 } 3021 } 3022 3023 if (!haveBg) { 3024 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3025 long now = SystemClock.uptimeMillis(); 3026 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3027 ProcessRecord rec = mLruProcesses.get(i); 3028 if (rec != app && rec.thread != null && 3029 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3030 // The low memory report is overriding any current 3031 // state for a GC request. Make sure to do 3032 // heavy/important/visible/foreground processes first. 3033 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3034 rec.lastRequestedGc = 0; 3035 } else { 3036 rec.lastRequestedGc = rec.lastLowMemory; 3037 } 3038 rec.reportLowMemory = true; 3039 rec.lastLowMemory = now; 3040 mProcessesToGc.remove(rec); 3041 addProcessToGcListLocked(rec); 3042 } 3043 } 3044 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3045 scheduleAppGcsLocked(); 3046 } 3047 } 3048 } else if (app.pid != pid) { 3049 // A new process has already been started. 3050 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3051 + ") has died and restarted (pid " + app.pid + ")."); 3052 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3053 } else if (DEBUG_PROCESSES) { 3054 Slog.d(TAG, "Received spurious death notification for thread " 3055 + thread.asBinder()); 3056 } 3057 } 3058 3059 /** 3060 * If a stack trace dump file is configured, dump process stack traces. 3061 * @param clearTraces causes the dump file to be erased prior to the new 3062 * traces being written, if true; when false, the new traces will be 3063 * appended to any existing file content. 3064 * @param firstPids of dalvik VM processes to dump stack traces for first 3065 * @param lastPids of dalvik VM processes to dump stack traces for last 3066 * @param nativeProcs optional list of native process names to dump stack crawls 3067 * @return file containing stack traces, or null if no dump file is configured 3068 */ 3069 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3070 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3071 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3072 if (tracesPath == null || tracesPath.length() == 0) { 3073 return null; 3074 } 3075 3076 File tracesFile = new File(tracesPath); 3077 try { 3078 File tracesDir = tracesFile.getParentFile(); 3079 if (!tracesDir.exists()) { 3080 tracesFile.mkdirs(); 3081 if (!SELinux.restorecon(tracesDir)) { 3082 return null; 3083 } 3084 } 3085 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3086 3087 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3088 tracesFile.createNewFile(); 3089 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3090 } catch (IOException e) { 3091 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3092 return null; 3093 } 3094 3095 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3096 return tracesFile; 3097 } 3098 3099 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3100 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3101 // Use a FileObserver to detect when traces finish writing. 3102 // The order of traces is considered important to maintain for legibility. 3103 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3104 public synchronized void onEvent(int event, String path) { notify(); } 3105 }; 3106 3107 try { 3108 observer.startWatching(); 3109 3110 // First collect all of the stacks of the most important pids. 3111 if (firstPids != null) { 3112 try { 3113 int num = firstPids.size(); 3114 for (int i = 0; i < num; i++) { 3115 synchronized (observer) { 3116 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3117 observer.wait(200); // Wait for write-close, give up after 200msec 3118 } 3119 } 3120 } catch (InterruptedException e) { 3121 Log.wtf(TAG, e); 3122 } 3123 } 3124 3125 // Next measure CPU usage. 3126 if (processStats != null) { 3127 processStats.init(); 3128 System.gc(); 3129 processStats.update(); 3130 try { 3131 synchronized (processStats) { 3132 processStats.wait(500); // measure over 1/2 second. 3133 } 3134 } catch (InterruptedException e) { 3135 } 3136 processStats.update(); 3137 3138 // We'll take the stack crawls of just the top apps using CPU. 3139 final int N = processStats.countWorkingStats(); 3140 int numProcs = 0; 3141 for (int i=0; i<N && numProcs<5; i++) { 3142 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3143 if (lastPids.indexOfKey(stats.pid) >= 0) { 3144 numProcs++; 3145 try { 3146 synchronized (observer) { 3147 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3148 observer.wait(200); // Wait for write-close, give up after 200msec 3149 } 3150 } catch (InterruptedException e) { 3151 Log.wtf(TAG, e); 3152 } 3153 3154 } 3155 } 3156 } 3157 3158 } finally { 3159 observer.stopWatching(); 3160 } 3161 3162 if (nativeProcs != null) { 3163 int[] pids = Process.getPidsForCommands(nativeProcs); 3164 if (pids != null) { 3165 for (int pid : pids) { 3166 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3167 } 3168 } 3169 } 3170 } 3171 3172 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3173 if (true || IS_USER_BUILD) { 3174 return; 3175 } 3176 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3177 if (tracesPath == null || tracesPath.length() == 0) { 3178 return; 3179 } 3180 3181 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3182 StrictMode.allowThreadDiskWrites(); 3183 try { 3184 final File tracesFile = new File(tracesPath); 3185 final File tracesDir = tracesFile.getParentFile(); 3186 final File tracesTmp = new File(tracesDir, "__tmp__"); 3187 try { 3188 if (!tracesDir.exists()) { 3189 tracesFile.mkdirs(); 3190 if (!SELinux.restorecon(tracesDir.getPath())) { 3191 return; 3192 } 3193 } 3194 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3195 3196 if (tracesFile.exists()) { 3197 tracesTmp.delete(); 3198 tracesFile.renameTo(tracesTmp); 3199 } 3200 StringBuilder sb = new StringBuilder(); 3201 Time tobj = new Time(); 3202 tobj.set(System.currentTimeMillis()); 3203 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3204 sb.append(": "); 3205 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3206 sb.append(" since "); 3207 sb.append(msg); 3208 FileOutputStream fos = new FileOutputStream(tracesFile); 3209 fos.write(sb.toString().getBytes()); 3210 if (app == null) { 3211 fos.write("\n*** No application process!".getBytes()); 3212 } 3213 fos.close(); 3214 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3215 } catch (IOException e) { 3216 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3217 return; 3218 } 3219 3220 if (app != null) { 3221 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3222 firstPids.add(app.pid); 3223 dumpStackTraces(tracesPath, firstPids, null, null, null); 3224 } 3225 3226 File lastTracesFile = null; 3227 File curTracesFile = null; 3228 for (int i=9; i>=0; i--) { 3229 String name = String.format("slow%02d.txt", i); 3230 curTracesFile = new File(tracesDir, name); 3231 if (curTracesFile.exists()) { 3232 if (lastTracesFile != null) { 3233 curTracesFile.renameTo(lastTracesFile); 3234 } else { 3235 curTracesFile.delete(); 3236 } 3237 } 3238 lastTracesFile = curTracesFile; 3239 } 3240 tracesFile.renameTo(curTracesFile); 3241 if (tracesTmp.exists()) { 3242 tracesTmp.renameTo(tracesFile); 3243 } 3244 } finally { 3245 StrictMode.setThreadPolicy(oldPolicy); 3246 } 3247 } 3248 3249 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3250 ActivityRecord parent, final String annotation) { 3251 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3252 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3253 3254 if (mController != null) { 3255 try { 3256 // 0 == continue, -1 = kill process immediately 3257 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3258 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3259 } catch (RemoteException e) { 3260 mController = null; 3261 } 3262 } 3263 3264 long anrTime = SystemClock.uptimeMillis(); 3265 if (MONITOR_CPU_USAGE) { 3266 updateCpuStatsNow(); 3267 } 3268 3269 synchronized (this) { 3270 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3271 if (mShuttingDown) { 3272 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3273 return; 3274 } else if (app.notResponding) { 3275 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3276 return; 3277 } else if (app.crashing) { 3278 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3279 return; 3280 } 3281 3282 // In case we come through here for the same app before completing 3283 // this one, mark as anring now so we will bail out. 3284 app.notResponding = true; 3285 3286 // Log the ANR to the event log. 3287 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3288 app.processName, app.info.flags, annotation); 3289 3290 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3291 firstPids.add(app.pid); 3292 3293 int parentPid = app.pid; 3294 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3295 if (parentPid != app.pid) firstPids.add(parentPid); 3296 3297 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3298 3299 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3300 ProcessRecord r = mLruProcesses.get(i); 3301 if (r != null && r.thread != null) { 3302 int pid = r.pid; 3303 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3304 if (r.persistent) { 3305 firstPids.add(pid); 3306 } else { 3307 lastPids.put(pid, Boolean.TRUE); 3308 } 3309 } 3310 } 3311 } 3312 } 3313 3314 // Log the ANR to the main log. 3315 StringBuilder info = new StringBuilder(); 3316 info.setLength(0); 3317 info.append("ANR in ").append(app.processName); 3318 if (activity != null && activity.shortComponentName != null) { 3319 info.append(" (").append(activity.shortComponentName).append(")"); 3320 } 3321 info.append("\n"); 3322 if (annotation != null) { 3323 info.append("Reason: ").append(annotation).append("\n"); 3324 } 3325 if (parent != null && parent != activity) { 3326 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3327 } 3328 3329 final ProcessStats processStats = new ProcessStats(true); 3330 3331 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3332 3333 String cpuInfo = null; 3334 if (MONITOR_CPU_USAGE) { 3335 updateCpuStatsNow(); 3336 synchronized (mProcessStatsThread) { 3337 cpuInfo = mProcessStats.printCurrentState(anrTime); 3338 } 3339 info.append(processStats.printCurrentLoad()); 3340 info.append(cpuInfo); 3341 } 3342 3343 info.append(processStats.printCurrentState(anrTime)); 3344 3345 Slog.e(TAG, info.toString()); 3346 if (tracesFile == null) { 3347 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3348 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3349 } 3350 3351 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3352 cpuInfo, tracesFile, null); 3353 3354 if (mController != null) { 3355 try { 3356 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3357 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3358 if (res != 0) { 3359 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3360 return; 3361 } 3362 } catch (RemoteException e) { 3363 mController = null; 3364 } 3365 } 3366 3367 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3368 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3369 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3370 3371 synchronized (this) { 3372 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3373 Slog.w(TAG, "Killing " + app + ": background ANR"); 3374 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 3375 app.processName, app.setAdj, "background ANR"); 3376 Process.killProcessQuiet(app.pid); 3377 return; 3378 } 3379 3380 // Set the app's notResponding state, and look up the errorReportReceiver 3381 makeAppNotRespondingLocked(app, 3382 activity != null ? activity.shortComponentName : null, 3383 annotation != null ? "ANR " + annotation : "ANR", 3384 info.toString()); 3385 3386 // Bring up the infamous App Not Responding dialog 3387 Message msg = Message.obtain(); 3388 HashMap map = new HashMap(); 3389 msg.what = SHOW_NOT_RESPONDING_MSG; 3390 msg.obj = map; 3391 map.put("app", app); 3392 if (activity != null) { 3393 map.put("activity", activity); 3394 } 3395 3396 mHandler.sendMessage(msg); 3397 } 3398 } 3399 3400 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3401 if (!mLaunchWarningShown) { 3402 mLaunchWarningShown = true; 3403 mHandler.post(new Runnable() { 3404 @Override 3405 public void run() { 3406 synchronized (ActivityManagerService.this) { 3407 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3408 d.show(); 3409 mHandler.postDelayed(new Runnable() { 3410 @Override 3411 public void run() { 3412 synchronized (ActivityManagerService.this) { 3413 d.dismiss(); 3414 mLaunchWarningShown = false; 3415 } 3416 } 3417 }, 4000); 3418 } 3419 } 3420 }); 3421 } 3422 } 3423 3424 public boolean clearApplicationUserData(final String packageName, 3425 final IPackageDataObserver observer, int userId) { 3426 enforceNotIsolatedCaller("clearApplicationUserData"); 3427 int uid = Binder.getCallingUid(); 3428 int pid = Binder.getCallingPid(); 3429 userId = handleIncomingUser(pid, uid, 3430 userId, false, true, "clearApplicationUserData", null); 3431 long callingId = Binder.clearCallingIdentity(); 3432 try { 3433 IPackageManager pm = AppGlobals.getPackageManager(); 3434 int pkgUid = -1; 3435 synchronized(this) { 3436 try { 3437 pkgUid = pm.getPackageUid(packageName, userId); 3438 } catch (RemoteException e) { 3439 } 3440 if (pkgUid == -1) { 3441 Slog.w(TAG, "Invalid packageName:" + packageName); 3442 return false; 3443 } 3444 if (uid == pkgUid || checkComponentPermission( 3445 android.Manifest.permission.CLEAR_APP_USER_DATA, 3446 pid, uid, -1, true) 3447 == PackageManager.PERMISSION_GRANTED) { 3448 forceStopPackageLocked(packageName, pkgUid); 3449 } else { 3450 throw new SecurityException(pid+" does not have permission:"+ 3451 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3452 "for process:"+packageName); 3453 } 3454 } 3455 3456 try { 3457 //clear application user data 3458 pm.clearApplicationUserData(packageName, observer, userId); 3459 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3460 Uri.fromParts("package", packageName, null)); 3461 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3462 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3463 null, null, 0, null, null, null, false, false, userId); 3464 } catch (RemoteException e) { 3465 } 3466 } finally { 3467 Binder.restoreCallingIdentity(callingId); 3468 } 3469 return true; 3470 } 3471 3472 public void killBackgroundProcesses(final String packageName, int userId) { 3473 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3474 != PackageManager.PERMISSION_GRANTED && 3475 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3476 != PackageManager.PERMISSION_GRANTED) { 3477 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3478 + Binder.getCallingPid() 3479 + ", uid=" + Binder.getCallingUid() 3480 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3481 Slog.w(TAG, msg); 3482 throw new SecurityException(msg); 3483 } 3484 3485 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3486 userId, true, true, "killBackgroundProcesses", null); 3487 long callingId = Binder.clearCallingIdentity(); 3488 try { 3489 IPackageManager pm = AppGlobals.getPackageManager(); 3490 synchronized(this) { 3491 int appId = -1; 3492 try { 3493 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3494 } catch (RemoteException e) { 3495 } 3496 if (appId == -1) { 3497 Slog.w(TAG, "Invalid packageName: " + packageName); 3498 return; 3499 } 3500 killPackageProcessesLocked(packageName, appId, userId, 3501 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3502 } 3503 } finally { 3504 Binder.restoreCallingIdentity(callingId); 3505 } 3506 } 3507 3508 public void killAllBackgroundProcesses() { 3509 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3510 != PackageManager.PERMISSION_GRANTED) { 3511 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3512 + Binder.getCallingPid() 3513 + ", uid=" + Binder.getCallingUid() 3514 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3515 Slog.w(TAG, msg); 3516 throw new SecurityException(msg); 3517 } 3518 3519 long callingId = Binder.clearCallingIdentity(); 3520 try { 3521 synchronized(this) { 3522 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3523 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3524 final int NA = apps.size(); 3525 for (int ia=0; ia<NA; ia++) { 3526 ProcessRecord app = apps.valueAt(ia); 3527 if (app.persistent) { 3528 // we don't kill persistent processes 3529 continue; 3530 } 3531 if (app.removed) { 3532 procs.add(app); 3533 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3534 app.removed = true; 3535 procs.add(app); 3536 } 3537 } 3538 } 3539 3540 int N = procs.size(); 3541 for (int i=0; i<N; i++) { 3542 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3543 } 3544 } 3545 } finally { 3546 Binder.restoreCallingIdentity(callingId); 3547 } 3548 } 3549 3550 public void forceStopPackage(final String packageName, int userId) { 3551 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3552 != PackageManager.PERMISSION_GRANTED) { 3553 String msg = "Permission Denial: forceStopPackage() from pid=" 3554 + Binder.getCallingPid() 3555 + ", uid=" + Binder.getCallingUid() 3556 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3557 Slog.w(TAG, msg); 3558 throw new SecurityException(msg); 3559 } 3560 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3561 userId, true, true, "forceStopPackage", null); 3562 long callingId = Binder.clearCallingIdentity(); 3563 try { 3564 IPackageManager pm = AppGlobals.getPackageManager(); 3565 synchronized(this) { 3566 int[] users = userId == UserHandle.USER_ALL 3567 ? getUsersLocked() : new int[] { userId }; 3568 for (int user : users) { 3569 int pkgUid = -1; 3570 try { 3571 pkgUid = pm.getPackageUid(packageName, user); 3572 } catch (RemoteException e) { 3573 } 3574 if (pkgUid == -1) { 3575 Slog.w(TAG, "Invalid packageName: " + packageName); 3576 continue; 3577 } 3578 try { 3579 pm.setPackageStoppedState(packageName, true, user); 3580 } catch (RemoteException e) { 3581 } catch (IllegalArgumentException e) { 3582 Slog.w(TAG, "Failed trying to unstop package " 3583 + packageName + ": " + e); 3584 } 3585 if (isUserRunningLocked(user)) { 3586 forceStopPackageLocked(packageName, pkgUid); 3587 } 3588 } 3589 } 3590 } finally { 3591 Binder.restoreCallingIdentity(callingId); 3592 } 3593 } 3594 3595 /* 3596 * The pkg name and app id have to be specified. 3597 */ 3598 public void killApplicationWithAppId(String pkg, int appid) { 3599 if (pkg == null) { 3600 return; 3601 } 3602 // Make sure the uid is valid. 3603 if (appid < 0) { 3604 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3605 return; 3606 } 3607 int callerUid = Binder.getCallingUid(); 3608 // Only the system server can kill an application 3609 if (callerUid == Process.SYSTEM_UID) { 3610 // Post an aysnc message to kill the application 3611 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3612 msg.arg1 = appid; 3613 msg.arg2 = 0; 3614 msg.obj = pkg; 3615 mHandler.sendMessage(msg); 3616 } else { 3617 throw new SecurityException(callerUid + " cannot kill pkg: " + 3618 pkg); 3619 } 3620 } 3621 3622 public void closeSystemDialogs(String reason) { 3623 enforceNotIsolatedCaller("closeSystemDialogs"); 3624 3625 final int pid = Binder.getCallingPid(); 3626 final int uid = Binder.getCallingUid(); 3627 final long origId = Binder.clearCallingIdentity(); 3628 try { 3629 synchronized (this) { 3630 // Only allow this from foreground processes, so that background 3631 // applications can't abuse it to prevent system UI from being shown. 3632 if (uid >= Process.FIRST_APPLICATION_UID) { 3633 ProcessRecord proc; 3634 synchronized (mPidsSelfLocked) { 3635 proc = mPidsSelfLocked.get(pid); 3636 } 3637 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3638 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3639 + " from background process " + proc); 3640 return; 3641 } 3642 } 3643 closeSystemDialogsLocked(reason); 3644 } 3645 } finally { 3646 Binder.restoreCallingIdentity(origId); 3647 } 3648 } 3649 3650 void closeSystemDialogsLocked(String reason) { 3651 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3652 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3653 | Intent.FLAG_RECEIVER_FOREGROUND); 3654 if (reason != null) { 3655 intent.putExtra("reason", reason); 3656 } 3657 mWindowManager.closeSystemDialogs(reason); 3658 3659 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3660 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3661 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3662 r.stack.finishActivityLocked(r, i, 3663 Activity.RESULT_CANCELED, null, "close-sys", true); 3664 } 3665 } 3666 3667 broadcastIntentLocked(null, null, intent, null, 3668 null, 0, null, null, null, false, false, -1, 3669 Process.SYSTEM_UID, UserHandle.USER_ALL); 3670 } 3671 3672 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3673 throws RemoteException { 3674 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3675 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3676 for (int i=pids.length-1; i>=0; i--) { 3677 infos[i] = new Debug.MemoryInfo(); 3678 Debug.getMemoryInfo(pids[i], infos[i]); 3679 } 3680 return infos; 3681 } 3682 3683 public long[] getProcessPss(int[] pids) throws RemoteException { 3684 enforceNotIsolatedCaller("getProcessPss"); 3685 long[] pss = new long[pids.length]; 3686 for (int i=pids.length-1; i>=0; i--) { 3687 pss[i] = Debug.getPss(pids[i]); 3688 } 3689 return pss; 3690 } 3691 3692 public void killApplicationProcess(String processName, int uid) { 3693 if (processName == null) { 3694 return; 3695 } 3696 3697 int callerUid = Binder.getCallingUid(); 3698 // Only the system server can kill an application 3699 if (callerUid == Process.SYSTEM_UID) { 3700 synchronized (this) { 3701 ProcessRecord app = getProcessRecordLocked(processName, uid); 3702 if (app != null && app.thread != null) { 3703 try { 3704 app.thread.scheduleSuicide(); 3705 } catch (RemoteException e) { 3706 // If the other end already died, then our work here is done. 3707 } 3708 } else { 3709 Slog.w(TAG, "Process/uid not found attempting kill of " 3710 + processName + " / " + uid); 3711 } 3712 } 3713 } else { 3714 throw new SecurityException(callerUid + " cannot kill app process: " + 3715 processName); 3716 } 3717 } 3718 3719 private void forceStopPackageLocked(final String packageName, int uid) { 3720 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3721 false, true, false, UserHandle.getUserId(uid)); 3722 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3723 Uri.fromParts("package", packageName, null)); 3724 if (!mProcessesReady) { 3725 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3726 | Intent.FLAG_RECEIVER_FOREGROUND); 3727 } 3728 intent.putExtra(Intent.EXTRA_UID, uid); 3729 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3730 broadcastIntentLocked(null, null, intent, 3731 null, null, 0, null, null, null, 3732 false, false, 3733 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3734 } 3735 3736 private void forceStopUserLocked(int userId) { 3737 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3738 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 3740 | Intent.FLAG_RECEIVER_FOREGROUND); 3741 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3742 broadcastIntentLocked(null, null, intent, 3743 null, null, 0, null, null, null, 3744 false, false, 3745 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3746 } 3747 3748 private final boolean killPackageProcessesLocked(String packageName, int appId, 3749 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3750 boolean doit, boolean evenPersistent, String reason) { 3751 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3752 3753 // Remove all processes this package may have touched: all with the 3754 // same UID (except for the system or root user), and all whose name 3755 // matches the package name. 3756 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3757 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3758 final int NA = apps.size(); 3759 for (int ia=0; ia<NA; ia++) { 3760 ProcessRecord app = apps.valueAt(ia); 3761 if (app.persistent && !evenPersistent) { 3762 // we don't kill persistent processes 3763 continue; 3764 } 3765 if (app.removed) { 3766 if (doit) { 3767 procs.add(app); 3768 } 3769 continue; 3770 } 3771 3772 // Skip process if it doesn't meet our oom adj requirement. 3773 if (app.setAdj < minOomAdj) { 3774 continue; 3775 } 3776 3777 // If no package is specified, we call all processes under the 3778 // give user id. 3779 if (packageName == null) { 3780 if (app.userId != userId) { 3781 continue; 3782 } 3783 // Package has been specified, we want to hit all processes 3784 // that match it. We need to qualify this by the processes 3785 // that are running under the specified app and user ID. 3786 } else { 3787 if (UserHandle.getAppId(app.uid) != appId) { 3788 continue; 3789 } 3790 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3791 continue; 3792 } 3793 if (!app.pkgList.contains(packageName)) { 3794 continue; 3795 } 3796 } 3797 3798 // Process has passed all conditions, kill it! 3799 if (!doit) { 3800 return true; 3801 } 3802 app.removed = true; 3803 procs.add(app); 3804 } 3805 } 3806 3807 int N = procs.size(); 3808 for (int i=0; i<N; i++) { 3809 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3810 } 3811 return N > 0; 3812 } 3813 3814 private final boolean forceStopPackageLocked(String name, int appId, 3815 boolean callerWillRestart, boolean purgeCache, boolean doit, 3816 boolean evenPersistent, int userId) { 3817 int i; 3818 int N; 3819 3820 if (userId == UserHandle.USER_ALL && name == null) { 3821 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3822 } 3823 3824 if (appId < 0 && name != null) { 3825 try { 3826 appId = UserHandle.getAppId( 3827 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3828 } catch (RemoteException e) { 3829 } 3830 } 3831 3832 if (doit) { 3833 if (name != null) { 3834 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3835 + " user=" + userId); 3836 } else { 3837 Slog.i(TAG, "Force stopping user " + userId); 3838 } 3839 3840 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3841 while (badApps.hasNext()) { 3842 SparseArray<Long> ba = badApps.next(); 3843 for (i=ba.size()-1; i>=0; i--) { 3844 boolean remove = false; 3845 final int entUid = ba.keyAt(i); 3846 if (name != null) { 3847 if (userId == UserHandle.USER_ALL) { 3848 if (UserHandle.getAppId(entUid) == appId) { 3849 remove = true; 3850 } 3851 } else { 3852 if (entUid == UserHandle.getUid(userId, appId)) { 3853 remove = true; 3854 } 3855 } 3856 } else if (UserHandle.getUserId(entUid) == userId) { 3857 remove = true; 3858 } 3859 if (remove) { 3860 ba.removeAt(i); 3861 } 3862 } 3863 if (ba.size() == 0) { 3864 badApps.remove(); 3865 } 3866 } 3867 } 3868 3869 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3870 -100, callerWillRestart, false, doit, evenPersistent, 3871 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3872 3873 TaskRecord lastTask = null; 3874 for (i=0; i<mMainStack.mHistory.size(); i++) { 3875 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3876 final boolean samePackage = r.packageName.equals(name) 3877 || (name == null && r.userId == userId); 3878 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3879 && (samePackage || r.task == lastTask) 3880 && (r.app == null || evenPersistent || !r.app.persistent)) { 3881 if (!doit) { 3882 if (r.finishing) { 3883 // If this activity is just finishing, then it is not 3884 // interesting as far as something to stop. 3885 continue; 3886 } 3887 return true; 3888 } 3889 didSomething = true; 3890 Slog.i(TAG, " Force finishing activity " + r); 3891 if (samePackage) { 3892 if (r.app != null) { 3893 r.app.removed = true; 3894 } 3895 r.app = null; 3896 } 3897 lastTask = r.task; 3898 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3899 null, "force-stop", true)) { 3900 i--; 3901 } 3902 } 3903 } 3904 3905 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3906 if (!doit) { 3907 return true; 3908 } 3909 didSomething = true; 3910 } 3911 3912 if (name == null) { 3913 // Remove all sticky broadcasts from this user. 3914 mStickyBroadcasts.remove(userId); 3915 } 3916 3917 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3918 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3919 userId, providers)) { 3920 if (!doit) { 3921 return true; 3922 } 3923 didSomething = true; 3924 } 3925 N = providers.size(); 3926 for (i=0; i<N; i++) { 3927 removeDyingProviderLocked(null, providers.get(i), true); 3928 } 3929 3930 if (mIntentSenderRecords.size() > 0) { 3931 Iterator<WeakReference<PendingIntentRecord>> it 3932 = mIntentSenderRecords.values().iterator(); 3933 while (it.hasNext()) { 3934 WeakReference<PendingIntentRecord> wpir = it.next(); 3935 if (wpir == null) { 3936 it.remove(); 3937 continue; 3938 } 3939 PendingIntentRecord pir = wpir.get(); 3940 if (pir == null) { 3941 it.remove(); 3942 continue; 3943 } 3944 if (name == null) { 3945 // Stopping user, remove all objects for the user. 3946 if (pir.key.userId != userId) { 3947 // Not the same user, skip it. 3948 continue; 3949 } 3950 } else { 3951 if (UserHandle.getAppId(pir.uid) != appId) { 3952 // Different app id, skip it. 3953 continue; 3954 } 3955 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3956 // Different user, skip it. 3957 continue; 3958 } 3959 if (!pir.key.packageName.equals(name)) { 3960 // Different package, skip it. 3961 continue; 3962 } 3963 } 3964 if (!doit) { 3965 return true; 3966 } 3967 didSomething = true; 3968 it.remove(); 3969 pir.canceled = true; 3970 if (pir.key.activity != null) { 3971 pir.key.activity.pendingResults.remove(pir.ref); 3972 } 3973 } 3974 } 3975 3976 if (doit) { 3977 if (purgeCache && name != null) { 3978 AttributeCache ac = AttributeCache.instance(); 3979 if (ac != null) { 3980 ac.removePackage(name); 3981 } 3982 } 3983 if (mBooted) { 3984 mMainStack.resumeTopActivityLocked(null); 3985 mMainStack.scheduleIdleLocked(); 3986 } 3987 } 3988 3989 return didSomething; 3990 } 3991 3992 private final boolean removeProcessLocked(ProcessRecord app, 3993 boolean callerWillRestart, boolean allowRestart, String reason) { 3994 final String name = app.processName; 3995 final int uid = app.uid; 3996 if (DEBUG_PROCESSES) Slog.d( 3997 TAG, "Force removing proc " + app.toShortString() + " (" + name 3998 + "/" + uid + ")"); 3999 4000 mProcessNames.remove(name, uid); 4001 mIsolatedProcesses.remove(app.uid); 4002 if (mHeavyWeightProcess == app) { 4003 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4004 mHeavyWeightProcess.userId, 0)); 4005 mHeavyWeightProcess = null; 4006 } 4007 boolean needRestart = false; 4008 if (app.pid > 0 && app.pid != MY_PID) { 4009 int pid = app.pid; 4010 synchronized (mPidsSelfLocked) { 4011 mPidsSelfLocked.remove(pid); 4012 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4013 } 4014 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4015 handleAppDiedLocked(app, true, allowRestart); 4016 mLruProcesses.remove(app); 4017 Process.killProcessQuiet(pid); 4018 4019 if (app.persistent && !app.isolated) { 4020 if (!callerWillRestart) { 4021 addAppLocked(app.info, false); 4022 } else { 4023 needRestart = true; 4024 } 4025 } 4026 } else { 4027 mRemovedProcesses.add(app); 4028 } 4029 4030 return needRestart; 4031 } 4032 4033 private final void processStartTimedOutLocked(ProcessRecord app) { 4034 final int pid = app.pid; 4035 boolean gone = false; 4036 synchronized (mPidsSelfLocked) { 4037 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4038 if (knownApp != null && knownApp.thread == null) { 4039 mPidsSelfLocked.remove(pid); 4040 gone = true; 4041 } 4042 } 4043 4044 if (gone) { 4045 Slog.w(TAG, "Process " + app + " failed to attach"); 4046 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4047 pid, app.uid, app.processName); 4048 mProcessNames.remove(app.processName, app.uid); 4049 mIsolatedProcesses.remove(app.uid); 4050 if (mHeavyWeightProcess == app) { 4051 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4052 mHeavyWeightProcess.userId, 0)); 4053 mHeavyWeightProcess = null; 4054 } 4055 // Take care of any launching providers waiting for this process. 4056 checkAppInLaunchingProvidersLocked(app, true); 4057 // Take care of any services that are waiting for the process. 4058 mServices.processStartTimedOutLocked(app); 4059 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid, 4060 app.processName, app.setAdj, "start timeout"); 4061 Process.killProcessQuiet(pid); 4062 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4063 Slog.w(TAG, "Unattached app died before backup, skipping"); 4064 try { 4065 IBackupManager bm = IBackupManager.Stub.asInterface( 4066 ServiceManager.getService(Context.BACKUP_SERVICE)); 4067 bm.agentDisconnected(app.info.packageName); 4068 } catch (RemoteException e) { 4069 // Can't happen; the backup manager is local 4070 } 4071 } 4072 if (isPendingBroadcastProcessLocked(pid)) { 4073 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4074 skipPendingBroadcastLocked(pid); 4075 } 4076 } else { 4077 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4078 } 4079 } 4080 4081 private final boolean attachApplicationLocked(IApplicationThread thread, 4082 int pid) { 4083 4084 // Find the application record that is being attached... either via 4085 // the pid if we are running in multiple processes, or just pull the 4086 // next app record if we are emulating process with anonymous threads. 4087 ProcessRecord app; 4088 if (pid != MY_PID && pid >= 0) { 4089 synchronized (mPidsSelfLocked) { 4090 app = mPidsSelfLocked.get(pid); 4091 } 4092 } else { 4093 app = null; 4094 } 4095 4096 if (app == null) { 4097 Slog.w(TAG, "No pending application record for pid " + pid 4098 + " (IApplicationThread " + thread + "); dropping process"); 4099 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4100 if (pid > 0 && pid != MY_PID) { 4101 Process.killProcessQuiet(pid); 4102 } else { 4103 try { 4104 thread.scheduleExit(); 4105 } catch (Exception e) { 4106 // Ignore exceptions. 4107 } 4108 } 4109 return false; 4110 } 4111 4112 // If this application record is still attached to a previous 4113 // process, clean it up now. 4114 if (app.thread != null) { 4115 handleAppDiedLocked(app, true, true); 4116 } 4117 4118 // Tell the process all about itself. 4119 4120 if (localLOGV) Slog.v( 4121 TAG, "Binding process pid " + pid + " to record " + app); 4122 4123 String processName = app.processName; 4124 try { 4125 AppDeathRecipient adr = new AppDeathRecipient( 4126 app, pid, thread); 4127 thread.asBinder().linkToDeath(adr, 0); 4128 app.deathRecipient = adr; 4129 } catch (RemoteException e) { 4130 app.resetPackageList(); 4131 startProcessLocked(app, "link fail", processName); 4132 return false; 4133 } 4134 4135 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4136 4137 app.thread = thread; 4138 app.curAdj = app.setAdj = -100; 4139 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4140 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4141 app.forcingToForeground = null; 4142 app.foregroundServices = false; 4143 app.hasShownUi = false; 4144 app.debugging = false; 4145 4146 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4147 4148 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4149 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4150 4151 if (!normalMode) { 4152 Slog.i(TAG, "Launching preboot mode app: " + app); 4153 } 4154 4155 if (localLOGV) Slog.v( 4156 TAG, "New app record " + app 4157 + " thread=" + thread.asBinder() + " pid=" + pid); 4158 try { 4159 int testMode = IApplicationThread.DEBUG_OFF; 4160 if (mDebugApp != null && mDebugApp.equals(processName)) { 4161 testMode = mWaitForDebugger 4162 ? IApplicationThread.DEBUG_WAIT 4163 : IApplicationThread.DEBUG_ON; 4164 app.debugging = true; 4165 if (mDebugTransient) { 4166 mDebugApp = mOrigDebugApp; 4167 mWaitForDebugger = mOrigWaitForDebugger; 4168 } 4169 } 4170 String profileFile = app.instrumentationProfileFile; 4171 ParcelFileDescriptor profileFd = null; 4172 boolean profileAutoStop = false; 4173 if (mProfileApp != null && mProfileApp.equals(processName)) { 4174 mProfileProc = app; 4175 profileFile = mProfileFile; 4176 profileFd = mProfileFd; 4177 profileAutoStop = mAutoStopProfiler; 4178 } 4179 boolean enableOpenGlTrace = false; 4180 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4181 enableOpenGlTrace = true; 4182 mOpenGlTraceApp = null; 4183 } 4184 4185 // If the app is being launched for restore or full backup, set it up specially 4186 boolean isRestrictedBackupMode = false; 4187 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4188 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4189 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4190 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4191 } 4192 4193 ensurePackageDexOpt(app.instrumentationInfo != null 4194 ? app.instrumentationInfo.packageName 4195 : app.info.packageName); 4196 if (app.instrumentationClass != null) { 4197 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4198 } 4199 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4200 + processName + " with config " + mConfiguration); 4201 ApplicationInfo appInfo = app.instrumentationInfo != null 4202 ? app.instrumentationInfo : app.info; 4203 app.compat = compatibilityInfoForPackageLocked(appInfo); 4204 if (profileFd != null) { 4205 profileFd = profileFd.dup(); 4206 } 4207 thread.bindApplication(processName, appInfo, providers, 4208 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4209 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4210 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4211 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4212 mCoreSettingsObserver.getCoreSettingsLocked()); 4213 updateLruProcessLocked(app, false); 4214 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4215 } catch (Exception e) { 4216 // todo: Yikes! What should we do? For now we will try to 4217 // start another process, but that could easily get us in 4218 // an infinite loop of restarting processes... 4219 Slog.w(TAG, "Exception thrown during bind!", e); 4220 4221 app.resetPackageList(); 4222 app.unlinkDeathRecipient(); 4223 startProcessLocked(app, "bind fail", processName); 4224 return false; 4225 } 4226 4227 // Remove this record from the list of starting applications. 4228 mPersistentStartingProcesses.remove(app); 4229 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4230 "Attach application locked removing on hold: " + app); 4231 mProcessesOnHold.remove(app); 4232 4233 boolean badApp = false; 4234 boolean didSomething = false; 4235 4236 // See if the top visible activity is waiting to run in this process... 4237 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4238 if (hr != null && normalMode) { 4239 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4240 && processName.equals(hr.processName)) { 4241 try { 4242 if (mHeadless) { 4243 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4244 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4245 didSomething = true; 4246 } 4247 } catch (Exception e) { 4248 Slog.w(TAG, "Exception in new application when starting activity " 4249 + hr.intent.getComponent().flattenToShortString(), e); 4250 badApp = true; 4251 } 4252 } else { 4253 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4254 } 4255 } 4256 4257 // Find any services that should be running in this process... 4258 if (!badApp) { 4259 try { 4260 didSomething |= mServices.attachApplicationLocked(app, processName); 4261 } catch (Exception e) { 4262 badApp = true; 4263 } 4264 } 4265 4266 // Check if a next-broadcast receiver is in this process... 4267 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4268 try { 4269 didSomething = sendPendingBroadcastsLocked(app); 4270 } catch (Exception e) { 4271 // If the app died trying to launch the receiver we declare it 'bad' 4272 badApp = true; 4273 } 4274 } 4275 4276 // Check whether the next backup agent is in this process... 4277 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4278 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4279 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4280 try { 4281 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4282 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4283 mBackupTarget.backupMode); 4284 } catch (Exception e) { 4285 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4286 e.printStackTrace(); 4287 } 4288 } 4289 4290 if (badApp) { 4291 // todo: Also need to kill application to deal with all 4292 // kinds of exceptions. 4293 handleAppDiedLocked(app, false, true); 4294 return false; 4295 } 4296 4297 if (!didSomething) { 4298 updateOomAdjLocked(); 4299 } 4300 4301 return true; 4302 } 4303 4304 public final void attachApplication(IApplicationThread thread) { 4305 synchronized (this) { 4306 int callingPid = Binder.getCallingPid(); 4307 final long origId = Binder.clearCallingIdentity(); 4308 attachApplicationLocked(thread, callingPid); 4309 Binder.restoreCallingIdentity(origId); 4310 } 4311 } 4312 4313 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4314 final long origId = Binder.clearCallingIdentity(); 4315 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4316 if (stopProfiling) { 4317 synchronized (this) { 4318 if (mProfileProc == r.app) { 4319 if (mProfileFd != null) { 4320 try { 4321 mProfileFd.close(); 4322 } catch (IOException e) { 4323 } 4324 clearProfilerLocked(); 4325 } 4326 } 4327 } 4328 } 4329 Binder.restoreCallingIdentity(origId); 4330 } 4331 4332 void enableScreenAfterBoot() { 4333 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4334 SystemClock.uptimeMillis()); 4335 mWindowManager.enableScreenAfterBoot(); 4336 4337 synchronized (this) { 4338 updateEventDispatchingLocked(); 4339 } 4340 } 4341 4342 public void showBootMessage(final CharSequence msg, final boolean always) { 4343 enforceNotIsolatedCaller("showBootMessage"); 4344 mWindowManager.showBootMessage(msg, always); 4345 } 4346 4347 public void dismissKeyguardOnNextActivity() { 4348 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4349 final long token = Binder.clearCallingIdentity(); 4350 try { 4351 synchronized (this) { 4352 if (mLockScreenShown) { 4353 mLockScreenShown = false; 4354 comeOutOfSleepIfNeededLocked(); 4355 } 4356 mMainStack.dismissKeyguardOnNextActivityLocked(); 4357 } 4358 } finally { 4359 Binder.restoreCallingIdentity(token); 4360 } 4361 } 4362 4363 final void finishBooting() { 4364 IntentFilter pkgFilter = new IntentFilter(); 4365 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4366 pkgFilter.addDataScheme("package"); 4367 mContext.registerReceiver(new BroadcastReceiver() { 4368 @Override 4369 public void onReceive(Context context, Intent intent) { 4370 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4371 if (pkgs != null) { 4372 for (String pkg : pkgs) { 4373 synchronized (ActivityManagerService.this) { 4374 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4375 setResultCode(Activity.RESULT_OK); 4376 return; 4377 } 4378 } 4379 } 4380 } 4381 } 4382 }, pkgFilter); 4383 4384 synchronized (this) { 4385 // Ensure that any processes we had put on hold are now started 4386 // up. 4387 final int NP = mProcessesOnHold.size(); 4388 if (NP > 0) { 4389 ArrayList<ProcessRecord> procs = 4390 new ArrayList<ProcessRecord>(mProcessesOnHold); 4391 for (int ip=0; ip<NP; ip++) { 4392 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4393 + procs.get(ip)); 4394 startProcessLocked(procs.get(ip), "on-hold", null); 4395 } 4396 } 4397 4398 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4399 // Start looking for apps that are abusing wake locks. 4400 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4401 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4402 // Tell anyone interested that we are done booting! 4403 SystemProperties.set("sys.boot_completed", "1"); 4404 SystemProperties.set("dev.bootcomplete", "1"); 4405 for (int i=0; i<mStartedUsers.size(); i++) { 4406 UserStartedState uss = mStartedUsers.valueAt(i); 4407 if (uss.mState == UserStartedState.STATE_BOOTING) { 4408 uss.mState = UserStartedState.STATE_RUNNING; 4409 final int userId = mStartedUsers.keyAt(i); 4410 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4411 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4412 broadcastIntentLocked(null, null, intent, 4413 null, null, 0, null, null, 4414 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4415 false, false, MY_PID, Process.SYSTEM_UID, userId); 4416 } 4417 } 4418 } 4419 } 4420 } 4421 4422 final void ensureBootCompleted() { 4423 boolean booting; 4424 boolean enableScreen; 4425 synchronized (this) { 4426 booting = mBooting; 4427 mBooting = false; 4428 enableScreen = !mBooted; 4429 mBooted = true; 4430 } 4431 4432 if (booting) { 4433 finishBooting(); 4434 } 4435 4436 if (enableScreen) { 4437 enableScreenAfterBoot(); 4438 } 4439 } 4440 4441 public final void activityResumed(IBinder token) { 4442 final long origId = Binder.clearCallingIdentity(); 4443 mMainStack.activityResumed(token); 4444 Binder.restoreCallingIdentity(origId); 4445 } 4446 4447 public final void activityPaused(IBinder token) { 4448 final long origId = Binder.clearCallingIdentity(); 4449 mMainStack.activityPaused(token, false); 4450 Binder.restoreCallingIdentity(origId); 4451 } 4452 4453 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4454 CharSequence description) { 4455 if (localLOGV) Slog.v( 4456 TAG, "Activity stopped: token=" + token); 4457 4458 // Refuse possible leaked file descriptors 4459 if (icicle != null && icicle.hasFileDescriptors()) { 4460 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4461 } 4462 4463 ActivityRecord r = null; 4464 4465 final long origId = Binder.clearCallingIdentity(); 4466 4467 synchronized (this) { 4468 r = mMainStack.isInStackLocked(token); 4469 if (r != null) { 4470 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4471 } 4472 } 4473 4474 if (r != null) { 4475 sendPendingThumbnail(r, null, null, null, false); 4476 } 4477 4478 trimApplications(); 4479 4480 Binder.restoreCallingIdentity(origId); 4481 } 4482 4483 public final void activityDestroyed(IBinder token) { 4484 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4485 mMainStack.activityDestroyed(token); 4486 } 4487 4488 public String getCallingPackage(IBinder token) { 4489 synchronized (this) { 4490 ActivityRecord r = getCallingRecordLocked(token); 4491 return r != null && r.app != null ? r.info.packageName : null; 4492 } 4493 } 4494 4495 public ComponentName getCallingActivity(IBinder token) { 4496 synchronized (this) { 4497 ActivityRecord r = getCallingRecordLocked(token); 4498 return r != null ? r.intent.getComponent() : null; 4499 } 4500 } 4501 4502 private ActivityRecord getCallingRecordLocked(IBinder token) { 4503 ActivityRecord r = mMainStack.isInStackLocked(token); 4504 if (r == null) { 4505 return null; 4506 } 4507 return r.resultTo; 4508 } 4509 4510 public ComponentName getActivityClassForToken(IBinder token) { 4511 synchronized(this) { 4512 ActivityRecord r = mMainStack.isInStackLocked(token); 4513 if (r == null) { 4514 return null; 4515 } 4516 return r.intent.getComponent(); 4517 } 4518 } 4519 4520 public String getPackageForToken(IBinder token) { 4521 synchronized(this) { 4522 ActivityRecord r = mMainStack.isInStackLocked(token); 4523 if (r == null) { 4524 return null; 4525 } 4526 return r.packageName; 4527 } 4528 } 4529 4530 public IIntentSender getIntentSender(int type, 4531 String packageName, IBinder token, String resultWho, 4532 int requestCode, Intent[] intents, String[] resolvedTypes, 4533 int flags, Bundle options, int userId) { 4534 enforceNotIsolatedCaller("getIntentSender"); 4535 // Refuse possible leaked file descriptors 4536 if (intents != null) { 4537 if (intents.length < 1) { 4538 throw new IllegalArgumentException("Intents array length must be >= 1"); 4539 } 4540 for (int i=0; i<intents.length; i++) { 4541 Intent intent = intents[i]; 4542 if (intent != null) { 4543 if (intent.hasFileDescriptors()) { 4544 throw new IllegalArgumentException("File descriptors passed in Intent"); 4545 } 4546 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4547 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4548 throw new IllegalArgumentException( 4549 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4550 } 4551 intents[i] = new Intent(intent); 4552 } 4553 } 4554 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4555 throw new IllegalArgumentException( 4556 "Intent array length does not match resolvedTypes length"); 4557 } 4558 } 4559 if (options != null) { 4560 if (options.hasFileDescriptors()) { 4561 throw new IllegalArgumentException("File descriptors passed in options"); 4562 } 4563 } 4564 4565 synchronized(this) { 4566 int callingUid = Binder.getCallingUid(); 4567 int origUserId = userId; 4568 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 4569 type == ActivityManager.INTENT_SENDER_BROADCAST, true, 4570 "getIntentSender", null); 4571 if (origUserId == UserHandle.USER_CURRENT) { 4572 // We don't want to evaluate this until the pending intent is 4573 // actually executed. However, we do want to always do the 4574 // security checking for it above. 4575 userId = UserHandle.USER_CURRENT; 4576 } 4577 try { 4578 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4579 int uid = AppGlobals.getPackageManager() 4580 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4581 if (!UserHandle.isSameApp(callingUid, uid)) { 4582 String msg = "Permission Denial: getIntentSender() from pid=" 4583 + Binder.getCallingPid() 4584 + ", uid=" + Binder.getCallingUid() 4585 + ", (need uid=" + uid + ")" 4586 + " is not allowed to send as package " + packageName; 4587 Slog.w(TAG, msg); 4588 throw new SecurityException(msg); 4589 } 4590 } 4591 4592 return getIntentSenderLocked(type, packageName, callingUid, userId, 4593 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4594 4595 } catch (RemoteException e) { 4596 throw new SecurityException(e); 4597 } 4598 } 4599 } 4600 4601 IIntentSender getIntentSenderLocked(int type, String packageName, 4602 int callingUid, int userId, IBinder token, String resultWho, 4603 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4604 Bundle options) { 4605 if (DEBUG_MU) 4606 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4607 ActivityRecord activity = null; 4608 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4609 activity = mMainStack.isInStackLocked(token); 4610 if (activity == null) { 4611 return null; 4612 } 4613 if (activity.finishing) { 4614 return null; 4615 } 4616 } 4617 4618 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4619 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4620 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4621 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4622 |PendingIntent.FLAG_UPDATE_CURRENT); 4623 4624 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4625 type, packageName, activity, resultWho, 4626 requestCode, intents, resolvedTypes, flags, options, userId); 4627 WeakReference<PendingIntentRecord> ref; 4628 ref = mIntentSenderRecords.get(key); 4629 PendingIntentRecord rec = ref != null ? ref.get() : null; 4630 if (rec != null) { 4631 if (!cancelCurrent) { 4632 if (updateCurrent) { 4633 if (rec.key.requestIntent != null) { 4634 rec.key.requestIntent.replaceExtras(intents != null ? 4635 intents[intents.length - 1] : null); 4636 } 4637 if (intents != null) { 4638 intents[intents.length-1] = rec.key.requestIntent; 4639 rec.key.allIntents = intents; 4640 rec.key.allResolvedTypes = resolvedTypes; 4641 } else { 4642 rec.key.allIntents = null; 4643 rec.key.allResolvedTypes = null; 4644 } 4645 } 4646 return rec; 4647 } 4648 rec.canceled = true; 4649 mIntentSenderRecords.remove(key); 4650 } 4651 if (noCreate) { 4652 return rec; 4653 } 4654 rec = new PendingIntentRecord(this, key, callingUid); 4655 mIntentSenderRecords.put(key, rec.ref); 4656 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4657 if (activity.pendingResults == null) { 4658 activity.pendingResults 4659 = new HashSet<WeakReference<PendingIntentRecord>>(); 4660 } 4661 activity.pendingResults.add(rec.ref); 4662 } 4663 return rec; 4664 } 4665 4666 public void cancelIntentSender(IIntentSender sender) { 4667 if (!(sender instanceof PendingIntentRecord)) { 4668 return; 4669 } 4670 synchronized(this) { 4671 PendingIntentRecord rec = (PendingIntentRecord)sender; 4672 try { 4673 int uid = AppGlobals.getPackageManager() 4674 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4675 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4676 String msg = "Permission Denial: cancelIntentSender() from pid=" 4677 + Binder.getCallingPid() 4678 + ", uid=" + Binder.getCallingUid() 4679 + " is not allowed to cancel packges " 4680 + rec.key.packageName; 4681 Slog.w(TAG, msg); 4682 throw new SecurityException(msg); 4683 } 4684 } catch (RemoteException e) { 4685 throw new SecurityException(e); 4686 } 4687 cancelIntentSenderLocked(rec, true); 4688 } 4689 } 4690 4691 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4692 rec.canceled = true; 4693 mIntentSenderRecords.remove(rec.key); 4694 if (cleanActivity && rec.key.activity != null) { 4695 rec.key.activity.pendingResults.remove(rec.ref); 4696 } 4697 } 4698 4699 public String getPackageForIntentSender(IIntentSender pendingResult) { 4700 if (!(pendingResult instanceof PendingIntentRecord)) { 4701 return null; 4702 } 4703 try { 4704 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4705 return res.key.packageName; 4706 } catch (ClassCastException e) { 4707 } 4708 return null; 4709 } 4710 4711 public int getUidForIntentSender(IIntentSender sender) { 4712 if (sender instanceof PendingIntentRecord) { 4713 try { 4714 PendingIntentRecord res = (PendingIntentRecord)sender; 4715 return res.uid; 4716 } catch (ClassCastException e) { 4717 } 4718 } 4719 return -1; 4720 } 4721 4722 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4723 if (!(pendingResult instanceof PendingIntentRecord)) { 4724 return false; 4725 } 4726 try { 4727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4728 if (res.key.allIntents == null) { 4729 return false; 4730 } 4731 for (int i=0; i<res.key.allIntents.length; i++) { 4732 Intent intent = res.key.allIntents[i]; 4733 if (intent.getPackage() != null && intent.getComponent() != null) { 4734 return false; 4735 } 4736 } 4737 return true; 4738 } catch (ClassCastException e) { 4739 } 4740 return false; 4741 } 4742 4743 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4744 if (!(pendingResult instanceof PendingIntentRecord)) { 4745 return false; 4746 } 4747 try { 4748 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4749 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4750 return true; 4751 } 4752 return false; 4753 } catch (ClassCastException e) { 4754 } 4755 return false; 4756 } 4757 4758 public void setProcessLimit(int max) { 4759 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4760 "setProcessLimit()"); 4761 synchronized (this) { 4762 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4763 mProcessLimitOverride = max; 4764 } 4765 trimApplications(); 4766 } 4767 4768 public int getProcessLimit() { 4769 synchronized (this) { 4770 return mProcessLimitOverride; 4771 } 4772 } 4773 4774 void foregroundTokenDied(ForegroundToken token) { 4775 synchronized (ActivityManagerService.this) { 4776 synchronized (mPidsSelfLocked) { 4777 ForegroundToken cur 4778 = mForegroundProcesses.get(token.pid); 4779 if (cur != token) { 4780 return; 4781 } 4782 mForegroundProcesses.remove(token.pid); 4783 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4784 if (pr == null) { 4785 return; 4786 } 4787 pr.forcingToForeground = null; 4788 pr.foregroundServices = false; 4789 } 4790 updateOomAdjLocked(); 4791 } 4792 } 4793 4794 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4795 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4796 "setProcessForeground()"); 4797 synchronized(this) { 4798 boolean changed = false; 4799 4800 synchronized (mPidsSelfLocked) { 4801 ProcessRecord pr = mPidsSelfLocked.get(pid); 4802 if (pr == null && isForeground) { 4803 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4804 return; 4805 } 4806 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4807 if (oldToken != null) { 4808 oldToken.token.unlinkToDeath(oldToken, 0); 4809 mForegroundProcesses.remove(pid); 4810 if (pr != null) { 4811 pr.forcingToForeground = null; 4812 } 4813 changed = true; 4814 } 4815 if (isForeground && token != null) { 4816 ForegroundToken newToken = new ForegroundToken() { 4817 public void binderDied() { 4818 foregroundTokenDied(this); 4819 } 4820 }; 4821 newToken.pid = pid; 4822 newToken.token = token; 4823 try { 4824 token.linkToDeath(newToken, 0); 4825 mForegroundProcesses.put(pid, newToken); 4826 pr.forcingToForeground = token; 4827 changed = true; 4828 } catch (RemoteException e) { 4829 // If the process died while doing this, we will later 4830 // do the cleanup with the process death link. 4831 } 4832 } 4833 } 4834 4835 if (changed) { 4836 updateOomAdjLocked(); 4837 } 4838 } 4839 } 4840 4841 // ========================================================= 4842 // PERMISSIONS 4843 // ========================================================= 4844 4845 static class PermissionController extends IPermissionController.Stub { 4846 ActivityManagerService mActivityManagerService; 4847 PermissionController(ActivityManagerService activityManagerService) { 4848 mActivityManagerService = activityManagerService; 4849 } 4850 4851 public boolean checkPermission(String permission, int pid, int uid) { 4852 return mActivityManagerService.checkPermission(permission, pid, 4853 uid) == PackageManager.PERMISSION_GRANTED; 4854 } 4855 } 4856 4857 /** 4858 * This can be called with or without the global lock held. 4859 */ 4860 int checkComponentPermission(String permission, int pid, int uid, 4861 int owningUid, boolean exported) { 4862 // We might be performing an operation on behalf of an indirect binder 4863 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4864 // client identity accordingly before proceeding. 4865 Identity tlsIdentity = sCallerIdentity.get(); 4866 if (tlsIdentity != null) { 4867 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4868 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4869 uid = tlsIdentity.uid; 4870 pid = tlsIdentity.pid; 4871 } 4872 4873 if (pid == MY_PID) { 4874 return PackageManager.PERMISSION_GRANTED; 4875 } 4876 4877 return ActivityManager.checkComponentPermission(permission, uid, 4878 owningUid, exported); 4879 } 4880 4881 /** 4882 * As the only public entry point for permissions checking, this method 4883 * can enforce the semantic that requesting a check on a null global 4884 * permission is automatically denied. (Internally a null permission 4885 * string is used when calling {@link #checkComponentPermission} in cases 4886 * when only uid-based security is needed.) 4887 * 4888 * This can be called with or without the global lock held. 4889 */ 4890 public int checkPermission(String permission, int pid, int uid) { 4891 if (permission == null) { 4892 return PackageManager.PERMISSION_DENIED; 4893 } 4894 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4895 } 4896 4897 /** 4898 * Binder IPC calls go through the public entry point. 4899 * This can be called with or without the global lock held. 4900 */ 4901 int checkCallingPermission(String permission) { 4902 return checkPermission(permission, 4903 Binder.getCallingPid(), 4904 UserHandle.getAppId(Binder.getCallingUid())); 4905 } 4906 4907 /** 4908 * This can be called with or without the global lock held. 4909 */ 4910 void enforceCallingPermission(String permission, String func) { 4911 if (checkCallingPermission(permission) 4912 == PackageManager.PERMISSION_GRANTED) { 4913 return; 4914 } 4915 4916 String msg = "Permission Denial: " + func + " from pid=" 4917 + Binder.getCallingPid() 4918 + ", uid=" + Binder.getCallingUid() 4919 + " requires " + permission; 4920 Slog.w(TAG, msg); 4921 throw new SecurityException(msg); 4922 } 4923 4924 /** 4925 * Determine if UID is holding permissions required to access {@link Uri} in 4926 * the given {@link ProviderInfo}. Final permission checking is always done 4927 * in {@link ContentProvider}. 4928 */ 4929 private final boolean checkHoldingPermissionsLocked( 4930 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4931 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4932 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4933 4934 if (pi.applicationInfo.uid == uid) { 4935 return true; 4936 } else if (!pi.exported) { 4937 return false; 4938 } 4939 4940 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4941 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4942 try { 4943 // check if target holds top-level <provider> permissions 4944 if (!readMet && pi.readPermission != null 4945 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4946 readMet = true; 4947 } 4948 if (!writeMet && pi.writePermission != null 4949 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4950 writeMet = true; 4951 } 4952 4953 // track if unprotected read/write is allowed; any denied 4954 // <path-permission> below removes this ability 4955 boolean allowDefaultRead = pi.readPermission == null; 4956 boolean allowDefaultWrite = pi.writePermission == null; 4957 4958 // check if target holds any <path-permission> that match uri 4959 final PathPermission[] pps = pi.pathPermissions; 4960 if (pps != null) { 4961 final String path = uri.getPath(); 4962 int i = pps.length; 4963 while (i > 0 && (!readMet || !writeMet)) { 4964 i--; 4965 PathPermission pp = pps[i]; 4966 if (pp.match(path)) { 4967 if (!readMet) { 4968 final String pprperm = pp.getReadPermission(); 4969 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4970 + pprperm + " for " + pp.getPath() 4971 + ": match=" + pp.match(path) 4972 + " check=" + pm.checkUidPermission(pprperm, uid)); 4973 if (pprperm != null) { 4974 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4975 readMet = true; 4976 } else { 4977 allowDefaultRead = false; 4978 } 4979 } 4980 } 4981 if (!writeMet) { 4982 final String ppwperm = pp.getWritePermission(); 4983 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4984 + ppwperm + " for " + pp.getPath() 4985 + ": match=" + pp.match(path) 4986 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4987 if (ppwperm != null) { 4988 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4989 writeMet = true; 4990 } else { 4991 allowDefaultWrite = false; 4992 } 4993 } 4994 } 4995 } 4996 } 4997 } 4998 4999 // grant unprotected <provider> read/write, if not blocked by 5000 // <path-permission> above 5001 if (allowDefaultRead) readMet = true; 5002 if (allowDefaultWrite) writeMet = true; 5003 5004 } catch (RemoteException e) { 5005 return false; 5006 } 5007 5008 return readMet && writeMet; 5009 } 5010 5011 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5012 int modeFlags) { 5013 // Root gets to do everything. 5014 if (uid == 0) { 5015 return true; 5016 } 5017 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5018 if (perms == null) return false; 5019 UriPermission perm = perms.get(uri); 5020 if (perm == null) return false; 5021 return (modeFlags&perm.modeFlags) == modeFlags; 5022 } 5023 5024 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5025 enforceNotIsolatedCaller("checkUriPermission"); 5026 5027 // Another redirected-binder-call permissions check as in 5028 // {@link checkComponentPermission}. 5029 Identity tlsIdentity = sCallerIdentity.get(); 5030 if (tlsIdentity != null) { 5031 uid = tlsIdentity.uid; 5032 pid = tlsIdentity.pid; 5033 } 5034 5035 // Our own process gets to do everything. 5036 if (pid == MY_PID) { 5037 return PackageManager.PERMISSION_GRANTED; 5038 } 5039 synchronized(this) { 5040 return checkUriPermissionLocked(uri, uid, modeFlags) 5041 ? PackageManager.PERMISSION_GRANTED 5042 : PackageManager.PERMISSION_DENIED; 5043 } 5044 } 5045 5046 /** 5047 * Check if the targetPkg can be granted permission to access uri by 5048 * the callingUid using the given modeFlags. Throws a security exception 5049 * if callingUid is not allowed to do this. Returns the uid of the target 5050 * if the URI permission grant should be performed; returns -1 if it is not 5051 * needed (for example targetPkg already has permission to access the URI). 5052 * If you already know the uid of the target, you can supply it in 5053 * lastTargetUid else set that to -1. 5054 */ 5055 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5056 Uri uri, int modeFlags, int lastTargetUid) { 5057 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5058 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5059 if (modeFlags == 0) { 5060 return -1; 5061 } 5062 5063 if (targetPkg != null) { 5064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5065 "Checking grant " + targetPkg + " permission to " + uri); 5066 } 5067 5068 final IPackageManager pm = AppGlobals.getPackageManager(); 5069 5070 // If this is not a content: uri, we can't do anything with it. 5071 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5072 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5073 "Can't grant URI permission for non-content URI: " + uri); 5074 return -1; 5075 } 5076 5077 String name = uri.getAuthority(); 5078 ProviderInfo pi = null; 5079 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5080 UserHandle.getUserId(callingUid)); 5081 if (cpr != null) { 5082 pi = cpr.info; 5083 } else { 5084 try { 5085 pi = pm.resolveContentProvider(name, 5086 PackageManager.GET_URI_PERMISSION_PATTERNS, 5087 UserHandle.getUserId(callingUid)); 5088 } catch (RemoteException ex) { 5089 } 5090 } 5091 if (pi == null) { 5092 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5093 return -1; 5094 } 5095 5096 int targetUid = lastTargetUid; 5097 if (targetUid < 0 && targetPkg != null) { 5098 try { 5099 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5100 if (targetUid < 0) { 5101 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5102 "Can't grant URI permission no uid for: " + targetPkg); 5103 return -1; 5104 } 5105 } catch (RemoteException ex) { 5106 return -1; 5107 } 5108 } 5109 5110 if (targetUid >= 0) { 5111 // First... does the target actually need this permission? 5112 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5113 // No need to grant the target this permission. 5114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5115 "Target " + targetPkg + " already has full permission to " + uri); 5116 return -1; 5117 } 5118 } else { 5119 // First... there is no target package, so can anyone access it? 5120 boolean allowed = pi.exported; 5121 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5122 if (pi.readPermission != null) { 5123 allowed = false; 5124 } 5125 } 5126 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5127 if (pi.writePermission != null) { 5128 allowed = false; 5129 } 5130 } 5131 if (allowed) { 5132 return -1; 5133 } 5134 } 5135 5136 // Second... is the provider allowing granting of URI permissions? 5137 if (!pi.grantUriPermissions) { 5138 throw new SecurityException("Provider " + pi.packageName 5139 + "/" + pi.name 5140 + " does not allow granting of Uri permissions (uri " 5141 + uri + ")"); 5142 } 5143 if (pi.uriPermissionPatterns != null) { 5144 final int N = pi.uriPermissionPatterns.length; 5145 boolean allowed = false; 5146 for (int i=0; i<N; i++) { 5147 if (pi.uriPermissionPatterns[i] != null 5148 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5149 allowed = true; 5150 break; 5151 } 5152 } 5153 if (!allowed) { 5154 throw new SecurityException("Provider " + pi.packageName 5155 + "/" + pi.name 5156 + " does not allow granting of permission to path of Uri " 5157 + uri); 5158 } 5159 } 5160 5161 // Third... does the caller itself have permission to access 5162 // this uri? 5163 if (callingUid != Process.myUid()) { 5164 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5165 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5166 throw new SecurityException("Uid " + callingUid 5167 + " does not have permission to uri " + uri); 5168 } 5169 } 5170 } 5171 5172 return targetUid; 5173 } 5174 5175 public int checkGrantUriPermission(int callingUid, String targetPkg, 5176 Uri uri, int modeFlags) { 5177 enforceNotIsolatedCaller("checkGrantUriPermission"); 5178 synchronized(this) { 5179 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5180 } 5181 } 5182 5183 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5184 Uri uri, int modeFlags, UriPermissionOwner owner) { 5185 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5186 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5187 if (modeFlags == 0) { 5188 return; 5189 } 5190 5191 // So here we are: the caller has the assumed permission 5192 // to the uri, and the target doesn't. Let's now give this to 5193 // the target. 5194 5195 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5196 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5197 5198 HashMap<Uri, UriPermission> targetUris 5199 = mGrantedUriPermissions.get(targetUid); 5200 if (targetUris == null) { 5201 targetUris = new HashMap<Uri, UriPermission>(); 5202 mGrantedUriPermissions.put(targetUid, targetUris); 5203 } 5204 5205 UriPermission perm = targetUris.get(uri); 5206 if (perm == null) { 5207 perm = new UriPermission(targetUid, uri); 5208 targetUris.put(uri, perm); 5209 } 5210 5211 perm.modeFlags |= modeFlags; 5212 if (owner == null) { 5213 perm.globalModeFlags |= modeFlags; 5214 } else { 5215 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5216 perm.readOwners.add(owner); 5217 owner.addReadPermission(perm); 5218 } 5219 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5220 perm.writeOwners.add(owner); 5221 owner.addWritePermission(perm); 5222 } 5223 } 5224 } 5225 5226 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5227 int modeFlags, UriPermissionOwner owner) { 5228 if (targetPkg == null) { 5229 throw new NullPointerException("targetPkg"); 5230 } 5231 5232 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5233 if (targetUid < 0) { 5234 return; 5235 } 5236 5237 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5238 } 5239 5240 static class NeededUriGrants extends ArrayList<Uri> { 5241 final String targetPkg; 5242 final int targetUid; 5243 final int flags; 5244 5245 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5246 targetPkg = _targetPkg; 5247 targetUid = _targetUid; 5248 flags = _flags; 5249 } 5250 } 5251 5252 /** 5253 * Like checkGrantUriPermissionLocked, but takes an Intent. 5254 */ 5255 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5256 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5257 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5258 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5259 + " clip=" + (intent != null ? intent.getClipData() : null) 5260 + " from " + intent + "; flags=0x" 5261 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5262 5263 if (targetPkg == null) { 5264 throw new NullPointerException("targetPkg"); 5265 } 5266 5267 if (intent == null) { 5268 return null; 5269 } 5270 Uri data = intent.getData(); 5271 ClipData clip = intent.getClipData(); 5272 if (data == null && clip == null) { 5273 return null; 5274 } 5275 if (data != null) { 5276 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5277 mode, needed != null ? needed.targetUid : -1); 5278 if (target > 0) { 5279 if (needed == null) { 5280 needed = new NeededUriGrants(targetPkg, target, mode); 5281 } 5282 needed.add(data); 5283 } 5284 } 5285 if (clip != null) { 5286 for (int i=0; i<clip.getItemCount(); i++) { 5287 Uri uri = clip.getItemAt(i).getUri(); 5288 if (uri != null) { 5289 int target = -1; 5290 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5291 mode, needed != null ? needed.targetUid : -1); 5292 if (target > 0) { 5293 if (needed == null) { 5294 needed = new NeededUriGrants(targetPkg, target, mode); 5295 } 5296 needed.add(uri); 5297 } 5298 } else { 5299 Intent clipIntent = clip.getItemAt(i).getIntent(); 5300 if (clipIntent != null) { 5301 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5302 callingUid, targetPkg, clipIntent, mode, needed); 5303 if (newNeeded != null) { 5304 needed = newNeeded; 5305 } 5306 } 5307 } 5308 } 5309 } 5310 5311 return needed; 5312 } 5313 5314 /** 5315 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5316 */ 5317 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5318 UriPermissionOwner owner) { 5319 if (needed != null) { 5320 for (int i=0; i<needed.size(); i++) { 5321 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5322 needed.get(i), needed.flags, owner); 5323 } 5324 } 5325 } 5326 5327 void grantUriPermissionFromIntentLocked(int callingUid, 5328 String targetPkg, Intent intent, UriPermissionOwner owner) { 5329 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5330 intent, intent != null ? intent.getFlags() : 0, null); 5331 if (needed == null) { 5332 return; 5333 } 5334 5335 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5336 } 5337 5338 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5339 Uri uri, int modeFlags) { 5340 enforceNotIsolatedCaller("grantUriPermission"); 5341 synchronized(this) { 5342 final ProcessRecord r = getRecordForAppLocked(caller); 5343 if (r == null) { 5344 throw new SecurityException("Unable to find app for caller " 5345 + caller 5346 + " when granting permission to uri " + uri); 5347 } 5348 if (targetPkg == null) { 5349 throw new IllegalArgumentException("null target"); 5350 } 5351 if (uri == null) { 5352 throw new IllegalArgumentException("null uri"); 5353 } 5354 5355 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5356 null); 5357 } 5358 } 5359 5360 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5361 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5362 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5363 HashMap<Uri, UriPermission> perms 5364 = mGrantedUriPermissions.get(perm.uid); 5365 if (perms != null) { 5366 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5367 "Removing " + perm.uid + " permission to " + perm.uri); 5368 perms.remove(perm.uri); 5369 if (perms.size() == 0) { 5370 mGrantedUriPermissions.remove(perm.uid); 5371 } 5372 } 5373 } 5374 } 5375 5376 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5377 int modeFlags) { 5378 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5379 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5380 if (modeFlags == 0) { 5381 return; 5382 } 5383 5384 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5385 "Revoking all granted permissions to " + uri); 5386 5387 final IPackageManager pm = AppGlobals.getPackageManager(); 5388 5389 final String authority = uri.getAuthority(); 5390 ProviderInfo pi = null; 5391 int userId = UserHandle.getUserId(callingUid); 5392 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5393 if (cpr != null) { 5394 pi = cpr.info; 5395 } else { 5396 try { 5397 pi = pm.resolveContentProvider(authority, 5398 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5399 } catch (RemoteException ex) { 5400 } 5401 } 5402 if (pi == null) { 5403 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5404 return; 5405 } 5406 5407 // Does the caller have this permission on the URI? 5408 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5409 // Right now, if you are not the original owner of the permission, 5410 // you are not allowed to revoke it. 5411 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5412 throw new SecurityException("Uid " + callingUid 5413 + " does not have permission to uri " + uri); 5414 //} 5415 } 5416 5417 // Go through all of the permissions and remove any that match. 5418 final List<String> SEGMENTS = uri.getPathSegments(); 5419 if (SEGMENTS != null) { 5420 final int NS = SEGMENTS.size(); 5421 int N = mGrantedUriPermissions.size(); 5422 for (int i=0; i<N; i++) { 5423 HashMap<Uri, UriPermission> perms 5424 = mGrantedUriPermissions.valueAt(i); 5425 Iterator<UriPermission> it = perms.values().iterator(); 5426 toploop: 5427 while (it.hasNext()) { 5428 UriPermission perm = it.next(); 5429 Uri targetUri = perm.uri; 5430 if (!authority.equals(targetUri.getAuthority())) { 5431 continue; 5432 } 5433 List<String> targetSegments = targetUri.getPathSegments(); 5434 if (targetSegments == null) { 5435 continue; 5436 } 5437 if (targetSegments.size() < NS) { 5438 continue; 5439 } 5440 for (int j=0; j<NS; j++) { 5441 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5442 continue toploop; 5443 } 5444 } 5445 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5446 "Revoking " + perm.uid + " permission to " + perm.uri); 5447 perm.clearModes(modeFlags); 5448 if (perm.modeFlags == 0) { 5449 it.remove(); 5450 } 5451 } 5452 if (perms.size() == 0) { 5453 mGrantedUriPermissions.remove( 5454 mGrantedUriPermissions.keyAt(i)); 5455 N--; 5456 i--; 5457 } 5458 } 5459 } 5460 } 5461 5462 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5463 int modeFlags) { 5464 enforceNotIsolatedCaller("revokeUriPermission"); 5465 synchronized(this) { 5466 final ProcessRecord r = getRecordForAppLocked(caller); 5467 if (r == null) { 5468 throw new SecurityException("Unable to find app for caller " 5469 + caller 5470 + " when revoking permission to uri " + uri); 5471 } 5472 if (uri == null) { 5473 Slog.w(TAG, "revokeUriPermission: null uri"); 5474 return; 5475 } 5476 5477 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5478 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5479 if (modeFlags == 0) { 5480 return; 5481 } 5482 5483 final IPackageManager pm = AppGlobals.getPackageManager(); 5484 5485 final String authority = uri.getAuthority(); 5486 ProviderInfo pi = null; 5487 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5488 if (cpr != null) { 5489 pi = cpr.info; 5490 } else { 5491 try { 5492 pi = pm.resolveContentProvider(authority, 5493 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5494 } catch (RemoteException ex) { 5495 } 5496 } 5497 if (pi == null) { 5498 Slog.w(TAG, "No content provider found for permission revoke: " 5499 + uri.toSafeString()); 5500 return; 5501 } 5502 5503 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5504 } 5505 } 5506 5507 @Override 5508 public IBinder newUriPermissionOwner(String name) { 5509 enforceNotIsolatedCaller("newUriPermissionOwner"); 5510 synchronized(this) { 5511 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5512 return owner.getExternalTokenLocked(); 5513 } 5514 } 5515 5516 @Override 5517 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5518 Uri uri, int modeFlags) { 5519 synchronized(this) { 5520 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5521 if (owner == null) { 5522 throw new IllegalArgumentException("Unknown owner: " + token); 5523 } 5524 if (fromUid != Binder.getCallingUid()) { 5525 if (Binder.getCallingUid() != Process.myUid()) { 5526 // Only system code can grant URI permissions on behalf 5527 // of other users. 5528 throw new SecurityException("nice try"); 5529 } 5530 } 5531 if (targetPkg == null) { 5532 throw new IllegalArgumentException("null target"); 5533 } 5534 if (uri == null) { 5535 throw new IllegalArgumentException("null uri"); 5536 } 5537 5538 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5539 } 5540 } 5541 5542 @Override 5543 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5544 synchronized(this) { 5545 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5546 if (owner == null) { 5547 throw new IllegalArgumentException("Unknown owner: " + token); 5548 } 5549 5550 if (uri == null) { 5551 owner.removeUriPermissionsLocked(mode); 5552 } else { 5553 owner.removeUriPermissionLocked(uri, mode); 5554 } 5555 } 5556 } 5557 5558 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5559 synchronized (this) { 5560 ProcessRecord app = 5561 who != null ? getRecordForAppLocked(who) : null; 5562 if (app == null) return; 5563 5564 Message msg = Message.obtain(); 5565 msg.what = WAIT_FOR_DEBUGGER_MSG; 5566 msg.obj = app; 5567 msg.arg1 = waiting ? 1 : 0; 5568 mHandler.sendMessage(msg); 5569 } 5570 } 5571 5572 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5573 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5574 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5575 outInfo.availMem = Process.getFreeMemory(); 5576 outInfo.totalMem = Process.getTotalMemory(); 5577 outInfo.threshold = homeAppMem; 5578 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5579 outInfo.hiddenAppThreshold = hiddenAppMem; 5580 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5581 ProcessList.SERVICE_ADJ); 5582 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5583 ProcessList.VISIBLE_APP_ADJ); 5584 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5585 ProcessList.FOREGROUND_APP_ADJ); 5586 } 5587 5588 // ========================================================= 5589 // TASK MANAGEMENT 5590 // ========================================================= 5591 5592 public List getTasks(int maxNum, int flags, 5593 IThumbnailReceiver receiver) { 5594 ArrayList list = new ArrayList(); 5595 5596 PendingThumbnailsRecord pending = null; 5597 IApplicationThread topThumbnail = null; 5598 ActivityRecord topRecord = null; 5599 5600 synchronized(this) { 5601 if (localLOGV) Slog.v( 5602 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5603 + ", receiver=" + receiver); 5604 5605 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5606 != PackageManager.PERMISSION_GRANTED) { 5607 if (receiver != null) { 5608 // If the caller wants to wait for pending thumbnails, 5609 // it ain't gonna get them. 5610 try { 5611 receiver.finished(); 5612 } catch (RemoteException ex) { 5613 } 5614 } 5615 String msg = "Permission Denial: getTasks() from pid=" 5616 + Binder.getCallingPid() 5617 + ", uid=" + Binder.getCallingUid() 5618 + " requires " + android.Manifest.permission.GET_TASKS; 5619 Slog.w(TAG, msg); 5620 throw new SecurityException(msg); 5621 } 5622 5623 int pos = mMainStack.mHistory.size()-1; 5624 ActivityRecord next = 5625 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5626 ActivityRecord top = null; 5627 TaskRecord curTask = null; 5628 int numActivities = 0; 5629 int numRunning = 0; 5630 while (pos >= 0 && maxNum > 0) { 5631 final ActivityRecord r = next; 5632 pos--; 5633 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5634 5635 // Initialize state for next task if needed. 5636 if (top == null || 5637 (top.state == ActivityState.INITIALIZING 5638 && top.task == r.task)) { 5639 top = r; 5640 curTask = r.task; 5641 numActivities = numRunning = 0; 5642 } 5643 5644 // Add 'r' into the current task. 5645 numActivities++; 5646 if (r.app != null && r.app.thread != null) { 5647 numRunning++; 5648 } 5649 5650 if (localLOGV) Slog.v( 5651 TAG, r.intent.getComponent().flattenToShortString() 5652 + ": task=" + r.task); 5653 5654 // If the next one is a different task, generate a new 5655 // TaskInfo entry for what we have. 5656 if (next == null || next.task != curTask) { 5657 ActivityManager.RunningTaskInfo ci 5658 = new ActivityManager.RunningTaskInfo(); 5659 ci.id = curTask.taskId; 5660 ci.baseActivity = r.intent.getComponent(); 5661 ci.topActivity = top.intent.getComponent(); 5662 if (top.thumbHolder != null) { 5663 ci.description = top.thumbHolder.lastDescription; 5664 } 5665 ci.numActivities = numActivities; 5666 ci.numRunning = numRunning; 5667 //System.out.println( 5668 // "#" + maxNum + ": " + " descr=" + ci.description); 5669 if (ci.thumbnail == null && receiver != null) { 5670 if (localLOGV) Slog.v( 5671 TAG, "State=" + top.state + "Idle=" + top.idle 5672 + " app=" + top.app 5673 + " thr=" + (top.app != null ? top.app.thread : null)); 5674 if (top.state == ActivityState.RESUMED 5675 || top.state == ActivityState.PAUSING) { 5676 if (top.idle && top.app != null 5677 && top.app.thread != null) { 5678 topRecord = top; 5679 topThumbnail = top.app.thread; 5680 } else { 5681 top.thumbnailNeeded = true; 5682 } 5683 } 5684 if (pending == null) { 5685 pending = new PendingThumbnailsRecord(receiver); 5686 } 5687 pending.pendingRecords.add(top); 5688 } 5689 list.add(ci); 5690 maxNum--; 5691 top = null; 5692 } 5693 } 5694 5695 if (pending != null) { 5696 mPendingThumbnails.add(pending); 5697 } 5698 } 5699 5700 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5701 5702 if (topThumbnail != null) { 5703 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5704 try { 5705 topThumbnail.requestThumbnail(topRecord.appToken); 5706 } catch (Exception e) { 5707 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5708 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5709 } 5710 } 5711 5712 if (pending == null && receiver != null) { 5713 // In this case all thumbnails were available and the client 5714 // is being asked to be told when the remaining ones come in... 5715 // which is unusually, since the top-most currently running 5716 // activity should never have a canned thumbnail! Oh well. 5717 try { 5718 receiver.finished(); 5719 } catch (RemoteException ex) { 5720 } 5721 } 5722 5723 return list; 5724 } 5725 5726 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5727 int flags, int userId) { 5728 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 5729 false, true, "getRecentTasks", null); 5730 5731 synchronized (this) { 5732 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5733 "getRecentTasks()"); 5734 final boolean detailed = checkCallingPermission( 5735 android.Manifest.permission.GET_DETAILED_TASKS) 5736 == PackageManager.PERMISSION_GRANTED; 5737 5738 IPackageManager pm = AppGlobals.getPackageManager(); 5739 5740 final int N = mRecentTasks.size(); 5741 ArrayList<ActivityManager.RecentTaskInfo> res 5742 = new ArrayList<ActivityManager.RecentTaskInfo>( 5743 maxNum < N ? maxNum : N); 5744 for (int i=0; i<N && maxNum > 0; i++) { 5745 TaskRecord tr = mRecentTasks.get(i); 5746 // Only add calling user's recent tasks 5747 if (tr.userId != userId) continue; 5748 // Return the entry if desired by the caller. We always return 5749 // the first entry, because callers always expect this to be the 5750 // foreground app. We may filter others if the caller has 5751 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5752 // we should exclude the entry. 5753 5754 if (i == 0 5755 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5756 || (tr.intent == null) 5757 || ((tr.intent.getFlags() 5758 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5759 ActivityManager.RecentTaskInfo rti 5760 = new ActivityManager.RecentTaskInfo(); 5761 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5762 rti.persistentId = tr.taskId; 5763 rti.baseIntent = new Intent( 5764 tr.intent != null ? tr.intent : tr.affinityIntent); 5765 if (!detailed) { 5766 rti.baseIntent.replaceExtras((Bundle)null); 5767 } 5768 rti.origActivity = tr.origActivity; 5769 rti.description = tr.lastDescription; 5770 5771 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5772 // Check whether this activity is currently available. 5773 try { 5774 if (rti.origActivity != null) { 5775 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5776 == null) { 5777 continue; 5778 } 5779 } else if (rti.baseIntent != null) { 5780 if (pm.queryIntentActivities(rti.baseIntent, 5781 null, 0, userId) == null) { 5782 continue; 5783 } 5784 } 5785 } catch (RemoteException e) { 5786 // Will never happen. 5787 } 5788 } 5789 5790 res.add(rti); 5791 maxNum--; 5792 } 5793 } 5794 return res; 5795 } 5796 } 5797 5798 private TaskRecord taskForIdLocked(int id) { 5799 final int N = mRecentTasks.size(); 5800 for (int i=0; i<N; i++) { 5801 TaskRecord tr = mRecentTasks.get(i); 5802 if (tr.taskId == id) { 5803 return tr; 5804 } 5805 } 5806 return null; 5807 } 5808 5809 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5810 synchronized (this) { 5811 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5812 "getTaskThumbnails()"); 5813 TaskRecord tr = taskForIdLocked(id); 5814 if (tr != null) { 5815 return mMainStack.getTaskThumbnailsLocked(tr); 5816 } 5817 } 5818 return null; 5819 } 5820 5821 public Bitmap getTaskTopThumbnail(int id) { 5822 synchronized (this) { 5823 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5824 "getTaskTopThumbnail()"); 5825 TaskRecord tr = taskForIdLocked(id); 5826 if (tr != null) { 5827 return mMainStack.getTaskTopThumbnailLocked(tr); 5828 } 5829 } 5830 return null; 5831 } 5832 5833 public boolean removeSubTask(int taskId, int subTaskIndex) { 5834 synchronized (this) { 5835 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5836 "removeSubTask()"); 5837 long ident = Binder.clearCallingIdentity(); 5838 try { 5839 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5840 true) != null; 5841 } finally { 5842 Binder.restoreCallingIdentity(ident); 5843 } 5844 } 5845 } 5846 5847 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5848 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5849 Intent baseIntent = new Intent( 5850 tr.intent != null ? tr.intent : tr.affinityIntent); 5851 ComponentName component = baseIntent.getComponent(); 5852 if (component == null) { 5853 Slog.w(TAG, "Now component for base intent of task: " + tr); 5854 return; 5855 } 5856 5857 // Find any running services associated with this app. 5858 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5859 5860 if (killProcesses) { 5861 // Find any running processes associated with this app. 5862 final String pkg = component.getPackageName(); 5863 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5864 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5865 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5866 for (int i=0; i<uids.size(); i++) { 5867 ProcessRecord proc = uids.valueAt(i); 5868 if (proc.userId != tr.userId) { 5869 continue; 5870 } 5871 if (!proc.pkgList.contains(pkg)) { 5872 continue; 5873 } 5874 procs.add(proc); 5875 } 5876 } 5877 5878 // Kill the running processes. 5879 for (int i=0; i<procs.size(); i++) { 5880 ProcessRecord pr = procs.get(i); 5881 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5882 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5883 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 5884 pr.processName, pr.setAdj, "remove task"); 5885 pr.killedBackground = true; 5886 Process.killProcessQuiet(pr.pid); 5887 } else { 5888 pr.waitingToKill = "remove task"; 5889 } 5890 } 5891 } 5892 } 5893 5894 public boolean removeTask(int taskId, int flags) { 5895 synchronized (this) { 5896 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5897 "removeTask()"); 5898 long ident = Binder.clearCallingIdentity(); 5899 try { 5900 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5901 false); 5902 if (r != null) { 5903 mRecentTasks.remove(r.task); 5904 cleanUpRemovedTaskLocked(r.task, flags); 5905 return true; 5906 } else { 5907 TaskRecord tr = null; 5908 int i=0; 5909 while (i < mRecentTasks.size()) { 5910 TaskRecord t = mRecentTasks.get(i); 5911 if (t.taskId == taskId) { 5912 tr = t; 5913 break; 5914 } 5915 i++; 5916 } 5917 if (tr != null) { 5918 if (tr.numActivities <= 0) { 5919 // Caller is just removing a recent task that is 5920 // not actively running. That is easy! 5921 mRecentTasks.remove(i); 5922 cleanUpRemovedTaskLocked(tr, flags); 5923 return true; 5924 } else { 5925 Slog.w(TAG, "removeTask: task " + taskId 5926 + " does not have activities to remove, " 5927 + " but numActivities=" + tr.numActivities 5928 + ": " + tr); 5929 } 5930 } 5931 } 5932 } finally { 5933 Binder.restoreCallingIdentity(ident); 5934 } 5935 } 5936 return false; 5937 } 5938 5939 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5940 int j; 5941 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5942 TaskRecord jt = startTask; 5943 5944 // First look backwards 5945 for (j=startIndex-1; j>=0; j--) { 5946 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5947 if (r.task != jt) { 5948 jt = r.task; 5949 if (affinity.equals(jt.affinity)) { 5950 return j; 5951 } 5952 } 5953 } 5954 5955 // Now look forwards 5956 final int N = mMainStack.mHistory.size(); 5957 jt = startTask; 5958 for (j=startIndex+1; j<N; j++) { 5959 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5960 if (r.task != jt) { 5961 if (affinity.equals(jt.affinity)) { 5962 return j; 5963 } 5964 jt = r.task; 5965 } 5966 } 5967 5968 // Might it be at the top? 5969 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5970 return N-1; 5971 } 5972 5973 return -1; 5974 } 5975 5976 /** 5977 * TODO: Add mController hook 5978 */ 5979 public void moveTaskToFront(int task, int flags, Bundle options) { 5980 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5981 "moveTaskToFront()"); 5982 5983 synchronized(this) { 5984 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5985 Binder.getCallingUid(), "Task to front")) { 5986 ActivityOptions.abort(options); 5987 return; 5988 } 5989 final long origId = Binder.clearCallingIdentity(); 5990 try { 5991 TaskRecord tr = taskForIdLocked(task); 5992 if (tr != null) { 5993 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5994 mMainStack.mUserLeaving = true; 5995 } 5996 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5997 // Caller wants the home activity moved with it. To accomplish this, 5998 // we'll just move the home task to the top first. 5999 mMainStack.moveHomeToFrontLocked(); 6000 } 6001 mMainStack.moveTaskToFrontLocked(tr, null, options); 6002 return; 6003 } 6004 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6005 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6006 if (hr.task.taskId == task) { 6007 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6008 mMainStack.mUserLeaving = true; 6009 } 6010 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6011 // Caller wants the home activity moved with it. To accomplish this, 6012 // we'll just move the home task to the top first. 6013 mMainStack.moveHomeToFrontLocked(); 6014 } 6015 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6016 return; 6017 } 6018 } 6019 } finally { 6020 Binder.restoreCallingIdentity(origId); 6021 } 6022 ActivityOptions.abort(options); 6023 } 6024 } 6025 6026 public void moveTaskToBack(int task) { 6027 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6028 "moveTaskToBack()"); 6029 6030 synchronized(this) { 6031 if (mMainStack.mResumedActivity != null 6032 && mMainStack.mResumedActivity.task.taskId == task) { 6033 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6034 Binder.getCallingUid(), "Task to back")) { 6035 return; 6036 } 6037 } 6038 final long origId = Binder.clearCallingIdentity(); 6039 mMainStack.moveTaskToBackLocked(task, null); 6040 Binder.restoreCallingIdentity(origId); 6041 } 6042 } 6043 6044 /** 6045 * Moves an activity, and all of the other activities within the same task, to the bottom 6046 * of the history stack. The activity's order within the task is unchanged. 6047 * 6048 * @param token A reference to the activity we wish to move 6049 * @param nonRoot If false then this only works if the activity is the root 6050 * of a task; if true it will work for any activity in a task. 6051 * @return Returns true if the move completed, false if not. 6052 */ 6053 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6054 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6055 synchronized(this) { 6056 final long origId = Binder.clearCallingIdentity(); 6057 int taskId = getTaskForActivityLocked(token, !nonRoot); 6058 if (taskId >= 0) { 6059 return mMainStack.moveTaskToBackLocked(taskId, null); 6060 } 6061 Binder.restoreCallingIdentity(origId); 6062 } 6063 return false; 6064 } 6065 6066 public void moveTaskBackwards(int task) { 6067 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6068 "moveTaskBackwards()"); 6069 6070 synchronized(this) { 6071 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6072 Binder.getCallingUid(), "Task backwards")) { 6073 return; 6074 } 6075 final long origId = Binder.clearCallingIdentity(); 6076 moveTaskBackwardsLocked(task); 6077 Binder.restoreCallingIdentity(origId); 6078 } 6079 } 6080 6081 private final void moveTaskBackwardsLocked(int task) { 6082 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6083 } 6084 6085 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6086 synchronized(this) { 6087 return getTaskForActivityLocked(token, onlyRoot); 6088 } 6089 } 6090 6091 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6092 final int N = mMainStack.mHistory.size(); 6093 TaskRecord lastTask = null; 6094 for (int i=0; i<N; i++) { 6095 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6096 if (r.appToken == token) { 6097 if (!onlyRoot || lastTask != r.task) { 6098 return r.task.taskId; 6099 } 6100 return -1; 6101 } 6102 lastTask = r.task; 6103 } 6104 6105 return -1; 6106 } 6107 6108 // ========================================================= 6109 // THUMBNAILS 6110 // ========================================================= 6111 6112 public void reportThumbnail(IBinder token, 6113 Bitmap thumbnail, CharSequence description) { 6114 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6115 final long origId = Binder.clearCallingIdentity(); 6116 sendPendingThumbnail(null, token, thumbnail, description, true); 6117 Binder.restoreCallingIdentity(origId); 6118 } 6119 6120 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6121 Bitmap thumbnail, CharSequence description, boolean always) { 6122 TaskRecord task = null; 6123 ArrayList receivers = null; 6124 6125 //System.out.println("Send pending thumbnail: " + r); 6126 6127 synchronized(this) { 6128 if (r == null) { 6129 r = mMainStack.isInStackLocked(token); 6130 if (r == null) { 6131 return; 6132 } 6133 } 6134 if (thumbnail == null && r.thumbHolder != null) { 6135 thumbnail = r.thumbHolder.lastThumbnail; 6136 description = r.thumbHolder.lastDescription; 6137 } 6138 if (thumbnail == null && !always) { 6139 // If there is no thumbnail, and this entry is not actually 6140 // going away, then abort for now and pick up the next 6141 // thumbnail we get. 6142 return; 6143 } 6144 task = r.task; 6145 6146 int N = mPendingThumbnails.size(); 6147 int i=0; 6148 while (i<N) { 6149 PendingThumbnailsRecord pr = 6150 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6151 //System.out.println("Looking in " + pr.pendingRecords); 6152 if (pr.pendingRecords.remove(r)) { 6153 if (receivers == null) { 6154 receivers = new ArrayList(); 6155 } 6156 receivers.add(pr); 6157 if (pr.pendingRecords.size() == 0) { 6158 pr.finished = true; 6159 mPendingThumbnails.remove(i); 6160 N--; 6161 continue; 6162 } 6163 } 6164 i++; 6165 } 6166 } 6167 6168 if (receivers != null) { 6169 final int N = receivers.size(); 6170 for (int i=0; i<N; i++) { 6171 try { 6172 PendingThumbnailsRecord pr = 6173 (PendingThumbnailsRecord)receivers.get(i); 6174 pr.receiver.newThumbnail( 6175 task != null ? task.taskId : -1, thumbnail, description); 6176 if (pr.finished) { 6177 pr.receiver.finished(); 6178 } 6179 } catch (Exception e) { 6180 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6181 } 6182 } 6183 } 6184 } 6185 6186 // ========================================================= 6187 // CONTENT PROVIDERS 6188 // ========================================================= 6189 6190 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6191 List<ProviderInfo> providers = null; 6192 try { 6193 providers = AppGlobals.getPackageManager(). 6194 queryContentProviders(app.processName, app.uid, 6195 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6196 } catch (RemoteException ex) { 6197 } 6198 if (DEBUG_MU) 6199 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6200 int userId = app.userId; 6201 if (providers != null) { 6202 int N = providers.size(); 6203 for (int i=0; i<N; i++) { 6204 ProviderInfo cpi = 6205 (ProviderInfo)providers.get(i); 6206 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6207 cpi.name, cpi.flags); 6208 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6209 // This is a singleton provider, but a user besides the 6210 // default user is asking to initialize a process it runs 6211 // in... well, no, it doesn't actually run in this process, 6212 // it runs in the process of the default user. Get rid of it. 6213 providers.remove(i); 6214 N--; 6215 continue; 6216 } 6217 6218 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6219 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6220 if (cpr == null) { 6221 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6222 mProviderMap.putProviderByClass(comp, cpr); 6223 } 6224 if (DEBUG_MU) 6225 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6226 app.pubProviders.put(cpi.name, cpr); 6227 app.addPackage(cpi.applicationInfo.packageName); 6228 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6229 } 6230 } 6231 return providers; 6232 } 6233 6234 /** 6235 * Check if {@link ProcessRecord} has a possible chance at accessing the 6236 * given {@link ProviderInfo}. Final permission checking is always done 6237 * in {@link ContentProvider}. 6238 */ 6239 private final String checkContentProviderPermissionLocked( 6240 ProviderInfo cpi, ProcessRecord r) { 6241 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6242 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6243 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6244 cpi.applicationInfo.uid, cpi.exported) 6245 == PackageManager.PERMISSION_GRANTED) { 6246 return null; 6247 } 6248 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6249 cpi.applicationInfo.uid, cpi.exported) 6250 == PackageManager.PERMISSION_GRANTED) { 6251 return null; 6252 } 6253 6254 PathPermission[] pps = cpi.pathPermissions; 6255 if (pps != null) { 6256 int i = pps.length; 6257 while (i > 0) { 6258 i--; 6259 PathPermission pp = pps[i]; 6260 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6261 cpi.applicationInfo.uid, cpi.exported) 6262 == PackageManager.PERMISSION_GRANTED) { 6263 return null; 6264 } 6265 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6266 cpi.applicationInfo.uid, cpi.exported) 6267 == PackageManager.PERMISSION_GRANTED) { 6268 return null; 6269 } 6270 } 6271 } 6272 6273 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6274 if (perms != null) { 6275 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6276 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6277 return null; 6278 } 6279 } 6280 } 6281 6282 String msg; 6283 if (!cpi.exported) { 6284 msg = "Permission Denial: opening provider " + cpi.name 6285 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6286 + ", uid=" + callingUid + ") that is not exported from uid " 6287 + cpi.applicationInfo.uid; 6288 } else { 6289 msg = "Permission Denial: opening provider " + cpi.name 6290 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6291 + ", uid=" + callingUid + ") requires " 6292 + cpi.readPermission + " or " + cpi.writePermission; 6293 } 6294 Slog.w(TAG, msg); 6295 return msg; 6296 } 6297 6298 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6299 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6300 if (r != null) { 6301 for (int i=0; i<r.conProviders.size(); i++) { 6302 ContentProviderConnection conn = r.conProviders.get(i); 6303 if (conn.provider == cpr) { 6304 if (DEBUG_PROVIDER) Slog.v(TAG, 6305 "Adding provider requested by " 6306 + r.processName + " from process " 6307 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6308 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6309 if (stable) { 6310 conn.stableCount++; 6311 conn.numStableIncs++; 6312 } else { 6313 conn.unstableCount++; 6314 conn.numUnstableIncs++; 6315 } 6316 return conn; 6317 } 6318 } 6319 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6320 if (stable) { 6321 conn.stableCount = 1; 6322 conn.numStableIncs = 1; 6323 } else { 6324 conn.unstableCount = 1; 6325 conn.numUnstableIncs = 1; 6326 } 6327 cpr.connections.add(conn); 6328 r.conProviders.add(conn); 6329 return conn; 6330 } 6331 cpr.addExternalProcessHandleLocked(externalProcessToken); 6332 return null; 6333 } 6334 6335 boolean decProviderCountLocked(ContentProviderConnection conn, 6336 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6337 if (conn != null) { 6338 cpr = conn.provider; 6339 if (DEBUG_PROVIDER) Slog.v(TAG, 6340 "Removing provider requested by " 6341 + conn.client.processName + " from process " 6342 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6343 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6344 if (stable) { 6345 conn.stableCount--; 6346 } else { 6347 conn.unstableCount--; 6348 } 6349 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6350 cpr.connections.remove(conn); 6351 conn.client.conProviders.remove(conn); 6352 return true; 6353 } 6354 return false; 6355 } 6356 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6357 return false; 6358 } 6359 6360 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6361 String name, IBinder token, boolean stable, int userId) { 6362 ContentProviderRecord cpr; 6363 ContentProviderConnection conn = null; 6364 ProviderInfo cpi = null; 6365 6366 synchronized(this) { 6367 ProcessRecord r = null; 6368 if (caller != null) { 6369 r = getRecordForAppLocked(caller); 6370 if (r == null) { 6371 throw new SecurityException( 6372 "Unable to find app for caller " + caller 6373 + " (pid=" + Binder.getCallingPid() 6374 + ") when getting content provider " + name); 6375 } 6376 } 6377 6378 // First check if this content provider has been published... 6379 cpr = mProviderMap.getProviderByName(name, userId); 6380 boolean providerRunning = cpr != null; 6381 if (providerRunning) { 6382 cpi = cpr.info; 6383 String msg; 6384 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6385 throw new SecurityException(msg); 6386 } 6387 6388 if (r != null && cpr.canRunHere(r)) { 6389 // This provider has been published or is in the process 6390 // of being published... but it is also allowed to run 6391 // in the caller's process, so don't make a connection 6392 // and just let the caller instantiate its own instance. 6393 ContentProviderHolder holder = cpr.newHolder(null); 6394 // don't give caller the provider object, it needs 6395 // to make its own. 6396 holder.provider = null; 6397 return holder; 6398 } 6399 6400 final long origId = Binder.clearCallingIdentity(); 6401 6402 // In this case the provider instance already exists, so we can 6403 // return it right away. 6404 conn = incProviderCountLocked(r, cpr, token, stable); 6405 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6406 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6407 // If this is a perceptible app accessing the provider, 6408 // make sure to count it as being accessed and thus 6409 // back up on the LRU list. This is good because 6410 // content providers are often expensive to start. 6411 updateLruProcessLocked(cpr.proc, false); 6412 } 6413 } 6414 6415 if (cpr.proc != null) { 6416 if (false) { 6417 if (cpr.name.flattenToShortString().equals( 6418 "com.android.providers.calendar/.CalendarProvider2")) { 6419 Slog.v(TAG, "****************** KILLING " 6420 + cpr.name.flattenToShortString()); 6421 Process.killProcess(cpr.proc.pid); 6422 } 6423 } 6424 boolean success = updateOomAdjLocked(cpr.proc); 6425 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6426 // NOTE: there is still a race here where a signal could be 6427 // pending on the process even though we managed to update its 6428 // adj level. Not sure what to do about this, but at least 6429 // the race is now smaller. 6430 if (!success) { 6431 // Uh oh... it looks like the provider's process 6432 // has been killed on us. We need to wait for a new 6433 // process to be started, and make sure its death 6434 // doesn't kill our process. 6435 Slog.i(TAG, 6436 "Existing provider " + cpr.name.flattenToShortString() 6437 + " is crashing; detaching " + r); 6438 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6439 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6440 if (!lastRef) { 6441 // This wasn't the last ref our process had on 6442 // the provider... we have now been killed, bail. 6443 return null; 6444 } 6445 providerRunning = false; 6446 conn = null; 6447 } 6448 } 6449 6450 Binder.restoreCallingIdentity(origId); 6451 } 6452 6453 boolean singleton; 6454 if (!providerRunning) { 6455 try { 6456 cpi = AppGlobals.getPackageManager(). 6457 resolveContentProvider(name, 6458 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6459 } catch (RemoteException ex) { 6460 } 6461 if (cpi == null) { 6462 return null; 6463 } 6464 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6465 cpi.name, cpi.flags); 6466 if (singleton) { 6467 userId = 0; 6468 } 6469 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6470 6471 String msg; 6472 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6473 throw new SecurityException(msg); 6474 } 6475 6476 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6477 && !cpi.processName.equals("system")) { 6478 // If this content provider does not run in the system 6479 // process, and the system is not yet ready to run other 6480 // processes, then fail fast instead of hanging. 6481 throw new IllegalArgumentException( 6482 "Attempt to launch content provider before system ready"); 6483 } 6484 6485 // Make sure that the user who owns this provider is started. If not, 6486 // we don't want to allow it to run. 6487 if (mStartedUsers.get(userId) == null) { 6488 Slog.w(TAG, "Unable to launch app " 6489 + cpi.applicationInfo.packageName + "/" 6490 + cpi.applicationInfo.uid + " for provider " 6491 + name + ": user " + userId + " is stopped"); 6492 return null; 6493 } 6494 6495 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6496 cpr = mProviderMap.getProviderByClass(comp, userId); 6497 final boolean firstClass = cpr == null; 6498 if (firstClass) { 6499 try { 6500 ApplicationInfo ai = 6501 AppGlobals.getPackageManager(). 6502 getApplicationInfo( 6503 cpi.applicationInfo.packageName, 6504 STOCK_PM_FLAGS, userId); 6505 if (ai == null) { 6506 Slog.w(TAG, "No package info for content provider " 6507 + cpi.name); 6508 return null; 6509 } 6510 ai = getAppInfoForUser(ai, userId); 6511 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6512 } catch (RemoteException ex) { 6513 // pm is in same process, this will never happen. 6514 } 6515 } 6516 6517 if (r != null && cpr.canRunHere(r)) { 6518 // If this is a multiprocess provider, then just return its 6519 // info and allow the caller to instantiate it. Only do 6520 // this if the provider is the same user as the caller's 6521 // process, or can run as root (so can be in any process). 6522 return cpr.newHolder(null); 6523 } 6524 6525 if (DEBUG_PROVIDER) { 6526 RuntimeException e = new RuntimeException("here"); 6527 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6528 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6529 } 6530 6531 // This is single process, and our app is now connecting to it. 6532 // See if we are already in the process of launching this 6533 // provider. 6534 final int N = mLaunchingProviders.size(); 6535 int i; 6536 for (i=0; i<N; i++) { 6537 if (mLaunchingProviders.get(i) == cpr) { 6538 break; 6539 } 6540 } 6541 6542 // If the provider is not already being launched, then get it 6543 // started. 6544 if (i >= N) { 6545 final long origId = Binder.clearCallingIdentity(); 6546 6547 try { 6548 // Content provider is now in use, its package can't be stopped. 6549 try { 6550 AppGlobals.getPackageManager().setPackageStoppedState( 6551 cpr.appInfo.packageName, false, userId); 6552 } catch (RemoteException e) { 6553 } catch (IllegalArgumentException e) { 6554 Slog.w(TAG, "Failed trying to unstop package " 6555 + cpr.appInfo.packageName + ": " + e); 6556 } 6557 6558 ProcessRecord proc = startProcessLocked(cpi.processName, 6559 cpr.appInfo, false, 0, "content provider", 6560 new ComponentName(cpi.applicationInfo.packageName, 6561 cpi.name), false, false); 6562 if (proc == null) { 6563 Slog.w(TAG, "Unable to launch app " 6564 + cpi.applicationInfo.packageName + "/" 6565 + cpi.applicationInfo.uid + " for provider " 6566 + name + ": process is bad"); 6567 return null; 6568 } 6569 cpr.launchingApp = proc; 6570 mLaunchingProviders.add(cpr); 6571 } finally { 6572 Binder.restoreCallingIdentity(origId); 6573 } 6574 } 6575 6576 // Make sure the provider is published (the same provider class 6577 // may be published under multiple names). 6578 if (firstClass) { 6579 mProviderMap.putProviderByClass(comp, cpr); 6580 } 6581 6582 mProviderMap.putProviderByName(name, cpr); 6583 conn = incProviderCountLocked(r, cpr, token, stable); 6584 if (conn != null) { 6585 conn.waiting = true; 6586 } 6587 } 6588 } 6589 6590 // Wait for the provider to be published... 6591 synchronized (cpr) { 6592 while (cpr.provider == null) { 6593 if (cpr.launchingApp == null) { 6594 Slog.w(TAG, "Unable to launch app " 6595 + cpi.applicationInfo.packageName + "/" 6596 + cpi.applicationInfo.uid + " for provider " 6597 + name + ": launching app became null"); 6598 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6599 UserHandle.getUserId(cpi.applicationInfo.uid), 6600 cpi.applicationInfo.packageName, 6601 cpi.applicationInfo.uid, name); 6602 return null; 6603 } 6604 try { 6605 if (DEBUG_MU) { 6606 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6607 + cpr.launchingApp); 6608 } 6609 if (conn != null) { 6610 conn.waiting = true; 6611 } 6612 cpr.wait(); 6613 } catch (InterruptedException ex) { 6614 } finally { 6615 if (conn != null) { 6616 conn.waiting = false; 6617 } 6618 } 6619 } 6620 } 6621 return cpr != null ? cpr.newHolder(conn) : null; 6622 } 6623 6624 public final ContentProviderHolder getContentProvider( 6625 IApplicationThread caller, String name, int userId, boolean stable) { 6626 enforceNotIsolatedCaller("getContentProvider"); 6627 if (caller == null) { 6628 String msg = "null IApplicationThread when getting content provider " 6629 + name; 6630 Slog.w(TAG, msg); 6631 throw new SecurityException(msg); 6632 } 6633 6634 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6635 false, true, "getContentProvider", null); 6636 return getContentProviderImpl(caller, name, null, stable, userId); 6637 } 6638 6639 public ContentProviderHolder getContentProviderExternal( 6640 String name, int userId, IBinder token) { 6641 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6642 "Do not have permission in call getContentProviderExternal()"); 6643 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6644 false, true, "getContentProvider", null); 6645 return getContentProviderExternalUnchecked(name, token, userId); 6646 } 6647 6648 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6649 IBinder token, int userId) { 6650 return getContentProviderImpl(null, name, token, true, userId); 6651 } 6652 6653 /** 6654 * Drop a content provider from a ProcessRecord's bookkeeping 6655 * @param cpr 6656 */ 6657 public void removeContentProvider(IBinder connection, boolean stable) { 6658 enforceNotIsolatedCaller("removeContentProvider"); 6659 synchronized (this) { 6660 ContentProviderConnection conn; 6661 try { 6662 conn = (ContentProviderConnection)connection; 6663 } catch (ClassCastException e) { 6664 String msg ="removeContentProvider: " + connection 6665 + " not a ContentProviderConnection"; 6666 Slog.w(TAG, msg); 6667 throw new IllegalArgumentException(msg); 6668 } 6669 if (conn == null) { 6670 throw new NullPointerException("connection is null"); 6671 } 6672 if (decProviderCountLocked(conn, null, null, stable)) { 6673 updateOomAdjLocked(); 6674 } 6675 } 6676 } 6677 6678 public void removeContentProviderExternal(String name, IBinder token) { 6679 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6680 "Do not have permission in call removeContentProviderExternal()"); 6681 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6682 } 6683 6684 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6685 synchronized (this) { 6686 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6687 if(cpr == null) { 6688 //remove from mProvidersByClass 6689 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6690 return; 6691 } 6692 6693 //update content provider record entry info 6694 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6695 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6696 if (localCpr.hasExternalProcessHandles()) { 6697 if (localCpr.removeExternalProcessHandleLocked(token)) { 6698 updateOomAdjLocked(); 6699 } else { 6700 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6701 + " with no external reference for token: " 6702 + token + "."); 6703 } 6704 } else { 6705 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6706 + " with no external references."); 6707 } 6708 } 6709 } 6710 6711 public final void publishContentProviders(IApplicationThread caller, 6712 List<ContentProviderHolder> providers) { 6713 if (providers == null) { 6714 return; 6715 } 6716 6717 enforceNotIsolatedCaller("publishContentProviders"); 6718 synchronized (this) { 6719 final ProcessRecord r = getRecordForAppLocked(caller); 6720 if (DEBUG_MU) 6721 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6722 if (r == null) { 6723 throw new SecurityException( 6724 "Unable to find app for caller " + caller 6725 + " (pid=" + Binder.getCallingPid() 6726 + ") when publishing content providers"); 6727 } 6728 6729 final long origId = Binder.clearCallingIdentity(); 6730 6731 final int N = providers.size(); 6732 for (int i=0; i<N; i++) { 6733 ContentProviderHolder src = providers.get(i); 6734 if (src == null || src.info == null || src.provider == null) { 6735 continue; 6736 } 6737 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6738 if (DEBUG_MU) 6739 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6740 if (dst != null) { 6741 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6742 mProviderMap.putProviderByClass(comp, dst); 6743 String names[] = dst.info.authority.split(";"); 6744 for (int j = 0; j < names.length; j++) { 6745 mProviderMap.putProviderByName(names[j], dst); 6746 } 6747 6748 int NL = mLaunchingProviders.size(); 6749 int j; 6750 for (j=0; j<NL; j++) { 6751 if (mLaunchingProviders.get(j) == dst) { 6752 mLaunchingProviders.remove(j); 6753 j--; 6754 NL--; 6755 } 6756 } 6757 synchronized (dst) { 6758 dst.provider = src.provider; 6759 dst.proc = r; 6760 dst.notifyAll(); 6761 } 6762 updateOomAdjLocked(r); 6763 } 6764 } 6765 6766 Binder.restoreCallingIdentity(origId); 6767 } 6768 } 6769 6770 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6771 ContentProviderConnection conn; 6772 try { 6773 conn = (ContentProviderConnection)connection; 6774 } catch (ClassCastException e) { 6775 String msg ="refContentProvider: " + connection 6776 + " not a ContentProviderConnection"; 6777 Slog.w(TAG, msg); 6778 throw new IllegalArgumentException(msg); 6779 } 6780 if (conn == null) { 6781 throw new NullPointerException("connection is null"); 6782 } 6783 6784 synchronized (this) { 6785 if (stable > 0) { 6786 conn.numStableIncs += stable; 6787 } 6788 stable = conn.stableCount + stable; 6789 if (stable < 0) { 6790 throw new IllegalStateException("stableCount < 0: " + stable); 6791 } 6792 6793 if (unstable > 0) { 6794 conn.numUnstableIncs += unstable; 6795 } 6796 unstable = conn.unstableCount + unstable; 6797 if (unstable < 0) { 6798 throw new IllegalStateException("unstableCount < 0: " + unstable); 6799 } 6800 6801 if ((stable+unstable) <= 0) { 6802 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6803 + stable + " unstable=" + unstable); 6804 } 6805 conn.stableCount = stable; 6806 conn.unstableCount = unstable; 6807 return !conn.dead; 6808 } 6809 } 6810 6811 public void unstableProviderDied(IBinder connection) { 6812 ContentProviderConnection conn; 6813 try { 6814 conn = (ContentProviderConnection)connection; 6815 } catch (ClassCastException e) { 6816 String msg ="refContentProvider: " + connection 6817 + " not a ContentProviderConnection"; 6818 Slog.w(TAG, msg); 6819 throw new IllegalArgumentException(msg); 6820 } 6821 if (conn == null) { 6822 throw new NullPointerException("connection is null"); 6823 } 6824 6825 // Safely retrieve the content provider associated with the connection. 6826 IContentProvider provider; 6827 synchronized (this) { 6828 provider = conn.provider.provider; 6829 } 6830 6831 if (provider == null) { 6832 // Um, yeah, we're way ahead of you. 6833 return; 6834 } 6835 6836 // Make sure the caller is being honest with us. 6837 if (provider.asBinder().pingBinder()) { 6838 // Er, no, still looks good to us. 6839 synchronized (this) { 6840 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6841 + " says " + conn + " died, but we don't agree"); 6842 return; 6843 } 6844 } 6845 6846 // Well look at that! It's dead! 6847 synchronized (this) { 6848 if (conn.provider.provider != provider) { 6849 // But something changed... good enough. 6850 return; 6851 } 6852 6853 ProcessRecord proc = conn.provider.proc; 6854 if (proc == null || proc.thread == null) { 6855 // Seems like the process is already cleaned up. 6856 return; 6857 } 6858 6859 // As far as we're concerned, this is just like receiving a 6860 // death notification... just a bit prematurely. 6861 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6862 + ") early provider death"); 6863 final long ident = Binder.clearCallingIdentity(); 6864 try { 6865 appDiedLocked(proc, proc.pid, proc.thread); 6866 } finally { 6867 Binder.restoreCallingIdentity(ident); 6868 } 6869 } 6870 } 6871 6872 public static final void installSystemProviders() { 6873 List<ProviderInfo> providers; 6874 synchronized (mSelf) { 6875 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6876 providers = mSelf.generateApplicationProvidersLocked(app); 6877 if (providers != null) { 6878 for (int i=providers.size()-1; i>=0; i--) { 6879 ProviderInfo pi = (ProviderInfo)providers.get(i); 6880 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6881 Slog.w(TAG, "Not installing system proc provider " + pi.name 6882 + ": not system .apk"); 6883 providers.remove(i); 6884 } 6885 } 6886 } 6887 } 6888 if (providers != null) { 6889 mSystemThread.installSystemProviders(providers); 6890 } 6891 6892 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6893 6894 mSelf.mUsageStatsService.monitorPackages(); 6895 } 6896 6897 /** 6898 * Allows app to retrieve the MIME type of a URI without having permission 6899 * to access its content provider. 6900 * 6901 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6902 * 6903 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6904 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6905 */ 6906 public String getProviderMimeType(Uri uri, int userId) { 6907 enforceNotIsolatedCaller("getProviderMimeType"); 6908 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6909 userId, false, true, "getProviderMimeType", null); 6910 final String name = uri.getAuthority(); 6911 final long ident = Binder.clearCallingIdentity(); 6912 ContentProviderHolder holder = null; 6913 6914 try { 6915 holder = getContentProviderExternalUnchecked(name, null, userId); 6916 if (holder != null) { 6917 return holder.provider.getType(uri); 6918 } 6919 } catch (RemoteException e) { 6920 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6921 return null; 6922 } finally { 6923 if (holder != null) { 6924 removeContentProviderExternalUnchecked(name, null, userId); 6925 } 6926 Binder.restoreCallingIdentity(ident); 6927 } 6928 6929 return null; 6930 } 6931 6932 // ========================================================= 6933 // GLOBAL MANAGEMENT 6934 // ========================================================= 6935 6936 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6937 ApplicationInfo info, String customProcess, boolean isolated) { 6938 String proc = customProcess != null ? customProcess : info.processName; 6939 BatteryStatsImpl.Uid.Proc ps = null; 6940 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6941 int uid = info.uid; 6942 if (isolated) { 6943 int userId = UserHandle.getUserId(uid); 6944 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6945 uid = 0; 6946 while (true) { 6947 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6948 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6949 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6950 } 6951 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6952 mNextIsolatedProcessUid++; 6953 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6954 // No process for this uid, use it. 6955 break; 6956 } 6957 stepsLeft--; 6958 if (stepsLeft <= 0) { 6959 return null; 6960 } 6961 } 6962 } 6963 synchronized (stats) { 6964 ps = stats.getProcessStatsLocked(info.uid, proc); 6965 } 6966 return new ProcessRecord(ps, thread, info, proc, uid); 6967 } 6968 6969 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6970 ProcessRecord app; 6971 if (!isolated) { 6972 app = getProcessRecordLocked(info.processName, info.uid); 6973 } else { 6974 app = null; 6975 } 6976 6977 if (app == null) { 6978 app = newProcessRecordLocked(null, info, null, isolated); 6979 mProcessNames.put(info.processName, app.uid, app); 6980 if (isolated) { 6981 mIsolatedProcesses.put(app.uid, app); 6982 } 6983 updateLruProcessLocked(app, true); 6984 } 6985 6986 // This package really, really can not be stopped. 6987 try { 6988 AppGlobals.getPackageManager().setPackageStoppedState( 6989 info.packageName, false, UserHandle.getUserId(app.uid)); 6990 } catch (RemoteException e) { 6991 } catch (IllegalArgumentException e) { 6992 Slog.w(TAG, "Failed trying to unstop package " 6993 + info.packageName + ": " + e); 6994 } 6995 6996 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6997 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6998 app.persistent = true; 6999 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7000 } 7001 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7002 mPersistentStartingProcesses.add(app); 7003 startProcessLocked(app, "added application", app.processName); 7004 } 7005 7006 return app; 7007 } 7008 7009 public void unhandledBack() { 7010 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7011 "unhandledBack()"); 7012 7013 synchronized(this) { 7014 int count = mMainStack.mHistory.size(); 7015 if (DEBUG_SWITCH) Slog.d( 7016 TAG, "Performing unhandledBack(): stack size = " + count); 7017 if (count > 1) { 7018 final long origId = Binder.clearCallingIdentity(); 7019 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7020 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7021 Binder.restoreCallingIdentity(origId); 7022 } 7023 } 7024 } 7025 7026 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7027 enforceNotIsolatedCaller("openContentUri"); 7028 final int userId = UserHandle.getCallingUserId(); 7029 String name = uri.getAuthority(); 7030 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7031 ParcelFileDescriptor pfd = null; 7032 if (cph != null) { 7033 // We record the binder invoker's uid in thread-local storage before 7034 // going to the content provider to open the file. Later, in the code 7035 // that handles all permissions checks, we look for this uid and use 7036 // that rather than the Activity Manager's own uid. The effect is that 7037 // we do the check against the caller's permissions even though it looks 7038 // to the content provider like the Activity Manager itself is making 7039 // the request. 7040 sCallerIdentity.set(new Identity( 7041 Binder.getCallingPid(), Binder.getCallingUid())); 7042 try { 7043 pfd = cph.provider.openFile(uri, "r"); 7044 } catch (FileNotFoundException e) { 7045 // do nothing; pfd will be returned null 7046 } finally { 7047 // Ensure that whatever happens, we clean up the identity state 7048 sCallerIdentity.remove(); 7049 } 7050 7051 // We've got the fd now, so we're done with the provider. 7052 removeContentProviderExternalUnchecked(name, null, userId); 7053 } else { 7054 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7055 } 7056 return pfd; 7057 } 7058 7059 // Actually is sleeping or shutting down or whatever else in the future 7060 // is an inactive state. 7061 public boolean isSleeping() { 7062 return mSleeping || mShuttingDown; 7063 } 7064 7065 public void goingToSleep() { 7066 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7067 != PackageManager.PERMISSION_GRANTED) { 7068 throw new SecurityException("Requires permission " 7069 + android.Manifest.permission.DEVICE_POWER); 7070 } 7071 7072 synchronized(this) { 7073 mWentToSleep = true; 7074 updateEventDispatchingLocked(); 7075 7076 if (!mSleeping) { 7077 mSleeping = true; 7078 mMainStack.stopIfSleepingLocked(); 7079 7080 // Initialize the wake times of all processes. 7081 checkExcessivePowerUsageLocked(false); 7082 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7083 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7084 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7085 } 7086 } 7087 } 7088 7089 public boolean shutdown(int timeout) { 7090 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7091 != PackageManager.PERMISSION_GRANTED) { 7092 throw new SecurityException("Requires permission " 7093 + android.Manifest.permission.SHUTDOWN); 7094 } 7095 7096 boolean timedout = false; 7097 7098 synchronized(this) { 7099 mShuttingDown = true; 7100 updateEventDispatchingLocked(); 7101 7102 if (mMainStack.mResumedActivity != null) { 7103 mMainStack.stopIfSleepingLocked(); 7104 final long endTime = System.currentTimeMillis() + timeout; 7105 while (mMainStack.mResumedActivity != null 7106 || mMainStack.mPausingActivity != null) { 7107 long delay = endTime - System.currentTimeMillis(); 7108 if (delay <= 0) { 7109 Slog.w(TAG, "Activity manager shutdown timed out"); 7110 timedout = true; 7111 break; 7112 } 7113 try { 7114 this.wait(); 7115 } catch (InterruptedException e) { 7116 } 7117 } 7118 } 7119 } 7120 7121 mUsageStatsService.shutdown(); 7122 mBatteryStatsService.shutdown(); 7123 7124 return timedout; 7125 } 7126 7127 public final void activitySlept(IBinder token) { 7128 if (localLOGV) Slog.v( 7129 TAG, "Activity slept: token=" + token); 7130 7131 ActivityRecord r = null; 7132 7133 final long origId = Binder.clearCallingIdentity(); 7134 7135 synchronized (this) { 7136 r = mMainStack.isInStackLocked(token); 7137 if (r != null) { 7138 mMainStack.activitySleptLocked(r); 7139 } 7140 } 7141 7142 Binder.restoreCallingIdentity(origId); 7143 } 7144 7145 private void comeOutOfSleepIfNeededLocked() { 7146 if (!mWentToSleep && !mLockScreenShown) { 7147 if (mSleeping) { 7148 mSleeping = false; 7149 mMainStack.awakeFromSleepingLocked(); 7150 mMainStack.resumeTopActivityLocked(null); 7151 } 7152 } 7153 } 7154 7155 public void wakingUp() { 7156 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7157 != PackageManager.PERMISSION_GRANTED) { 7158 throw new SecurityException("Requires permission " 7159 + android.Manifest.permission.DEVICE_POWER); 7160 } 7161 7162 synchronized(this) { 7163 mWentToSleep = false; 7164 updateEventDispatchingLocked(); 7165 comeOutOfSleepIfNeededLocked(); 7166 } 7167 } 7168 7169 private void updateEventDispatchingLocked() { 7170 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7171 } 7172 7173 public void setLockScreenShown(boolean shown) { 7174 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7175 != PackageManager.PERMISSION_GRANTED) { 7176 throw new SecurityException("Requires permission " 7177 + android.Manifest.permission.DEVICE_POWER); 7178 } 7179 7180 synchronized(this) { 7181 mLockScreenShown = shown; 7182 comeOutOfSleepIfNeededLocked(); 7183 } 7184 } 7185 7186 public void stopAppSwitches() { 7187 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7188 != PackageManager.PERMISSION_GRANTED) { 7189 throw new SecurityException("Requires permission " 7190 + android.Manifest.permission.STOP_APP_SWITCHES); 7191 } 7192 7193 synchronized(this) { 7194 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7195 + APP_SWITCH_DELAY_TIME; 7196 mDidAppSwitch = false; 7197 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7198 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7199 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7200 } 7201 } 7202 7203 public void resumeAppSwitches() { 7204 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7205 != PackageManager.PERMISSION_GRANTED) { 7206 throw new SecurityException("Requires permission " 7207 + android.Manifest.permission.STOP_APP_SWITCHES); 7208 } 7209 7210 synchronized(this) { 7211 // Note that we don't execute any pending app switches... we will 7212 // let those wait until either the timeout, or the next start 7213 // activity request. 7214 mAppSwitchesAllowedTime = 0; 7215 } 7216 } 7217 7218 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7219 String name) { 7220 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7221 return true; 7222 } 7223 7224 final int perm = checkComponentPermission( 7225 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7226 callingUid, -1, true); 7227 if (perm == PackageManager.PERMISSION_GRANTED) { 7228 return true; 7229 } 7230 7231 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7232 return false; 7233 } 7234 7235 public void setDebugApp(String packageName, boolean waitForDebugger, 7236 boolean persistent) { 7237 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7238 "setDebugApp()"); 7239 7240 // Note that this is not really thread safe if there are multiple 7241 // callers into it at the same time, but that's not a situation we 7242 // care about. 7243 if (persistent) { 7244 final ContentResolver resolver = mContext.getContentResolver(); 7245 Settings.System.putString( 7246 resolver, Settings.System.DEBUG_APP, 7247 packageName); 7248 Settings.System.putInt( 7249 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7250 waitForDebugger ? 1 : 0); 7251 } 7252 7253 synchronized (this) { 7254 if (!persistent) { 7255 mOrigDebugApp = mDebugApp; 7256 mOrigWaitForDebugger = mWaitForDebugger; 7257 } 7258 mDebugApp = packageName; 7259 mWaitForDebugger = waitForDebugger; 7260 mDebugTransient = !persistent; 7261 if (packageName != null) { 7262 final long origId = Binder.clearCallingIdentity(); 7263 forceStopPackageLocked(packageName, -1, false, false, true, true, 7264 UserHandle.USER_ALL); 7265 Binder.restoreCallingIdentity(origId); 7266 } 7267 } 7268 } 7269 7270 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7271 synchronized (this) { 7272 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7273 if (!isDebuggable) { 7274 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7275 throw new SecurityException("Process not debuggable: " + app.packageName); 7276 } 7277 } 7278 7279 mOpenGlTraceApp = processName; 7280 } 7281 } 7282 7283 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7284 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7285 synchronized (this) { 7286 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7287 if (!isDebuggable) { 7288 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7289 throw new SecurityException("Process not debuggable: " + app.packageName); 7290 } 7291 } 7292 mProfileApp = processName; 7293 mProfileFile = profileFile; 7294 if (mProfileFd != null) { 7295 try { 7296 mProfileFd.close(); 7297 } catch (IOException e) { 7298 } 7299 mProfileFd = null; 7300 } 7301 mProfileFd = profileFd; 7302 mProfileType = 0; 7303 mAutoStopProfiler = autoStopProfiler; 7304 } 7305 } 7306 7307 public void setAlwaysFinish(boolean enabled) { 7308 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7309 "setAlwaysFinish()"); 7310 7311 Settings.System.putInt( 7312 mContext.getContentResolver(), 7313 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7314 7315 synchronized (this) { 7316 mAlwaysFinishActivities = enabled; 7317 } 7318 } 7319 7320 public void setActivityController(IActivityController controller) { 7321 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7322 "setActivityController()"); 7323 synchronized (this) { 7324 mController = controller; 7325 } 7326 } 7327 7328 public boolean isUserAMonkey() { 7329 // For now the fact that there is a controller implies 7330 // we have a monkey. 7331 synchronized (this) { 7332 return mController != null; 7333 } 7334 } 7335 7336 public void requestBugReport() { 7337 // No permission check because this can't do anything harmful -- 7338 // it will just eventually cause the user to be presented with 7339 // a UI to select where the bug report goes. 7340 SystemProperties.set("ctl.start", "bugreport"); 7341 } 7342 7343 public void registerProcessObserver(IProcessObserver observer) { 7344 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7345 "registerProcessObserver()"); 7346 synchronized (this) { 7347 mProcessObservers.register(observer); 7348 } 7349 } 7350 7351 public void unregisterProcessObserver(IProcessObserver observer) { 7352 synchronized (this) { 7353 mProcessObservers.unregister(observer); 7354 } 7355 } 7356 7357 public void setImmersive(IBinder token, boolean immersive) { 7358 synchronized(this) { 7359 ActivityRecord r = mMainStack.isInStackLocked(token); 7360 if (r == null) { 7361 throw new IllegalArgumentException(); 7362 } 7363 r.immersive = immersive; 7364 } 7365 } 7366 7367 public boolean isImmersive(IBinder token) { 7368 synchronized (this) { 7369 ActivityRecord r = mMainStack.isInStackLocked(token); 7370 if (r == null) { 7371 throw new IllegalArgumentException(); 7372 } 7373 return r.immersive; 7374 } 7375 } 7376 7377 public boolean isTopActivityImmersive() { 7378 enforceNotIsolatedCaller("startActivity"); 7379 synchronized (this) { 7380 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7381 return (r != null) ? r.immersive : false; 7382 } 7383 } 7384 7385 public final void enterSafeMode() { 7386 synchronized(this) { 7387 // It only makes sense to do this before the system is ready 7388 // and started launching other packages. 7389 if (!mSystemReady) { 7390 try { 7391 AppGlobals.getPackageManager().enterSafeMode(); 7392 } catch (RemoteException e) { 7393 } 7394 } 7395 } 7396 } 7397 7398 public final void showSafeModeOverlay() { 7399 View v = LayoutInflater.from(mContext).inflate( 7400 com.android.internal.R.layout.safe_mode, null); 7401 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7402 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7403 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7404 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7405 lp.gravity = Gravity.BOTTOM | Gravity.START; 7406 lp.format = v.getBackground().getOpacity(); 7407 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7408 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7409 ((WindowManager)mContext.getSystemService( 7410 Context.WINDOW_SERVICE)).addView(v, lp); 7411 } 7412 7413 public void noteWakeupAlarm(IIntentSender sender) { 7414 if (!(sender instanceof PendingIntentRecord)) { 7415 return; 7416 } 7417 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7418 synchronized (stats) { 7419 if (mBatteryStatsService.isOnBattery()) { 7420 mBatteryStatsService.enforceCallingPermission(); 7421 PendingIntentRecord rec = (PendingIntentRecord)sender; 7422 int MY_UID = Binder.getCallingUid(); 7423 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7424 BatteryStatsImpl.Uid.Pkg pkg = 7425 stats.getPackageStatsLocked(uid, rec.key.packageName); 7426 pkg.incWakeupsLocked(); 7427 } 7428 } 7429 } 7430 7431 public boolean killPids(int[] pids, String pReason, boolean secure) { 7432 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7433 throw new SecurityException("killPids only available to the system"); 7434 } 7435 String reason = (pReason == null) ? "Unknown" : pReason; 7436 // XXX Note: don't acquire main activity lock here, because the window 7437 // manager calls in with its locks held. 7438 7439 boolean killed = false; 7440 synchronized (mPidsSelfLocked) { 7441 int[] types = new int[pids.length]; 7442 int worstType = 0; 7443 for (int i=0; i<pids.length; i++) { 7444 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7445 if (proc != null) { 7446 int type = proc.setAdj; 7447 types[i] = type; 7448 if (type > worstType) { 7449 worstType = type; 7450 } 7451 } 7452 } 7453 7454 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7455 // then constrain it so we will kill all hidden procs. 7456 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7457 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7458 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7459 } 7460 7461 // If this is not a secure call, don't let it kill processes that 7462 // are important. 7463 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7464 worstType = ProcessList.SERVICE_ADJ; 7465 } 7466 7467 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7468 for (int i=0; i<pids.length; i++) { 7469 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7470 if (proc == null) { 7471 continue; 7472 } 7473 int adj = proc.setAdj; 7474 if (adj >= worstType && !proc.killedBackground) { 7475 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7476 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid, 7477 proc.processName, adj, reason); 7478 killed = true; 7479 proc.killedBackground = true; 7480 Process.killProcessQuiet(pids[i]); 7481 } 7482 } 7483 } 7484 return killed; 7485 } 7486 7487 @Override 7488 public boolean killProcessesBelowForeground(String reason) { 7489 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7490 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7491 } 7492 7493 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7494 } 7495 7496 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7497 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7498 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7499 } 7500 7501 boolean killed = false; 7502 synchronized (mPidsSelfLocked) { 7503 final int size = mPidsSelfLocked.size(); 7504 for (int i = 0; i < size; i++) { 7505 final int pid = mPidsSelfLocked.keyAt(i); 7506 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7507 if (proc == null) continue; 7508 7509 final int adj = proc.setAdj; 7510 if (adj > belowAdj && !proc.killedBackground) { 7511 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7512 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, 7513 proc.pid, proc.processName, adj, reason); 7514 killed = true; 7515 proc.killedBackground = true; 7516 Process.killProcessQuiet(pid); 7517 } 7518 } 7519 } 7520 return killed; 7521 } 7522 7523 public final void startRunning(String pkg, String cls, String action, 7524 String data) { 7525 synchronized(this) { 7526 if (mStartRunning) { 7527 return; 7528 } 7529 mStartRunning = true; 7530 mTopComponent = pkg != null && cls != null 7531 ? new ComponentName(pkg, cls) : null; 7532 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7533 mTopData = data; 7534 if (!mSystemReady) { 7535 return; 7536 } 7537 } 7538 7539 systemReady(null); 7540 } 7541 7542 private void retrieveSettings() { 7543 final ContentResolver resolver = mContext.getContentResolver(); 7544 String debugApp = Settings.System.getString( 7545 resolver, Settings.System.DEBUG_APP); 7546 boolean waitForDebugger = Settings.System.getInt( 7547 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7548 boolean alwaysFinishActivities = Settings.System.getInt( 7549 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7550 7551 Configuration configuration = new Configuration(); 7552 Settings.System.getConfiguration(resolver, configuration); 7553 7554 synchronized (this) { 7555 mDebugApp = mOrigDebugApp = debugApp; 7556 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7557 mAlwaysFinishActivities = alwaysFinishActivities; 7558 // This happens before any activities are started, so we can 7559 // change mConfiguration in-place. 7560 updateConfigurationLocked(configuration, null, false, true); 7561 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7562 } 7563 } 7564 7565 public boolean testIsSystemReady() { 7566 // no need to synchronize(this) just to read & return the value 7567 return mSystemReady; 7568 } 7569 7570 private static File getCalledPreBootReceiversFile() { 7571 File dataDir = Environment.getDataDirectory(); 7572 File systemDir = new File(dataDir, "system"); 7573 File fname = new File(systemDir, "called_pre_boots.dat"); 7574 return fname; 7575 } 7576 7577 static final int LAST_DONE_VERSION = 10000; 7578 7579 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7580 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7581 File file = getCalledPreBootReceiversFile(); 7582 FileInputStream fis = null; 7583 try { 7584 fis = new FileInputStream(file); 7585 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7586 int fvers = dis.readInt(); 7587 if (fvers == LAST_DONE_VERSION) { 7588 String vers = dis.readUTF(); 7589 String codename = dis.readUTF(); 7590 String build = dis.readUTF(); 7591 if (android.os.Build.VERSION.RELEASE.equals(vers) 7592 && android.os.Build.VERSION.CODENAME.equals(codename) 7593 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7594 int num = dis.readInt(); 7595 while (num > 0) { 7596 num--; 7597 String pkg = dis.readUTF(); 7598 String cls = dis.readUTF(); 7599 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7600 } 7601 } 7602 } 7603 } catch (FileNotFoundException e) { 7604 } catch (IOException e) { 7605 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7606 } finally { 7607 if (fis != null) { 7608 try { 7609 fis.close(); 7610 } catch (IOException e) { 7611 } 7612 } 7613 } 7614 return lastDoneReceivers; 7615 } 7616 7617 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7618 File file = getCalledPreBootReceiversFile(); 7619 FileOutputStream fos = null; 7620 DataOutputStream dos = null; 7621 try { 7622 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7623 fos = new FileOutputStream(file); 7624 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7625 dos.writeInt(LAST_DONE_VERSION); 7626 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7627 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7628 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7629 dos.writeInt(list.size()); 7630 for (int i=0; i<list.size(); i++) { 7631 dos.writeUTF(list.get(i).getPackageName()); 7632 dos.writeUTF(list.get(i).getClassName()); 7633 } 7634 } catch (IOException e) { 7635 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7636 file.delete(); 7637 } finally { 7638 FileUtils.sync(fos); 7639 if (dos != null) { 7640 try { 7641 dos.close(); 7642 } catch (IOException e) { 7643 // TODO Auto-generated catch block 7644 e.printStackTrace(); 7645 } 7646 } 7647 } 7648 } 7649 7650 public void systemReady(final Runnable goingCallback) { 7651 synchronized(this) { 7652 if (mSystemReady) { 7653 if (goingCallback != null) goingCallback.run(); 7654 return; 7655 } 7656 7657 // Check to see if there are any update receivers to run. 7658 if (!mDidUpdate) { 7659 if (mWaitingUpdate) { 7660 return; 7661 } 7662 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7663 List<ResolveInfo> ris = null; 7664 try { 7665 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7666 intent, null, 0, 0); 7667 } catch (RemoteException e) { 7668 } 7669 if (ris != null) { 7670 for (int i=ris.size()-1; i>=0; i--) { 7671 if ((ris.get(i).activityInfo.applicationInfo.flags 7672 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7673 ris.remove(i); 7674 } 7675 } 7676 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7677 7678 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7679 7680 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7681 for (int i=0; i<ris.size(); i++) { 7682 ActivityInfo ai = ris.get(i).activityInfo; 7683 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7684 if (lastDoneReceivers.contains(comp)) { 7685 ris.remove(i); 7686 i--; 7687 } 7688 } 7689 7690 final int[] users = getUsersLocked(); 7691 for (int i=0; i<ris.size(); i++) { 7692 ActivityInfo ai = ris.get(i).activityInfo; 7693 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7694 doneReceivers.add(comp); 7695 intent.setComponent(comp); 7696 for (int j=0; j<users.length; j++) { 7697 IIntentReceiver finisher = null; 7698 if (i == ris.size()-1 && j == users.length-1) { 7699 finisher = new IIntentReceiver.Stub() { 7700 public void performReceive(Intent intent, int resultCode, 7701 String data, Bundle extras, boolean ordered, 7702 boolean sticky, int sendingUser) { 7703 // The raw IIntentReceiver interface is called 7704 // with the AM lock held, so redispatch to 7705 // execute our code without the lock. 7706 mHandler.post(new Runnable() { 7707 public void run() { 7708 synchronized (ActivityManagerService.this) { 7709 mDidUpdate = true; 7710 } 7711 writeLastDonePreBootReceivers(doneReceivers); 7712 showBootMessage(mContext.getText( 7713 R.string.android_upgrading_complete), 7714 false); 7715 systemReady(goingCallback); 7716 } 7717 }); 7718 } 7719 }; 7720 } 7721 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7722 + " for user " + users[j]); 7723 broadcastIntentLocked(null, null, intent, null, finisher, 7724 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7725 users[j]); 7726 if (finisher != null) { 7727 mWaitingUpdate = true; 7728 } 7729 } 7730 } 7731 } 7732 if (mWaitingUpdate) { 7733 return; 7734 } 7735 mDidUpdate = true; 7736 } 7737 7738 mSystemReady = true; 7739 if (!mStartRunning) { 7740 return; 7741 } 7742 } 7743 7744 ArrayList<ProcessRecord> procsToKill = null; 7745 synchronized(mPidsSelfLocked) { 7746 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7747 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7748 if (!isAllowedWhileBooting(proc.info)){ 7749 if (procsToKill == null) { 7750 procsToKill = new ArrayList<ProcessRecord>(); 7751 } 7752 procsToKill.add(proc); 7753 } 7754 } 7755 } 7756 7757 synchronized(this) { 7758 if (procsToKill != null) { 7759 for (int i=procsToKill.size()-1; i>=0; i--) { 7760 ProcessRecord proc = procsToKill.get(i); 7761 Slog.i(TAG, "Removing system update proc: " + proc); 7762 removeProcessLocked(proc, true, false, "system update done"); 7763 } 7764 } 7765 7766 // Now that we have cleaned up any update processes, we 7767 // are ready to start launching real processes and know that 7768 // we won't trample on them any more. 7769 mProcessesReady = true; 7770 } 7771 7772 Slog.i(TAG, "System now ready"); 7773 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7774 SystemClock.uptimeMillis()); 7775 7776 synchronized(this) { 7777 // Make sure we have no pre-ready processes sitting around. 7778 7779 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7780 ResolveInfo ri = mContext.getPackageManager() 7781 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7782 STOCK_PM_FLAGS); 7783 CharSequence errorMsg = null; 7784 if (ri != null) { 7785 ActivityInfo ai = ri.activityInfo; 7786 ApplicationInfo app = ai.applicationInfo; 7787 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7788 mTopAction = Intent.ACTION_FACTORY_TEST; 7789 mTopData = null; 7790 mTopComponent = new ComponentName(app.packageName, 7791 ai.name); 7792 } else { 7793 errorMsg = mContext.getResources().getText( 7794 com.android.internal.R.string.factorytest_not_system); 7795 } 7796 } else { 7797 errorMsg = mContext.getResources().getText( 7798 com.android.internal.R.string.factorytest_no_action); 7799 } 7800 if (errorMsg != null) { 7801 mTopAction = null; 7802 mTopData = null; 7803 mTopComponent = null; 7804 Message msg = Message.obtain(); 7805 msg.what = SHOW_FACTORY_ERROR_MSG; 7806 msg.getData().putCharSequence("msg", errorMsg); 7807 mHandler.sendMessage(msg); 7808 } 7809 } 7810 } 7811 7812 retrieveSettings(); 7813 7814 if (goingCallback != null) goingCallback.run(); 7815 7816 synchronized (this) { 7817 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7818 try { 7819 List apps = AppGlobals.getPackageManager(). 7820 getPersistentApplications(STOCK_PM_FLAGS); 7821 if (apps != null) { 7822 int N = apps.size(); 7823 int i; 7824 for (i=0; i<N; i++) { 7825 ApplicationInfo info 7826 = (ApplicationInfo)apps.get(i); 7827 if (info != null && 7828 !info.packageName.equals("android")) { 7829 addAppLocked(info, false); 7830 } 7831 } 7832 } 7833 } catch (RemoteException ex) { 7834 // pm is in same process, this will never happen. 7835 } 7836 } 7837 7838 // Start up initial activity. 7839 mBooting = true; 7840 7841 try { 7842 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7843 Message msg = Message.obtain(); 7844 msg.what = SHOW_UID_ERROR_MSG; 7845 mHandler.sendMessage(msg); 7846 } 7847 } catch (RemoteException e) { 7848 } 7849 7850 long ident = Binder.clearCallingIdentity(); 7851 try { 7852 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7853 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 7854 | Intent.FLAG_RECEIVER_FOREGROUND); 7855 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7856 broadcastIntentLocked(null, null, intent, 7857 null, null, 0, null, null, null, 7858 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7859 } finally { 7860 Binder.restoreCallingIdentity(ident); 7861 } 7862 mMainStack.resumeTopActivityLocked(null); 7863 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7864 } 7865 } 7866 7867 private boolean makeAppCrashingLocked(ProcessRecord app, 7868 String shortMsg, String longMsg, String stackTrace) { 7869 app.crashing = true; 7870 app.crashingReport = generateProcessError(app, 7871 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7872 startAppProblemLocked(app); 7873 app.stopFreezingAllLocked(); 7874 return handleAppCrashLocked(app); 7875 } 7876 7877 private void makeAppNotRespondingLocked(ProcessRecord app, 7878 String activity, String shortMsg, String longMsg) { 7879 app.notResponding = true; 7880 app.notRespondingReport = generateProcessError(app, 7881 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7882 activity, shortMsg, longMsg, null); 7883 startAppProblemLocked(app); 7884 app.stopFreezingAllLocked(); 7885 } 7886 7887 /** 7888 * Generate a process error record, suitable for attachment to a ProcessRecord. 7889 * 7890 * @param app The ProcessRecord in which the error occurred. 7891 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7892 * ActivityManager.AppErrorStateInfo 7893 * @param activity The activity associated with the crash, if known. 7894 * @param shortMsg Short message describing the crash. 7895 * @param longMsg Long message describing the crash. 7896 * @param stackTrace Full crash stack trace, may be null. 7897 * 7898 * @return Returns a fully-formed AppErrorStateInfo record. 7899 */ 7900 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7901 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7902 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7903 7904 report.condition = condition; 7905 report.processName = app.processName; 7906 report.pid = app.pid; 7907 report.uid = app.info.uid; 7908 report.tag = activity; 7909 report.shortMsg = shortMsg; 7910 report.longMsg = longMsg; 7911 report.stackTrace = stackTrace; 7912 7913 return report; 7914 } 7915 7916 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7917 synchronized (this) { 7918 app.crashing = false; 7919 app.crashingReport = null; 7920 app.notResponding = false; 7921 app.notRespondingReport = null; 7922 if (app.anrDialog == fromDialog) { 7923 app.anrDialog = null; 7924 } 7925 if (app.waitDialog == fromDialog) { 7926 app.waitDialog = null; 7927 } 7928 if (app.pid > 0 && app.pid != MY_PID) { 7929 handleAppCrashLocked(app); 7930 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7931 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 7932 app.processName, app.setAdj, "user's request after error"); 7933 Process.killProcessQuiet(app.pid); 7934 } 7935 } 7936 } 7937 7938 private boolean handleAppCrashLocked(ProcessRecord app) { 7939 if (mHeadless) { 7940 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7941 return false; 7942 } 7943 long now = SystemClock.uptimeMillis(); 7944 7945 Long crashTime; 7946 if (!app.isolated) { 7947 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7948 } else { 7949 crashTime = null; 7950 } 7951 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7952 // This process loses! 7953 Slog.w(TAG, "Process " + app.info.processName 7954 + " has crashed too many times: killing!"); 7955 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7956 app.userId, app.info.processName, app.uid); 7957 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7958 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7959 if (r.app == app) { 7960 Slog.w(TAG, " Force finishing activity " 7961 + r.intent.getComponent().flattenToShortString()); 7962 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7963 null, "crashed", false); 7964 } 7965 } 7966 if (!app.persistent) { 7967 // We don't want to start this process again until the user 7968 // explicitly does so... but for persistent process, we really 7969 // need to keep it running. If a persistent process is actually 7970 // repeatedly crashing, then badness for everyone. 7971 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 7972 app.info.processName); 7973 if (!app.isolated) { 7974 // XXX We don't have a way to mark isolated processes 7975 // as bad, since they don't have a peristent identity. 7976 mBadProcesses.put(app.info.processName, app.uid, now); 7977 mProcessCrashTimes.remove(app.info.processName, app.uid); 7978 } 7979 app.bad = true; 7980 app.removed = true; 7981 // Don't let services in this process be restarted and potentially 7982 // annoy the user repeatedly. Unless it is persistent, since those 7983 // processes run critical code. 7984 removeProcessLocked(app, false, false, "crash"); 7985 mMainStack.resumeTopActivityLocked(null); 7986 return false; 7987 } 7988 mMainStack.resumeTopActivityLocked(null); 7989 } else { 7990 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7991 if (r != null && r.app == app) { 7992 // If the top running activity is from this crashing 7993 // process, then terminate it to avoid getting in a loop. 7994 Slog.w(TAG, " Force finishing activity " 7995 + r.intent.getComponent().flattenToShortString()); 7996 int index = mMainStack.indexOfActivityLocked(r); 7997 r.stack.finishActivityLocked(r, index, 7998 Activity.RESULT_CANCELED, null, "crashed", false); 7999 // Also terminate any activities below it that aren't yet 8000 // stopped, to avoid a situation where one will get 8001 // re-start our crashing activity once it gets resumed again. 8002 index--; 8003 if (index >= 0) { 8004 r = (ActivityRecord)mMainStack.mHistory.get(index); 8005 if (r.state == ActivityState.RESUMED 8006 || r.state == ActivityState.PAUSING 8007 || r.state == ActivityState.PAUSED) { 8008 if (!r.isHomeActivity || mHomeProcess != r.app) { 8009 Slog.w(TAG, " Force finishing activity " 8010 + r.intent.getComponent().flattenToShortString()); 8011 r.stack.finishActivityLocked(r, index, 8012 Activity.RESULT_CANCELED, null, "crashed", false); 8013 } 8014 } 8015 } 8016 } 8017 } 8018 8019 // Bump up the crash count of any services currently running in the proc. 8020 if (app.services.size() != 0) { 8021 // Any services running in the application need to be placed 8022 // back in the pending list. 8023 Iterator<ServiceRecord> it = app.services.iterator(); 8024 while (it.hasNext()) { 8025 ServiceRecord sr = it.next(); 8026 sr.crashCount++; 8027 } 8028 } 8029 8030 // If the crashing process is what we consider to be the "home process" and it has been 8031 // replaced by a third-party app, clear the package preferred activities from packages 8032 // with a home activity running in the process to prevent a repeatedly crashing app 8033 // from blocking the user to manually clear the list. 8034 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8035 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8036 Iterator it = mHomeProcess.activities.iterator(); 8037 while (it.hasNext()) { 8038 ActivityRecord r = (ActivityRecord)it.next(); 8039 if (r.isHomeActivity) { 8040 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8041 try { 8042 ActivityThread.getPackageManager() 8043 .clearPackagePreferredActivities(r.packageName); 8044 } catch (RemoteException c) { 8045 // pm is in same process, this will never happen. 8046 } 8047 } 8048 } 8049 } 8050 8051 if (!app.isolated) { 8052 // XXX Can't keep track of crash times for isolated processes, 8053 // because they don't have a perisistent identity. 8054 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8055 } 8056 8057 return true; 8058 } 8059 8060 void startAppProblemLocked(ProcessRecord app) { 8061 if (app.userId == mCurrentUserId) { 8062 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8063 mContext, app.info.packageName, app.info.flags); 8064 } else { 8065 // If this app is not running under the current user, then we 8066 // can't give it a report button because that would require 8067 // launching the report UI under a different user. 8068 app.errorReportReceiver = null; 8069 } 8070 skipCurrentReceiverLocked(app); 8071 } 8072 8073 void skipCurrentReceiverLocked(ProcessRecord app) { 8074 for (BroadcastQueue queue : mBroadcastQueues) { 8075 queue.skipCurrentReceiverLocked(app); 8076 } 8077 } 8078 8079 /** 8080 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8081 * The application process will exit immediately after this call returns. 8082 * @param app object of the crashing app, null for the system server 8083 * @param crashInfo describing the exception 8084 */ 8085 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8086 ProcessRecord r = findAppProcess(app, "Crash"); 8087 final String processName = app == null ? "system_server" 8088 : (r == null ? "unknown" : r.processName); 8089 8090 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8091 UserHandle.getUserId(Binder.getCallingUid()), processName, 8092 r == null ? -1 : r.info.flags, 8093 crashInfo.exceptionClassName, 8094 crashInfo.exceptionMessage, 8095 crashInfo.throwFileName, 8096 crashInfo.throwLineNumber); 8097 8098 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8099 8100 crashApplication(r, crashInfo); 8101 } 8102 8103 public void handleApplicationStrictModeViolation( 8104 IBinder app, 8105 int violationMask, 8106 StrictMode.ViolationInfo info) { 8107 ProcessRecord r = findAppProcess(app, "StrictMode"); 8108 if (r == null) { 8109 return; 8110 } 8111 8112 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8113 Integer stackFingerprint = info.hashCode(); 8114 boolean logIt = true; 8115 synchronized (mAlreadyLoggedViolatedStacks) { 8116 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8117 logIt = false; 8118 // TODO: sub-sample into EventLog for these, with 8119 // the info.durationMillis? Then we'd get 8120 // the relative pain numbers, without logging all 8121 // the stack traces repeatedly. We'd want to do 8122 // likewise in the client code, which also does 8123 // dup suppression, before the Binder call. 8124 } else { 8125 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8126 mAlreadyLoggedViolatedStacks.clear(); 8127 } 8128 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8129 } 8130 } 8131 if (logIt) { 8132 logStrictModeViolationToDropBox(r, info); 8133 } 8134 } 8135 8136 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8137 AppErrorResult result = new AppErrorResult(); 8138 synchronized (this) { 8139 final long origId = Binder.clearCallingIdentity(); 8140 8141 Message msg = Message.obtain(); 8142 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8143 HashMap<String, Object> data = new HashMap<String, Object>(); 8144 data.put("result", result); 8145 data.put("app", r); 8146 data.put("violationMask", violationMask); 8147 data.put("info", info); 8148 msg.obj = data; 8149 mHandler.sendMessage(msg); 8150 8151 Binder.restoreCallingIdentity(origId); 8152 } 8153 int res = result.get(); 8154 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8155 } 8156 } 8157 8158 // Depending on the policy in effect, there could be a bunch of 8159 // these in quick succession so we try to batch these together to 8160 // minimize disk writes, number of dropbox entries, and maximize 8161 // compression, by having more fewer, larger records. 8162 private void logStrictModeViolationToDropBox( 8163 ProcessRecord process, 8164 StrictMode.ViolationInfo info) { 8165 if (info == null) { 8166 return; 8167 } 8168 final boolean isSystemApp = process == null || 8169 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8170 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8171 final String processName = process == null ? "unknown" : process.processName; 8172 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8173 final DropBoxManager dbox = (DropBoxManager) 8174 mContext.getSystemService(Context.DROPBOX_SERVICE); 8175 8176 // Exit early if the dropbox isn't configured to accept this report type. 8177 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8178 8179 boolean bufferWasEmpty; 8180 boolean needsFlush; 8181 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8182 synchronized (sb) { 8183 bufferWasEmpty = sb.length() == 0; 8184 appendDropBoxProcessHeaders(process, processName, sb); 8185 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8186 sb.append("System-App: ").append(isSystemApp).append("\n"); 8187 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8188 if (info.violationNumThisLoop != 0) { 8189 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8190 } 8191 if (info.numAnimationsRunning != 0) { 8192 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8193 } 8194 if (info.broadcastIntentAction != null) { 8195 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8196 } 8197 if (info.durationMillis != -1) { 8198 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8199 } 8200 if (info.numInstances != -1) { 8201 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8202 } 8203 if (info.tags != null) { 8204 for (String tag : info.tags) { 8205 sb.append("Span-Tag: ").append(tag).append("\n"); 8206 } 8207 } 8208 sb.append("\n"); 8209 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8210 sb.append(info.crashInfo.stackTrace); 8211 } 8212 sb.append("\n"); 8213 8214 // Only buffer up to ~64k. Various logging bits truncate 8215 // things at 128k. 8216 needsFlush = (sb.length() > 64 * 1024); 8217 } 8218 8219 // Flush immediately if the buffer's grown too large, or this 8220 // is a non-system app. Non-system apps are isolated with a 8221 // different tag & policy and not batched. 8222 // 8223 // Batching is useful during internal testing with 8224 // StrictMode settings turned up high. Without batching, 8225 // thousands of separate files could be created on boot. 8226 if (!isSystemApp || needsFlush) { 8227 new Thread("Error dump: " + dropboxTag) { 8228 @Override 8229 public void run() { 8230 String report; 8231 synchronized (sb) { 8232 report = sb.toString(); 8233 sb.delete(0, sb.length()); 8234 sb.trimToSize(); 8235 } 8236 if (report.length() != 0) { 8237 dbox.addText(dropboxTag, report); 8238 } 8239 } 8240 }.start(); 8241 return; 8242 } 8243 8244 // System app batching: 8245 if (!bufferWasEmpty) { 8246 // An existing dropbox-writing thread is outstanding, so 8247 // we don't need to start it up. The existing thread will 8248 // catch the buffer appends we just did. 8249 return; 8250 } 8251 8252 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8253 // (After this point, we shouldn't access AMS internal data structures.) 8254 new Thread("Error dump: " + dropboxTag) { 8255 @Override 8256 public void run() { 8257 // 5 second sleep to let stacks arrive and be batched together 8258 try { 8259 Thread.sleep(5000); // 5 seconds 8260 } catch (InterruptedException e) {} 8261 8262 String errorReport; 8263 synchronized (mStrictModeBuffer) { 8264 errorReport = mStrictModeBuffer.toString(); 8265 if (errorReport.length() == 0) { 8266 return; 8267 } 8268 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8269 mStrictModeBuffer.trimToSize(); 8270 } 8271 dbox.addText(dropboxTag, errorReport); 8272 } 8273 }.start(); 8274 } 8275 8276 /** 8277 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8278 * @param app object of the crashing app, null for the system server 8279 * @param tag reported by the caller 8280 * @param crashInfo describing the context of the error 8281 * @return true if the process should exit immediately (WTF is fatal) 8282 */ 8283 public boolean handleApplicationWtf(IBinder app, String tag, 8284 ApplicationErrorReport.CrashInfo crashInfo) { 8285 ProcessRecord r = findAppProcess(app, "WTF"); 8286 final String processName = app == null ? "system_server" 8287 : (r == null ? "unknown" : r.processName); 8288 8289 EventLog.writeEvent(EventLogTags.AM_WTF, 8290 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 8291 processName, 8292 r == null ? -1 : r.info.flags, 8293 tag, crashInfo.exceptionMessage); 8294 8295 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8296 8297 if (r != null && r.pid != Process.myPid() && 8298 Settings.Global.getInt(mContext.getContentResolver(), 8299 Settings.Global.WTF_IS_FATAL, 0) != 0) { 8300 crashApplication(r, crashInfo); 8301 return true; 8302 } else { 8303 return false; 8304 } 8305 } 8306 8307 /** 8308 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8309 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8310 */ 8311 private ProcessRecord findAppProcess(IBinder app, String reason) { 8312 if (app == null) { 8313 return null; 8314 } 8315 8316 synchronized (this) { 8317 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8318 final int NA = apps.size(); 8319 for (int ia=0; ia<NA; ia++) { 8320 ProcessRecord p = apps.valueAt(ia); 8321 if (p.thread != null && p.thread.asBinder() == app) { 8322 return p; 8323 } 8324 } 8325 } 8326 8327 Slog.w(TAG, "Can't find mystery application for " + reason 8328 + " from pid=" + Binder.getCallingPid() 8329 + " uid=" + Binder.getCallingUid() + ": " + app); 8330 return null; 8331 } 8332 } 8333 8334 /** 8335 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8336 * to append various headers to the dropbox log text. 8337 */ 8338 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8339 StringBuilder sb) { 8340 // Watchdog thread ends up invoking this function (with 8341 // a null ProcessRecord) to add the stack file to dropbox. 8342 // Do not acquire a lock on this (am) in such cases, as it 8343 // could cause a potential deadlock, if and when watchdog 8344 // is invoked due to unavailability of lock on am and it 8345 // would prevent watchdog from killing system_server. 8346 if (process == null) { 8347 sb.append("Process: ").append(processName).append("\n"); 8348 return; 8349 } 8350 // Note: ProcessRecord 'process' is guarded by the service 8351 // instance. (notably process.pkgList, which could otherwise change 8352 // concurrently during execution of this method) 8353 synchronized (this) { 8354 sb.append("Process: ").append(processName).append("\n"); 8355 int flags = process.info.flags; 8356 IPackageManager pm = AppGlobals.getPackageManager(); 8357 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8358 for (String pkg : process.pkgList) { 8359 sb.append("Package: ").append(pkg); 8360 try { 8361 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8362 if (pi != null) { 8363 sb.append(" v").append(pi.versionCode); 8364 if (pi.versionName != null) { 8365 sb.append(" (").append(pi.versionName).append(")"); 8366 } 8367 } 8368 } catch (RemoteException e) { 8369 Slog.e(TAG, "Error getting package info: " + pkg, e); 8370 } 8371 sb.append("\n"); 8372 } 8373 } 8374 } 8375 8376 private static String processClass(ProcessRecord process) { 8377 if (process == null || process.pid == MY_PID) { 8378 return "system_server"; 8379 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8380 return "system_app"; 8381 } else { 8382 return "data_app"; 8383 } 8384 } 8385 8386 /** 8387 * Write a description of an error (crash, WTF, ANR) to the drop box. 8388 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8389 * @param process which caused the error, null means the system server 8390 * @param activity which triggered the error, null if unknown 8391 * @param parent activity related to the error, null if unknown 8392 * @param subject line related to the error, null if absent 8393 * @param report in long form describing the error, null if absent 8394 * @param logFile to include in the report, null if none 8395 * @param crashInfo giving an application stack trace, null if absent 8396 */ 8397 public void addErrorToDropBox(String eventType, 8398 ProcessRecord process, String processName, ActivityRecord activity, 8399 ActivityRecord parent, String subject, 8400 final String report, final File logFile, 8401 final ApplicationErrorReport.CrashInfo crashInfo) { 8402 // NOTE -- this must never acquire the ActivityManagerService lock, 8403 // otherwise the watchdog may be prevented from resetting the system. 8404 8405 final String dropboxTag = processClass(process) + "_" + eventType; 8406 final DropBoxManager dbox = (DropBoxManager) 8407 mContext.getSystemService(Context.DROPBOX_SERVICE); 8408 8409 // Exit early if the dropbox isn't configured to accept this report type. 8410 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8411 8412 final StringBuilder sb = new StringBuilder(1024); 8413 appendDropBoxProcessHeaders(process, processName, sb); 8414 if (activity != null) { 8415 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8416 } 8417 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8418 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8419 } 8420 if (parent != null && parent != activity) { 8421 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8422 } 8423 if (subject != null) { 8424 sb.append("Subject: ").append(subject).append("\n"); 8425 } 8426 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8427 if (Debug.isDebuggerConnected()) { 8428 sb.append("Debugger: Connected\n"); 8429 } 8430 sb.append("\n"); 8431 8432 // Do the rest in a worker thread to avoid blocking the caller on I/O 8433 // (After this point, we shouldn't access AMS internal data structures.) 8434 Thread worker = new Thread("Error dump: " + dropboxTag) { 8435 @Override 8436 public void run() { 8437 if (report != null) { 8438 sb.append(report); 8439 } 8440 if (logFile != null) { 8441 try { 8442 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8443 } catch (IOException e) { 8444 Slog.e(TAG, "Error reading " + logFile, e); 8445 } 8446 } 8447 if (crashInfo != null && crashInfo.stackTrace != null) { 8448 sb.append(crashInfo.stackTrace); 8449 } 8450 8451 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 8452 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 8453 if (lines > 0) { 8454 sb.append("\n"); 8455 8456 // Merge several logcat streams, and take the last N lines 8457 InputStreamReader input = null; 8458 try { 8459 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8460 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8461 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8462 8463 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8464 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8465 input = new InputStreamReader(logcat.getInputStream()); 8466 8467 int num; 8468 char[] buf = new char[8192]; 8469 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8470 } catch (IOException e) { 8471 Slog.e(TAG, "Error running logcat", e); 8472 } finally { 8473 if (input != null) try { input.close(); } catch (IOException e) {} 8474 } 8475 } 8476 8477 dbox.addText(dropboxTag, sb.toString()); 8478 } 8479 }; 8480 8481 if (process == null) { 8482 // If process is null, we are being called from some internal code 8483 // and may be about to die -- run this synchronously. 8484 worker.run(); 8485 } else { 8486 worker.start(); 8487 } 8488 } 8489 8490 /** 8491 * Bring up the "unexpected error" dialog box for a crashing app. 8492 * Deal with edge cases (intercepts from instrumented applications, 8493 * ActivityController, error intent receivers, that sort of thing). 8494 * @param r the application crashing 8495 * @param crashInfo describing the failure 8496 */ 8497 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8498 long timeMillis = System.currentTimeMillis(); 8499 String shortMsg = crashInfo.exceptionClassName; 8500 String longMsg = crashInfo.exceptionMessage; 8501 String stackTrace = crashInfo.stackTrace; 8502 if (shortMsg != null && longMsg != null) { 8503 longMsg = shortMsg + ": " + longMsg; 8504 } else if (shortMsg != null) { 8505 longMsg = shortMsg; 8506 } 8507 8508 AppErrorResult result = new AppErrorResult(); 8509 synchronized (this) { 8510 if (mController != null) { 8511 try { 8512 String name = r != null ? r.processName : null; 8513 int pid = r != null ? r.pid : Binder.getCallingPid(); 8514 if (!mController.appCrashed(name, pid, 8515 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8516 Slog.w(TAG, "Force-killing crashed app " + name 8517 + " at watcher's request"); 8518 Process.killProcess(pid); 8519 return; 8520 } 8521 } catch (RemoteException e) { 8522 mController = null; 8523 } 8524 } 8525 8526 final long origId = Binder.clearCallingIdentity(); 8527 8528 // If this process is running instrumentation, finish it. 8529 if (r != null && r.instrumentationClass != null) { 8530 Slog.w(TAG, "Error in app " + r.processName 8531 + " running instrumentation " + r.instrumentationClass + ":"); 8532 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8533 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8534 Bundle info = new Bundle(); 8535 info.putString("shortMsg", shortMsg); 8536 info.putString("longMsg", longMsg); 8537 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8538 Binder.restoreCallingIdentity(origId); 8539 return; 8540 } 8541 8542 // If we can't identify the process or it's already exceeded its crash quota, 8543 // quit right away without showing a crash dialog. 8544 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8545 Binder.restoreCallingIdentity(origId); 8546 return; 8547 } 8548 8549 Message msg = Message.obtain(); 8550 msg.what = SHOW_ERROR_MSG; 8551 HashMap data = new HashMap(); 8552 data.put("result", result); 8553 data.put("app", r); 8554 msg.obj = data; 8555 mHandler.sendMessage(msg); 8556 8557 Binder.restoreCallingIdentity(origId); 8558 } 8559 8560 int res = result.get(); 8561 8562 Intent appErrorIntent = null; 8563 synchronized (this) { 8564 if (r != null && !r.isolated) { 8565 // XXX Can't keep track of crash time for isolated processes, 8566 // since they don't have a persistent identity. 8567 mProcessCrashTimes.put(r.info.processName, r.uid, 8568 SystemClock.uptimeMillis()); 8569 } 8570 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8571 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8572 } 8573 } 8574 8575 if (appErrorIntent != null) { 8576 try { 8577 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 8578 } catch (ActivityNotFoundException e) { 8579 Slog.w(TAG, "bug report receiver dissappeared", e); 8580 } 8581 } 8582 } 8583 8584 Intent createAppErrorIntentLocked(ProcessRecord r, 8585 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8586 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8587 if (report == null) { 8588 return null; 8589 } 8590 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8591 result.setComponent(r.errorReportReceiver); 8592 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8593 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8594 return result; 8595 } 8596 8597 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8598 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8599 if (r.errorReportReceiver == null) { 8600 return null; 8601 } 8602 8603 if (!r.crashing && !r.notResponding) { 8604 return null; 8605 } 8606 8607 ApplicationErrorReport report = new ApplicationErrorReport(); 8608 report.packageName = r.info.packageName; 8609 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8610 report.processName = r.processName; 8611 report.time = timeMillis; 8612 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8613 8614 if (r.crashing) { 8615 report.type = ApplicationErrorReport.TYPE_CRASH; 8616 report.crashInfo = crashInfo; 8617 } else if (r.notResponding) { 8618 report.type = ApplicationErrorReport.TYPE_ANR; 8619 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8620 8621 report.anrInfo.activity = r.notRespondingReport.tag; 8622 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8623 report.anrInfo.info = r.notRespondingReport.longMsg; 8624 } 8625 8626 return report; 8627 } 8628 8629 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8630 enforceNotIsolatedCaller("getProcessesInErrorState"); 8631 // assume our apps are happy - lazy create the list 8632 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8633 8634 final boolean allUsers = ActivityManager.checkUidPermission( 8635 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8636 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8637 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8638 8639 synchronized (this) { 8640 8641 // iterate across all processes 8642 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8643 ProcessRecord app = mLruProcesses.get(i); 8644 if (!allUsers && app.userId != userId) { 8645 continue; 8646 } 8647 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8648 // This one's in trouble, so we'll generate a report for it 8649 // crashes are higher priority (in case there's a crash *and* an anr) 8650 ActivityManager.ProcessErrorStateInfo report = null; 8651 if (app.crashing) { 8652 report = app.crashingReport; 8653 } else if (app.notResponding) { 8654 report = app.notRespondingReport; 8655 } 8656 8657 if (report != null) { 8658 if (errList == null) { 8659 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8660 } 8661 errList.add(report); 8662 } else { 8663 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8664 " crashing = " + app.crashing + 8665 " notResponding = " + app.notResponding); 8666 } 8667 } 8668 } 8669 } 8670 8671 return errList; 8672 } 8673 8674 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8675 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8676 if (currApp != null) { 8677 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8678 } 8679 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8680 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8681 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8682 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8683 if (currApp != null) { 8684 currApp.lru = 0; 8685 } 8686 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8687 } else if (adj >= ProcessList.SERVICE_ADJ) { 8688 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8689 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8690 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8691 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8692 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8693 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8694 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8695 } else { 8696 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8697 } 8698 } 8699 8700 private void fillInProcMemInfo(ProcessRecord app, 8701 ActivityManager.RunningAppProcessInfo outInfo) { 8702 outInfo.pid = app.pid; 8703 outInfo.uid = app.info.uid; 8704 if (mHeavyWeightProcess == app) { 8705 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8706 } 8707 if (app.persistent) { 8708 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8709 } 8710 if (app.hasActivities) { 8711 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8712 } 8713 outInfo.lastTrimLevel = app.trimMemoryLevel; 8714 int adj = app.curAdj; 8715 outInfo.importance = oomAdjToImportance(adj, outInfo); 8716 outInfo.importanceReasonCode = app.adjTypeCode; 8717 } 8718 8719 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8720 enforceNotIsolatedCaller("getRunningAppProcesses"); 8721 // Lazy instantiation of list 8722 List<ActivityManager.RunningAppProcessInfo> runList = null; 8723 final boolean allUsers = ActivityManager.checkUidPermission( 8724 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8725 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8726 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8727 synchronized (this) { 8728 // Iterate across all processes 8729 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8730 ProcessRecord app = mLruProcesses.get(i); 8731 if (!allUsers && app.userId != userId) { 8732 continue; 8733 } 8734 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8735 // Generate process state info for running application 8736 ActivityManager.RunningAppProcessInfo currApp = 8737 new ActivityManager.RunningAppProcessInfo(app.processName, 8738 app.pid, app.getPackageList()); 8739 fillInProcMemInfo(app, currApp); 8740 if (app.adjSource instanceof ProcessRecord) { 8741 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8742 currApp.importanceReasonImportance = oomAdjToImportance( 8743 app.adjSourceOom, null); 8744 } else if (app.adjSource instanceof ActivityRecord) { 8745 ActivityRecord r = (ActivityRecord)app.adjSource; 8746 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8747 } 8748 if (app.adjTarget instanceof ComponentName) { 8749 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8750 } 8751 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8752 // + " lru=" + currApp.lru); 8753 if (runList == null) { 8754 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8755 } 8756 runList.add(currApp); 8757 } 8758 } 8759 } 8760 return runList; 8761 } 8762 8763 public List<ApplicationInfo> getRunningExternalApplications() { 8764 enforceNotIsolatedCaller("getRunningExternalApplications"); 8765 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8766 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8767 if (runningApps != null && runningApps.size() > 0) { 8768 Set<String> extList = new HashSet<String>(); 8769 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8770 if (app.pkgList != null) { 8771 for (String pkg : app.pkgList) { 8772 extList.add(pkg); 8773 } 8774 } 8775 } 8776 IPackageManager pm = AppGlobals.getPackageManager(); 8777 for (String pkg : extList) { 8778 try { 8779 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8780 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8781 retList.add(info); 8782 } 8783 } catch (RemoteException e) { 8784 } 8785 } 8786 } 8787 return retList; 8788 } 8789 8790 @Override 8791 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8792 enforceNotIsolatedCaller("getMyMemoryState"); 8793 synchronized (this) { 8794 ProcessRecord proc; 8795 synchronized (mPidsSelfLocked) { 8796 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8797 } 8798 fillInProcMemInfo(proc, outInfo); 8799 } 8800 } 8801 8802 @Override 8803 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8804 if (checkCallingPermission(android.Manifest.permission.DUMP) 8805 != PackageManager.PERMISSION_GRANTED) { 8806 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8807 + Binder.getCallingPid() 8808 + ", uid=" + Binder.getCallingUid() 8809 + " without permission " 8810 + android.Manifest.permission.DUMP); 8811 return; 8812 } 8813 8814 boolean dumpAll = false; 8815 boolean dumpClient = false; 8816 String dumpPackage = null; 8817 8818 int opti = 0; 8819 while (opti < args.length) { 8820 String opt = args[opti]; 8821 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8822 break; 8823 } 8824 opti++; 8825 if ("-a".equals(opt)) { 8826 dumpAll = true; 8827 } else if ("-c".equals(opt)) { 8828 dumpClient = true; 8829 } else if ("-h".equals(opt)) { 8830 pw.println("Activity manager dump options:"); 8831 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8832 pw.println(" cmd may be one of:"); 8833 pw.println(" a[ctivities]: activity stack state"); 8834 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8835 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8836 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8837 pw.println(" o[om]: out of memory management"); 8838 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8839 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8840 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8841 pw.println(" service [COMP_SPEC]: service client-side state"); 8842 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8843 pw.println(" all: dump all activities"); 8844 pw.println(" top: dump the top activity"); 8845 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8846 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8847 pw.println(" a partial substring in a component name, a"); 8848 pw.println(" hex object identifier."); 8849 pw.println(" -a: include all available server state."); 8850 pw.println(" -c: include client state."); 8851 return; 8852 } else { 8853 pw.println("Unknown argument: " + opt + "; use -h for help"); 8854 } 8855 } 8856 8857 long origId = Binder.clearCallingIdentity(); 8858 boolean more = false; 8859 // Is the caller requesting to dump a particular piece of data? 8860 if (opti < args.length) { 8861 String cmd = args[opti]; 8862 opti++; 8863 if ("activities".equals(cmd) || "a".equals(cmd)) { 8864 synchronized (this) { 8865 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8866 } 8867 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8868 String[] newArgs; 8869 String name; 8870 if (opti >= args.length) { 8871 name = null; 8872 newArgs = EMPTY_STRING_ARRAY; 8873 } else { 8874 name = args[opti]; 8875 opti++; 8876 newArgs = new String[args.length - opti]; 8877 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8878 args.length - opti); 8879 } 8880 synchronized (this) { 8881 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8882 } 8883 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8884 String[] newArgs; 8885 String name; 8886 if (opti >= args.length) { 8887 name = null; 8888 newArgs = EMPTY_STRING_ARRAY; 8889 } else { 8890 name = args[opti]; 8891 opti++; 8892 newArgs = new String[args.length - opti]; 8893 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8894 args.length - opti); 8895 } 8896 synchronized (this) { 8897 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8898 } 8899 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8900 String[] newArgs; 8901 String name; 8902 if (opti >= args.length) { 8903 name = null; 8904 newArgs = EMPTY_STRING_ARRAY; 8905 } else { 8906 name = args[opti]; 8907 opti++; 8908 newArgs = new String[args.length - opti]; 8909 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8910 args.length - opti); 8911 } 8912 synchronized (this) { 8913 dumpProcessesLocked(fd, pw, args, opti, true, name); 8914 } 8915 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8916 synchronized (this) { 8917 dumpOomLocked(fd, pw, args, opti, true); 8918 } 8919 } else if ("provider".equals(cmd)) { 8920 String[] newArgs; 8921 String name; 8922 if (opti >= args.length) { 8923 name = null; 8924 newArgs = EMPTY_STRING_ARRAY; 8925 } else { 8926 name = args[opti]; 8927 opti++; 8928 newArgs = new String[args.length - opti]; 8929 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8930 } 8931 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8932 pw.println("No providers match: " + name); 8933 pw.println("Use -h for help."); 8934 } 8935 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8936 synchronized (this) { 8937 dumpProvidersLocked(fd, pw, args, opti, true, null); 8938 } 8939 } else if ("service".equals(cmd)) { 8940 String[] newArgs; 8941 String name; 8942 if (opti >= args.length) { 8943 name = null; 8944 newArgs = EMPTY_STRING_ARRAY; 8945 } else { 8946 name = args[opti]; 8947 opti++; 8948 newArgs = new String[args.length - opti]; 8949 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8950 args.length - opti); 8951 } 8952 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8953 pw.println("No services match: " + name); 8954 pw.println("Use -h for help."); 8955 } 8956 } else if ("package".equals(cmd)) { 8957 String[] newArgs; 8958 if (opti >= args.length) { 8959 pw.println("package: no package name specified"); 8960 pw.println("Use -h for help."); 8961 } else { 8962 dumpPackage = args[opti]; 8963 opti++; 8964 newArgs = new String[args.length - opti]; 8965 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8966 args.length - opti); 8967 args = newArgs; 8968 opti = 0; 8969 more = true; 8970 } 8971 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8972 synchronized (this) { 8973 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8974 } 8975 } else { 8976 // Dumping a single activity? 8977 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8978 pw.println("Bad activity command, or no activities match: " + cmd); 8979 pw.println("Use -h for help."); 8980 } 8981 } 8982 if (!more) { 8983 Binder.restoreCallingIdentity(origId); 8984 return; 8985 } 8986 } 8987 8988 // No piece of data specified, dump everything. 8989 synchronized (this) { 8990 boolean needSep; 8991 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8992 if (needSep) { 8993 pw.println(" "); 8994 } 8995 if (dumpAll) { 8996 pw.println("-------------------------------------------------------------------------------"); 8997 } 8998 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8999 if (needSep) { 9000 pw.println(" "); 9001 } 9002 if (dumpAll) { 9003 pw.println("-------------------------------------------------------------------------------"); 9004 } 9005 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9006 if (needSep) { 9007 pw.println(" "); 9008 } 9009 if (dumpAll) { 9010 pw.println("-------------------------------------------------------------------------------"); 9011 } 9012 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9013 if (needSep) { 9014 pw.println(" "); 9015 } 9016 if (dumpAll) { 9017 pw.println("-------------------------------------------------------------------------------"); 9018 } 9019 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9020 if (needSep) { 9021 pw.println(" "); 9022 } 9023 if (dumpAll) { 9024 pw.println("-------------------------------------------------------------------------------"); 9025 } 9026 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9027 } 9028 Binder.restoreCallingIdentity(origId); 9029 } 9030 9031 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9032 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9033 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9034 pw.println(" Main stack:"); 9035 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9036 dumpPackage); 9037 pw.println(" "); 9038 pw.println(" Running activities (most recent first):"); 9039 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9040 dumpPackage); 9041 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9042 pw.println(" "); 9043 pw.println(" Activities waiting for another to become visible:"); 9044 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9045 !dumpAll, false, dumpPackage); 9046 } 9047 if (mMainStack.mStoppingActivities.size() > 0) { 9048 pw.println(" "); 9049 pw.println(" Activities waiting to stop:"); 9050 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9051 !dumpAll, false, dumpPackage); 9052 } 9053 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9054 pw.println(" "); 9055 pw.println(" Activities waiting to sleep:"); 9056 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9057 !dumpAll, false, dumpPackage); 9058 } 9059 if (mMainStack.mFinishingActivities.size() > 0) { 9060 pw.println(" "); 9061 pw.println(" Activities waiting to finish:"); 9062 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9063 !dumpAll, false, dumpPackage); 9064 } 9065 9066 pw.println(" "); 9067 if (mMainStack.mPausingActivity != null) { 9068 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9069 } 9070 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9071 pw.println(" mFocusedActivity: " + mFocusedActivity); 9072 if (dumpAll) { 9073 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9074 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9075 pw.println(" mDismissKeyguardOnNextActivity: " 9076 + mMainStack.mDismissKeyguardOnNextActivity); 9077 } 9078 9079 if (mRecentTasks.size() > 0) { 9080 pw.println(); 9081 pw.println(" Recent tasks:"); 9082 9083 final int N = mRecentTasks.size(); 9084 for (int i=0; i<N; i++) { 9085 TaskRecord tr = mRecentTasks.get(i); 9086 if (dumpPackage != null) { 9087 if (tr.realActivity == null || 9088 !dumpPackage.equals(tr.realActivity)) { 9089 continue; 9090 } 9091 } 9092 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9093 pw.println(tr); 9094 if (dumpAll) { 9095 mRecentTasks.get(i).dump(pw, " "); 9096 } 9097 } 9098 } 9099 9100 if (dumpAll) { 9101 pw.println(" "); 9102 pw.println(" mCurTask: " + mCurTask); 9103 } 9104 9105 return true; 9106 } 9107 9108 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9109 int opti, boolean dumpAll, String dumpPackage) { 9110 boolean needSep = false; 9111 int numPers = 0; 9112 9113 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9114 9115 if (dumpAll) { 9116 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9117 final int NA = procs.size(); 9118 for (int ia=0; ia<NA; ia++) { 9119 ProcessRecord r = procs.valueAt(ia); 9120 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9121 continue; 9122 } 9123 if (!needSep) { 9124 pw.println(" All known processes:"); 9125 needSep = true; 9126 } 9127 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9128 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9129 pw.print(" "); pw.println(r); 9130 r.dump(pw, " "); 9131 if (r.persistent) { 9132 numPers++; 9133 } 9134 } 9135 } 9136 } 9137 9138 if (mIsolatedProcesses.size() > 0) { 9139 if (needSep) pw.println(" "); 9140 needSep = true; 9141 pw.println(" Isolated process list (sorted by uid):"); 9142 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9143 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9144 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9145 continue; 9146 } 9147 pw.println(String.format("%sIsolated #%2d: %s", 9148 " ", i, r.toString())); 9149 } 9150 } 9151 9152 if (mLruProcesses.size() > 0) { 9153 if (needSep) pw.println(" "); 9154 needSep = true; 9155 pw.println(" Process LRU list (sorted by oom_adj):"); 9156 dumpProcessOomList(pw, this, mLruProcesses, " ", 9157 "Proc", "PERS", false, dumpPackage); 9158 needSep = true; 9159 } 9160 9161 if (dumpAll) { 9162 synchronized (mPidsSelfLocked) { 9163 boolean printed = false; 9164 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9165 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9166 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9167 continue; 9168 } 9169 if (!printed) { 9170 if (needSep) pw.println(" "); 9171 needSep = true; 9172 pw.println(" PID mappings:"); 9173 printed = true; 9174 } 9175 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9176 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9177 } 9178 } 9179 } 9180 9181 if (mForegroundProcesses.size() > 0) { 9182 synchronized (mPidsSelfLocked) { 9183 boolean printed = false; 9184 for (int i=0; i<mForegroundProcesses.size(); i++) { 9185 ProcessRecord r = mPidsSelfLocked.get( 9186 mForegroundProcesses.valueAt(i).pid); 9187 if (dumpPackage != null && (r == null 9188 || !dumpPackage.equals(r.info.packageName))) { 9189 continue; 9190 } 9191 if (!printed) { 9192 if (needSep) pw.println(" "); 9193 needSep = true; 9194 pw.println(" Foreground Processes:"); 9195 printed = true; 9196 } 9197 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9198 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9199 } 9200 } 9201 } 9202 9203 if (mPersistentStartingProcesses.size() > 0) { 9204 if (needSep) pw.println(" "); 9205 needSep = true; 9206 pw.println(" Persisent processes that are starting:"); 9207 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9208 "Starting Norm", "Restarting PERS", dumpPackage); 9209 } 9210 9211 if (mRemovedProcesses.size() > 0) { 9212 if (needSep) pw.println(" "); 9213 needSep = true; 9214 pw.println(" Processes that are being removed:"); 9215 dumpProcessList(pw, this, mRemovedProcesses, " ", 9216 "Removed Norm", "Removed PERS", dumpPackage); 9217 } 9218 9219 if (mProcessesOnHold.size() > 0) { 9220 if (needSep) pw.println(" "); 9221 needSep = true; 9222 pw.println(" Processes that are on old until the system is ready:"); 9223 dumpProcessList(pw, this, mProcessesOnHold, " ", 9224 "OnHold Norm", "OnHold PERS", dumpPackage); 9225 } 9226 9227 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9228 9229 if (mProcessCrashTimes.getMap().size() > 0) { 9230 boolean printed = false; 9231 long now = SystemClock.uptimeMillis(); 9232 for (Map.Entry<String, SparseArray<Long>> procs 9233 : mProcessCrashTimes.getMap().entrySet()) { 9234 String pname = procs.getKey(); 9235 SparseArray<Long> uids = procs.getValue(); 9236 final int N = uids.size(); 9237 for (int i=0; i<N; i++) { 9238 int puid = uids.keyAt(i); 9239 ProcessRecord r = mProcessNames.get(pname, puid); 9240 if (dumpPackage != null && (r == null 9241 || !dumpPackage.equals(r.info.packageName))) { 9242 continue; 9243 } 9244 if (!printed) { 9245 if (needSep) pw.println(" "); 9246 needSep = true; 9247 pw.println(" Time since processes crashed:"); 9248 printed = true; 9249 } 9250 pw.print(" Process "); pw.print(pname); 9251 pw.print(" uid "); pw.print(puid); 9252 pw.print(": last crashed "); 9253 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9254 pw.println(" ago"); 9255 } 9256 } 9257 } 9258 9259 if (mBadProcesses.getMap().size() > 0) { 9260 boolean printed = false; 9261 for (Map.Entry<String, SparseArray<Long>> procs 9262 : mBadProcesses.getMap().entrySet()) { 9263 String pname = procs.getKey(); 9264 SparseArray<Long> uids = procs.getValue(); 9265 final int N = uids.size(); 9266 for (int i=0; i<N; i++) { 9267 int puid = uids.keyAt(i); 9268 ProcessRecord r = mProcessNames.get(pname, puid); 9269 if (dumpPackage != null && (r == null 9270 || !dumpPackage.equals(r.info.packageName))) { 9271 continue; 9272 } 9273 if (!printed) { 9274 if (needSep) pw.println(" "); 9275 needSep = true; 9276 pw.println(" Bad processes:"); 9277 } 9278 pw.print(" Bad process "); pw.print(pname); 9279 pw.print(" uid "); pw.print(puid); 9280 pw.print(": crashed at time "); 9281 pw.println(uids.valueAt(i)); 9282 } 9283 } 9284 } 9285 9286 pw.println(); 9287 pw.println(" mStartedUsers:"); 9288 for (int i=0; i<mStartedUsers.size(); i++) { 9289 UserStartedState uss = mStartedUsers.valueAt(i); 9290 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9291 pw.print(": "); uss.dump("", pw); 9292 } 9293 pw.print(" mUserLru: ["); 9294 for (int i=0; i<mUserLru.size(); i++) { 9295 if (i > 0) pw.print(", "); 9296 pw.print(mUserLru.get(i)); 9297 } 9298 pw.println("]"); 9299 if (dumpAll) { 9300 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9301 } 9302 pw.println(" mHomeProcess: " + mHomeProcess); 9303 pw.println(" mPreviousProcess: " + mPreviousProcess); 9304 if (dumpAll) { 9305 StringBuilder sb = new StringBuilder(128); 9306 sb.append(" mPreviousProcessVisibleTime: "); 9307 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9308 pw.println(sb); 9309 } 9310 if (mHeavyWeightProcess != null) { 9311 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9312 } 9313 pw.println(" mConfiguration: " + mConfiguration); 9314 if (dumpAll) { 9315 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9316 if (mCompatModePackages.getPackages().size() > 0) { 9317 boolean printed = false; 9318 for (Map.Entry<String, Integer> entry 9319 : mCompatModePackages.getPackages().entrySet()) { 9320 String pkg = entry.getKey(); 9321 int mode = entry.getValue(); 9322 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9323 continue; 9324 } 9325 if (!printed) { 9326 pw.println(" mScreenCompatPackages:"); 9327 printed = true; 9328 } 9329 pw.print(" "); pw.print(pkg); pw.print(": "); 9330 pw.print(mode); pw.println(); 9331 } 9332 } 9333 } 9334 if (mSleeping || mWentToSleep || mLockScreenShown) { 9335 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9336 + " mLockScreenShown " + mLockScreenShown); 9337 } 9338 if (mShuttingDown) { 9339 pw.println(" mShuttingDown=" + mShuttingDown); 9340 } 9341 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9342 || mOrigWaitForDebugger) { 9343 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9344 + " mDebugTransient=" + mDebugTransient 9345 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9346 } 9347 if (mOpenGlTraceApp != null) { 9348 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9349 } 9350 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9351 || mProfileFd != null) { 9352 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9353 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9354 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9355 + mAutoStopProfiler); 9356 } 9357 if (mAlwaysFinishActivities || mController != null) { 9358 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9359 + " mController=" + mController); 9360 } 9361 if (dumpAll) { 9362 pw.println(" Total persistent processes: " + numPers); 9363 pw.println(" mStartRunning=" + mStartRunning 9364 + " mProcessesReady=" + mProcessesReady 9365 + " mSystemReady=" + mSystemReady); 9366 pw.println(" mBooting=" + mBooting 9367 + " mBooted=" + mBooted 9368 + " mFactoryTest=" + mFactoryTest); 9369 pw.print(" mLastPowerCheckRealtime="); 9370 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9371 pw.println(""); 9372 pw.print(" mLastPowerCheckUptime="); 9373 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9374 pw.println(""); 9375 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9376 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9377 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9378 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9379 + " mNumHiddenProcs=" + mNumHiddenProcs 9380 + " mNumServiceProcs=" + mNumServiceProcs 9381 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9382 } 9383 9384 return true; 9385 } 9386 9387 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9388 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9389 if (mProcessesToGc.size() > 0) { 9390 boolean printed = false; 9391 long now = SystemClock.uptimeMillis(); 9392 for (int i=0; i<mProcessesToGc.size(); i++) { 9393 ProcessRecord proc = mProcessesToGc.get(i); 9394 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9395 continue; 9396 } 9397 if (!printed) { 9398 if (needSep) pw.println(" "); 9399 needSep = true; 9400 pw.println(" Processes that are waiting to GC:"); 9401 printed = true; 9402 } 9403 pw.print(" Process "); pw.println(proc); 9404 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9405 pw.print(", last gced="); 9406 pw.print(now-proc.lastRequestedGc); 9407 pw.print(" ms ago, last lowMem="); 9408 pw.print(now-proc.lastLowMemory); 9409 pw.println(" ms ago"); 9410 9411 } 9412 } 9413 return needSep; 9414 } 9415 9416 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9417 int opti, boolean dumpAll) { 9418 boolean needSep = false; 9419 9420 if (mLruProcesses.size() > 0) { 9421 if (needSep) pw.println(" "); 9422 needSep = true; 9423 pw.println(" OOM levels:"); 9424 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9425 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9426 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9427 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9428 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9429 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9430 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9431 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9432 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9433 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9434 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9435 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9436 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9437 9438 if (needSep) pw.println(" "); 9439 needSep = true; 9440 pw.println(" Process OOM control:"); 9441 dumpProcessOomList(pw, this, mLruProcesses, " ", 9442 "Proc", "PERS", true, null); 9443 needSep = true; 9444 } 9445 9446 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9447 9448 pw.println(); 9449 pw.println(" mHomeProcess: " + mHomeProcess); 9450 pw.println(" mPreviousProcess: " + mPreviousProcess); 9451 if (mHeavyWeightProcess != null) { 9452 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9453 } 9454 9455 return true; 9456 } 9457 9458 /** 9459 * There are three ways to call this: 9460 * - no provider specified: dump all the providers 9461 * - a flattened component name that matched an existing provider was specified as the 9462 * first arg: dump that one provider 9463 * - the first arg isn't the flattened component name of an existing provider: 9464 * dump all providers whose component contains the first arg as a substring 9465 */ 9466 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9467 int opti, boolean dumpAll) { 9468 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9469 } 9470 9471 static class ItemMatcher { 9472 ArrayList<ComponentName> components; 9473 ArrayList<String> strings; 9474 ArrayList<Integer> objects; 9475 boolean all; 9476 9477 ItemMatcher() { 9478 all = true; 9479 } 9480 9481 void build(String name) { 9482 ComponentName componentName = ComponentName.unflattenFromString(name); 9483 if (componentName != null) { 9484 if (components == null) { 9485 components = new ArrayList<ComponentName>(); 9486 } 9487 components.add(componentName); 9488 all = false; 9489 } else { 9490 int objectId = 0; 9491 // Not a '/' separated full component name; maybe an object ID? 9492 try { 9493 objectId = Integer.parseInt(name, 16); 9494 if (objects == null) { 9495 objects = new ArrayList<Integer>(); 9496 } 9497 objects.add(objectId); 9498 all = false; 9499 } catch (RuntimeException e) { 9500 // Not an integer; just do string match. 9501 if (strings == null) { 9502 strings = new ArrayList<String>(); 9503 } 9504 strings.add(name); 9505 all = false; 9506 } 9507 } 9508 } 9509 9510 int build(String[] args, int opti) { 9511 for (; opti<args.length; opti++) { 9512 String name = args[opti]; 9513 if ("--".equals(name)) { 9514 return opti+1; 9515 } 9516 build(name); 9517 } 9518 return opti; 9519 } 9520 9521 boolean match(Object object, ComponentName comp) { 9522 if (all) { 9523 return true; 9524 } 9525 if (components != null) { 9526 for (int i=0; i<components.size(); i++) { 9527 if (components.get(i).equals(comp)) { 9528 return true; 9529 } 9530 } 9531 } 9532 if (objects != null) { 9533 for (int i=0; i<objects.size(); i++) { 9534 if (System.identityHashCode(object) == objects.get(i)) { 9535 return true; 9536 } 9537 } 9538 } 9539 if (strings != null) { 9540 String flat = comp.flattenToString(); 9541 for (int i=0; i<strings.size(); i++) { 9542 if (flat.contains(strings.get(i))) { 9543 return true; 9544 } 9545 } 9546 } 9547 return false; 9548 } 9549 } 9550 9551 /** 9552 * There are three things that cmd can be: 9553 * - a flattened component name that matches an existing activity 9554 * - the cmd arg isn't the flattened component name of an existing activity: 9555 * dump all activity whose component contains the cmd as a substring 9556 * - A hex number of the ActivityRecord object instance. 9557 */ 9558 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9559 int opti, boolean dumpAll) { 9560 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9561 9562 if ("all".equals(name)) { 9563 synchronized (this) { 9564 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9565 activities.add(r1); 9566 } 9567 } 9568 } else if ("top".equals(name)) { 9569 synchronized (this) { 9570 final int N = mMainStack.mHistory.size(); 9571 if (N > 0) { 9572 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9573 } 9574 } 9575 } else { 9576 ItemMatcher matcher = new ItemMatcher(); 9577 matcher.build(name); 9578 9579 synchronized (this) { 9580 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9581 if (matcher.match(r1, r1.intent.getComponent())) { 9582 activities.add(r1); 9583 } 9584 } 9585 } 9586 } 9587 9588 if (activities.size() <= 0) { 9589 return false; 9590 } 9591 9592 String[] newArgs = new String[args.length - opti]; 9593 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9594 9595 TaskRecord lastTask = null; 9596 boolean needSep = false; 9597 for (int i=activities.size()-1; i>=0; i--) { 9598 ActivityRecord r = (ActivityRecord)activities.get(i); 9599 if (needSep) { 9600 pw.println(); 9601 } 9602 needSep = true; 9603 synchronized (this) { 9604 if (lastTask != r.task) { 9605 lastTask = r.task; 9606 pw.print("TASK "); pw.print(lastTask.affinity); 9607 pw.print(" id="); pw.println(lastTask.taskId); 9608 if (dumpAll) { 9609 lastTask.dump(pw, " "); 9610 } 9611 } 9612 } 9613 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9614 } 9615 return true; 9616 } 9617 9618 /** 9619 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9620 * there is a thread associated with the activity. 9621 */ 9622 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9623 final ActivityRecord r, String[] args, boolean dumpAll) { 9624 String innerPrefix = prefix + " "; 9625 synchronized (this) { 9626 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9627 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9628 pw.print(" pid="); 9629 if (r.app != null) pw.println(r.app.pid); 9630 else pw.println("(not running)"); 9631 if (dumpAll) { 9632 r.dump(pw, innerPrefix); 9633 } 9634 } 9635 if (r.app != null && r.app.thread != null) { 9636 // flush anything that is already in the PrintWriter since the thread is going 9637 // to write to the file descriptor directly 9638 pw.flush(); 9639 try { 9640 TransferPipe tp = new TransferPipe(); 9641 try { 9642 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9643 r.appToken, innerPrefix, args); 9644 tp.go(fd); 9645 } finally { 9646 tp.kill(); 9647 } 9648 } catch (IOException e) { 9649 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9650 } catch (RemoteException e) { 9651 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9652 } 9653 } 9654 } 9655 9656 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9657 int opti, boolean dumpAll, String dumpPackage) { 9658 boolean needSep = false; 9659 boolean onlyHistory = false; 9660 9661 if ("history".equals(dumpPackage)) { 9662 onlyHistory = true; 9663 dumpPackage = null; 9664 } 9665 9666 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9667 if (!onlyHistory && dumpAll) { 9668 if (mRegisteredReceivers.size() > 0) { 9669 boolean printed = false; 9670 Iterator it = mRegisteredReceivers.values().iterator(); 9671 while (it.hasNext()) { 9672 ReceiverList r = (ReceiverList)it.next(); 9673 if (dumpPackage != null && (r.app == null || 9674 !dumpPackage.equals(r.app.info.packageName))) { 9675 continue; 9676 } 9677 if (!printed) { 9678 pw.println(" Registered Receivers:"); 9679 needSep = true; 9680 printed = true; 9681 } 9682 pw.print(" * "); pw.println(r); 9683 r.dump(pw, " "); 9684 } 9685 } 9686 9687 if (mReceiverResolver.dump(pw, needSep ? 9688 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9689 " ", dumpPackage, false)) { 9690 needSep = true; 9691 } 9692 } 9693 9694 for (BroadcastQueue q : mBroadcastQueues) { 9695 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9696 } 9697 9698 needSep = true; 9699 9700 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9701 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9702 if (needSep) { 9703 pw.println(); 9704 } 9705 needSep = true; 9706 pw.print(" Sticky broadcasts for user "); 9707 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9708 StringBuilder sb = new StringBuilder(128); 9709 for (Map.Entry<String, ArrayList<Intent>> ent 9710 : mStickyBroadcasts.valueAt(user).entrySet()) { 9711 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9712 if (dumpAll) { 9713 pw.println(":"); 9714 ArrayList<Intent> intents = ent.getValue(); 9715 final int N = intents.size(); 9716 for (int i=0; i<N; i++) { 9717 sb.setLength(0); 9718 sb.append(" Intent: "); 9719 intents.get(i).toShortString(sb, false, true, false, false); 9720 pw.println(sb.toString()); 9721 Bundle bundle = intents.get(i).getExtras(); 9722 if (bundle != null) { 9723 pw.print(" "); 9724 pw.println(bundle.toString()); 9725 } 9726 } 9727 } else { 9728 pw.println(""); 9729 } 9730 } 9731 } 9732 } 9733 9734 if (!onlyHistory && dumpAll) { 9735 pw.println(); 9736 for (BroadcastQueue queue : mBroadcastQueues) { 9737 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9738 + queue.mBroadcastsScheduled); 9739 } 9740 pw.println(" mHandler:"); 9741 mHandler.dump(new PrintWriterPrinter(pw), " "); 9742 needSep = true; 9743 } 9744 9745 return needSep; 9746 } 9747 9748 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9749 int opti, boolean dumpAll, String dumpPackage) { 9750 boolean needSep = true; 9751 9752 ItemMatcher matcher = new ItemMatcher(); 9753 matcher.build(args, opti); 9754 9755 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9756 9757 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9758 9759 if (mLaunchingProviders.size() > 0) { 9760 boolean printed = false; 9761 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9762 ContentProviderRecord r = mLaunchingProviders.get(i); 9763 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9764 continue; 9765 } 9766 if (!printed) { 9767 if (needSep) pw.println(" "); 9768 needSep = true; 9769 pw.println(" Launching content providers:"); 9770 printed = true; 9771 } 9772 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9773 pw.println(r); 9774 } 9775 } 9776 9777 if (mGrantedUriPermissions.size() > 0) { 9778 if (needSep) pw.println(); 9779 needSep = true; 9780 pw.println("Granted Uri Permissions:"); 9781 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9782 int uid = mGrantedUriPermissions.keyAt(i); 9783 HashMap<Uri, UriPermission> perms 9784 = mGrantedUriPermissions.valueAt(i); 9785 pw.print(" * UID "); pw.print(uid); 9786 pw.println(" holds:"); 9787 for (UriPermission perm : perms.values()) { 9788 pw.print(" "); pw.println(perm); 9789 if (dumpAll) { 9790 perm.dump(pw, " "); 9791 } 9792 } 9793 } 9794 needSep = true; 9795 } 9796 9797 return needSep; 9798 } 9799 9800 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9801 int opti, boolean dumpAll, String dumpPackage) { 9802 boolean needSep = false; 9803 9804 if (mIntentSenderRecords.size() > 0) { 9805 boolean printed = false; 9806 Iterator<WeakReference<PendingIntentRecord>> it 9807 = mIntentSenderRecords.values().iterator(); 9808 while (it.hasNext()) { 9809 WeakReference<PendingIntentRecord> ref = it.next(); 9810 PendingIntentRecord rec = ref != null ? ref.get(): null; 9811 if (dumpPackage != null && (rec == null 9812 || !dumpPackage.equals(rec.key.packageName))) { 9813 continue; 9814 } 9815 if (!printed) { 9816 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9817 printed = true; 9818 } 9819 needSep = true; 9820 if (rec != null) { 9821 pw.print(" * "); pw.println(rec); 9822 if (dumpAll) { 9823 rec.dump(pw, " "); 9824 } 9825 } else { 9826 pw.print(" * "); pw.println(ref); 9827 } 9828 } 9829 } 9830 9831 return needSep; 9832 } 9833 9834 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9835 String prefix, String label, boolean complete, boolean brief, boolean client, 9836 String dumpPackage) { 9837 TaskRecord lastTask = null; 9838 boolean needNL = false; 9839 final String innerPrefix = prefix + " "; 9840 final String[] args = new String[0]; 9841 for (int i=list.size()-1; i>=0; i--) { 9842 final ActivityRecord r = (ActivityRecord)list.get(i); 9843 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9844 continue; 9845 } 9846 final boolean full = !brief && (complete || !r.isInHistory()); 9847 if (needNL) { 9848 pw.println(" "); 9849 needNL = false; 9850 } 9851 if (lastTask != r.task) { 9852 lastTask = r.task; 9853 pw.print(prefix); 9854 pw.print(full ? "* " : " "); 9855 pw.println(lastTask); 9856 if (full) { 9857 lastTask.dump(pw, prefix + " "); 9858 } else if (complete) { 9859 // Complete + brief == give a summary. Isn't that obvious?!? 9860 if (lastTask.intent != null) { 9861 pw.print(prefix); pw.print(" "); 9862 pw.println(lastTask.intent.toInsecureStringWithClip()); 9863 } 9864 } 9865 } 9866 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9867 pw.print(" #"); pw.print(i); pw.print(": "); 9868 pw.println(r); 9869 if (full) { 9870 r.dump(pw, innerPrefix); 9871 } else if (complete) { 9872 // Complete + brief == give a summary. Isn't that obvious?!? 9873 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9874 if (r.app != null) { 9875 pw.print(innerPrefix); pw.println(r.app); 9876 } 9877 } 9878 if (client && r.app != null && r.app.thread != null) { 9879 // flush anything that is already in the PrintWriter since the thread is going 9880 // to write to the file descriptor directly 9881 pw.flush(); 9882 try { 9883 TransferPipe tp = new TransferPipe(); 9884 try { 9885 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9886 r.appToken, innerPrefix, args); 9887 // Short timeout, since blocking here can 9888 // deadlock with the application. 9889 tp.go(fd, 2000); 9890 } finally { 9891 tp.kill(); 9892 } 9893 } catch (IOException e) { 9894 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9895 } catch (RemoteException e) { 9896 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9897 } 9898 needNL = true; 9899 } 9900 } 9901 } 9902 9903 private static String buildOomTag(String prefix, String space, int val, int base) { 9904 if (val == base) { 9905 if (space == null) return prefix; 9906 return prefix + " "; 9907 } 9908 return prefix + "+" + Integer.toString(val-base); 9909 } 9910 9911 private static final int dumpProcessList(PrintWriter pw, 9912 ActivityManagerService service, List list, 9913 String prefix, String normalLabel, String persistentLabel, 9914 String dumpPackage) { 9915 int numPers = 0; 9916 final int N = list.size()-1; 9917 for (int i=N; i>=0; i--) { 9918 ProcessRecord r = (ProcessRecord)list.get(i); 9919 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9920 continue; 9921 } 9922 pw.println(String.format("%s%s #%2d: %s", 9923 prefix, (r.persistent ? persistentLabel : normalLabel), 9924 i, r.toString())); 9925 if (r.persistent) { 9926 numPers++; 9927 } 9928 } 9929 return numPers; 9930 } 9931 9932 private static final boolean dumpProcessOomList(PrintWriter pw, 9933 ActivityManagerService service, List<ProcessRecord> origList, 9934 String prefix, String normalLabel, String persistentLabel, 9935 boolean inclDetails, String dumpPackage) { 9936 9937 ArrayList<Pair<ProcessRecord, Integer>> list 9938 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9939 for (int i=0; i<origList.size(); i++) { 9940 ProcessRecord r = origList.get(i); 9941 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9942 continue; 9943 } 9944 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9945 } 9946 9947 if (list.size() <= 0) { 9948 return false; 9949 } 9950 9951 Comparator<Pair<ProcessRecord, Integer>> comparator 9952 = new Comparator<Pair<ProcessRecord, Integer>>() { 9953 @Override 9954 public int compare(Pair<ProcessRecord, Integer> object1, 9955 Pair<ProcessRecord, Integer> object2) { 9956 if (object1.first.setAdj != object2.first.setAdj) { 9957 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9958 } 9959 if (object1.second.intValue() != object2.second.intValue()) { 9960 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9961 } 9962 return 0; 9963 } 9964 }; 9965 9966 Collections.sort(list, comparator); 9967 9968 final long curRealtime = SystemClock.elapsedRealtime(); 9969 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9970 final long curUptime = SystemClock.uptimeMillis(); 9971 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9972 9973 for (int i=list.size()-1; i>=0; i--) { 9974 ProcessRecord r = list.get(i).first; 9975 String oomAdj; 9976 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9977 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9978 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9979 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9980 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9981 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9982 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9983 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9984 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9985 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9986 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9987 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9988 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9989 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9990 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9991 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9992 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9993 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9994 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9995 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9996 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9997 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9998 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9999 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10000 } else { 10001 oomAdj = Integer.toString(r.setAdj); 10002 } 10003 String schedGroup; 10004 switch (r.setSchedGroup) { 10005 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10006 schedGroup = "B"; 10007 break; 10008 case Process.THREAD_GROUP_DEFAULT: 10009 schedGroup = "F"; 10010 break; 10011 default: 10012 schedGroup = Integer.toString(r.setSchedGroup); 10013 break; 10014 } 10015 String foreground; 10016 if (r.foregroundActivities) { 10017 foreground = "A"; 10018 } else if (r.foregroundServices) { 10019 foreground = "S"; 10020 } else { 10021 foreground = " "; 10022 } 10023 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10024 prefix, (r.persistent ? persistentLabel : normalLabel), 10025 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10026 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10027 if (r.adjSource != null || r.adjTarget != null) { 10028 pw.print(prefix); 10029 pw.print(" "); 10030 if (r.adjTarget instanceof ComponentName) { 10031 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10032 } else if (r.adjTarget != null) { 10033 pw.print(r.adjTarget.toString()); 10034 } else { 10035 pw.print("{null}"); 10036 } 10037 pw.print("<="); 10038 if (r.adjSource instanceof ProcessRecord) { 10039 pw.print("Proc{"); 10040 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10041 pw.println("}"); 10042 } else if (r.adjSource != null) { 10043 pw.println(r.adjSource.toString()); 10044 } else { 10045 pw.println("{null}"); 10046 } 10047 } 10048 if (inclDetails) { 10049 pw.print(prefix); 10050 pw.print(" "); 10051 pw.print("oom: max="); pw.print(r.maxAdj); 10052 pw.print(" hidden="); pw.print(r.hiddenAdj); 10053 pw.print(" client="); pw.print(r.clientHiddenAdj); 10054 pw.print(" empty="); pw.print(r.emptyAdj); 10055 pw.print(" curRaw="); pw.print(r.curRawAdj); 10056 pw.print(" setRaw="); pw.print(r.setRawAdj); 10057 pw.print(" cur="); pw.print(r.curAdj); 10058 pw.print(" set="); pw.println(r.setAdj); 10059 pw.print(prefix); 10060 pw.print(" "); 10061 pw.print("keeping="); pw.print(r.keeping); 10062 pw.print(" hidden="); pw.print(r.hidden); 10063 pw.print(" empty="); pw.print(r.empty); 10064 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10065 10066 if (!r.keeping) { 10067 if (r.lastWakeTime != 0) { 10068 long wtime; 10069 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10070 synchronized (stats) { 10071 wtime = stats.getProcessWakeTime(r.info.uid, 10072 r.pid, curRealtime); 10073 } 10074 long timeUsed = wtime - r.lastWakeTime; 10075 pw.print(prefix); 10076 pw.print(" "); 10077 pw.print("keep awake over "); 10078 TimeUtils.formatDuration(realtimeSince, pw); 10079 pw.print(" used "); 10080 TimeUtils.formatDuration(timeUsed, pw); 10081 pw.print(" ("); 10082 pw.print((timeUsed*100)/realtimeSince); 10083 pw.println("%)"); 10084 } 10085 if (r.lastCpuTime != 0) { 10086 long timeUsed = r.curCpuTime - r.lastCpuTime; 10087 pw.print(prefix); 10088 pw.print(" "); 10089 pw.print("run cpu over "); 10090 TimeUtils.formatDuration(uptimeSince, pw); 10091 pw.print(" used "); 10092 TimeUtils.formatDuration(timeUsed, pw); 10093 pw.print(" ("); 10094 pw.print((timeUsed*100)/uptimeSince); 10095 pw.println("%)"); 10096 } 10097 } 10098 } 10099 } 10100 return true; 10101 } 10102 10103 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10104 ArrayList<ProcessRecord> procs; 10105 synchronized (this) { 10106 if (args != null && args.length > start 10107 && args[start].charAt(0) != '-') { 10108 procs = new ArrayList<ProcessRecord>(); 10109 int pid = -1; 10110 try { 10111 pid = Integer.parseInt(args[start]); 10112 } catch (NumberFormatException e) { 10113 10114 } 10115 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10116 ProcessRecord proc = mLruProcesses.get(i); 10117 if (proc.pid == pid) { 10118 procs.add(proc); 10119 } else if (proc.processName.equals(args[start])) { 10120 procs.add(proc); 10121 } 10122 } 10123 if (procs.size() <= 0) { 10124 pw.println("No process found for: " + args[start]); 10125 return null; 10126 } 10127 } else { 10128 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10129 } 10130 } 10131 return procs; 10132 } 10133 10134 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10135 PrintWriter pw, String[] args) { 10136 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10137 if (procs == null) { 10138 return; 10139 } 10140 10141 long uptime = SystemClock.uptimeMillis(); 10142 long realtime = SystemClock.elapsedRealtime(); 10143 pw.println("Applications Graphics Acceleration Info:"); 10144 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10145 10146 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10147 ProcessRecord r = procs.get(i); 10148 if (r.thread != null) { 10149 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10150 pw.flush(); 10151 try { 10152 TransferPipe tp = new TransferPipe(); 10153 try { 10154 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10155 tp.go(fd); 10156 } finally { 10157 tp.kill(); 10158 } 10159 } catch (IOException e) { 10160 pw.println("Failure while dumping the app: " + r); 10161 pw.flush(); 10162 } catch (RemoteException e) { 10163 pw.println("Got a RemoteException while dumping the app " + r); 10164 pw.flush(); 10165 } 10166 } 10167 } 10168 } 10169 10170 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10171 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10172 if (procs == null) { 10173 return; 10174 } 10175 10176 pw.println("Applications Database Info:"); 10177 10178 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10179 ProcessRecord r = procs.get(i); 10180 if (r.thread != null) { 10181 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10182 pw.flush(); 10183 try { 10184 TransferPipe tp = new TransferPipe(); 10185 try { 10186 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10187 tp.go(fd); 10188 } finally { 10189 tp.kill(); 10190 } 10191 } catch (IOException e) { 10192 pw.println("Failure while dumping the app: " + r); 10193 pw.flush(); 10194 } catch (RemoteException e) { 10195 pw.println("Got a RemoteException while dumping the app " + r); 10196 pw.flush(); 10197 } 10198 } 10199 } 10200 } 10201 10202 final static class MemItem { 10203 final String label; 10204 final String shortLabel; 10205 final long pss; 10206 final int id; 10207 ArrayList<MemItem> subitems; 10208 10209 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10210 label = _label; 10211 shortLabel = _shortLabel; 10212 pss = _pss; 10213 id = _id; 10214 } 10215 } 10216 10217 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10218 boolean sort) { 10219 if (sort) { 10220 Collections.sort(items, new Comparator<MemItem>() { 10221 @Override 10222 public int compare(MemItem lhs, MemItem rhs) { 10223 if (lhs.pss < rhs.pss) { 10224 return 1; 10225 } else if (lhs.pss > rhs.pss) { 10226 return -1; 10227 } 10228 return 0; 10229 } 10230 }); 10231 } 10232 10233 for (int i=0; i<items.size(); i++) { 10234 MemItem mi = items.get(i); 10235 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10236 if (mi.subitems != null) { 10237 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10238 } 10239 } 10240 } 10241 10242 // These are in KB. 10243 static final long[] DUMP_MEM_BUCKETS = new long[] { 10244 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10245 120*1024, 160*1024, 200*1024, 10246 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10247 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10248 }; 10249 10250 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10251 boolean stackLike) { 10252 int start = label.lastIndexOf('.'); 10253 if (start >= 0) start++; 10254 else start = 0; 10255 int end = label.length(); 10256 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10257 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10258 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10259 out.append(bucket); 10260 out.append(stackLike ? "MB." : "MB "); 10261 out.append(label, start, end); 10262 return; 10263 } 10264 } 10265 out.append(memKB/1024); 10266 out.append(stackLike ? "MB." : "MB "); 10267 out.append(label, start, end); 10268 } 10269 10270 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10271 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10272 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10273 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10274 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10275 }; 10276 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10277 "System", "Persistent", "Foreground", 10278 "Visible", "Perceptible", "Heavy Weight", 10279 "Backup", "A Services", "Home", "Previous", 10280 "B Services", "Background" 10281 }; 10282 10283 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10284 PrintWriter pw, String prefix, String[] args, boolean brief, 10285 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10286 boolean dumpAll = false; 10287 boolean oomOnly = false; 10288 10289 int opti = 0; 10290 while (opti < args.length) { 10291 String opt = args[opti]; 10292 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10293 break; 10294 } 10295 opti++; 10296 if ("-a".equals(opt)) { 10297 dumpAll = true; 10298 } else if ("--oom".equals(opt)) { 10299 oomOnly = true; 10300 } else if ("-h".equals(opt)) { 10301 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10302 pw.println(" -a: include all available information for each process."); 10303 pw.println(" --oom: only show processes organized by oom adj."); 10304 pw.println("If [process] is specified it can be the name or "); 10305 pw.println("pid of a specific process to dump."); 10306 return; 10307 } else { 10308 pw.println("Unknown argument: " + opt + "; use -h for help"); 10309 } 10310 } 10311 10312 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10313 if (procs == null) { 10314 return; 10315 } 10316 10317 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10318 long uptime = SystemClock.uptimeMillis(); 10319 long realtime = SystemClock.elapsedRealtime(); 10320 10321 if (procs.size() == 1 || isCheckinRequest) { 10322 dumpAll = true; 10323 } 10324 10325 if (isCheckinRequest) { 10326 // short checkin version 10327 pw.println(uptime + "," + realtime); 10328 pw.flush(); 10329 } else { 10330 pw.println("Applications Memory Usage (kB):"); 10331 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10332 } 10333 10334 String[] innerArgs = new String[args.length-opti]; 10335 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10336 10337 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10338 long nativePss=0, dalvikPss=0, otherPss=0; 10339 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10340 10341 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10342 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10343 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10344 10345 long totalPss = 0; 10346 10347 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10348 ProcessRecord r = procs.get(i); 10349 if (r.thread != null) { 10350 if (!isCheckinRequest && dumpAll) { 10351 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10352 pw.flush(); 10353 } 10354 Debug.MemoryInfo mi = null; 10355 if (dumpAll) { 10356 try { 10357 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10358 } catch (RemoteException e) { 10359 if (!isCheckinRequest) { 10360 pw.println("Got RemoteException!"); 10361 pw.flush(); 10362 } 10363 } 10364 } else { 10365 mi = new Debug.MemoryInfo(); 10366 Debug.getMemoryInfo(r.pid, mi); 10367 } 10368 10369 if (!isCheckinRequest && mi != null) { 10370 long myTotalPss = mi.getTotalPss(); 10371 totalPss += myTotalPss; 10372 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10373 r.processName, myTotalPss, 0); 10374 procMems.add(pssItem); 10375 10376 nativePss += mi.nativePss; 10377 dalvikPss += mi.dalvikPss; 10378 otherPss += mi.otherPss; 10379 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10380 long mem = mi.getOtherPss(j); 10381 miscPss[j] += mem; 10382 otherPss -= mem; 10383 } 10384 10385 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10386 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10387 || oomIndex == (oomPss.length-1)) { 10388 oomPss[oomIndex] += myTotalPss; 10389 if (oomProcs[oomIndex] == null) { 10390 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10391 } 10392 oomProcs[oomIndex].add(pssItem); 10393 break; 10394 } 10395 } 10396 } 10397 } 10398 } 10399 10400 if (!isCheckinRequest && procs.size() > 1) { 10401 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10402 10403 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10404 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10405 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10406 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10407 String label = Debug.MemoryInfo.getOtherLabel(j); 10408 catMems.add(new MemItem(label, label, miscPss[j], j)); 10409 } 10410 10411 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10412 for (int j=0; j<oomPss.length; j++) { 10413 if (oomPss[j] != 0) { 10414 String label = DUMP_MEM_OOM_LABEL[j]; 10415 MemItem item = new MemItem(label, label, oomPss[j], 10416 DUMP_MEM_OOM_ADJ[j]); 10417 item.subitems = oomProcs[j]; 10418 oomMems.add(item); 10419 } 10420 } 10421 10422 if (outTag != null || outStack != null) { 10423 if (outTag != null) { 10424 appendMemBucket(outTag, totalPss, "total", false); 10425 } 10426 if (outStack != null) { 10427 appendMemBucket(outStack, totalPss, "total", true); 10428 } 10429 boolean firstLine = true; 10430 for (int i=0; i<oomMems.size(); i++) { 10431 MemItem miCat = oomMems.get(i); 10432 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10433 continue; 10434 } 10435 if (miCat.id < ProcessList.SERVICE_ADJ 10436 || miCat.id == ProcessList.HOME_APP_ADJ 10437 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10438 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10439 outTag.append(" / "); 10440 } 10441 if (outStack != null) { 10442 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10443 if (firstLine) { 10444 outStack.append(":"); 10445 firstLine = false; 10446 } 10447 outStack.append("\n\t at "); 10448 } else { 10449 outStack.append("$"); 10450 } 10451 } 10452 for (int j=0; j<miCat.subitems.size(); j++) { 10453 MemItem mi = miCat.subitems.get(j); 10454 if (j > 0) { 10455 if (outTag != null) { 10456 outTag.append(" "); 10457 } 10458 if (outStack != null) { 10459 outStack.append("$"); 10460 } 10461 } 10462 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10463 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10464 } 10465 if (outStack != null) { 10466 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10467 } 10468 } 10469 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10470 outStack.append("("); 10471 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10472 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10473 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10474 outStack.append(":"); 10475 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10476 } 10477 } 10478 outStack.append(")"); 10479 } 10480 } 10481 } 10482 } 10483 10484 if (!brief && !oomOnly) { 10485 pw.println(); 10486 pw.println("Total PSS by process:"); 10487 dumpMemItems(pw, " ", procMems, true); 10488 pw.println(); 10489 } 10490 pw.println("Total PSS by OOM adjustment:"); 10491 dumpMemItems(pw, " ", oomMems, false); 10492 if (!oomOnly) { 10493 PrintWriter out = categoryPw != null ? categoryPw : pw; 10494 out.println(); 10495 out.println("Total PSS by category:"); 10496 dumpMemItems(out, " ", catMems, true); 10497 } 10498 pw.println(); 10499 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10500 final int[] SINGLE_LONG_FORMAT = new int[] { 10501 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10502 }; 10503 long[] longOut = new long[1]; 10504 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10505 SINGLE_LONG_FORMAT, null, longOut, null); 10506 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10507 longOut[0] = 0; 10508 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10509 SINGLE_LONG_FORMAT, null, longOut, null); 10510 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10511 longOut[0] = 0; 10512 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10513 SINGLE_LONG_FORMAT, null, longOut, null); 10514 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10515 longOut[0] = 0; 10516 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10517 SINGLE_LONG_FORMAT, null, longOut, null); 10518 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10519 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10520 pw.print(shared); pw.println(" kB"); 10521 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10522 pw.print(voltile); pw.println(" kB volatile"); 10523 } 10524 } 10525 10526 /** 10527 * Searches array of arguments for the specified string 10528 * @param args array of argument strings 10529 * @param value value to search for 10530 * @return true if the value is contained in the array 10531 */ 10532 private static boolean scanArgs(String[] args, String value) { 10533 if (args != null) { 10534 for (String arg : args) { 10535 if (value.equals(arg)) { 10536 return true; 10537 } 10538 } 10539 } 10540 return false; 10541 } 10542 10543 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10544 ContentProviderRecord cpr, boolean always) { 10545 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10546 10547 if (!inLaunching || always) { 10548 synchronized (cpr) { 10549 cpr.launchingApp = null; 10550 cpr.notifyAll(); 10551 } 10552 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10553 String names[] = cpr.info.authority.split(";"); 10554 for (int j = 0; j < names.length; j++) { 10555 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10556 } 10557 } 10558 10559 for (int i=0; i<cpr.connections.size(); i++) { 10560 ContentProviderConnection conn = cpr.connections.get(i); 10561 if (conn.waiting) { 10562 // If this connection is waiting for the provider, then we don't 10563 // need to mess with its process unless we are always removing 10564 // or for some reason the provider is not currently launching. 10565 if (inLaunching && !always) { 10566 continue; 10567 } 10568 } 10569 ProcessRecord capp = conn.client; 10570 conn.dead = true; 10571 if (conn.stableCount > 0) { 10572 if (!capp.persistent && capp.thread != null 10573 && capp.pid != 0 10574 && capp.pid != MY_PID) { 10575 Slog.i(TAG, "Kill " + capp.processName 10576 + " (pid " + capp.pid + "): provider " + cpr.info.name 10577 + " in dying process " + (proc != null ? proc.processName : "??")); 10578 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid, 10579 capp.processName, capp.setAdj, "dying provider " 10580 + cpr.name.toShortString()); 10581 Process.killProcessQuiet(capp.pid); 10582 } 10583 } else if (capp.thread != null && conn.provider.provider != null) { 10584 try { 10585 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10586 } catch (RemoteException e) { 10587 } 10588 // In the protocol here, we don't expect the client to correctly 10589 // clean up this connection, we'll just remove it. 10590 cpr.connections.remove(i); 10591 conn.client.conProviders.remove(conn); 10592 } 10593 } 10594 10595 if (inLaunching && always) { 10596 mLaunchingProviders.remove(cpr); 10597 } 10598 return inLaunching; 10599 } 10600 10601 /** 10602 * Main code for cleaning up a process when it has gone away. This is 10603 * called both as a result of the process dying, or directly when stopping 10604 * a process when running in single process mode. 10605 */ 10606 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10607 boolean restarting, boolean allowRestart, int index) { 10608 if (index >= 0) { 10609 mLruProcesses.remove(index); 10610 } 10611 10612 mProcessesToGc.remove(app); 10613 10614 // Dismiss any open dialogs. 10615 if (app.crashDialog != null) { 10616 app.crashDialog.dismiss(); 10617 app.crashDialog = null; 10618 } 10619 if (app.anrDialog != null) { 10620 app.anrDialog.dismiss(); 10621 app.anrDialog = null; 10622 } 10623 if (app.waitDialog != null) { 10624 app.waitDialog.dismiss(); 10625 app.waitDialog = null; 10626 } 10627 10628 app.crashing = false; 10629 app.notResponding = false; 10630 10631 app.resetPackageList(); 10632 app.unlinkDeathRecipient(); 10633 app.thread = null; 10634 app.forcingToForeground = null; 10635 app.foregroundServices = false; 10636 app.foregroundActivities = false; 10637 app.hasShownUi = false; 10638 app.hasAboveClient = false; 10639 10640 mServices.killServicesLocked(app, allowRestart); 10641 10642 boolean restart = false; 10643 10644 // Remove published content providers. 10645 if (!app.pubProviders.isEmpty()) { 10646 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10647 while (it.hasNext()) { 10648 ContentProviderRecord cpr = it.next(); 10649 10650 final boolean always = app.bad || !allowRestart; 10651 if (removeDyingProviderLocked(app, cpr, always) || always) { 10652 // We left the provider in the launching list, need to 10653 // restart it. 10654 restart = true; 10655 } 10656 10657 cpr.provider = null; 10658 cpr.proc = null; 10659 } 10660 app.pubProviders.clear(); 10661 } 10662 10663 // Take care of any launching providers waiting for this process. 10664 if (checkAppInLaunchingProvidersLocked(app, false)) { 10665 restart = true; 10666 } 10667 10668 // Unregister from connected content providers. 10669 if (!app.conProviders.isEmpty()) { 10670 for (int i=0; i<app.conProviders.size(); i++) { 10671 ContentProviderConnection conn = app.conProviders.get(i); 10672 conn.provider.connections.remove(conn); 10673 } 10674 app.conProviders.clear(); 10675 } 10676 10677 // At this point there may be remaining entries in mLaunchingProviders 10678 // where we were the only one waiting, so they are no longer of use. 10679 // Look for these and clean up if found. 10680 // XXX Commented out for now. Trying to figure out a way to reproduce 10681 // the actual situation to identify what is actually going on. 10682 if (false) { 10683 for (int i=0; i<mLaunchingProviders.size(); i++) { 10684 ContentProviderRecord cpr = (ContentProviderRecord) 10685 mLaunchingProviders.get(i); 10686 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10687 synchronized (cpr) { 10688 cpr.launchingApp = null; 10689 cpr.notifyAll(); 10690 } 10691 } 10692 } 10693 } 10694 10695 skipCurrentReceiverLocked(app); 10696 10697 // Unregister any receivers. 10698 if (app.receivers.size() > 0) { 10699 Iterator<ReceiverList> it = app.receivers.iterator(); 10700 while (it.hasNext()) { 10701 removeReceiverLocked(it.next()); 10702 } 10703 app.receivers.clear(); 10704 } 10705 10706 // If the app is undergoing backup, tell the backup manager about it 10707 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10708 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 10709 + mBackupTarget.appInfo + " died during backup"); 10710 try { 10711 IBackupManager bm = IBackupManager.Stub.asInterface( 10712 ServiceManager.getService(Context.BACKUP_SERVICE)); 10713 bm.agentDisconnected(app.info.packageName); 10714 } catch (RemoteException e) { 10715 // can't happen; backup manager is local 10716 } 10717 } 10718 10719 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10720 ProcessChangeItem item = mPendingProcessChanges.get(i); 10721 if (item.pid == app.pid) { 10722 mPendingProcessChanges.remove(i); 10723 mAvailProcessChanges.add(item); 10724 } 10725 } 10726 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10727 10728 // If the caller is restarting this app, then leave it in its 10729 // current lists and let the caller take care of it. 10730 if (restarting) { 10731 return; 10732 } 10733 10734 if (!app.persistent || app.isolated) { 10735 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 10736 "Removing non-persistent process during cleanup: " + app); 10737 mProcessNames.remove(app.processName, app.uid); 10738 mIsolatedProcesses.remove(app.uid); 10739 if (mHeavyWeightProcess == app) { 10740 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10741 mHeavyWeightProcess.userId, 0)); 10742 mHeavyWeightProcess = null; 10743 } 10744 } else if (!app.removed) { 10745 // This app is persistent, so we need to keep its record around. 10746 // If it is not already on the pending app list, add it there 10747 // and start a new process for it. 10748 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10749 mPersistentStartingProcesses.add(app); 10750 restart = true; 10751 } 10752 } 10753 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 10754 "Clean-up removing on hold: " + app); 10755 mProcessesOnHold.remove(app); 10756 10757 if (app == mHomeProcess) { 10758 mHomeProcess = null; 10759 } 10760 if (app == mPreviousProcess) { 10761 mPreviousProcess = null; 10762 } 10763 10764 if (restart && !app.isolated) { 10765 // We have components that still need to be running in the 10766 // process, so re-launch it. 10767 mProcessNames.put(app.processName, app.uid, app); 10768 startProcessLocked(app, "restart", app.processName); 10769 } else if (app.pid > 0 && app.pid != MY_PID) { 10770 // Goodbye! 10771 synchronized (mPidsSelfLocked) { 10772 mPidsSelfLocked.remove(app.pid); 10773 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10774 } 10775 app.setPid(0); 10776 } 10777 } 10778 10779 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10780 // Look through the content providers we are waiting to have launched, 10781 // and if any run in this process then either schedule a restart of 10782 // the process or kill the client waiting for it if this process has 10783 // gone bad. 10784 int NL = mLaunchingProviders.size(); 10785 boolean restart = false; 10786 for (int i=0; i<NL; i++) { 10787 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10788 if (cpr.launchingApp == app) { 10789 if (!alwaysBad && !app.bad) { 10790 restart = true; 10791 } else { 10792 removeDyingProviderLocked(app, cpr, true); 10793 // cpr should have been removed from mLaunchingProviders 10794 NL = mLaunchingProviders.size(); 10795 i--; 10796 } 10797 } 10798 } 10799 return restart; 10800 } 10801 10802 // ========================================================= 10803 // SERVICES 10804 // ========================================================= 10805 10806 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10807 int flags) { 10808 enforceNotIsolatedCaller("getServices"); 10809 synchronized (this) { 10810 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10811 } 10812 } 10813 10814 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10815 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10816 synchronized (this) { 10817 return mServices.getRunningServiceControlPanelLocked(name); 10818 } 10819 } 10820 10821 public ComponentName startService(IApplicationThread caller, Intent service, 10822 String resolvedType, int userId) { 10823 enforceNotIsolatedCaller("startService"); 10824 // Refuse possible leaked file descriptors 10825 if (service != null && service.hasFileDescriptors() == true) { 10826 throw new IllegalArgumentException("File descriptors passed in Intent"); 10827 } 10828 10829 if (DEBUG_SERVICE) 10830 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10831 synchronized(this) { 10832 final int callingPid = Binder.getCallingPid(); 10833 final int callingUid = Binder.getCallingUid(); 10834 checkValidCaller(callingUid, userId); 10835 final long origId = Binder.clearCallingIdentity(); 10836 ComponentName res = mServices.startServiceLocked(caller, service, 10837 resolvedType, callingPid, callingUid, userId); 10838 Binder.restoreCallingIdentity(origId); 10839 return res; 10840 } 10841 } 10842 10843 ComponentName startServiceInPackage(int uid, 10844 Intent service, String resolvedType, int userId) { 10845 synchronized(this) { 10846 if (DEBUG_SERVICE) 10847 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10848 final long origId = Binder.clearCallingIdentity(); 10849 ComponentName res = mServices.startServiceLocked(null, service, 10850 resolvedType, -1, uid, userId); 10851 Binder.restoreCallingIdentity(origId); 10852 return res; 10853 } 10854 } 10855 10856 public int stopService(IApplicationThread caller, Intent service, 10857 String resolvedType, int userId) { 10858 enforceNotIsolatedCaller("stopService"); 10859 // Refuse possible leaked file descriptors 10860 if (service != null && service.hasFileDescriptors() == true) { 10861 throw new IllegalArgumentException("File descriptors passed in Intent"); 10862 } 10863 10864 checkValidCaller(Binder.getCallingUid(), userId); 10865 10866 synchronized(this) { 10867 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10868 } 10869 } 10870 10871 public IBinder peekService(Intent service, String resolvedType) { 10872 enforceNotIsolatedCaller("peekService"); 10873 // Refuse possible leaked file descriptors 10874 if (service != null && service.hasFileDescriptors() == true) { 10875 throw new IllegalArgumentException("File descriptors passed in Intent"); 10876 } 10877 synchronized(this) { 10878 return mServices.peekServiceLocked(service, resolvedType); 10879 } 10880 } 10881 10882 public boolean stopServiceToken(ComponentName className, IBinder token, 10883 int startId) { 10884 synchronized(this) { 10885 return mServices.stopServiceTokenLocked(className, token, startId); 10886 } 10887 } 10888 10889 public void setServiceForeground(ComponentName className, IBinder token, 10890 int id, Notification notification, boolean removeNotification) { 10891 synchronized(this) { 10892 mServices.setServiceForegroundLocked(className, token, id, notification, 10893 removeNotification); 10894 } 10895 } 10896 10897 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10898 boolean requireFull, String name, String callerPackage) { 10899 final int callingUserId = UserHandle.getUserId(callingUid); 10900 if (callingUserId != userId) { 10901 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10902 if ((requireFull || checkComponentPermission( 10903 android.Manifest.permission.INTERACT_ACROSS_USERS, 10904 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10905 && checkComponentPermission( 10906 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10907 callingPid, callingUid, -1, true) 10908 != PackageManager.PERMISSION_GRANTED) { 10909 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10910 // In this case, they would like to just execute as their 10911 // owner user instead of failing. 10912 userId = callingUserId; 10913 } else { 10914 StringBuilder builder = new StringBuilder(128); 10915 builder.append("Permission Denial: "); 10916 builder.append(name); 10917 if (callerPackage != null) { 10918 builder.append(" from "); 10919 builder.append(callerPackage); 10920 } 10921 builder.append(" asks to run as user "); 10922 builder.append(userId); 10923 builder.append(" but is calling from user "); 10924 builder.append(UserHandle.getUserId(callingUid)); 10925 builder.append("; this requires "); 10926 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10927 if (!requireFull) { 10928 builder.append(" or "); 10929 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10930 } 10931 String msg = builder.toString(); 10932 Slog.w(TAG, msg); 10933 throw new SecurityException(msg); 10934 } 10935 } 10936 } 10937 if (userId == UserHandle.USER_CURRENT 10938 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10939 // Note that we may be accessing this outside of a lock... 10940 // shouldn't be a big deal, if this is being called outside 10941 // of a locked context there is intrinsically a race with 10942 // the value the caller will receive and someone else changing it. 10943 userId = mCurrentUserId; 10944 } 10945 if (!allowAll && userId < 0) { 10946 throw new IllegalArgumentException( 10947 "Call does not support special user #" + userId); 10948 } 10949 } 10950 return userId; 10951 } 10952 10953 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10954 String className, int flags) { 10955 boolean result = false; 10956 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10957 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10958 if (ActivityManager.checkUidPermission( 10959 android.Manifest.permission.INTERACT_ACROSS_USERS, 10960 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10961 ComponentName comp = new ComponentName(aInfo.packageName, className); 10962 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10963 + " requests FLAG_SINGLE_USER, but app does not hold " 10964 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10965 Slog.w(TAG, msg); 10966 throw new SecurityException(msg); 10967 } 10968 result = true; 10969 } 10970 } else if (componentProcessName == aInfo.packageName) { 10971 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10972 } else if ("system".equals(componentProcessName)) { 10973 result = true; 10974 } 10975 if (DEBUG_MU) { 10976 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10977 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10978 } 10979 return result; 10980 } 10981 10982 public int bindService(IApplicationThread caller, IBinder token, 10983 Intent service, String resolvedType, 10984 IServiceConnection connection, int flags, int userId) { 10985 enforceNotIsolatedCaller("bindService"); 10986 // Refuse possible leaked file descriptors 10987 if (service != null && service.hasFileDescriptors() == true) { 10988 throw new IllegalArgumentException("File descriptors passed in Intent"); 10989 } 10990 10991 synchronized(this) { 10992 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10993 connection, flags, userId); 10994 } 10995 } 10996 10997 public boolean unbindService(IServiceConnection connection) { 10998 synchronized (this) { 10999 return mServices.unbindServiceLocked(connection); 11000 } 11001 } 11002 11003 public void publishService(IBinder token, Intent intent, IBinder service) { 11004 // Refuse possible leaked file descriptors 11005 if (intent != null && intent.hasFileDescriptors() == true) { 11006 throw new IllegalArgumentException("File descriptors passed in Intent"); 11007 } 11008 11009 synchronized(this) { 11010 if (!(token instanceof ServiceRecord)) { 11011 throw new IllegalArgumentException("Invalid service token"); 11012 } 11013 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11014 } 11015 } 11016 11017 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11018 // Refuse possible leaked file descriptors 11019 if (intent != null && intent.hasFileDescriptors() == true) { 11020 throw new IllegalArgumentException("File descriptors passed in Intent"); 11021 } 11022 11023 synchronized(this) { 11024 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11025 } 11026 } 11027 11028 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11029 synchronized(this) { 11030 if (!(token instanceof ServiceRecord)) { 11031 throw new IllegalArgumentException("Invalid service token"); 11032 } 11033 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11034 } 11035 } 11036 11037 // ========================================================= 11038 // BACKUP AND RESTORE 11039 // ========================================================= 11040 11041 // Cause the target app to be launched if necessary and its backup agent 11042 // instantiated. The backup agent will invoke backupAgentCreated() on the 11043 // activity manager to announce its creation. 11044 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11045 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11046 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11047 11048 synchronized(this) { 11049 // !!! TODO: currently no check here that we're already bound 11050 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11051 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11052 synchronized (stats) { 11053 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11054 } 11055 11056 // Backup agent is now in use, its package can't be stopped. 11057 try { 11058 AppGlobals.getPackageManager().setPackageStoppedState( 11059 app.packageName, false, UserHandle.getUserId(app.uid)); 11060 } catch (RemoteException e) { 11061 } catch (IllegalArgumentException e) { 11062 Slog.w(TAG, "Failed trying to unstop package " 11063 + app.packageName + ": " + e); 11064 } 11065 11066 BackupRecord r = new BackupRecord(ss, app, backupMode); 11067 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11068 ? new ComponentName(app.packageName, app.backupAgentName) 11069 : new ComponentName("android", "FullBackupAgent"); 11070 // startProcessLocked() returns existing proc's record if it's already running 11071 ProcessRecord proc = startProcessLocked(app.processName, app, 11072 false, 0, "backup", hostingName, false, false); 11073 if (proc == null) { 11074 Slog.e(TAG, "Unable to start backup agent process " + r); 11075 return false; 11076 } 11077 11078 r.app = proc; 11079 mBackupTarget = r; 11080 mBackupAppName = app.packageName; 11081 11082 // Try not to kill the process during backup 11083 updateOomAdjLocked(proc); 11084 11085 // If the process is already attached, schedule the creation of the backup agent now. 11086 // If it is not yet live, this will be done when it attaches to the framework. 11087 if (proc.thread != null) { 11088 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11089 try { 11090 proc.thread.scheduleCreateBackupAgent(app, 11091 compatibilityInfoForPackageLocked(app), backupMode); 11092 } catch (RemoteException e) { 11093 // Will time out on the backup manager side 11094 } 11095 } else { 11096 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11097 } 11098 // Invariants: at this point, the target app process exists and the application 11099 // is either already running or in the process of coming up. mBackupTarget and 11100 // mBackupAppName describe the app, so that when it binds back to the AM we 11101 // know that it's scheduled for a backup-agent operation. 11102 } 11103 11104 return true; 11105 } 11106 11107 // A backup agent has just come up 11108 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11109 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11110 + " = " + agent); 11111 11112 synchronized(this) { 11113 if (!agentPackageName.equals(mBackupAppName)) { 11114 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11115 return; 11116 } 11117 } 11118 11119 long oldIdent = Binder.clearCallingIdentity(); 11120 try { 11121 IBackupManager bm = IBackupManager.Stub.asInterface( 11122 ServiceManager.getService(Context.BACKUP_SERVICE)); 11123 bm.agentConnected(agentPackageName, agent); 11124 } catch (RemoteException e) { 11125 // can't happen; the backup manager service is local 11126 } catch (Exception e) { 11127 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11128 e.printStackTrace(); 11129 } finally { 11130 Binder.restoreCallingIdentity(oldIdent); 11131 } 11132 } 11133 11134 // done with this agent 11135 public void unbindBackupAgent(ApplicationInfo appInfo) { 11136 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11137 if (appInfo == null) { 11138 Slog.w(TAG, "unbind backup agent for null app"); 11139 return; 11140 } 11141 11142 synchronized(this) { 11143 if (mBackupAppName == null) { 11144 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11145 return; 11146 } 11147 11148 if (!mBackupAppName.equals(appInfo.packageName)) { 11149 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11150 return; 11151 } 11152 11153 ProcessRecord proc = mBackupTarget.app; 11154 mBackupTarget = null; 11155 mBackupAppName = null; 11156 11157 // Not backing this app up any more; reset its OOM adjustment 11158 updateOomAdjLocked(proc); 11159 11160 // If the app crashed during backup, 'thread' will be null here 11161 if (proc.thread != null) { 11162 try { 11163 proc.thread.scheduleDestroyBackupAgent(appInfo, 11164 compatibilityInfoForPackageLocked(appInfo)); 11165 } catch (Exception e) { 11166 Slog.e(TAG, "Exception when unbinding backup agent:"); 11167 e.printStackTrace(); 11168 } 11169 } 11170 } 11171 } 11172 // ========================================================= 11173 // BROADCASTS 11174 // ========================================================= 11175 11176 private final List getStickiesLocked(String action, IntentFilter filter, 11177 List cur, int userId) { 11178 final ContentResolver resolver = mContext.getContentResolver(); 11179 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11180 if (stickies == null) { 11181 return cur; 11182 } 11183 final ArrayList<Intent> list = stickies.get(action); 11184 if (list == null) { 11185 return cur; 11186 } 11187 int N = list.size(); 11188 for (int i=0; i<N; i++) { 11189 Intent intent = list.get(i); 11190 if (filter.match(resolver, intent, true, TAG) >= 0) { 11191 if (cur == null) { 11192 cur = new ArrayList<Intent>(); 11193 } 11194 cur.add(intent); 11195 } 11196 } 11197 return cur; 11198 } 11199 11200 boolean isPendingBroadcastProcessLocked(int pid) { 11201 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11202 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11203 } 11204 11205 void skipPendingBroadcastLocked(int pid) { 11206 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11207 for (BroadcastQueue queue : mBroadcastQueues) { 11208 queue.skipPendingBroadcastLocked(pid); 11209 } 11210 } 11211 11212 // The app just attached; send any pending broadcasts that it should receive 11213 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11214 boolean didSomething = false; 11215 for (BroadcastQueue queue : mBroadcastQueues) { 11216 didSomething |= queue.sendPendingBroadcastsLocked(app); 11217 } 11218 return didSomething; 11219 } 11220 11221 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11222 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11223 enforceNotIsolatedCaller("registerReceiver"); 11224 int callingUid; 11225 int callingPid; 11226 synchronized(this) { 11227 ProcessRecord callerApp = null; 11228 if (caller != null) { 11229 callerApp = getRecordForAppLocked(caller); 11230 if (callerApp == null) { 11231 throw new SecurityException( 11232 "Unable to find app for caller " + caller 11233 + " (pid=" + Binder.getCallingPid() 11234 + ") when registering receiver " + receiver); 11235 } 11236 if (callerApp.info.uid != Process.SYSTEM_UID && 11237 !callerApp.pkgList.contains(callerPackage)) { 11238 throw new SecurityException("Given caller package " + callerPackage 11239 + " is not running in process " + callerApp); 11240 } 11241 callingUid = callerApp.info.uid; 11242 callingPid = callerApp.pid; 11243 } else { 11244 callerPackage = null; 11245 callingUid = Binder.getCallingUid(); 11246 callingPid = Binder.getCallingPid(); 11247 } 11248 11249 userId = this.handleIncomingUser(callingPid, callingUid, userId, 11250 true, true, "registerReceiver", callerPackage); 11251 11252 List allSticky = null; 11253 11254 // Look for any matching sticky broadcasts... 11255 Iterator actions = filter.actionsIterator(); 11256 if (actions != null) { 11257 while (actions.hasNext()) { 11258 String action = (String)actions.next(); 11259 allSticky = getStickiesLocked(action, filter, allSticky, 11260 UserHandle.USER_ALL); 11261 allSticky = getStickiesLocked(action, filter, allSticky, 11262 UserHandle.getUserId(callingUid)); 11263 } 11264 } else { 11265 allSticky = getStickiesLocked(null, filter, allSticky, 11266 UserHandle.USER_ALL); 11267 allSticky = getStickiesLocked(null, filter, allSticky, 11268 UserHandle.getUserId(callingUid)); 11269 } 11270 11271 // The first sticky in the list is returned directly back to 11272 // the client. 11273 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11274 11275 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11276 + ": " + sticky); 11277 11278 if (receiver == null) { 11279 return sticky; 11280 } 11281 11282 ReceiverList rl 11283 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11284 if (rl == null) { 11285 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11286 userId, receiver); 11287 if (rl.app != null) { 11288 rl.app.receivers.add(rl); 11289 } else { 11290 try { 11291 receiver.asBinder().linkToDeath(rl, 0); 11292 } catch (RemoteException e) { 11293 return sticky; 11294 } 11295 rl.linkedToDeath = true; 11296 } 11297 mRegisteredReceivers.put(receiver.asBinder(), rl); 11298 } else if (rl.uid != callingUid) { 11299 throw new IllegalArgumentException( 11300 "Receiver requested to register for uid " + callingUid 11301 + " was previously registered for uid " + rl.uid); 11302 } else if (rl.pid != callingPid) { 11303 throw new IllegalArgumentException( 11304 "Receiver requested to register for pid " + callingPid 11305 + " was previously registered for pid " + rl.pid); 11306 } else if (rl.userId != userId) { 11307 throw new IllegalArgumentException( 11308 "Receiver requested to register for user " + userId 11309 + " was previously registered for user " + rl.userId); 11310 } 11311 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11312 permission, callingUid, userId); 11313 rl.add(bf); 11314 if (!bf.debugCheck()) { 11315 Slog.w(TAG, "==> For Dynamic broadast"); 11316 } 11317 mReceiverResolver.addFilter(bf); 11318 11319 // Enqueue broadcasts for all existing stickies that match 11320 // this filter. 11321 if (allSticky != null) { 11322 ArrayList receivers = new ArrayList(); 11323 receivers.add(bf); 11324 11325 int N = allSticky.size(); 11326 for (int i=0; i<N; i++) { 11327 Intent intent = (Intent)allSticky.get(i); 11328 BroadcastQueue queue = broadcastQueueForIntent(intent); 11329 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11330 null, -1, -1, null, receivers, null, 0, null, null, 11331 false, true, true, -1); 11332 queue.enqueueParallelBroadcastLocked(r); 11333 queue.scheduleBroadcastsLocked(); 11334 } 11335 } 11336 11337 return sticky; 11338 } 11339 } 11340 11341 public void unregisterReceiver(IIntentReceiver receiver) { 11342 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11343 11344 final long origId = Binder.clearCallingIdentity(); 11345 try { 11346 boolean doTrim = false; 11347 11348 synchronized(this) { 11349 ReceiverList rl 11350 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11351 if (rl != null) { 11352 if (rl.curBroadcast != null) { 11353 BroadcastRecord r = rl.curBroadcast; 11354 final boolean doNext = finishReceiverLocked( 11355 receiver.asBinder(), r.resultCode, r.resultData, 11356 r.resultExtras, r.resultAbort, true); 11357 if (doNext) { 11358 doTrim = true; 11359 r.queue.processNextBroadcast(false); 11360 } 11361 } 11362 11363 if (rl.app != null) { 11364 rl.app.receivers.remove(rl); 11365 } 11366 removeReceiverLocked(rl); 11367 if (rl.linkedToDeath) { 11368 rl.linkedToDeath = false; 11369 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11370 } 11371 } 11372 } 11373 11374 // If we actually concluded any broadcasts, we might now be able 11375 // to trim the recipients' apps from our working set 11376 if (doTrim) { 11377 trimApplications(); 11378 return; 11379 } 11380 11381 } finally { 11382 Binder.restoreCallingIdentity(origId); 11383 } 11384 } 11385 11386 void removeReceiverLocked(ReceiverList rl) { 11387 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11388 int N = rl.size(); 11389 for (int i=0; i<N; i++) { 11390 mReceiverResolver.removeFilter(rl.get(i)); 11391 } 11392 } 11393 11394 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11395 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11396 ProcessRecord r = mLruProcesses.get(i); 11397 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11398 try { 11399 r.thread.dispatchPackageBroadcast(cmd, packages); 11400 } catch (RemoteException ex) { 11401 } 11402 } 11403 } 11404 } 11405 11406 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11407 int[] users) { 11408 List<ResolveInfo> receivers = null; 11409 try { 11410 HashSet<ComponentName> singleUserReceivers = null; 11411 boolean scannedFirstReceivers = false; 11412 for (int user : users) { 11413 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11414 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11415 if (user != 0 && newReceivers != null) { 11416 // If this is not the primary user, we need to check for 11417 // any receivers that should be filtered out. 11418 for (int i=0; i<newReceivers.size(); i++) { 11419 ResolveInfo ri = newReceivers.get(i); 11420 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 11421 newReceivers.remove(i); 11422 i--; 11423 } 11424 } 11425 } 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 = handleIncomingUser(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 int callingAppId = UserHandle.getAppId(callingUid); 11514 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 11515 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 11516 callingUid == 0) { 11517 // Always okay. 11518 } else if (callerApp == null || !callerApp.persistent) { 11519 try { 11520 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11521 intent.getAction())) { 11522 String msg = "Permission Denial: not allowed to send broadcast " 11523 + intent.getAction() + " from pid=" 11524 + callingPid + ", uid=" + callingUid; 11525 Slog.w(TAG, msg); 11526 throw new SecurityException(msg); 11527 } 11528 } catch (RemoteException e) { 11529 Slog.w(TAG, "Remote exception", e); 11530 return ActivityManager.BROADCAST_SUCCESS; 11531 } 11532 } 11533 11534 // Handle special intents: if this broadcast is from the package 11535 // manager about a package being removed, we need to remove all of 11536 // its activities from the history stack. 11537 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11538 intent.getAction()); 11539 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11540 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11541 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11542 || uidRemoved) { 11543 if (checkComponentPermission( 11544 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11545 callingPid, callingUid, -1, true) 11546 == PackageManager.PERMISSION_GRANTED) { 11547 if (uidRemoved) { 11548 final Bundle intentExtras = intent.getExtras(); 11549 final int uid = intentExtras != null 11550 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11551 if (uid >= 0) { 11552 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11553 synchronized (bs) { 11554 bs.removeUidStatsLocked(uid); 11555 } 11556 } 11557 } else { 11558 // If resources are unavailable just force stop all 11559 // those packages and flush the attribute cache as well. 11560 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11561 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11562 if (list != null && (list.length > 0)) { 11563 for (String pkg : list) { 11564 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11565 } 11566 sendPackageBroadcastLocked( 11567 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11568 } 11569 } else { 11570 Uri data = intent.getData(); 11571 String ssp; 11572 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11573 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11574 forceStopPackageLocked(ssp, 11575 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11576 false, userId); 11577 } 11578 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11579 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11580 new String[] {ssp}, userId); 11581 } 11582 } 11583 } 11584 } 11585 } else { 11586 String msg = "Permission Denial: " + intent.getAction() 11587 + " broadcast from " + callerPackage + " (pid=" + callingPid 11588 + ", uid=" + callingUid + ")" 11589 + " requires " 11590 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11591 Slog.w(TAG, msg); 11592 throw new SecurityException(msg); 11593 } 11594 11595 // Special case for adding a package: by default turn on compatibility 11596 // mode. 11597 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11598 Uri data = intent.getData(); 11599 String ssp; 11600 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11601 mCompatModePackages.handlePackageAddedLocked(ssp, 11602 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11603 } 11604 } 11605 11606 /* 11607 * If this is the time zone changed action, queue up a message that will reset the timezone 11608 * of all currently running processes. This message will get queued up before the broadcast 11609 * happens. 11610 */ 11611 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11612 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11613 } 11614 11615 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11616 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11617 } 11618 11619 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11620 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11621 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11622 } 11623 11624 // Add to the sticky list if requested. 11625 if (sticky) { 11626 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11627 callingPid, callingUid) 11628 != PackageManager.PERMISSION_GRANTED) { 11629 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11630 + callingPid + ", uid=" + callingUid 11631 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11632 Slog.w(TAG, msg); 11633 throw new SecurityException(msg); 11634 } 11635 if (requiredPermission != null) { 11636 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11637 + " and enforce permission " + requiredPermission); 11638 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11639 } 11640 if (intent.getComponent() != null) { 11641 throw new SecurityException( 11642 "Sticky broadcasts can't target a specific component"); 11643 } 11644 // We use userId directly here, since the "all" target is maintained 11645 // as a separate set of sticky broadcasts. 11646 if (userId != UserHandle.USER_ALL) { 11647 // But first, if this is not a broadcast to all users, then 11648 // make sure it doesn't conflict with an existing broadcast to 11649 // all users. 11650 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11651 UserHandle.USER_ALL); 11652 if (stickies != null) { 11653 ArrayList<Intent> list = stickies.get(intent.getAction()); 11654 if (list != null) { 11655 int N = list.size(); 11656 int i; 11657 for (i=0; i<N; i++) { 11658 if (intent.filterEquals(list.get(i))) { 11659 throw new IllegalArgumentException( 11660 "Sticky broadcast " + intent + " for user " 11661 + userId + " conflicts with existing global broadcast"); 11662 } 11663 } 11664 } 11665 } 11666 } 11667 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11668 if (stickies == null) { 11669 stickies = new HashMap<String, ArrayList<Intent>>(); 11670 mStickyBroadcasts.put(userId, stickies); 11671 } 11672 ArrayList<Intent> list = stickies.get(intent.getAction()); 11673 if (list == null) { 11674 list = new ArrayList<Intent>(); 11675 stickies.put(intent.getAction(), list); 11676 } 11677 int N = list.size(); 11678 int i; 11679 for (i=0; i<N; i++) { 11680 if (intent.filterEquals(list.get(i))) { 11681 // This sticky already exists, replace it. 11682 list.set(i, new Intent(intent)); 11683 break; 11684 } 11685 } 11686 if (i >= N) { 11687 list.add(new Intent(intent)); 11688 } 11689 } 11690 11691 int[] users; 11692 if (userId == UserHandle.USER_ALL) { 11693 // Caller wants broadcast to go to all started users. 11694 users = mStartedUserArray; 11695 } else { 11696 // Caller wants broadcast to go to one specific user. 11697 users = mCurrentUserArray; 11698 } 11699 11700 // Figure out who all will receive this broadcast. 11701 List receivers = null; 11702 List<BroadcastFilter> registeredReceivers = null; 11703 // Need to resolve the intent to interested receivers... 11704 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11705 == 0) { 11706 receivers = collectReceiverComponents(intent, resolvedType, users); 11707 } 11708 if (intent.getComponent() == null) { 11709 registeredReceivers = mReceiverResolver.queryIntent(intent, 11710 resolvedType, false, userId); 11711 } 11712 11713 final boolean replacePending = 11714 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11715 11716 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11717 + " replacePending=" + replacePending); 11718 11719 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11720 if (!ordered && NR > 0) { 11721 // If we are not serializing this broadcast, then send the 11722 // registered receivers separately so they don't wait for the 11723 // components to be launched. 11724 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11725 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11726 callerPackage, callingPid, callingUid, requiredPermission, 11727 registeredReceivers, resultTo, resultCode, resultData, map, 11728 ordered, sticky, false, userId); 11729 if (DEBUG_BROADCAST) Slog.v( 11730 TAG, "Enqueueing parallel broadcast " + r); 11731 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11732 if (!replaced) { 11733 queue.enqueueParallelBroadcastLocked(r); 11734 queue.scheduleBroadcastsLocked(); 11735 } 11736 registeredReceivers = null; 11737 NR = 0; 11738 } 11739 11740 // Merge into one list. 11741 int ir = 0; 11742 if (receivers != null) { 11743 // A special case for PACKAGE_ADDED: do not allow the package 11744 // being added to see this broadcast. This prevents them from 11745 // using this as a back door to get run as soon as they are 11746 // installed. Maybe in the future we want to have a special install 11747 // broadcast or such for apps, but we'd like to deliberately make 11748 // this decision. 11749 String skipPackages[] = null; 11750 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11751 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11752 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11753 Uri data = intent.getData(); 11754 if (data != null) { 11755 String pkgName = data.getSchemeSpecificPart(); 11756 if (pkgName != null) { 11757 skipPackages = new String[] { pkgName }; 11758 } 11759 } 11760 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11761 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11762 } 11763 if (skipPackages != null && (skipPackages.length > 0)) { 11764 for (String skipPackage : skipPackages) { 11765 if (skipPackage != null) { 11766 int NT = receivers.size(); 11767 for (int it=0; it<NT; it++) { 11768 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11769 if (curt.activityInfo.packageName.equals(skipPackage)) { 11770 receivers.remove(it); 11771 it--; 11772 NT--; 11773 } 11774 } 11775 } 11776 } 11777 } 11778 11779 int NT = receivers != null ? receivers.size() : 0; 11780 int it = 0; 11781 ResolveInfo curt = null; 11782 BroadcastFilter curr = null; 11783 while (it < NT && ir < NR) { 11784 if (curt == null) { 11785 curt = (ResolveInfo)receivers.get(it); 11786 } 11787 if (curr == null) { 11788 curr = registeredReceivers.get(ir); 11789 } 11790 if (curr.getPriority() >= curt.priority) { 11791 // Insert this broadcast record into the final list. 11792 receivers.add(it, curr); 11793 ir++; 11794 curr = null; 11795 it++; 11796 NT++; 11797 } else { 11798 // Skip to the next ResolveInfo in the final list. 11799 it++; 11800 curt = null; 11801 } 11802 } 11803 } 11804 while (ir < NR) { 11805 if (receivers == null) { 11806 receivers = new ArrayList(); 11807 } 11808 receivers.add(registeredReceivers.get(ir)); 11809 ir++; 11810 } 11811 11812 if ((receivers != null && receivers.size() > 0) 11813 || resultTo != null) { 11814 BroadcastQueue queue = broadcastQueueForIntent(intent); 11815 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11816 callerPackage, callingPid, callingUid, requiredPermission, 11817 receivers, resultTo, resultCode, resultData, map, ordered, 11818 sticky, false, userId); 11819 if (DEBUG_BROADCAST) Slog.v( 11820 TAG, "Enqueueing ordered broadcast " + r 11821 + ": prev had " + queue.mOrderedBroadcasts.size()); 11822 if (DEBUG_BROADCAST) { 11823 int seq = r.intent.getIntExtra("seq", -1); 11824 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11825 } 11826 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11827 if (!replaced) { 11828 queue.enqueueOrderedBroadcastLocked(r); 11829 queue.scheduleBroadcastsLocked(); 11830 } 11831 } 11832 11833 return ActivityManager.BROADCAST_SUCCESS; 11834 } 11835 11836 final Intent verifyBroadcastLocked(Intent intent) { 11837 // Refuse possible leaked file descriptors 11838 if (intent != null && intent.hasFileDescriptors() == true) { 11839 throw new IllegalArgumentException("File descriptors passed in Intent"); 11840 } 11841 11842 int flags = intent.getFlags(); 11843 11844 if (!mProcessesReady) { 11845 // if the caller really truly claims to know what they're doing, go 11846 // ahead and allow the broadcast without launching any receivers 11847 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11848 intent = new Intent(intent); 11849 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11850 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11851 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11852 + " before boot completion"); 11853 throw new IllegalStateException("Cannot broadcast before boot completed"); 11854 } 11855 } 11856 11857 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11858 throw new IllegalArgumentException( 11859 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11860 } 11861 11862 return intent; 11863 } 11864 11865 public final int broadcastIntent(IApplicationThread caller, 11866 Intent intent, String resolvedType, IIntentReceiver resultTo, 11867 int resultCode, String resultData, Bundle map, 11868 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11869 enforceNotIsolatedCaller("broadcastIntent"); 11870 synchronized(this) { 11871 intent = verifyBroadcastLocked(intent); 11872 11873 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11874 final int callingPid = Binder.getCallingPid(); 11875 final int callingUid = Binder.getCallingUid(); 11876 final long origId = Binder.clearCallingIdentity(); 11877 int res = broadcastIntentLocked(callerApp, 11878 callerApp != null ? callerApp.info.packageName : null, 11879 intent, resolvedType, resultTo, 11880 resultCode, resultData, map, requiredPermission, serialized, sticky, 11881 callingPid, callingUid, userId); 11882 Binder.restoreCallingIdentity(origId); 11883 return res; 11884 } 11885 } 11886 11887 int broadcastIntentInPackage(String packageName, int uid, 11888 Intent intent, String resolvedType, IIntentReceiver resultTo, 11889 int resultCode, String resultData, Bundle map, 11890 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11891 synchronized(this) { 11892 intent = verifyBroadcastLocked(intent); 11893 11894 final long origId = Binder.clearCallingIdentity(); 11895 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11896 resultTo, resultCode, resultData, map, requiredPermission, 11897 serialized, sticky, -1, uid, userId); 11898 Binder.restoreCallingIdentity(origId); 11899 return res; 11900 } 11901 } 11902 11903 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11904 // Refuse possible leaked file descriptors 11905 if (intent != null && intent.hasFileDescriptors() == true) { 11906 throw new IllegalArgumentException("File descriptors passed in Intent"); 11907 } 11908 11909 userId = handleIncomingUser(Binder.getCallingPid(), 11910 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11911 11912 synchronized(this) { 11913 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11914 != PackageManager.PERMISSION_GRANTED) { 11915 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11916 + Binder.getCallingPid() 11917 + ", uid=" + Binder.getCallingUid() 11918 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11919 Slog.w(TAG, msg); 11920 throw new SecurityException(msg); 11921 } 11922 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11923 if (stickies != null) { 11924 ArrayList<Intent> list = stickies.get(intent.getAction()); 11925 if (list != null) { 11926 int N = list.size(); 11927 int i; 11928 for (i=0; i<N; i++) { 11929 if (intent.filterEquals(list.get(i))) { 11930 list.remove(i); 11931 break; 11932 } 11933 } 11934 if (list.size() <= 0) { 11935 stickies.remove(intent.getAction()); 11936 } 11937 } 11938 if (stickies.size() <= 0) { 11939 mStickyBroadcasts.remove(userId); 11940 } 11941 } 11942 } 11943 } 11944 11945 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11946 String resultData, Bundle resultExtras, boolean resultAbort, 11947 boolean explicit) { 11948 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11949 if (r == null) { 11950 Slog.w(TAG, "finishReceiver called but not found on queue"); 11951 return false; 11952 } 11953 11954 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11955 explicit); 11956 } 11957 11958 public void finishReceiver(IBinder who, int resultCode, String resultData, 11959 Bundle resultExtras, boolean resultAbort) { 11960 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11961 11962 // Refuse possible leaked file descriptors 11963 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11964 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11965 } 11966 11967 final long origId = Binder.clearCallingIdentity(); 11968 try { 11969 boolean doNext = false; 11970 BroadcastRecord r = null; 11971 11972 synchronized(this) { 11973 r = broadcastRecordForReceiverLocked(who); 11974 if (r != null) { 11975 doNext = r.queue.finishReceiverLocked(r, resultCode, 11976 resultData, resultExtras, resultAbort, true); 11977 } 11978 } 11979 11980 if (doNext) { 11981 r.queue.processNextBroadcast(false); 11982 } 11983 trimApplications(); 11984 } finally { 11985 Binder.restoreCallingIdentity(origId); 11986 } 11987 } 11988 11989 // ========================================================= 11990 // INSTRUMENTATION 11991 // ========================================================= 11992 11993 public boolean startInstrumentation(ComponentName className, 11994 String profileFile, int flags, Bundle arguments, 11995 IInstrumentationWatcher watcher, int userId) { 11996 enforceNotIsolatedCaller("startInstrumentation"); 11997 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 11998 userId, false, true, "startInstrumentation", null); 11999 // Refuse possible leaked file descriptors 12000 if (arguments != null && arguments.hasFileDescriptors()) { 12001 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12002 } 12003 12004 synchronized(this) { 12005 InstrumentationInfo ii = null; 12006 ApplicationInfo ai = null; 12007 try { 12008 ii = mContext.getPackageManager().getInstrumentationInfo( 12009 className, STOCK_PM_FLAGS); 12010 ai = AppGlobals.getPackageManager().getApplicationInfo( 12011 ii.targetPackage, STOCK_PM_FLAGS, userId); 12012 } catch (PackageManager.NameNotFoundException e) { 12013 } catch (RemoteException e) { 12014 } 12015 if (ii == null) { 12016 reportStartInstrumentationFailure(watcher, className, 12017 "Unable to find instrumentation info for: " + className); 12018 return false; 12019 } 12020 if (ai == null) { 12021 reportStartInstrumentationFailure(watcher, className, 12022 "Unable to find instrumentation target package: " + ii.targetPackage); 12023 return false; 12024 } 12025 12026 int match = mContext.getPackageManager().checkSignatures( 12027 ii.targetPackage, ii.packageName); 12028 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12029 String msg = "Permission Denial: starting instrumentation " 12030 + className + " from pid=" 12031 + Binder.getCallingPid() 12032 + ", uid=" + Binder.getCallingPid() 12033 + " not allowed because package " + ii.packageName 12034 + " does not have a signature matching the target " 12035 + ii.targetPackage; 12036 reportStartInstrumentationFailure(watcher, className, msg); 12037 throw new SecurityException(msg); 12038 } 12039 12040 final long origId = Binder.clearCallingIdentity(); 12041 // Instrumentation can kill and relaunch even persistent processes 12042 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12043 ProcessRecord app = addAppLocked(ai, false); 12044 app.instrumentationClass = className; 12045 app.instrumentationInfo = ai; 12046 app.instrumentationProfileFile = profileFile; 12047 app.instrumentationArguments = arguments; 12048 app.instrumentationWatcher = watcher; 12049 app.instrumentationResultClass = className; 12050 Binder.restoreCallingIdentity(origId); 12051 } 12052 12053 return true; 12054 } 12055 12056 /** 12057 * Report errors that occur while attempting to start Instrumentation. Always writes the 12058 * error to the logs, but if somebody is watching, send the report there too. This enables 12059 * the "am" command to report errors with more information. 12060 * 12061 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12062 * @param cn The component name of the instrumentation. 12063 * @param report The error report. 12064 */ 12065 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12066 ComponentName cn, String report) { 12067 Slog.w(TAG, report); 12068 try { 12069 if (watcher != null) { 12070 Bundle results = new Bundle(); 12071 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12072 results.putString("Error", report); 12073 watcher.instrumentationStatus(cn, -1, results); 12074 } 12075 } catch (RemoteException e) { 12076 Slog.w(TAG, e); 12077 } 12078 } 12079 12080 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12081 if (app.instrumentationWatcher != null) { 12082 try { 12083 // NOTE: IInstrumentationWatcher *must* be oneway here 12084 app.instrumentationWatcher.instrumentationFinished( 12085 app.instrumentationClass, 12086 resultCode, 12087 results); 12088 } catch (RemoteException e) { 12089 } 12090 } 12091 app.instrumentationWatcher = null; 12092 app.instrumentationClass = null; 12093 app.instrumentationInfo = null; 12094 app.instrumentationProfileFile = null; 12095 app.instrumentationArguments = null; 12096 12097 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12098 } 12099 12100 public void finishInstrumentation(IApplicationThread target, 12101 int resultCode, Bundle results) { 12102 int userId = UserHandle.getCallingUserId(); 12103 // Refuse possible leaked file descriptors 12104 if (results != null && results.hasFileDescriptors()) { 12105 throw new IllegalArgumentException("File descriptors passed in Intent"); 12106 } 12107 12108 synchronized(this) { 12109 ProcessRecord app = getRecordForAppLocked(target); 12110 if (app == null) { 12111 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12112 return; 12113 } 12114 final long origId = Binder.clearCallingIdentity(); 12115 finishInstrumentationLocked(app, resultCode, results); 12116 Binder.restoreCallingIdentity(origId); 12117 } 12118 } 12119 12120 // ========================================================= 12121 // CONFIGURATION 12122 // ========================================================= 12123 12124 public ConfigurationInfo getDeviceConfigurationInfo() { 12125 ConfigurationInfo config = new ConfigurationInfo(); 12126 synchronized (this) { 12127 config.reqTouchScreen = mConfiguration.touchscreen; 12128 config.reqKeyboardType = mConfiguration.keyboard; 12129 config.reqNavigation = mConfiguration.navigation; 12130 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12131 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12132 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12133 } 12134 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12135 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12136 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12137 } 12138 config.reqGlEsVersion = GL_ES_VERSION; 12139 } 12140 return config; 12141 } 12142 12143 public Configuration getConfiguration() { 12144 Configuration ci; 12145 synchronized(this) { 12146 ci = new Configuration(mConfiguration); 12147 } 12148 return ci; 12149 } 12150 12151 public void updatePersistentConfiguration(Configuration values) { 12152 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12153 "updateConfiguration()"); 12154 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12155 "updateConfiguration()"); 12156 if (values == null) { 12157 throw new NullPointerException("Configuration must not be null"); 12158 } 12159 12160 synchronized(this) { 12161 final long origId = Binder.clearCallingIdentity(); 12162 updateConfigurationLocked(values, null, true, false); 12163 Binder.restoreCallingIdentity(origId); 12164 } 12165 } 12166 12167 public void updateConfiguration(Configuration values) { 12168 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12169 "updateConfiguration()"); 12170 12171 synchronized(this) { 12172 if (values == null && mWindowManager != null) { 12173 // sentinel: fetch the current configuration from the window manager 12174 values = mWindowManager.computeNewConfiguration(); 12175 } 12176 12177 if (mWindowManager != null) { 12178 mProcessList.applyDisplaySize(mWindowManager); 12179 } 12180 12181 final long origId = Binder.clearCallingIdentity(); 12182 if (values != null) { 12183 Settings.System.clearConfiguration(values); 12184 } 12185 updateConfigurationLocked(values, null, false, false); 12186 Binder.restoreCallingIdentity(origId); 12187 } 12188 } 12189 12190 /** 12191 * Do either or both things: (1) change the current configuration, and (2) 12192 * make sure the given activity is running with the (now) current 12193 * configuration. Returns true if the activity has been left running, or 12194 * false if <var>starting</var> is being destroyed to match the new 12195 * configuration. 12196 * @param persistent TODO 12197 */ 12198 boolean updateConfigurationLocked(Configuration values, 12199 ActivityRecord starting, boolean persistent, boolean initLocale) { 12200 // do nothing if we are headless 12201 if (mHeadless) return true; 12202 12203 int changes = 0; 12204 12205 boolean kept = true; 12206 12207 if (values != null) { 12208 Configuration newConfig = new Configuration(mConfiguration); 12209 changes = newConfig.updateFrom(values); 12210 if (changes != 0) { 12211 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12212 Slog.i(TAG, "Updating configuration to: " + values); 12213 } 12214 12215 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12216 12217 if (values.locale != null && !initLocale) { 12218 saveLocaleLocked(values.locale, 12219 !values.locale.equals(mConfiguration.locale), 12220 values.userSetLocale); 12221 } 12222 12223 mConfigurationSeq++; 12224 if (mConfigurationSeq <= 0) { 12225 mConfigurationSeq = 1; 12226 } 12227 newConfig.seq = mConfigurationSeq; 12228 mConfiguration = newConfig; 12229 Slog.i(TAG, "Config changed: " + newConfig); 12230 12231 final Configuration configCopy = new Configuration(mConfiguration); 12232 12233 // TODO: If our config changes, should we auto dismiss any currently 12234 // showing dialogs? 12235 mShowDialogs = shouldShowDialogs(newConfig); 12236 12237 AttributeCache ac = AttributeCache.instance(); 12238 if (ac != null) { 12239 ac.updateConfiguration(configCopy); 12240 } 12241 12242 // Make sure all resources in our process are updated 12243 // right now, so that anyone who is going to retrieve 12244 // resource values after we return will be sure to get 12245 // the new ones. This is especially important during 12246 // boot, where the first config change needs to guarantee 12247 // all resources have that config before following boot 12248 // code is executed. 12249 mSystemThread.applyConfigurationToResources(configCopy); 12250 12251 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12252 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12253 msg.obj = new Configuration(configCopy); 12254 mHandler.sendMessage(msg); 12255 } 12256 12257 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12258 ProcessRecord app = mLruProcesses.get(i); 12259 try { 12260 if (app.thread != null) { 12261 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12262 + app.processName + " new config " + mConfiguration); 12263 app.thread.scheduleConfigurationChanged(configCopy); 12264 } 12265 } catch (Exception e) { 12266 } 12267 } 12268 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12269 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12270 | Intent.FLAG_RECEIVER_REPLACE_PENDING 12271 | Intent.FLAG_RECEIVER_FOREGROUND); 12272 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12273 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12274 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12275 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 12276 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12277 broadcastIntentLocked(null, null, intent, 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, srec.userId); 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, int clientHiddenAdj, 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 if (app.hasActivities) { 12477 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 12478 } else if (app.hasClientActivities) { 12479 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj; 12480 } else { 12481 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj; 12482 } 12483 } 12484 return app.curRawAdj; 12485 } 12486 12487 if (app.thread == null) { 12488 app.adjSeq = mAdjSeq; 12489 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12490 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12491 } 12492 12493 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12494 app.adjSource = null; 12495 app.adjTarget = null; 12496 app.empty = false; 12497 app.hidden = false; 12498 app.hasClientActivities = false; 12499 12500 final int activitiesSize = app.activities.size(); 12501 12502 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12503 // The max adjustment doesn't allow this app to be anything 12504 // below foreground, so it is not worth doing work for it. 12505 app.adjType = "fixed"; 12506 app.adjSeq = mAdjSeq; 12507 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12508 app.hasActivities = false; 12509 app.foregroundActivities = false; 12510 app.keeping = true; 12511 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12512 // System process can do UI, and when they do we want to have 12513 // them trim their memory after the user leaves the UI. To 12514 // facilitate this, here we need to determine whether or not it 12515 // is currently showing UI. 12516 app.systemNoUi = true; 12517 if (app == TOP_APP) { 12518 app.systemNoUi = false; 12519 app.hasActivities = true; 12520 } else if (activitiesSize > 0) { 12521 for (int j = 0; j < activitiesSize; j++) { 12522 final ActivityRecord r = app.activities.get(j); 12523 if (r.visible) { 12524 app.systemNoUi = false; 12525 } 12526 if (r.app == app) { 12527 app.hasActivities = true; 12528 } 12529 } 12530 } 12531 return (app.curAdj=app.maxAdj); 12532 } 12533 12534 app.keeping = false; 12535 app.systemNoUi = false; 12536 app.hasActivities = false; 12537 12538 // Determine the importance of the process, starting with most 12539 // important to least, and assign an appropriate OOM adjustment. 12540 int adj; 12541 int schedGroup; 12542 boolean foregroundActivities = false; 12543 boolean interesting = false; 12544 BroadcastQueue queue; 12545 if (app == TOP_APP) { 12546 // The last app on the list is the foreground app. 12547 adj = ProcessList.FOREGROUND_APP_ADJ; 12548 schedGroup = Process.THREAD_GROUP_DEFAULT; 12549 app.adjType = "top-activity"; 12550 foregroundActivities = true; 12551 interesting = true; 12552 app.hasActivities = true; 12553 } else if (app.instrumentationClass != null) { 12554 // Don't want to kill running instrumentation. 12555 adj = ProcessList.FOREGROUND_APP_ADJ; 12556 schedGroup = Process.THREAD_GROUP_DEFAULT; 12557 app.adjType = "instrumentation"; 12558 interesting = true; 12559 } else if ((queue = isReceivingBroadcast(app)) != null) { 12560 // An app that is currently receiving a broadcast also 12561 // counts as being in the foreground for OOM killer purposes. 12562 // It's placed in a sched group based on the nature of the 12563 // broadcast as reflected by which queue it's active in. 12564 adj = ProcessList.FOREGROUND_APP_ADJ; 12565 schedGroup = (queue == mFgBroadcastQueue) 12566 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12567 app.adjType = "broadcast"; 12568 } else if (app.executingServices.size() > 0) { 12569 // An app that is currently executing a service callback also 12570 // counts as being in the foreground. 12571 adj = ProcessList.FOREGROUND_APP_ADJ; 12572 schedGroup = Process.THREAD_GROUP_DEFAULT; 12573 app.adjType = "exec-service"; 12574 } else { 12575 // Assume process is hidden (has activities); we will correct 12576 // later if this is not the case. 12577 adj = hiddenAdj; 12578 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12579 app.hidden = true; 12580 app.adjType = "bg-act"; 12581 } 12582 12583 boolean hasStoppingActivities = false; 12584 12585 // Examine all activities if not already foreground. 12586 if (!foregroundActivities && activitiesSize > 0) { 12587 for (int j = 0; j < activitiesSize; j++) { 12588 final ActivityRecord r = app.activities.get(j); 12589 if (r.visible) { 12590 // App has a visible activity; only upgrade adjustment. 12591 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12592 adj = ProcessList.VISIBLE_APP_ADJ; 12593 app.adjType = "visible"; 12594 } 12595 schedGroup = Process.THREAD_GROUP_DEFAULT; 12596 app.hidden = false; 12597 app.hasActivities = true; 12598 foregroundActivities = true; 12599 break; 12600 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12601 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12602 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12603 app.adjType = "pausing"; 12604 } 12605 app.hidden = false; 12606 foregroundActivities = true; 12607 } else if (r.state == ActivityState.STOPPING) { 12608 // We will apply the actual adjustment later, because 12609 // we want to allow this process to immediately go through 12610 // any memory trimming that is in effect. 12611 app.hidden = false; 12612 foregroundActivities = true; 12613 hasStoppingActivities = true; 12614 } 12615 if (r.app == app) { 12616 app.hasActivities = true; 12617 } 12618 } 12619 } 12620 12621 if (adj == hiddenAdj && !app.hasActivities) { 12622 if (app.hasClientActivities) { 12623 adj = clientHiddenAdj; 12624 app.adjType = "bg-client-act"; 12625 } else { 12626 // Whoops, this process is completely empty as far as we know 12627 // at this point. 12628 adj = emptyAdj; 12629 app.empty = true; 12630 app.adjType = "bg-empty"; 12631 } 12632 } 12633 12634 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12635 if (app.foregroundServices) { 12636 // The user is aware of this app, so make it visible. 12637 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12638 app.hidden = false; 12639 app.adjType = "fg-service"; 12640 schedGroup = Process.THREAD_GROUP_DEFAULT; 12641 } else if (app.forcingToForeground != null) { 12642 // The user is aware of this app, so make it visible. 12643 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12644 app.hidden = false; 12645 app.adjType = "force-fg"; 12646 app.adjSource = app.forcingToForeground; 12647 schedGroup = Process.THREAD_GROUP_DEFAULT; 12648 } 12649 } 12650 12651 if (app.foregroundServices) { 12652 interesting = true; 12653 } 12654 12655 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12656 // We don't want to kill the current heavy-weight process. 12657 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12658 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12659 app.hidden = false; 12660 app.adjType = "heavy"; 12661 } 12662 12663 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12664 // This process is hosting what we currently consider to be the 12665 // home app, so we don't want to let it go into the background. 12666 adj = ProcessList.HOME_APP_ADJ; 12667 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12668 app.hidden = false; 12669 app.adjType = "home"; 12670 } 12671 12672 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12673 && app.activities.size() > 0) { 12674 // This was the previous process that showed UI to the user. 12675 // We want to try to keep it around more aggressively, to give 12676 // a good experience around switching between two apps. 12677 adj = ProcessList.PREVIOUS_APP_ADJ; 12678 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12679 app.hidden = false; 12680 app.adjType = "previous"; 12681 } 12682 12683 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12684 + " reason=" + app.adjType); 12685 12686 // By default, we use the computed adjustment. It may be changed if 12687 // there are applications dependent on our services or providers, but 12688 // this gives us a baseline and makes sure we don't get into an 12689 // infinite recursion. 12690 app.adjSeq = mAdjSeq; 12691 app.curRawAdj = app.nonStoppingAdj = adj; 12692 12693 if (mBackupTarget != null && app == mBackupTarget.app) { 12694 // If possible we want to avoid killing apps while they're being backed up 12695 if (adj > ProcessList.BACKUP_APP_ADJ) { 12696 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12697 adj = ProcessList.BACKUP_APP_ADJ; 12698 app.adjType = "backup"; 12699 app.hidden = false; 12700 } 12701 } 12702 12703 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12704 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12705 final long now = SystemClock.uptimeMillis(); 12706 // This process is more important if the top activity is 12707 // bound to the service. 12708 Iterator<ServiceRecord> jt = app.services.iterator(); 12709 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12710 ServiceRecord s = jt.next(); 12711 if (s.startRequested) { 12712 if (app.hasShownUi && app != mHomeProcess) { 12713 // If this process has shown some UI, let it immediately 12714 // go to the LRU list because it may be pretty heavy with 12715 // UI stuff. We'll tag it with a label just to help 12716 // debug and understand what is going on. 12717 if (adj > ProcessList.SERVICE_ADJ) { 12718 app.adjType = "started-bg-ui-services"; 12719 } 12720 } else { 12721 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12722 // This service has seen some activity within 12723 // recent memory, so we will keep its process ahead 12724 // of the background processes. 12725 if (adj > ProcessList.SERVICE_ADJ) { 12726 adj = ProcessList.SERVICE_ADJ; 12727 app.adjType = "started-services"; 12728 app.hidden = false; 12729 } 12730 } 12731 // If we have let the service slide into the background 12732 // state, still have some text describing what it is doing 12733 // even though the service no longer has an impact. 12734 if (adj > ProcessList.SERVICE_ADJ) { 12735 app.adjType = "started-bg-services"; 12736 } 12737 } 12738 // Don't kill this process because it is doing work; it 12739 // has said it is doing work. 12740 app.keeping = true; 12741 } 12742 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12743 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12744 Iterator<ArrayList<ConnectionRecord>> kt 12745 = s.connections.values().iterator(); 12746 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12747 ArrayList<ConnectionRecord> clist = kt.next(); 12748 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12749 // XXX should compute this based on the max of 12750 // all connected clients. 12751 ConnectionRecord cr = clist.get(i); 12752 if (cr.binding.client == app) { 12753 // Binding to ourself is not interesting. 12754 continue; 12755 } 12756 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12757 ProcessRecord client = cr.binding.client; 12758 int clientAdj = adj; 12759 int myHiddenAdj = hiddenAdj; 12760 if (myHiddenAdj > client.hiddenAdj) { 12761 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12762 myHiddenAdj = client.hiddenAdj; 12763 } else { 12764 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12765 } 12766 } 12767 int myClientHiddenAdj = clientHiddenAdj; 12768 if (myClientHiddenAdj > client.clientHiddenAdj) { 12769 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12770 myClientHiddenAdj = client.clientHiddenAdj; 12771 } else { 12772 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12773 } 12774 } 12775 int myEmptyAdj = emptyAdj; 12776 if (myEmptyAdj > client.emptyAdj) { 12777 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12778 myEmptyAdj = client.emptyAdj; 12779 } else { 12780 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12781 } 12782 } 12783 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12784 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12785 String adjType = null; 12786 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12787 // Not doing bind OOM management, so treat 12788 // this guy more like a started service. 12789 if (app.hasShownUi && app != mHomeProcess) { 12790 // If this process has shown some UI, let it immediately 12791 // go to the LRU list because it may be pretty heavy with 12792 // UI stuff. We'll tag it with a label just to help 12793 // debug and understand what is going on. 12794 if (adj > clientAdj) { 12795 adjType = "bound-bg-ui-services"; 12796 } 12797 app.hidden = false; 12798 clientAdj = adj; 12799 } else { 12800 if (now >= (s.lastActivity 12801 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12802 // This service has not seen activity within 12803 // recent memory, so allow it to drop to the 12804 // LRU list if there is no other reason to keep 12805 // it around. We'll also tag it with a label just 12806 // to help debug and undertand what is going on. 12807 if (adj > clientAdj) { 12808 adjType = "bound-bg-services"; 12809 } 12810 clientAdj = adj; 12811 } 12812 } 12813 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 12814 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 12815 // If this connection is keeping the service 12816 // created, then we want to try to better follow 12817 // its memory management semantics for activities. 12818 // That is, if it is sitting in the background 12819 // LRU list as a hidden process (with activities), 12820 // we don't want the service it is connected to 12821 // to go into the empty LRU and quickly get killed, 12822 // because I'll we'll do is just end up restarting 12823 // the service. 12824 app.hasClientActivities |= client.hasActivities; 12825 } 12826 } 12827 if (adj > clientAdj) { 12828 // If this process has recently shown UI, and 12829 // the process that is binding to it is less 12830 // important than being visible, then we don't 12831 // care about the binding as much as we care 12832 // about letting this process get into the LRU 12833 // list to be killed and restarted if needed for 12834 // memory. 12835 if (app.hasShownUi && app != mHomeProcess 12836 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12837 adjType = "bound-bg-ui-services"; 12838 } else { 12839 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12840 |Context.BIND_IMPORTANT)) != 0) { 12841 adj = clientAdj; 12842 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12843 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12844 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12845 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12846 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12847 adj = clientAdj; 12848 } else { 12849 app.pendingUiClean = true; 12850 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12851 adj = ProcessList.VISIBLE_APP_ADJ; 12852 } 12853 } 12854 if (!client.hidden) { 12855 app.hidden = false; 12856 } 12857 if (client.keeping) { 12858 app.keeping = true; 12859 } 12860 adjType = "service"; 12861 } 12862 } 12863 if (adjType != null) { 12864 app.adjType = adjType; 12865 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12866 .REASON_SERVICE_IN_USE; 12867 app.adjSource = cr.binding.client; 12868 app.adjSourceOom = clientAdj; 12869 app.adjTarget = s.name; 12870 } 12871 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12872 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12873 schedGroup = Process.THREAD_GROUP_DEFAULT; 12874 } 12875 } 12876 } 12877 final ActivityRecord a = cr.activity; 12878 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12879 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12880 (a.visible || a.state == ActivityState.RESUMED 12881 || a.state == ActivityState.PAUSING)) { 12882 adj = ProcessList.FOREGROUND_APP_ADJ; 12883 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12884 schedGroup = Process.THREAD_GROUP_DEFAULT; 12885 } 12886 app.hidden = false; 12887 app.adjType = "service"; 12888 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12889 .REASON_SERVICE_IN_USE; 12890 app.adjSource = a; 12891 app.adjSourceOom = adj; 12892 app.adjTarget = s.name; 12893 } 12894 } 12895 } 12896 } 12897 } 12898 } 12899 12900 // Finally, if this process has active services running in it, we 12901 // would like to avoid killing it unless it would prevent the current 12902 // application from running. By default we put the process in 12903 // with the rest of the background processes; as we scan through 12904 // its services we may bump it up from there. 12905 if (adj > hiddenAdj) { 12906 adj = hiddenAdj; 12907 app.hidden = false; 12908 app.adjType = "bg-services"; 12909 } 12910 } 12911 12912 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12913 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12914 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12915 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12916 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12917 ContentProviderRecord cpr = jt.next(); 12918 for (int i = cpr.connections.size()-1; 12919 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12920 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12921 i--) { 12922 ContentProviderConnection conn = cpr.connections.get(i); 12923 ProcessRecord client = conn.client; 12924 if (client == app) { 12925 // Being our own client is not interesting. 12926 continue; 12927 } 12928 int myHiddenAdj = hiddenAdj; 12929 if (myHiddenAdj > client.hiddenAdj) { 12930 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12931 myHiddenAdj = client.hiddenAdj; 12932 } else { 12933 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12934 } 12935 } 12936 int myClientHiddenAdj = clientHiddenAdj; 12937 if (myClientHiddenAdj > client.clientHiddenAdj) { 12938 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { 12939 myClientHiddenAdj = client.clientHiddenAdj; 12940 } else { 12941 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12942 } 12943 } 12944 int myEmptyAdj = emptyAdj; 12945 if (myEmptyAdj > client.emptyAdj) { 12946 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12947 myEmptyAdj = client.emptyAdj; 12948 } else { 12949 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12950 } 12951 } 12952 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12953 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); 12954 if (adj > clientAdj) { 12955 if (app.hasShownUi && app != mHomeProcess 12956 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12957 app.adjType = "bg-ui-provider"; 12958 } else { 12959 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12960 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12961 app.adjType = "provider"; 12962 } 12963 if (!client.hidden) { 12964 app.hidden = false; 12965 } 12966 if (client.keeping) { 12967 app.keeping = true; 12968 } 12969 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12970 .REASON_PROVIDER_IN_USE; 12971 app.adjSource = client; 12972 app.adjSourceOom = clientAdj; 12973 app.adjTarget = cpr.name; 12974 } 12975 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12976 schedGroup = Process.THREAD_GROUP_DEFAULT; 12977 } 12978 } 12979 // If the provider has external (non-framework) process 12980 // dependencies, ensure that its adjustment is at least 12981 // FOREGROUND_APP_ADJ. 12982 if (cpr.hasExternalProcessHandles()) { 12983 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12984 adj = ProcessList.FOREGROUND_APP_ADJ; 12985 schedGroup = Process.THREAD_GROUP_DEFAULT; 12986 app.hidden = false; 12987 app.keeping = true; 12988 app.adjType = "provider"; 12989 app.adjTarget = cpr.name; 12990 } 12991 } 12992 } 12993 } 12994 12995 if (adj == ProcessList.SERVICE_ADJ) { 12996 if (doingAll) { 12997 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12998 mNewNumServiceProcs++; 12999 } 13000 if (app.serviceb) { 13001 adj = ProcessList.SERVICE_B_ADJ; 13002 } 13003 } else { 13004 app.serviceb = false; 13005 } 13006 13007 app.nonStoppingAdj = adj; 13008 13009 if (hasStoppingActivities) { 13010 // Only upgrade adjustment. 13011 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13012 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13013 app.adjType = "stopping"; 13014 } 13015 } 13016 13017 app.curRawAdj = adj; 13018 13019 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13020 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13021 if (adj > app.maxAdj) { 13022 adj = app.maxAdj; 13023 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 13024 schedGroup = Process.THREAD_GROUP_DEFAULT; 13025 } 13026 } 13027 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13028 app.keeping = true; 13029 } 13030 13031 if (app.hasAboveClient) { 13032 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13033 // then we need to drop its adjustment to be lower than the service's 13034 // in order to honor the request. We want to drop it by one adjustment 13035 // level... but there is special meaning applied to various levels so 13036 // we will skip some of them. 13037 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13038 // System process will not get dropped, ever 13039 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13040 adj = ProcessList.VISIBLE_APP_ADJ; 13041 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13042 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13043 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13044 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13045 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13046 adj++; 13047 } 13048 } 13049 13050 int importance = app.memImportance; 13051 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13052 app.curAdj = adj; 13053 app.curSchedGroup = schedGroup; 13054 if (!interesting) { 13055 // For this reporting, if there is not something explicitly 13056 // interesting in this process then we will push it to the 13057 // background importance. 13058 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13059 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13060 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13061 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13062 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13063 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13064 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13065 } else if (adj >= ProcessList.SERVICE_ADJ) { 13066 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13067 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13068 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13069 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13070 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13071 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13072 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13073 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13074 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13075 } else { 13076 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13077 } 13078 } 13079 13080 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13081 if (foregroundActivities != app.foregroundActivities) { 13082 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13083 } 13084 if (changes != 0) { 13085 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13086 app.memImportance = importance; 13087 app.foregroundActivities = foregroundActivities; 13088 int i = mPendingProcessChanges.size()-1; 13089 ProcessChangeItem item = null; 13090 while (i >= 0) { 13091 item = mPendingProcessChanges.get(i); 13092 if (item.pid == app.pid) { 13093 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13094 break; 13095 } 13096 i--; 13097 } 13098 if (i < 0) { 13099 // No existing item in pending changes; need a new one. 13100 final int NA = mAvailProcessChanges.size(); 13101 if (NA > 0) { 13102 item = mAvailProcessChanges.remove(NA-1); 13103 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13104 } else { 13105 item = new ProcessChangeItem(); 13106 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13107 } 13108 item.changes = 0; 13109 item.pid = app.pid; 13110 item.uid = app.info.uid; 13111 if (mPendingProcessChanges.size() == 0) { 13112 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13113 "*** Enqueueing dispatch processes changed!"); 13114 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13115 } 13116 mPendingProcessChanges.add(item); 13117 } 13118 item.changes |= changes; 13119 item.importance = importance; 13120 item.foregroundActivities = foregroundActivities; 13121 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13122 + Integer.toHexString(System.identityHashCode(item)) 13123 + " " + app.toShortString() + ": changes=" + item.changes 13124 + " importance=" + item.importance 13125 + " foreground=" + item.foregroundActivities 13126 + " type=" + app.adjType + " source=" + app.adjSource 13127 + " target=" + app.adjTarget); 13128 } 13129 13130 return app.curRawAdj; 13131 } 13132 13133 /** 13134 * Ask a given process to GC right now. 13135 */ 13136 final void performAppGcLocked(ProcessRecord app) { 13137 try { 13138 app.lastRequestedGc = SystemClock.uptimeMillis(); 13139 if (app.thread != null) { 13140 if (app.reportLowMemory) { 13141 app.reportLowMemory = false; 13142 app.thread.scheduleLowMemory(); 13143 } else { 13144 app.thread.processInBackground(); 13145 } 13146 } 13147 } catch (Exception e) { 13148 // whatever. 13149 } 13150 } 13151 13152 /** 13153 * Returns true if things are idle enough to perform GCs. 13154 */ 13155 private final boolean canGcNowLocked() { 13156 boolean processingBroadcasts = false; 13157 for (BroadcastQueue q : mBroadcastQueues) { 13158 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13159 processingBroadcasts = true; 13160 } 13161 } 13162 return !processingBroadcasts 13163 && (mSleeping || (mMainStack.mResumedActivity != null && 13164 mMainStack.mResumedActivity.idle)); 13165 } 13166 13167 /** 13168 * Perform GCs on all processes that are waiting for it, but only 13169 * if things are idle. 13170 */ 13171 final void performAppGcsLocked() { 13172 final int N = mProcessesToGc.size(); 13173 if (N <= 0) { 13174 return; 13175 } 13176 if (canGcNowLocked()) { 13177 while (mProcessesToGc.size() > 0) { 13178 ProcessRecord proc = mProcessesToGc.remove(0); 13179 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13180 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13181 <= SystemClock.uptimeMillis()) { 13182 // To avoid spamming the system, we will GC processes one 13183 // at a time, waiting a few seconds between each. 13184 performAppGcLocked(proc); 13185 scheduleAppGcsLocked(); 13186 return; 13187 } else { 13188 // It hasn't been long enough since we last GCed this 13189 // process... put it in the list to wait for its time. 13190 addProcessToGcListLocked(proc); 13191 break; 13192 } 13193 } 13194 } 13195 13196 scheduleAppGcsLocked(); 13197 } 13198 } 13199 13200 /** 13201 * If all looks good, perform GCs on all processes waiting for them. 13202 */ 13203 final void performAppGcsIfAppropriateLocked() { 13204 if (canGcNowLocked()) { 13205 performAppGcsLocked(); 13206 return; 13207 } 13208 // Still not idle, wait some more. 13209 scheduleAppGcsLocked(); 13210 } 13211 13212 /** 13213 * Schedule the execution of all pending app GCs. 13214 */ 13215 final void scheduleAppGcsLocked() { 13216 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13217 13218 if (mProcessesToGc.size() > 0) { 13219 // Schedule a GC for the time to the next process. 13220 ProcessRecord proc = mProcessesToGc.get(0); 13221 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13222 13223 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13224 long now = SystemClock.uptimeMillis(); 13225 if (when < (now+GC_TIMEOUT)) { 13226 when = now + GC_TIMEOUT; 13227 } 13228 mHandler.sendMessageAtTime(msg, when); 13229 } 13230 } 13231 13232 /** 13233 * Add a process to the array of processes waiting to be GCed. Keeps the 13234 * list in sorted order by the last GC time. The process can't already be 13235 * on the list. 13236 */ 13237 final void addProcessToGcListLocked(ProcessRecord proc) { 13238 boolean added = false; 13239 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13240 if (mProcessesToGc.get(i).lastRequestedGc < 13241 proc.lastRequestedGc) { 13242 added = true; 13243 mProcessesToGc.add(i+1, proc); 13244 break; 13245 } 13246 } 13247 if (!added) { 13248 mProcessesToGc.add(0, proc); 13249 } 13250 } 13251 13252 /** 13253 * Set up to ask a process to GC itself. This will either do it 13254 * immediately, or put it on the list of processes to gc the next 13255 * time things are idle. 13256 */ 13257 final void scheduleAppGcLocked(ProcessRecord app) { 13258 long now = SystemClock.uptimeMillis(); 13259 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13260 return; 13261 } 13262 if (!mProcessesToGc.contains(app)) { 13263 addProcessToGcListLocked(app); 13264 scheduleAppGcsLocked(); 13265 } 13266 } 13267 13268 final void checkExcessivePowerUsageLocked(boolean doKills) { 13269 updateCpuStatsNow(); 13270 13271 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13272 boolean doWakeKills = doKills; 13273 boolean doCpuKills = doKills; 13274 if (mLastPowerCheckRealtime == 0) { 13275 doWakeKills = false; 13276 } 13277 if (mLastPowerCheckUptime == 0) { 13278 doCpuKills = false; 13279 } 13280 if (stats.isScreenOn()) { 13281 doWakeKills = false; 13282 } 13283 final long curRealtime = SystemClock.elapsedRealtime(); 13284 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13285 final long curUptime = SystemClock.uptimeMillis(); 13286 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13287 mLastPowerCheckRealtime = curRealtime; 13288 mLastPowerCheckUptime = curUptime; 13289 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13290 doWakeKills = false; 13291 } 13292 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13293 doCpuKills = false; 13294 } 13295 int i = mLruProcesses.size(); 13296 while (i > 0) { 13297 i--; 13298 ProcessRecord app = mLruProcesses.get(i); 13299 if (!app.keeping) { 13300 long wtime; 13301 synchronized (stats) { 13302 wtime = stats.getProcessWakeTime(app.info.uid, 13303 app.pid, curRealtime); 13304 } 13305 long wtimeUsed = wtime - app.lastWakeTime; 13306 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13307 if (DEBUG_POWER) { 13308 StringBuilder sb = new StringBuilder(128); 13309 sb.append("Wake for "); 13310 app.toShortString(sb); 13311 sb.append(": over "); 13312 TimeUtils.formatDuration(realtimeSince, sb); 13313 sb.append(" used "); 13314 TimeUtils.formatDuration(wtimeUsed, sb); 13315 sb.append(" ("); 13316 sb.append((wtimeUsed*100)/realtimeSince); 13317 sb.append("%)"); 13318 Slog.i(TAG, sb.toString()); 13319 sb.setLength(0); 13320 sb.append("CPU for "); 13321 app.toShortString(sb); 13322 sb.append(": over "); 13323 TimeUtils.formatDuration(uptimeSince, sb); 13324 sb.append(" used "); 13325 TimeUtils.formatDuration(cputimeUsed, sb); 13326 sb.append(" ("); 13327 sb.append((cputimeUsed*100)/uptimeSince); 13328 sb.append("%)"); 13329 Slog.i(TAG, sb.toString()); 13330 } 13331 // If a process has held a wake lock for more 13332 // than 50% of the time during this period, 13333 // that sounds bad. Kill! 13334 if (doWakeKills && realtimeSince > 0 13335 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13336 synchronized (stats) { 13337 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13338 realtimeSince, wtimeUsed); 13339 } 13340 Slog.w(TAG, "Excessive wake lock in " + app.processName 13341 + " (pid " + app.pid + "): held " + wtimeUsed 13342 + " during " + realtimeSince); 13343 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13344 app.processName, app.setAdj, "excessive wake lock"); 13345 Process.killProcessQuiet(app.pid); 13346 } else if (doCpuKills && uptimeSince > 0 13347 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13348 synchronized (stats) { 13349 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13350 uptimeSince, cputimeUsed); 13351 } 13352 Slog.w(TAG, "Excessive CPU in " + app.processName 13353 + " (pid " + app.pid + "): used " + cputimeUsed 13354 + " during " + uptimeSince); 13355 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13356 app.processName, app.setAdj, "excessive cpu"); 13357 Process.killProcessQuiet(app.pid); 13358 } else { 13359 app.lastWakeTime = wtime; 13360 app.lastCpuTime = app.curCpuTime; 13361 } 13362 } 13363 } 13364 } 13365 13366 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13367 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13368 app.hiddenAdj = hiddenAdj; 13369 app.clientHiddenAdj = clientHiddenAdj; 13370 app.emptyAdj = emptyAdj; 13371 13372 if (app.thread == null) { 13373 return false; 13374 } 13375 13376 final boolean wasKeeping = app.keeping; 13377 13378 boolean success = true; 13379 13380 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13381 13382 if (app.curRawAdj != app.setRawAdj) { 13383 if (wasKeeping && !app.keeping) { 13384 // This app is no longer something we want to keep. Note 13385 // its current wake lock time to later know to kill it if 13386 // it is not behaving well. 13387 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13388 synchronized (stats) { 13389 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13390 app.pid, SystemClock.elapsedRealtime()); 13391 } 13392 app.lastCpuTime = app.curCpuTime; 13393 } 13394 13395 app.setRawAdj = app.curRawAdj; 13396 } 13397 13398 if (app.curAdj != app.setAdj) { 13399 if (Process.setOomAdj(app.pid, app.curAdj)) { 13400 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13401 TAG, "Set " + app.pid + " " + app.processName + 13402 " adj " + app.curAdj + ": " + app.adjType); 13403 app.setAdj = app.curAdj; 13404 } else { 13405 success = false; 13406 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13407 } 13408 } 13409 if (app.setSchedGroup != app.curSchedGroup) { 13410 app.setSchedGroup = app.curSchedGroup; 13411 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13412 "Setting process group of " + app.processName 13413 + " to " + app.curSchedGroup); 13414 if (app.waitingToKill != null && 13415 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13416 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13417 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13418 app.processName, app.setAdj, app.waitingToKill); 13419 app.killedBackground = true; 13420 Process.killProcessQuiet(app.pid); 13421 success = false; 13422 } else { 13423 if (true) { 13424 long oldId = Binder.clearCallingIdentity(); 13425 try { 13426 Process.setProcessGroup(app.pid, app.curSchedGroup); 13427 } catch (Exception e) { 13428 Slog.w(TAG, "Failed setting process group of " + app.pid 13429 + " to " + app.curSchedGroup); 13430 e.printStackTrace(); 13431 } finally { 13432 Binder.restoreCallingIdentity(oldId); 13433 } 13434 } else { 13435 if (app.thread != null) { 13436 try { 13437 app.thread.setSchedulingGroup(app.curSchedGroup); 13438 } catch (RemoteException e) { 13439 } 13440 } 13441 } 13442 } 13443 } 13444 return success; 13445 } 13446 13447 private final ActivityRecord resumedAppLocked() { 13448 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13449 if (resumedActivity == null || resumedActivity.app == null) { 13450 resumedActivity = mMainStack.mPausingActivity; 13451 if (resumedActivity == null || resumedActivity.app == null) { 13452 resumedActivity = mMainStack.topRunningActivityLocked(null); 13453 } 13454 } 13455 return resumedActivity; 13456 } 13457 13458 final boolean updateOomAdjLocked(ProcessRecord app) { 13459 final ActivityRecord TOP_ACT = resumedAppLocked(); 13460 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13461 int curAdj = app.curAdj; 13462 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13463 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13464 13465 mAdjSeq++; 13466 13467 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj, 13468 app.emptyAdj, TOP_APP, false); 13469 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13470 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13471 if (nowHidden != wasHidden) { 13472 // Changed to/from hidden state, so apps after it in the LRU 13473 // list may also be changed. 13474 updateOomAdjLocked(); 13475 } 13476 return success; 13477 } 13478 13479 final void updateOomAdjLocked() { 13480 final ActivityRecord TOP_ACT = resumedAppLocked(); 13481 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13482 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME; 13483 13484 if (false) { 13485 RuntimeException e = new RuntimeException(); 13486 e.fillInStackTrace(); 13487 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13488 } 13489 13490 mAdjSeq++; 13491 mNewNumServiceProcs = 0; 13492 13493 final int emptyProcessLimit; 13494 final int hiddenProcessLimit; 13495 if (mProcessLimit <= 0) { 13496 emptyProcessLimit = hiddenProcessLimit = 0; 13497 } else if (mProcessLimit == 1) { 13498 emptyProcessLimit = 1; 13499 hiddenProcessLimit = 0; 13500 } else { 13501 emptyProcessLimit = (mProcessLimit*2)/3; 13502 hiddenProcessLimit = mProcessLimit - emptyProcessLimit; 13503 } 13504 13505 // Let's determine how many processes we have running vs. 13506 // how many slots we have for background processes; we may want 13507 // to put multiple processes in a slot of there are enough of 13508 // them. 13509 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13510 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13511 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs; 13512 if (numEmptyProcs > hiddenProcessLimit) { 13513 // If there are more empty processes than our limit on hidden 13514 // processes, then use the hidden process limit for the factor. 13515 // This ensures that the really old empty processes get pushed 13516 // down to the bottom, so if we are running low on memory we will 13517 // have a better chance at keeping around more hidden processes 13518 // instead of a gazillion empty processes. 13519 numEmptyProcs = hiddenProcessLimit; 13520 } 13521 int emptyFactor = numEmptyProcs/numSlots; 13522 if (emptyFactor < 1) emptyFactor = 1; 13523 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13524 if (hiddenFactor < 1) hiddenFactor = 1; 13525 int stepHidden = 0; 13526 int stepEmpty = 0; 13527 int numHidden = 0; 13528 int numEmpty = 0; 13529 int numTrimming = 0; 13530 13531 mNumNonHiddenProcs = 0; 13532 mNumHiddenProcs = 0; 13533 13534 // First update the OOM adjustment for each of the 13535 // application processes based on their current state. 13536 int i = mLruProcesses.size(); 13537 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13538 int nextHiddenAdj = curHiddenAdj+1; 13539 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13540 int nextEmptyAdj = curEmptyAdj+2; 13541 int curClientHiddenAdj = curEmptyAdj; 13542 while (i > 0) { 13543 i--; 13544 ProcessRecord app = mLruProcesses.get(i); 13545 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13546 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true); 13547 if (!app.killedBackground) { 13548 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13549 // This process was assigned as a hidden process... step the 13550 // hidden level. 13551 mNumHiddenProcs++; 13552 if (curHiddenAdj != nextHiddenAdj) { 13553 stepHidden++; 13554 if (stepHidden >= hiddenFactor) { 13555 stepHidden = 0; 13556 curHiddenAdj = nextHiddenAdj; 13557 nextHiddenAdj += 2; 13558 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13559 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13560 } 13561 if (curClientHiddenAdj <= curHiddenAdj) { 13562 curClientHiddenAdj = curHiddenAdj + 1; 13563 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13564 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13565 } 13566 } 13567 } 13568 } 13569 numHidden++; 13570 if (numHidden > hiddenProcessLimit) { 13571 Slog.i(TAG, "No longer want " + app.processName 13572 + " (pid " + app.pid + "): hidden #" + numHidden); 13573 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13574 app.processName, app.setAdj, "too many background"); 13575 app.killedBackground = true; 13576 Process.killProcessQuiet(app.pid); 13577 } 13578 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) { 13579 // This process has a client that has activities. We will have 13580 // given it the current hidden adj; here we will just leave it 13581 // without stepping the hidden adj. 13582 curClientHiddenAdj++; 13583 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13584 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13585 } 13586 } else { 13587 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13588 // This process was assigned as an empty process... step the 13589 // empty level. 13590 if (curEmptyAdj != nextEmptyAdj) { 13591 stepEmpty++; 13592 if (stepEmpty >= emptyFactor) { 13593 stepEmpty = 0; 13594 curEmptyAdj = nextEmptyAdj; 13595 nextEmptyAdj += 2; 13596 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13597 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13598 } 13599 } 13600 } 13601 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13602 mNumNonHiddenProcs++; 13603 } 13604 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13605 && !app.hasClientActivities) { 13606 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 13607 && app.lastActivityTime < oldTime) { 13608 Slog.i(TAG, "No longer want " + app.processName 13609 + " (pid " + app.pid + "): empty for " 13610 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime) 13611 / 1000) + "s"); 13612 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13613 app.processName, app.setAdj, "old background process"); 13614 app.killedBackground = true; 13615 Process.killProcessQuiet(app.pid); 13616 } else { 13617 numEmpty++; 13618 if (numEmpty > emptyProcessLimit) { 13619 Slog.i(TAG, "No longer want " + app.processName 13620 + " (pid " + app.pid + "): empty #" + numEmpty); 13621 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13622 app.processName, app.setAdj, "too many background"); 13623 app.killedBackground = true; 13624 Process.killProcessQuiet(app.pid); 13625 } 13626 } 13627 } 13628 } 13629 if (app.isolated && app.services.size() <= 0) { 13630 // If this is an isolated process, and there are no 13631 // services running in it, then the process is no longer 13632 // needed. We agressively kill these because we can by 13633 // definition not re-use the same process again, and it is 13634 // good to avoid having whatever code was running in them 13635 // left sitting around after no longer needed. 13636 Slog.i(TAG, "Isolated process " + app.processName 13637 + " (pid " + app.pid + ") no longer needed"); 13638 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13639 app.processName, app.setAdj, "isolated not needed"); 13640 app.killedBackground = true; 13641 Process.killProcessQuiet(app.pid); 13642 } 13643 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13644 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13645 && !app.killedBackground) { 13646 numTrimming++; 13647 } 13648 } 13649 } 13650 13651 mNumServiceProcs = mNewNumServiceProcs; 13652 13653 // Now determine the memory trimming level of background processes. 13654 // Unfortunately we need to start at the back of the list to do this 13655 // properly. We only do this if the number of background apps we 13656 // are managing to keep around is less than half the maximum we desire; 13657 // if we are keeping a good number around, we'll let them use whatever 13658 // memory they want. 13659 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS 13660 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 13661 final int numHiddenAndEmpty = numHidden + numEmpty; 13662 final int N = mLruProcesses.size(); 13663 int factor = numTrimming/3; 13664 int minFactor = 2; 13665 if (mHomeProcess != null) minFactor++; 13666 if (mPreviousProcess != null) minFactor++; 13667 if (factor < minFactor) factor = minFactor; 13668 int step = 0; 13669 int fgTrimLevel; 13670 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 13671 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13672 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 13673 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13674 } else { 13675 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13676 } 13677 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13678 for (i=0; i<N; i++) { 13679 ProcessRecord app = mLruProcesses.get(i); 13680 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13681 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13682 && !app.killedBackground) { 13683 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13684 try { 13685 app.thread.scheduleTrimMemory(curLevel); 13686 } catch (RemoteException e) { 13687 } 13688 if (false) { 13689 // For now we won't do this; our memory trimming seems 13690 // to be good enough at this point that destroying 13691 // activities causes more harm than good. 13692 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13693 && app != mHomeProcess && app != mPreviousProcess) { 13694 // Need to do this on its own message because the stack may not 13695 // be in a consistent state at this point. 13696 // For these apps we will also finish their activities 13697 // to help them free memory. 13698 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13699 } 13700 } 13701 } 13702 app.trimMemoryLevel = curLevel; 13703 step++; 13704 if (step >= factor) { 13705 step = 0; 13706 switch (curLevel) { 13707 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13708 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13709 break; 13710 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13711 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13712 break; 13713 } 13714 } 13715 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13716 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13717 && app.thread != null) { 13718 try { 13719 app.thread.scheduleTrimMemory( 13720 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13721 } catch (RemoteException e) { 13722 } 13723 } 13724 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13725 } else { 13726 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13727 && app.pendingUiClean) { 13728 // If this application is now in the background and it 13729 // had done UI, then give it the special trim level to 13730 // have it free UI resources. 13731 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13732 if (app.trimMemoryLevel < level && app.thread != null) { 13733 try { 13734 app.thread.scheduleTrimMemory(level); 13735 } catch (RemoteException e) { 13736 } 13737 } 13738 app.pendingUiClean = false; 13739 } 13740 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13741 try { 13742 app.thread.scheduleTrimMemory(fgTrimLevel); 13743 } catch (RemoteException e) { 13744 } 13745 } 13746 app.trimMemoryLevel = fgTrimLevel; 13747 } 13748 } 13749 } else { 13750 final int N = mLruProcesses.size(); 13751 for (i=0; i<N; i++) { 13752 ProcessRecord app = mLruProcesses.get(i); 13753 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13754 && app.pendingUiClean) { 13755 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13756 && app.thread != null) { 13757 try { 13758 app.thread.scheduleTrimMemory( 13759 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13760 } catch (RemoteException e) { 13761 } 13762 } 13763 app.pendingUiClean = false; 13764 } 13765 app.trimMemoryLevel = 0; 13766 } 13767 } 13768 13769 if (mAlwaysFinishActivities) { 13770 // Need to do this on its own message because the stack may not 13771 // be in a consistent state at this point. 13772 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13773 } 13774 } 13775 13776 final void trimApplications() { 13777 synchronized (this) { 13778 int i; 13779 13780 // First remove any unused application processes whose package 13781 // has been removed. 13782 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13783 final ProcessRecord app = mRemovedProcesses.get(i); 13784 if (app.activities.size() == 0 13785 && app.curReceiver == null && app.services.size() == 0) { 13786 Slog.i( 13787 TAG, "Exiting empty application process " 13788 + app.processName + " (" 13789 + (app.thread != null ? app.thread.asBinder() : null) 13790 + ")\n"); 13791 if (app.pid > 0 && app.pid != MY_PID) { 13792 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 13793 app.processName, app.setAdj, "empty"); 13794 Process.killProcessQuiet(app.pid); 13795 } else { 13796 try { 13797 app.thread.scheduleExit(); 13798 } catch (Exception e) { 13799 // Ignore exceptions. 13800 } 13801 } 13802 cleanUpApplicationRecordLocked(app, false, true, -1); 13803 mRemovedProcesses.remove(i); 13804 13805 if (app.persistent) { 13806 if (app.persistent) { 13807 addAppLocked(app.info, false); 13808 } 13809 } 13810 } 13811 } 13812 13813 // Now update the oom adj for all processes. 13814 updateOomAdjLocked(); 13815 } 13816 } 13817 13818 /** This method sends the specified signal to each of the persistent apps */ 13819 public void signalPersistentProcesses(int sig) throws RemoteException { 13820 if (sig != Process.SIGNAL_USR1) { 13821 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13822 } 13823 13824 synchronized (this) { 13825 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13826 != PackageManager.PERMISSION_GRANTED) { 13827 throw new SecurityException("Requires permission " 13828 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13829 } 13830 13831 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13832 ProcessRecord r = mLruProcesses.get(i); 13833 if (r.thread != null && r.persistent) { 13834 Process.sendSignal(r.pid, sig); 13835 } 13836 } 13837 } 13838 } 13839 13840 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13841 if (proc == null || proc == mProfileProc) { 13842 proc = mProfileProc; 13843 path = mProfileFile; 13844 profileType = mProfileType; 13845 clearProfilerLocked(); 13846 } 13847 if (proc == null) { 13848 return; 13849 } 13850 try { 13851 proc.thread.profilerControl(false, path, null, profileType); 13852 } catch (RemoteException e) { 13853 throw new IllegalStateException("Process disappeared"); 13854 } 13855 } 13856 13857 private void clearProfilerLocked() { 13858 if (mProfileFd != null) { 13859 try { 13860 mProfileFd.close(); 13861 } catch (IOException e) { 13862 } 13863 } 13864 mProfileApp = null; 13865 mProfileProc = null; 13866 mProfileFile = null; 13867 mProfileType = 0; 13868 mAutoStopProfiler = false; 13869 } 13870 13871 public boolean profileControl(String process, int userId, boolean start, 13872 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13873 13874 try { 13875 synchronized (this) { 13876 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13877 // its own permission. 13878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13879 != PackageManager.PERMISSION_GRANTED) { 13880 throw new SecurityException("Requires permission " 13881 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13882 } 13883 13884 if (start && fd == null) { 13885 throw new IllegalArgumentException("null fd"); 13886 } 13887 13888 ProcessRecord proc = null; 13889 if (process != null) { 13890 proc = findProcessLocked(process, userId, "profileControl"); 13891 } 13892 13893 if (start && (proc == null || proc.thread == null)) { 13894 throw new IllegalArgumentException("Unknown process: " + process); 13895 } 13896 13897 if (start) { 13898 stopProfilerLocked(null, null, 0); 13899 setProfileApp(proc.info, proc.processName, path, fd, false); 13900 mProfileProc = proc; 13901 mProfileType = profileType; 13902 try { 13903 fd = fd.dup(); 13904 } catch (IOException e) { 13905 fd = null; 13906 } 13907 proc.thread.profilerControl(start, path, fd, profileType); 13908 fd = null; 13909 mProfileFd = null; 13910 } else { 13911 stopProfilerLocked(proc, path, profileType); 13912 if (fd != null) { 13913 try { 13914 fd.close(); 13915 } catch (IOException e) { 13916 } 13917 } 13918 } 13919 13920 return true; 13921 } 13922 } catch (RemoteException e) { 13923 throw new IllegalStateException("Process disappeared"); 13924 } finally { 13925 if (fd != null) { 13926 try { 13927 fd.close(); 13928 } catch (IOException e) { 13929 } 13930 } 13931 } 13932 } 13933 13934 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13935 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13936 userId, true, true, callName, null); 13937 ProcessRecord proc = null; 13938 try { 13939 int pid = Integer.parseInt(process); 13940 synchronized (mPidsSelfLocked) { 13941 proc = mPidsSelfLocked.get(pid); 13942 } 13943 } catch (NumberFormatException e) { 13944 } 13945 13946 if (proc == null) { 13947 HashMap<String, SparseArray<ProcessRecord>> all 13948 = mProcessNames.getMap(); 13949 SparseArray<ProcessRecord> procs = all.get(process); 13950 if (procs != null && procs.size() > 0) { 13951 proc = procs.valueAt(0); 13952 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13953 for (int i=1; i<procs.size(); i++) { 13954 ProcessRecord thisProc = procs.valueAt(i); 13955 if (thisProc.userId == userId) { 13956 proc = thisProc; 13957 break; 13958 } 13959 } 13960 } 13961 } 13962 } 13963 13964 return proc; 13965 } 13966 13967 public boolean dumpHeap(String process, int userId, boolean managed, 13968 String path, ParcelFileDescriptor fd) throws RemoteException { 13969 13970 try { 13971 synchronized (this) { 13972 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13973 // its own permission (same as profileControl). 13974 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13975 != PackageManager.PERMISSION_GRANTED) { 13976 throw new SecurityException("Requires permission " 13977 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13978 } 13979 13980 if (fd == null) { 13981 throw new IllegalArgumentException("null fd"); 13982 } 13983 13984 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13985 if (proc == null || proc.thread == null) { 13986 throw new IllegalArgumentException("Unknown process: " + process); 13987 } 13988 13989 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13990 if (!isDebuggable) { 13991 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13992 throw new SecurityException("Process not debuggable: " + proc); 13993 } 13994 } 13995 13996 proc.thread.dumpHeap(managed, path, fd); 13997 fd = null; 13998 return true; 13999 } 14000 } catch (RemoteException e) { 14001 throw new IllegalStateException("Process disappeared"); 14002 } finally { 14003 if (fd != null) { 14004 try { 14005 fd.close(); 14006 } catch (IOException e) { 14007 } 14008 } 14009 } 14010 } 14011 14012 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14013 public void monitor() { 14014 synchronized (this) { } 14015 } 14016 14017 void onCoreSettingsChange(Bundle settings) { 14018 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14019 ProcessRecord processRecord = mLruProcesses.get(i); 14020 try { 14021 if (processRecord.thread != null) { 14022 processRecord.thread.setCoreSettings(settings); 14023 } 14024 } catch (RemoteException re) { 14025 /* ignore */ 14026 } 14027 } 14028 } 14029 14030 // Multi-user methods 14031 14032 @Override 14033 public boolean switchUser(int userId) { 14034 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14035 != PackageManager.PERMISSION_GRANTED) { 14036 String msg = "Permission Denial: switchUser() from pid=" 14037 + Binder.getCallingPid() 14038 + ", uid=" + Binder.getCallingUid() 14039 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14040 Slog.w(TAG, msg); 14041 throw new SecurityException(msg); 14042 } 14043 14044 final long ident = Binder.clearCallingIdentity(); 14045 try { 14046 synchronized (this) { 14047 final int oldUserId = mCurrentUserId; 14048 if (oldUserId == userId) { 14049 return true; 14050 } 14051 14052 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 14053 if (userInfo == null) { 14054 Slog.w(TAG, "No user info for user #" + userId); 14055 return false; 14056 } 14057 14058 mWindowManager.lockNow(); 14059 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 14060 R.anim.screen_user_enter); 14061 14062 // If the user we are switching to is not currently started, then 14063 // we need to start it now. 14064 if (mStartedUsers.get(userId) == null) { 14065 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 14066 updateStartedUserArrayLocked(); 14067 } 14068 14069 mCurrentUserId = userId; 14070 mCurrentUserArray = new int[] { userId }; 14071 final Integer userIdInt = Integer.valueOf(userId); 14072 mUserLru.remove(userIdInt); 14073 mUserLru.add(userIdInt); 14074 14075 mWindowManager.setCurrentUser(userId); 14076 14077 final UserStartedState uss = mStartedUsers.get(userId); 14078 14079 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14080 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14081 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14082 oldUserId, userId, uss)); 14083 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14084 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14085 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14086 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14087 | Intent.FLAG_RECEIVER_FOREGROUND); 14088 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14089 broadcastIntentLocked(null, null, intent, 14090 null, null, 0, null, null, null, 14091 false, false, MY_PID, Process.SYSTEM_UID, userId); 14092 14093 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14094 if (userId != 0) { 14095 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14096 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14097 broadcastIntentLocked(null, null, intent, null, 14098 new IIntentReceiver.Stub() { 14099 public void performReceive(Intent intent, int resultCode, 14100 String data, Bundle extras, boolean ordered, 14101 boolean sticky, int sendingUser) { 14102 userInitialized(uss); 14103 } 14104 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14105 userId); 14106 uss.initializing = true; 14107 } else { 14108 getUserManagerLocked().makeInitialized(userInfo.id); 14109 } 14110 } 14111 14112 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14113 if (!haveActivities) { 14114 startHomeActivityLocked(userId); 14115 } 14116 14117 getUserManagerLocked().userForeground(userId); 14118 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14119 } 14120 } finally { 14121 Binder.restoreCallingIdentity(ident); 14122 } 14123 14124 return true; 14125 } 14126 14127 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14128 long ident = Binder.clearCallingIdentity(); 14129 try { 14130 Intent intent; 14131 if (oldUserId >= 0) { 14132 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14133 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14134 | Intent.FLAG_RECEIVER_FOREGROUND); 14135 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14136 broadcastIntentLocked(null, null, intent, 14137 null, null, 0, null, null, null, 14138 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14139 } 14140 if (newUserId >= 0) { 14141 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14142 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14143 | Intent.FLAG_RECEIVER_FOREGROUND); 14144 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14145 broadcastIntentLocked(null, null, intent, 14146 null, null, 0, null, null, null, 14147 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14148 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14149 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14150 | Intent.FLAG_RECEIVER_FOREGROUND); 14151 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14152 broadcastIntentLocked(null, null, intent, 14153 null, null, 0, null, null, 14154 android.Manifest.permission.MANAGE_USERS, 14155 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14156 } 14157 } finally { 14158 Binder.restoreCallingIdentity(ident); 14159 } 14160 } 14161 14162 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14163 final int newUserId) { 14164 final int N = mUserSwitchObservers.beginBroadcast(); 14165 if (N > 0) { 14166 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14167 int mCount = 0; 14168 @Override 14169 public void sendResult(Bundle data) throws RemoteException { 14170 synchronized (ActivityManagerService.this) { 14171 if (mCurUserSwitchCallback == this) { 14172 mCount++; 14173 if (mCount == N) { 14174 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14175 } 14176 } 14177 } 14178 } 14179 }; 14180 synchronized (this) { 14181 uss.switching = true; 14182 mCurUserSwitchCallback = callback; 14183 } 14184 for (int i=0; i<N; i++) { 14185 try { 14186 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14187 newUserId, callback); 14188 } catch (RemoteException e) { 14189 } 14190 } 14191 } else { 14192 synchronized (this) { 14193 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14194 } 14195 } 14196 mUserSwitchObservers.finishBroadcast(); 14197 } 14198 14199 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14200 synchronized (this) { 14201 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14202 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14203 } 14204 } 14205 14206 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14207 mCurUserSwitchCallback = null; 14208 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14209 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14210 oldUserId, newUserId, uss)); 14211 } 14212 14213 void userInitialized(UserStartedState uss) { 14214 synchronized (ActivityManagerService.this) { 14215 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 14216 uss.initializing = false; 14217 completeSwitchAndInitalizeLocked(uss); 14218 } 14219 } 14220 14221 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14222 final int N = mUserSwitchObservers.beginBroadcast(); 14223 for (int i=0; i<N; i++) { 14224 try { 14225 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14226 } catch (RemoteException e) { 14227 } 14228 } 14229 mUserSwitchObservers.finishBroadcast(); 14230 synchronized (this) { 14231 uss.switching = false; 14232 completeSwitchAndInitalizeLocked(uss); 14233 } 14234 } 14235 14236 void completeSwitchAndInitalizeLocked(UserStartedState uss) { 14237 if (!uss.switching && !uss.initializing) { 14238 mWindowManager.stopFreezingScreen(); 14239 } 14240 } 14241 14242 void finishUserSwitch(UserStartedState uss) { 14243 synchronized (this) { 14244 if (uss.mState == UserStartedState.STATE_BOOTING 14245 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14246 uss.mState = UserStartedState.STATE_RUNNING; 14247 final int userId = uss.mHandle.getIdentifier(); 14248 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14249 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14250 broadcastIntentLocked(null, null, intent, 14251 null, null, 0, null, null, 14252 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14253 false, false, MY_PID, Process.SYSTEM_UID, userId); 14254 } 14255 int num = mUserLru.size(); 14256 int i = 0; 14257 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14258 Integer oldUserId = mUserLru.get(i); 14259 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14260 if (oldUss == null) { 14261 // Shouldn't happen, but be sane if it does. 14262 mUserLru.remove(i); 14263 num--; 14264 continue; 14265 } 14266 if (oldUss.mState == UserStartedState.STATE_STOPPING) { 14267 // This user is already stopping, doesn't count. 14268 num--; 14269 i++; 14270 continue; 14271 } 14272 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14273 // Owner and current can't be stopped, but count as running. 14274 i++; 14275 continue; 14276 } 14277 // This is a user to be stopped. 14278 stopUserLocked(oldUserId, null); 14279 num--; 14280 i++; 14281 } 14282 } 14283 } 14284 14285 @Override 14286 public int stopUser(final int userId, final IStopUserCallback callback) { 14287 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14288 != PackageManager.PERMISSION_GRANTED) { 14289 String msg = "Permission Denial: switchUser() from pid=" 14290 + Binder.getCallingPid() 14291 + ", uid=" + Binder.getCallingUid() 14292 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14293 Slog.w(TAG, msg); 14294 throw new SecurityException(msg); 14295 } 14296 if (userId <= 0) { 14297 throw new IllegalArgumentException("Can't stop primary user " + userId); 14298 } 14299 synchronized (this) { 14300 return stopUserLocked(userId, callback); 14301 } 14302 } 14303 14304 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14305 if (mCurrentUserId == userId) { 14306 return ActivityManager.USER_OP_IS_CURRENT; 14307 } 14308 14309 final UserStartedState uss = mStartedUsers.get(userId); 14310 if (uss == null) { 14311 // User is not started, nothing to do... but we do need to 14312 // callback if requested. 14313 if (callback != null) { 14314 mHandler.post(new Runnable() { 14315 @Override 14316 public void run() { 14317 try { 14318 callback.userStopped(userId); 14319 } catch (RemoteException e) { 14320 } 14321 } 14322 }); 14323 } 14324 return ActivityManager.USER_OP_SUCCESS; 14325 } 14326 14327 if (callback != null) { 14328 uss.mStopCallbacks.add(callback); 14329 } 14330 14331 if (uss.mState != UserStartedState.STATE_STOPPING) { 14332 uss.mState = UserStartedState.STATE_STOPPING; 14333 14334 long ident = Binder.clearCallingIdentity(); 14335 try { 14336 // Inform of user switch 14337 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14338 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14339 @Override 14340 public void performReceive(Intent intent, int resultCode, String data, 14341 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14342 finishUserStop(uss); 14343 } 14344 }; 14345 broadcastIntentLocked(null, null, intent, 14346 null, resultReceiver, 0, null, null, null, 14347 true, false, MY_PID, Process.SYSTEM_UID, userId); 14348 } finally { 14349 Binder.restoreCallingIdentity(ident); 14350 } 14351 } 14352 14353 return ActivityManager.USER_OP_SUCCESS; 14354 } 14355 14356 void finishUserStop(UserStartedState uss) { 14357 final int userId = uss.mHandle.getIdentifier(); 14358 boolean stopped; 14359 ArrayList<IStopUserCallback> callbacks; 14360 synchronized (this) { 14361 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14362 if (uss.mState != UserStartedState.STATE_STOPPING 14363 || mStartedUsers.get(userId) != uss) { 14364 stopped = false; 14365 } else { 14366 stopped = true; 14367 // User can no longer run. 14368 mStartedUsers.remove(userId); 14369 mUserLru.remove(Integer.valueOf(userId)); 14370 updateStartedUserArrayLocked(); 14371 14372 // Clean up all state and processes associated with the user. 14373 // Kill all the processes for the user. 14374 forceStopUserLocked(userId); 14375 } 14376 } 14377 14378 for (int i=0; i<callbacks.size(); i++) { 14379 try { 14380 if (stopped) callbacks.get(i).userStopped(userId); 14381 else callbacks.get(i).userStopAborted(userId); 14382 } catch (RemoteException e) { 14383 } 14384 } 14385 } 14386 14387 @Override 14388 public UserInfo getCurrentUser() { 14389 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14390 != PackageManager.PERMISSION_GRANTED) && ( 14391 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14392 != PackageManager.PERMISSION_GRANTED)) { 14393 String msg = "Permission Denial: getCurrentUser() from pid=" 14394 + Binder.getCallingPid() 14395 + ", uid=" + Binder.getCallingUid() 14396 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14397 Slog.w(TAG, msg); 14398 throw new SecurityException(msg); 14399 } 14400 synchronized (this) { 14401 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14402 } 14403 } 14404 14405 int getCurrentUserIdLocked() { 14406 return mCurrentUserId; 14407 } 14408 14409 @Override 14410 public boolean isUserRunning(int userId) { 14411 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14412 != PackageManager.PERMISSION_GRANTED) { 14413 String msg = "Permission Denial: isUserRunning() from pid=" 14414 + Binder.getCallingPid() 14415 + ", uid=" + Binder.getCallingUid() 14416 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14417 Slog.w(TAG, msg); 14418 throw new SecurityException(msg); 14419 } 14420 synchronized (this) { 14421 return isUserRunningLocked(userId); 14422 } 14423 } 14424 14425 boolean isUserRunningLocked(int userId) { 14426 UserStartedState state = mStartedUsers.get(userId); 14427 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14428 } 14429 14430 @Override 14431 public int[] getRunningUserIds() { 14432 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14433 != PackageManager.PERMISSION_GRANTED) { 14434 String msg = "Permission Denial: isUserRunning() from pid=" 14435 + Binder.getCallingPid() 14436 + ", uid=" + Binder.getCallingUid() 14437 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14438 Slog.w(TAG, msg); 14439 throw new SecurityException(msg); 14440 } 14441 synchronized (this) { 14442 return mStartedUserArray; 14443 } 14444 } 14445 14446 private void updateStartedUserArrayLocked() { 14447 mStartedUserArray = new int[mStartedUsers.size()]; 14448 for (int i=0; i<mStartedUsers.size(); i++) { 14449 mStartedUserArray[i] = mStartedUsers.keyAt(i); 14450 } 14451 } 14452 14453 @Override 14454 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14455 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14456 != PackageManager.PERMISSION_GRANTED) { 14457 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14458 + Binder.getCallingPid() 14459 + ", uid=" + Binder.getCallingUid() 14460 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14461 Slog.w(TAG, msg); 14462 throw new SecurityException(msg); 14463 } 14464 14465 mUserSwitchObservers.register(observer); 14466 } 14467 14468 @Override 14469 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14470 mUserSwitchObservers.unregister(observer); 14471 } 14472 14473 private boolean userExists(int userId) { 14474 if (userId == 0) { 14475 return true; 14476 } 14477 UserManagerService ums = getUserManagerLocked(); 14478 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14479 } 14480 14481 int[] getUsersLocked() { 14482 UserManagerService ums = getUserManagerLocked(); 14483 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14484 } 14485 14486 UserManagerService getUserManagerLocked() { 14487 if (mUserManager == null) { 14488 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14489 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14490 } 14491 return mUserManager; 14492 } 14493 14494 private void checkValidCaller(int uid, int userId) { 14495 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14496 14497 throw new SecurityException("Caller uid=" + uid 14498 + " is not privileged to communicate with user=" + userId); 14499 } 14500 14501 private int applyUserId(int uid, int userId) { 14502 return UserHandle.getUid(userId, uid); 14503 } 14504 14505 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14506 if (info == null) return null; 14507 ApplicationInfo newInfo = new ApplicationInfo(info); 14508 newInfo.uid = applyUserId(info.uid, userId); 14509 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14510 + info.packageName; 14511 return newInfo; 14512 } 14513 14514 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14515 if (aInfo == null 14516 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14517 return aInfo; 14518 } 14519 14520 ActivityInfo info = new ActivityInfo(aInfo); 14521 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14522 return info; 14523 } 14524} 14525